diff --git a/DEPS b/DEPS index 5b093d18..ed216bbb 100644 --- a/DEPS +++ b/DEPS
@@ -209,11 +209,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '658d96662bc8b4a19cbd4c775e21ddde176f3d5d', + 'skia_revision': '2a63f82422744f3e5a813de74f05e5e7282e3388', # 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': 'bc9b57bdb0f2bc2896d490b13fa3b8cf4c6e1d1a', + 'v8_revision': '60368d5347ca37d070e7592f9cbba494f2cb2ec2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -221,11 +221,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '2622c7b049cd394eca9b12edddfb0bbe8c110475', + 'angle_revision': 'ce7d80bd43eba819b9b895a80327cb5cade28b8a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '9dd7a5171793ca09a52bb5c9037a759f1e0b1ffa', + 'swiftshader_revision': '21c3054afcd01aa1f142b91a965063abd563bcda', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -280,7 +280,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'e83a92e7b8e7dc762352103a1b6103f0313255ca', + 'catapult_revision': '8f9ae5d5d3347e0f1cc08b54272dfe7e0b4b0700', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -288,7 +288,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '07f7a07998c03b022c963ba8d286782189372186', + 'devtools_frontend_revision': '045d6a80fb823342232c991069a80cad50041b64', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -1332,7 +1332,7 @@ Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '3dd5b80bc4f172dd82925bb259cb7c82348409c5', 'src/third_party/openscreen/src': - Var('chromium_git') + '/openscreen' + '@' + '6e5b900796102a16ef85f69ad4f7ef228d662219', + Var('chromium_git') + '/openscreen' + '@' + 'cacde3327295076c1e93d772ca38b115cf93bbd4', 'src/third_party/openxr/src': { 'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + '97cfe495bb7a3853266b646d1c79e169387f9c7a', @@ -1349,7 +1349,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'e46c9b802f8761df0341aad1d7845b7732a48596', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'b3f455e9edced2a776ddcb5a2cdf5ddcefa8776f', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1430,7 +1430,7 @@ 'version': 'r2LsKQPbfi0NYEO8tfocwaJ1MMACXPDLkgCI0IjJq-YC' }, ], - 'condition': 'host_os == "linux" and checkout_fuchsia', + 'condition': 'host_os == "linux" and checkout_fuchsia_for_arm64_host', 'dep_type': 'cipd', }, @@ -1547,7 +1547,7 @@ 'src/third_party/usrsctp/usrsctplib': Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '22ba62ffe79c3881581ab430368bf3764d9533eb', - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@c47e201b15037753c0a089c09d561328b1e2b8ca', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@8ea5e4dc6455225072461adbb756c3e4f7c2b699', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + '732a76d9d3c70d6aa487216495eeb28518349c3a', @@ -1635,7 +1635,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@ff155bec5f1fab5084ac9735280fead01162d13a', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0cd4c506f8dd630e83a2e219bb8bd7ec97a46d2b', 'condition': 'checkout_src_internal', },
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index b43cbb49..2d8512a 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1784,6 +1784,7 @@ public_deps = [ "//ash/public/cpp", + "//ash/public/cpp/app_list/vector_icons:vector_icons", "//ash/public/cpp/resources:ash_public_unscaled_resources", "//ash/resources/vector_icons", "//ash/strings",
diff --git a/ash/app_list/bubble/app_list_bubble_view.cc b/ash/app_list/bubble/app_list_bubble_view.cc index c002aab..1983031 100644 --- a/ash/app_list/bubble/app_list_bubble_view.cc +++ b/ash/app_list/bubble/app_list_bubble_view.cc
@@ -13,6 +13,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" +#include "ash/style/ash_color_provider.h" #include "base/bind.h" #include "base/i18n/rtl.h" #include "ui/base/ui_base_types.h" @@ -78,6 +79,11 @@ set_parent_window( Shell::GetContainer(root_window, kShellWindowId_AppListContainer)); + // TODO(https://crbug.com/1204551): Add transparency and rounded corners. + // See TrayBubbleView and BubbleBorder. + set_color(AshColorProvider::Get()->GetBaseLayerColor( + AshColorProvider::BaseLayerType::kOpaque)); + auto* layout = SetLayoutManager( std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical)); layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kStretch);
diff --git a/ash/app_list/bubble/bubble_apps_page.cc b/ash/app_list/bubble/bubble_apps_page.cc index 5b450941..97e70b2 100644 --- a/ash/app_list/bubble/bubble_apps_page.cc +++ b/ash/app_list/bubble/bubble_apps_page.cc
@@ -6,10 +6,13 @@ #include <limits> #include <memory> +#include <string> #include <utility> #include "ash/app_list/bubble/scrollable_apps_grid_view.h" +#include "ash/bubble/bubble_utils.h" #include "base/check.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/text_constants.h" #include "ui/views/controls/label.h" #include "ui/views/controls/scroll_view.h" @@ -19,6 +22,15 @@ using views::BoxLayout; namespace ash { +namespace { + +std::unique_ptr<views::Label> CreateLabel(const std::u16string& text) { + auto label = std::make_unique<views::Label>(text); + bubble_utils::ApplyStyle(label.get(), bubble_utils::LabelStyle::kBody); + return label; +} + +} // namespace BubbleAppsPage::BubbleAppsPage(AppListViewDelegate* view_delegate) { DCHECK(view_delegate); @@ -31,6 +43,8 @@ scroll->SetDrawOverflowIndicator(false); scroll->SetHorizontalScrollBarMode( views::ScrollView::ScrollBarMode::kDisabled); + // Don't paint a background. The bubble already has one. + scroll->SetBackgroundColor(absl::nullopt); auto scroll_contents = std::make_unique<views::View>(); auto* layout = scroll_contents->SetLayoutManager( @@ -39,8 +53,7 @@ // TODO(https://crbug.com/1204551): Localized strings. // TODO(https://crbug.com/1204551): Styling. - auto* continue_label = - scroll_contents->AddChildView(std::make_unique<views::Label>(u"Label")); + auto* continue_label = scroll_contents->AddChildView(CreateLabel(u"Label")); continue_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); auto* continue_section = @@ -54,7 +67,7 @@ continue_layout->set_cross_axis_alignment( BoxLayout::CrossAxisAlignment::kStretch); for (int i = 0; i < 4; ++i) { - continue_section->AddChildView(std::make_unique<views::Label>(u"Item")); + continue_section->AddChildView(CreateLabel(u"Item")); } // TODO(https://crbug.com/1204551): Replace with real recent apps view. @@ -68,7 +81,7 @@ recent_apps_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); for (int i = 0; i < 5; ++i) { - recent_apps->AddChildView(std::make_unique<views::Label>(u"Item")); + recent_apps->AddChildView(CreateLabel(u"Item")); } // All apps section.
diff --git a/ash/app_list/bubble/bubble_search_page.cc b/ash/app_list/bubble/bubble_search_page.cc index e00e4b7f..5c0e836 100644 --- a/ash/app_list/bubble/bubble_search_page.cc +++ b/ash/app_list/bubble/bubble_search_page.cc
@@ -8,6 +8,8 @@ #include <memory> #include <utility> +#include "ash/bubble/bubble_utils.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/views/controls/label.h" #include "ui/views/controls/scroll_view.h" #include "ui/views/layout/box_layout.h" @@ -25,6 +27,8 @@ scroll->SetDrawOverflowIndicator(false); scroll->SetHorizontalScrollBarMode( views::ScrollView::ScrollBarMode::kDisabled); + // Don't paint a background. The bubble already has one. + scroll->SetBackgroundColor(absl::nullopt); auto scroll_contents = std::make_unique<views::View>(); scroll_contents->SetLayoutManager( @@ -38,7 +42,9 @@ results->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical, gfx::Insets(), kSpacing)); for (int i = 0; i < 20; ++i) { - results->AddChildView(std::make_unique<views::Label>(u"Result")); + auto label = std::make_unique<views::Label>(u"Result"); + bubble_utils::ApplyStyle(label.get(), bubble_utils::LabelStyle::kBody); + results->AddChildView(std::move(label)); } scroll->SetContents(std::move(scroll_contents));
diff --git a/ash/bubble/bubble_utils.cc b/ash/bubble/bubble_utils.cc index 51149c2..f6f97a5 100644 --- a/ash/bubble/bubble_utils.cc +++ b/ash/bubble/bubble_utils.cc
@@ -4,17 +4,51 @@ #include "ash/bubble/bubble_utils.h" +#include <memory> + #include "ash/capture_mode/capture_mode_util.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/root_window_controller.h" #include "ash/shell.h" +#include "ash/style/ash_color_provider.h" +#include "base/bind.h" +#include "base/callback.h" #include "base/check.h" #include "ui/aura/window.h" #include "ui/events/event.h" #include "ui/events/types/event_type.h" +#include "ui/views/controls/label.h" namespace ash { namespace bubble_utils { +namespace { + +// A label which invokes a constructor-specified callback in `OnThemeChanged()`. +class LabelWithThemeChangedCallback : public views::Label { + public: + using ThemeChangedCallback = base::RepeatingCallback<void(views::Label*)>; + + LabelWithThemeChangedCallback(const std::u16string& text, + ThemeChangedCallback theme_changed_callback) + : views::Label(text), + theme_changed_callback_(std::move(theme_changed_callback)) {} + + LabelWithThemeChangedCallback(const LabelWithThemeChangedCallback&) = delete; + LabelWithThemeChangedCallback& operator=( + const LabelWithThemeChangedCallback&) = delete; + ~LabelWithThemeChangedCallback() override = default; + + private: + // views::Label: + void OnThemeChanged() override { + views::Label::OnThemeChanged(); + theme_changed_callback_.Run(this); + } + + ThemeChangedCallback theme_changed_callback_; +}; + +} // namespace bool ShouldCloseBubbleForEvent(const ui::LocatedEvent& event) { // Should only be called for "press" type events. @@ -60,5 +94,47 @@ return true; } +void ApplyStyle(views::Label* label, LabelStyle style) { + label->SetAutoColorReadabilityEnabled(false); + label->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor( + AshColorProvider::ContentLayerType::kTextColorPrimary)); + + switch (style) { + case LabelStyle::kBadge: + label->SetFontList(gfx::FontList({"Roboto"}, gfx::Font::NORMAL, 14, + gfx::Font::Weight::MEDIUM)); + break; + case LabelStyle::kBody: + label->SetFontList(gfx::FontList({"Roboto"}, gfx::Font::NORMAL, 14, + gfx::Font::Weight::NORMAL)); + break; + case LabelStyle::kChip: + label->SetFontList(gfx::FontList({"Roboto"}, gfx::Font::NORMAL, 13, + gfx::Font::Weight::NORMAL)); + break; + case LabelStyle::kHeader: + label->SetFontList(gfx::FontList({"Roboto"}, gfx::Font::NORMAL, 16, + gfx::Font::Weight::MEDIUM)); + break; + } +} + +std::unique_ptr<views::Label> CreateLabel(LabelStyle style, + const std::u16string& text) { + auto label = std::make_unique<LabelWithThemeChangedCallback>( + text, + /*theme_changed_callback=*/base::BindRepeating( + [](LabelStyle style, views::Label* label) { + ApplyStyle(label, style); + }, + style)); + // Apply `style` to `label` manually in case the view is painted without ever + // having being added to the view hierarchy. In such cases, the `label` will + // not receive an `OnThemeChanged()` event. This occurs, for example, with + // holding space drag images. + ApplyStyle(label.get(), style); + return label; +} + } // namespace bubble_utils } // namespace ash
diff --git a/ash/bubble/bubble_utils.h b/ash/bubble/bubble_utils.h index aee494c7..69bcb60c 100644 --- a/ash/bubble/bubble_utils.h +++ b/ash/bubble/bubble_utils.h
@@ -5,12 +5,19 @@ #ifndef ASH_BUBBLE_BUBBLE_UTILS_H_ #define ASH_BUBBLE_BUBBLE_UTILS_H_ +#include <memory> +#include <string> + #include "ash/ash_export.h" namespace ui { class LocatedEvent; } // namespace ui +namespace views { +class Label; +} // namespace views + namespace ash { namespace bubble_utils { @@ -20,6 +27,23 @@ // bubble will close and immediately reopen). ASH_EXPORT bool ShouldCloseBubbleForEvent(const ui::LocatedEvent& event); +// Enumeration of supported label styles. +enum class LabelStyle { + kBadge, + kBody, + kChip, + kHeader, +}; + +// Applies the specified `style` to the given `label`. +ASH_EXPORT void ApplyStyle(views::Label* label, LabelStyle style); + +// Creates a label with optional `text` matching the specified `style`. The +// label will paint correctly even if it is not added to the view hierarchy. +std::unique_ptr<views::Label> CreateLabel( + LabelStyle style, + const std::u16string& text = std::u16string()); + } // namespace bubble_utils } // namespace ash
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 218a4f6f..331e399 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -650,7 +650,7 @@ // Enables or disables sticky settings in the Scan app. const base::Feature kScanAppStickySettings{"ScanAppStickySettings", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Enables or disables long kill timeout for session manager daemon. When // enabled, session manager daemon waits for a longer time (e.g. 12s) for chrome
diff --git a/ash/content/common/resources/navigation_selector.html b/ash/content/common/resources/navigation_selector.html index cc526678..7ab70008 100644 --- a/ash/content/common/resources/navigation_selector.html +++ b/ash/content/common/resources/navigation_selector.html
@@ -52,7 +52,8 @@ <div id="navigationSelectorMenu"> <template id="menuItems" is="dom-repeat" items="{{menuItems}}"> <template is="dom-if" if="[[!isCollapsible_(item)]]"> - <div class="navigation-item" tabindex="0" on-click="onSelected_"> + <div class$="{{computeInitialClass_(item.selectorItem)}}" tabindex="0" + on-click="onSelected_"> <iron-icon class="icon" icon="[[item.selectorItem.icon]]" alt=""> </iron-icon> [[item.selectorItem.name]] @@ -65,7 +66,7 @@ <iron-collapse opened="[[item.properties.isExpanded]]"> <template class="collapsed-list" is="dom-repeat" items="{{item.properties.subMenuItems}}"> - <div class="navigation-item nested-item" tabindex="0" + <div class$="{{computeInitialClass_(item)}}" tabindex="0" on-click="onNestedSelected_"> <iron-icon class="icon" icon="[[getIcon_(item)]]" alt=""> </iron-icon>
diff --git a/ash/content/common/resources/navigation_selector.js b/ash/content/common/resources/navigation_selector.js index 17f4dd20..cd88f80 100644 --- a/ash/content/common/resources/navigation_selector.js +++ b/ash/content/common/resources/navigation_selector.js
@@ -152,6 +152,20 @@ getIcon_(item) { return item.icon; } + + /** + * @param {!SelectorItem} item + * @return {string} + * @protected + */ + computeInitialClass_(item) { + let classList = "navigation-item"; + if (!!this.selectedItem && item.name == this.selectedItem.name) { + // Add the initial .selected class to the currently selected entry. + classList += " selected"; + } + return classList; + } } customElements.define(NavigationSelectorElement.is, NavigationSelectorElement); \ No newline at end of file
diff --git a/ash/content/shimless_rma/resources/onboarding_update_page.html b/ash/content/shimless_rma/resources/onboarding_update_page.html index c18d8da..d8fb1a8 100644 --- a/ash/content/shimless_rma/resources/onboarding_update_page.html +++ b/ash/content/shimless_rma/resources/onboarding_update_page.html
@@ -12,12 +12,12 @@ </p> <p hidden$="{{!checkInProgress_}}">Checking OS version...</p> <cr-button disabled="{{checkInProgress_}}" - hidden$="{{updateCheckBtnHidden_(networkAvailable, updateAvailable_)}}" - id="checkUpdate" on-click="onUpdateCheckBtnClicked_"> + hidden$="{{updateCheckButtonHidden_(networkAvailable, updateAvailable_)}}" + id="checkUpdate" on-click="onUpdateCheckButtonClicked_"> Check for updates </cr-button> <cr-button hidden$="{{!updateAvailable_}}" - id="performUpdate" on-click="onUpdateBtnClicked_"> + id="performUpdate" on-click="onUpdateButtonClicked_"> Update version and restart </cr-button> </div>
diff --git a/ash/content/shimless_rma/resources/onboarding_update_page.js b/ash/content/shimless_rma/resources/onboarding_update_page.js index 9401520..845ff63 100644 --- a/ash/content/shimless_rma/resources/onboarding_update_page.js +++ b/ash/content/shimless_rma/resources/onboarding_update_page.js
@@ -102,7 +102,7 @@ } /** @protected */ - onUpdateCheckBtnClicked_() { + onUpdateCheckButtonClicked_() { this.checkInProgress_ = true; this.shimlessRmaService_.checkForChromeUpdates().then((res) => { if (res.updateAvailable) { @@ -120,14 +120,14 @@ } /** @protected */ - onUpdateBtnClicked_() { + onUpdateButtonClicked_() { // TODO(joonbug): trigger update } /** * @protected */ - updateCheckBtnHidden_() { + updateCheckButtonHidden_() { return !this.networkAvailable || this.updateAvailable_; } };
diff --git a/ash/content/shimless_rma/resources/shimless_rma.html b/ash/content/shimless_rma/resources/shimless_rma.html index 7d340c5..02c5689 100644 --- a/ash/content/shimless_rma/resources/shimless_rma.html +++ b/ash/content/shimless_rma/resources/shimless_rma.html
@@ -2,10 +2,10 @@ </style> <div id="shimlessRMAContainer"> <div class="shimlessHeader"> - <cr-button - id="back" on-click="onBackBtnClicked_" - disabled="[[isBtnDisabled_(currentPage_.btnBack)]]" - hidden$="[[isBtnHidden_(currentPage_.btnBack)]]"> + <cr-button + id="back" on-click="onBackButtonClicked_" + disabled="[[isButtonDisabled_(currentPage_.buttonBack)]]" + hidden$="[[isButtonHidden_(currentPage_.buttonBack)]]"> Back </cr-button> </div> @@ -13,15 +13,15 @@ <div id="contentContainer"></div> <div class="shimlessFooter"> <cr-button - id="cancel" on-click="onCancelBtnClicked_" - disabled="[[isBtnDisabled_(currentPage_.btnCancel)]]" - hidden$="[[isBtnHidden_(currentPage_.btnCancel)]]"> + id="cancel" on-click="onCancelButtonClicked_" + disabled="[[isButtonDisabled_(currentPage_.buttonCancel)]]" + hidden$="[[isButtonHidden_(currentPage_.buttonCancel)]]"> Cancel </cr-button> <cr-button - id="next" on-click="onNextBtnClicked_" - disabled="[[isBtnDisabled_(currentPage_.btnNext)]]" - hidden$="[[isBtnHidden_(currentPage_.btnNext)]]"> + id="next" on-click="onNextButtonClicked_" + disabled="[[isButtonDisabled_(currentPage_.buttonNext)]]" + hidden$="[[isButtonHidden_(currentPage_.buttonNext)]]"> Next </cr-button> </div>
diff --git a/ash/content/shimless_rma/resources/shimless_rma.js b/ash/content/shimless_rma/resources/shimless_rma.js index b1e07640..081d95df 100644 --- a/ash/content/shimless_rma/resources/shimless_rma.js +++ b/ash/content/shimless_rma/resources/shimless_rma.js
@@ -17,7 +17,7 @@ * Enum for button states. * @enum {string} */ -export const BtnState = { +export const ButtonState = { VISIBLE: 'visible', DISABLED: 'disable', HIDDEN: 'hidden' @@ -26,10 +26,10 @@ /** * @typedef {{ * componentIs: string, - * btnNext: !BtnState, - * btnNextLabel: string, - * btnCancel: !BtnState, - * btnBack: !BtnState, + * buttonNext: !ButtonState, + * buttonNextLabel: string, + * buttonCancel: !ButtonState, + * buttonBack: !ButtonState, * }} */ let PageInfo; @@ -40,28 +40,28 @@ const StateComponentMapping = { [RmaState.kUnknown]: { componentIs: 'badcomponent', - btnNext: BtnState.HIDDEN, - btnCancel: BtnState.VISIBLE, - btnBack: BtnState.HIDDEN, + buttonNext: ButtonState.HIDDEN, + buttonCancel: ButtonState.VISIBLE, + buttonBack: ButtonState.HIDDEN, }, [RmaState.kWelcomeScreen]: { componentIs: 'onboarding-landing-page', - btnNext: BtnState.VISIBLE, - btnCancel: BtnState.VISIBLE, - btnBack: BtnState.HIDDEN, + buttonNext: ButtonState.VISIBLE, + buttonCancel: ButtonState.VISIBLE, + buttonBack: ButtonState.HIDDEN, }, // TODO(joonbug): update to correct RmaState [RmaState.kSelectComponents]: { componentIs: 'onboarding-update-page', - btnNext: BtnState.HIDDEN, - btnCancel: BtnState.VISIBLE, - btnBack: BtnState.VISIBLE, + buttonNext: ButtonState.HIDDEN, + buttonCancel: ButtonState.VISIBLE, + buttonBack: ButtonState.VISIBLE, }, [RmaState.kUpdateChrome]: { componentIs: 'onboarding-update-page', - btnNext: BtnState.HIDDEN, - btnCancel: BtnState.VISIBLE, - btnBack: BtnState.VISIBLE, + buttonNext: ButtonState.HIDDEN, + buttonCancel: ButtonState.VISIBLE, + buttonBack: ButtonState.VISIBLE, }, }; @@ -190,38 +190,38 @@ } /** @protected */ - isBtnHidden_(btn) { - return btn === 'hidden'; + isButtonHidden_(button) { + return button === 'hidden'; } /** @protected */ - isBtnDisabled_(btn) { - return btn === 'disabled'; + isButtonDisabled_(button) { + return button === 'disabled'; } /** - * @param {string} btnName - * @param {!BtnState} btnState + * @param {string} buttonName + * @param {!ButtonState} buttonState */ - updateBtnState(btnName, btnState) { - assert(this.currentPage_.hasOwnProperty(btnName)); - this.set(`currentPage_.${btnName}`, btnState); + updateButtonState(buttonName, buttonState) { + assert(this.currentPage_.hasOwnProperty(buttonName)); + this.set(`currentPage_.${buttonName}`, buttonState); } /** @protected */ - onBackBtnClicked_() { + onBackButtonClicked_() { // TODO(joonbug): error handling based on state.error this.fetchPrevState_().then((state) => this.loadState_(state.prevState)); } /** @protected */ - onNextBtnClicked_() { + onNextButtonClicked_() { const page = this.shadowRoot.querySelector(this.currentPage_.componentIs); assert(page); // Acquire promise to check whether current page is ready for next page. const prepPageAdvance = - page.onNextBtnClick || (() => Promise.resolve(RmaState.kUnknown)); + page.onNextButtonClick || (() => Promise.resolve(RmaState.kUnknown)); assert(typeof prepPageAdvance === 'function'); prepPageAdvance() @@ -233,7 +233,7 @@ } /** @protected */ - onCancelBtnClicked_() { + onCancelButtonClicked_() { this.loadState_(assert(this.initialState_)); } };
diff --git a/ash/fast_ink/view_tree_host_root_view.cc b/ash/fast_ink/view_tree_host_root_view.cc index d1c7254..8786ee0 100644 --- a/ash/fast_ink/view_tree_host_root_view.cc +++ b/ash/fast_ink/view_tree_host_root_view.cc
@@ -300,8 +300,10 @@ } ViewTreeHostRootView::~ViewTreeHostRootView() { - LayerTreeViewTreeFrameSinkHolder::DeleteWhenLastResourceHasBeenReclaimed( - std::move(frame_sink_holder_)); + if (frame_sink_holder_) { + LayerTreeViewTreeFrameSinkHolder::DeleteWhenLastResourceHasBeenReclaimed( + std::move(frame_sink_holder_)); + } } void ViewTreeHostRootView::Paint() {
diff --git a/ash/quick_answers/quick_answers_ui_controller.cc b/ash/quick_answers/quick_answers_ui_controller.cc index fd58ff44..795b1a6a 100644 --- a/ash/quick_answers/quick_answers_ui_controller.cc +++ b/ash/quick_answers/quick_answers_ui_controller.cc
@@ -4,7 +4,9 @@ #include "ash/quick_answers/quick_answers_ui_controller.h" +#include "ash/constants/ash_features.h" #include "ash/public/cpp/assistant/controller/assistant_interaction_controller.h" +#include "ash/public/cpp/new_window_delegate.h" #include "ash/quick_answers/quick_answers_controller_impl.h" #include "ash/quick_answers/ui/quick_answers_view.h" #include "ash/quick_answers/ui/user_notice_view.h" @@ -14,6 +16,7 @@ #include "chromeos/components/quick_answers/quick_answers_model.h" #include "chromeos/services/assistant/public/cpp/assistant_service.h" #include "mojo/public/cpp/bindings/remote.h" +#include "net/base/escape.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/aura/client/aura_constants.h" #include "ui/base/l10n/l10n_util.h" @@ -22,6 +25,12 @@ using chromeos::quick_answers::QuickAnswer; namespace ash { +namespace { + +constexpr char kGoogleSearchUrlPrefix[] = "https://www.google.com/search?q="; + +} // namespace + QuickAnswersUiController::QuickAnswersUiController( QuickAnswersControllerImpl* controller) : controller_(controller) {} @@ -53,9 +62,16 @@ // Route dismissal through |controller_| for logging impressions. controller_->DismissQuickAnswers(/*is_active=*/true); - ash::AssistantInteractionController::Get()->StartTextInteraction( - query_, /*allow_tts=*/false, - chromeos::assistant::AssistantQuerySource::kQuickAnswers); + if (chromeos::features::IsQuickAnswersStandaloneSettingsEnabled()) { + NewWindowDelegate::GetInstance()->NewTabWithUrl( + GURL(kGoogleSearchUrlPrefix + + net::EscapeUrlEncodedData(query_, /*use_plus=*/true)), + /*from_user_interaction=*/true); + } else { + ash::AssistantInteractionController::Get()->StartTextInteraction( + query_, /*allow_tts=*/false, + chromeos::assistant::AssistantQuerySource::kQuickAnswers); + } controller_->OnQuickAnswerClick(); }
diff --git a/ash/quick_answers/ui/quick_answers_view.cc b/ash/quick_answers/ui/quick_answers_view.cc index c5caa58e..2db2d84 100644 --- a/ash/quick_answers/ui/quick_answers_view.cc +++ b/ash/quick_answers/ui/quick_answers_view.cc
@@ -5,6 +5,7 @@ #include "ash/quick_answers/ui/quick_answers_view.h" #include "ash/constants/ash_features.h" +#include "ash/public/cpp/app_list/vector_icons/vector_icons.h" #include "ash/public/cpp/assistant/assistant_interface_binder.h" #include "ash/quick_answers/quick_answers_ui_controller.h" #include "ash/quick_answers/ui/quick_answers_pre_target_handler.h" @@ -55,6 +56,10 @@ constexpr int kAssistantIconSizeDip = 16; constexpr gfx::Insets kAssistantIconInsets(10, 10, 0, 8); +// Google icon. +constexpr int kGoogleIconSizeDip = 16; +constexpr gfx::Insets kGoogleIconInsets(10, 10, 0, 8); + // Spacing between lines in the main view. constexpr int kLineSpacingDip = 4; constexpr int kLineHeightDip = 20; @@ -283,6 +288,15 @@ chromeos::kAssistantIcon, kAssistantIconSizeDip, gfx::kPlaceholderColor)); } +void QuickAnswersView::AddGoogleIcon() { + // Add Google icon. + auto* google_icon = + main_view_->AddChildView(std::make_unique<views::ImageView>()); + google_icon->SetBorder(views::CreateEmptyBorder(kGoogleIconInsets)); + google_icon->SetImage(gfx::CreateVectorIcon( + kGoogleColorIcon, kGoogleIconSizeDip, gfx::kPlaceholderColor)); +} + void QuickAnswersView::AddDogfoodButton() { auto* dogfood_view = AddChildView(std::make_unique<View>()); auto* layout = @@ -334,8 +348,12 @@ layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStart); - // Add Assistant icon. - AddAssistantIcon(); + // Add branding icon. + if (chromeos::features::IsQuickAnswersStandaloneSettingsEnabled()) { + AddGoogleIcon(); + } else { + AddAssistantIcon(); + } // Add content view. content_view_ = main_view_->AddChildView(std::make_unique<View>());
diff --git a/ash/quick_answers/ui/quick_answers_view.h b/ash/quick_answers/ui/quick_answers_view.h index 22e91035..926c681 100644 --- a/ash/quick_answers/ui/quick_answers_view.h +++ b/ash/quick_answers/ui/quick_answers_view.h
@@ -68,6 +68,7 @@ void AddDogfoodButton(); void AddSettingsButton(); void AddAssistantIcon(); + void AddGoogleIcon(); void ResetContentView(); void SetBackgroundState(bool highlight); void UpdateBounds();
diff --git a/ash/system/holding_space/downloads_section.cc b/ash/system/holding_space/downloads_section.cc index 648e364..580cd03d7 100644 --- a/ash/system/holding_space/downloads_section.cc +++ b/ash/system/holding_space/downloads_section.cc
@@ -4,6 +4,7 @@ #include "ash/system/holding_space/downloads_section.h" +#include "ash/bubble/bubble_utils.h" #include "ash/public/cpp/holding_space/holding_space_client.h" #include "ash/public/cpp/holding_space/holding_space_constants.h" #include "ash/public/cpp/holding_space/holding_space_controller.h" @@ -13,7 +14,6 @@ #include "ash/style/ash_color_provider.h" #include "ash/system/holding_space/holding_space_item_chip_view.h" #include "ash/system/holding_space/holding_space_item_chips_container.h" -#include "ash/system/holding_space/holding_space_util.h" #include "base/bind.h" #include "base/callback_helpers.h" #include "ui/base/l10n/l10n_util.h" @@ -66,8 +66,8 @@ kHoldingSpaceDownloadsHeaderSpacing)); // Label. - auto* label = AddChildView(holding_space_util::CreateLabel( - holding_space_util::LabelStyle::kHeader, + auto* label = AddChildView(bubble_utils::CreateLabel( + bubble_utils::LabelStyle::kHeader, l10n_util::GetStringUTF16(IDS_ASH_HOLDING_SPACE_DOWNLOADS_TITLE))); label->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); layout->SetFlexForView(label, 1);
diff --git a/ash/system/holding_space/holding_space_drag_util.cc b/ash/system/holding_space/holding_space_drag_util.cc index ff99388..a9621df6 100644 --- a/ash/system/holding_space/holding_space_drag_util.cc +++ b/ash/system/holding_space/holding_space_drag_util.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "ash/bubble/bubble_utils.h" #include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/holding_space/holding_space_image.h" #include "ash/public/cpp/holding_space/holding_space_item.h" @@ -13,7 +14,6 @@ #include "ash/style/ash_color_provider.h" #include "ash/style/scoped_light_mode_as_default.h" #include "ash/system/holding_space/holding_space_item_view.h" -#include "ash/system/holding_space/holding_space_util.h" #include "base/containers/adapters.h" #include "base/i18n/rtl.h" #include "ui/compositor/canvas_painter.h" @@ -223,7 +223,8 @@ // Label. ScopedLightModeAsDefault scoped_light_mode; - auto* label = AddChildView(CreateLabel(LabelStyle::kChip, item->text())); + auto* label = AddChildView(bubble_utils::CreateLabel( + bubble_utils::LabelStyle::kChip, item->text())); label->SetElideBehavior(gfx::ElideBehavior::ELIDE_MIDDLE); label->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); layout->SetFlexForView(label, 1); @@ -310,7 +311,8 @@ views::BoxLayout::MainAxisAlignment::kCenter); // Label. - auto* label = AddChildView(CreateLabel(LabelStyle::kBadge)); + auto* label = AddChildView( + bubble_utils::CreateLabel(bubble_utils::LabelStyle::kBadge)); label->SetEnabledColor(AshColorProvider::Get()->IsDarkModeEnabled() ? gfx::kGoogleGrey900 : gfx::kGoogleGrey200);
diff --git a/ash/system/holding_space/holding_space_item_chip_view.cc b/ash/system/holding_space/holding_space_item_chip_view.cc index 2c04acd..40f4e7a9 100644 --- a/ash/system/holding_space/holding_space_item_chip_view.cc +++ b/ash/system/holding_space/holding_space_item_chip_view.cc
@@ -6,12 +6,12 @@ #include <algorithm> +#include "ash/bubble/bubble_utils.h" #include "ash/public/cpp/holding_space/holding_space_constants.h" #include "ash/public/cpp/holding_space/holding_space_item.h" #include "ash/public/cpp/rounded_image_view.h" #include "ash/style/ash_color_provider.h" #include "ash/system/holding_space/holding_space_item_view.h" -#include "ash/system/holding_space/holding_space_util.h" #include "ash/system/holding_space/holding_space_view_delegate.h" #include "base/bind.h" #include "ui/base/metadata/metadata_impl_macros.h" @@ -124,7 +124,7 @@ label_->SetPaintToLayer(); label_->layer()->SetFillsBoundsOpaquely(false); - holding_space_util::ApplyStyle(label_, holding_space_util::LabelStyle::kChip); + bubble_utils::ApplyStyle(label_, bubble_utils::LabelStyle::kChip); // Pin. views::View* pin_button_container =
diff --git a/ash/system/holding_space/holding_space_util.cc b/ash/system/holding_space/holding_space_util.cc index 59d48fb..ccae26f 100644 --- a/ash/system/holding_space/holding_space_util.cc +++ b/ash/system/holding_space/holding_space_util.cc
@@ -4,8 +4,9 @@ #include "ash/system/holding_space/holding_space_util.h" -#include "ash/style/ash_color_provider.h" -#include "base/bind.h" +#include <memory> + +#include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animation_element.h" #include "ui/compositor/layer_animation_observer.h" @@ -13,8 +14,8 @@ #include "ui/compositor/layer_animator.h" #include "ui/gfx/canvas.h" #include "ui/views/background.h" -#include "ui/views/controls/label.h" #include "ui/views/painter.h" +#include "ui/views/view.h" namespace ash { namespace holding_space_util { @@ -62,33 +63,6 @@ const absl::optional<gfx::InsetsF> insets_; }; -// LabelWithThemeChangedCallback ----------------------------------------------- - -// A label which invokes a constructor-specified callback in `OnThemeChanged()`. -class LabelWithThemeChangedCallback : public views::Label { - public: - using ThemeChangedCallback = base::RepeatingCallback<void(views::Label*)>; - - LabelWithThemeChangedCallback(const std::u16string& text, - ThemeChangedCallback theme_changed_callback) - : views::Label(text), - theme_changed_callback_(std::move(theme_changed_callback)) {} - - LabelWithThemeChangedCallback(const LabelWithThemeChangedCallback&) = delete; - LabelWithThemeChangedCallback& operator=( - const LabelWithThemeChangedCallback&) = delete; - ~LabelWithThemeChangedCallback() override = default; - - private: - // views::Label: - void OnThemeChanged() override { - views::Label::OnThemeChanged(); - theme_changed_callback_.Run(this); - } - - ThemeChangedCallback theme_changed_callback_; -}; - // Helpers --------------------------------------------------------------------- // Creates a `ui::LayerAnimationSequence` for the specified `element` with @@ -148,48 +122,6 @@ observer); } -void ApplyStyle(views::Label* label, LabelStyle style) { - label->SetAutoColorReadabilityEnabled(false); - label->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor( - AshColorProvider::ContentLayerType::kTextColorPrimary)); - - switch (style) { - case LabelStyle::kBadge: - label->SetFontList(gfx::FontList({"Roboto"}, gfx::Font::NORMAL, 14, - gfx::Font::Weight::MEDIUM)); - break; - case LabelStyle::kBody: - label->SetFontList(gfx::FontList({"Roboto"}, gfx::Font::NORMAL, 14, - gfx::Font::Weight::NORMAL)); - break; - case LabelStyle::kChip: - label->SetFontList(gfx::FontList({"Roboto"}, gfx::Font::NORMAL, 13, - gfx::Font::Weight::NORMAL)); - break; - case LabelStyle::kHeader: - label->SetFontList(gfx::FontList({"Roboto"}, gfx::Font::NORMAL, 16, - gfx::Font::Weight::MEDIUM)); - break; - } -} - -std::unique_ptr<views::Label> CreateLabel(LabelStyle style, - const std::u16string& text) { - auto label = std::make_unique<LabelWithThemeChangedCallback>( - text, - /*theme_changed_callback=*/base::BindRepeating( - [](LabelStyle style, views::Label* label) { - ApplyStyle(label, style); - }, - style)); - // Apply `style` to `label` manually in case the view is painted without ever - // having being added to the view hierarchy. In such cases, the `label` will - // not receive an `OnThemeChanged()` event. This occurs, for example, with - // holding space drag images. - ApplyStyle(label.get(), style); - return label; -} - std::unique_ptr<views::Background> CreateCircleBackground(SkColor color, size_t fixed_size) { return views::CreateBackgroundFromPainter(
diff --git a/ash/system/holding_space/holding_space_util.h b/ash/system/holding_space/holding_space_util.h index f55d2b2..140a6ac 100644 --- a/ash/system/holding_space/holding_space_util.h +++ b/ash/system/holding_space/holding_space_util.h
@@ -5,7 +5,7 @@ #ifndef ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_UTIL_H_ #define ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_UTIL_H_ -#include <string> +#include <memory> #include "base/time/time.h" #include "third_party/skia/include/core/SkColor.h" @@ -17,7 +17,6 @@ namespace views { class Background; -class Label; class View; } // namespace views @@ -37,23 +36,6 @@ base::TimeDelta duration, ui::LayerAnimationObserver* observer); -// TODO(crbug.com/1199925): Move to ash typography. -// Enumeration of supported label styles. -enum class LabelStyle { - kBadge, - kBody, - kChip, - kHeader, -}; - -// Applies the specified `style` to the given `label`. -void ApplyStyle(views::Label* label, LabelStyle style); - -// Creates a label with optional `text` matching the specified `style`. -std::unique_ptr<views::Label> CreateLabel( - LabelStyle style, - const std::u16string& text = std::u16string()); - // Creates a circular background of the specified `color` and `fixed_size`. std::unique_ptr<views::Background> CreateCircleBackground(SkColor color, size_t fixed_size);
diff --git a/ash/system/holding_space/pinned_files_section.cc b/ash/system/holding_space/pinned_files_section.cc index c43f338..8614b89c 100644 --- a/ash/system/holding_space/pinned_files_section.cc +++ b/ash/system/holding_space/pinned_files_section.cc
@@ -4,6 +4,7 @@ #include "ash/system/holding_space/pinned_files_section.h" +#include "ash/bubble/bubble_utils.h" #include "ash/public/cpp/holding_space/holding_space_client.h" #include "ash/public/cpp/holding_space/holding_space_constants.h" #include "ash/public/cpp/holding_space/holding_space_controller.h" @@ -17,7 +18,6 @@ #include "ash/style/ash_color_provider.h" #include "ash/system/holding_space/holding_space_item_chip_view.h" #include "ash/system/holding_space/holding_space_item_chips_container.h" -#include "ash/system/holding_space/holding_space_util.h" #include "ash/system/holding_space/holding_space_view_delegate.h" #include "base/bind.h" #include "base/callback_helpers.h" @@ -113,7 +113,7 @@ // Label. auto* label = AddChildView( - holding_space_util::CreateLabel(holding_space_util::LabelStyle::kChip)); + bubble_utils::CreateLabel(bubble_utils::LabelStyle::kChip)); label->SetText(l10n_util::GetStringUTF16( IDS_ASH_HOLDING_SPACE_PINNED_FILES_APP_CHIP_TEXT)); layout->SetFlexForView(label, 1); @@ -154,8 +154,8 @@ } std::unique_ptr<views::View> PinnedFilesSection::CreateHeader() { - auto header = holding_space_util::CreateLabel( - holding_space_util::LabelStyle::kHeader, + auto header = bubble_utils::CreateLabel( + bubble_utils::LabelStyle::kHeader, l10n_util::GetStringUTF16(IDS_ASH_HOLDING_SPACE_PINNED_TITLE)); header->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); header->SetPaintToLayer(); @@ -193,8 +193,8 @@ views::BoxLayout::CrossAxisAlignment::kStart); // Prompt. - auto* prompt = placeholder->AddChildView(holding_space_util::CreateLabel( - holding_space_util::LabelStyle::kBody, + auto* prompt = placeholder->AddChildView(bubble_utils::CreateLabel( + bubble_utils::LabelStyle::kBody, l10n_util::GetStringUTF16(IDS_ASH_HOLDING_SPACE_PINNED_EMPTY_PROMPT))); prompt->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); prompt->SetMultiLine(true);
diff --git a/ash/system/holding_space/screen_captures_section.cc b/ash/system/holding_space/screen_captures_section.cc index 559e949..ed42760 100644 --- a/ash/system/holding_space/screen_captures_section.cc +++ b/ash/system/holding_space/screen_captures_section.cc
@@ -4,11 +4,11 @@ #include "ash/system/holding_space/screen_captures_section.h" +#include "ash/bubble/bubble_utils.h" #include "ash/public/cpp/holding_space/holding_space_constants.h" #include "ash/public/cpp/holding_space/holding_space_item.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/holding_space/holding_space_item_screen_capture_view.h" -#include "ash/system/holding_space/holding_space_util.h" #include "ui/base/l10n/l10n_util.h" #include "ui/compositor/layer.h" #include "ui/views/accessibility/view_accessibility.h" @@ -35,8 +35,8 @@ } std::unique_ptr<views::View> ScreenCapturesSection::CreateHeader() { - auto header = holding_space_util::CreateLabel( - holding_space_util::LabelStyle::kHeader, + auto header = bubble_utils::CreateLabel( + bubble_utils::LabelStyle::kHeader, l10n_util::GetStringUTF16(IDS_ASH_HOLDING_SPACE_SCREEN_CAPTURES_TITLE)); header->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); header->SetPaintToLayer();
diff --git a/ash/wm/window_cycle/window_cycle_list.cc b/ash/wm/window_cycle/window_cycle_list.cc index eca54039..56ff1a5f 100644 --- a/ash/wm/window_cycle/window_cycle_list.cc +++ b/ash/wm/window_cycle/window_cycle_list.cc
@@ -1010,6 +1010,7 @@ ->IsInteractiveAltTabModeAllowed()) { return windows_.size() > 1u; } + int total_window_in_all_desks = GetNumberOfWindowsAllDesks(); return windows_.size() > 1u || (windows_.size() <= 1u && @@ -1160,30 +1161,25 @@ } void WindowCycleList::Scroll(int offset) { - const bool is_interactive_alt_tab_mode_allowed = - Shell::Get()->window_cycle_controller()->IsInteractiveAltTabModeAllowed(); - if (windows_.empty() && (!is_interactive_alt_tab_mode_allowed || - GetNumberOfWindowsAllDesks() == 0)) - return; - - // When there is only one window, we should give feedback to the user. If - // the window is minimized, we should also show it. - if (windows_.size() == 1 && - !Shell::Get()->window_cycle_controller()->IsSwitchingMode()) { - ::wm::AnimateWindow(windows_[0], ::wm::WINDOW_ANIMATION_TYPE_BOUNCE); + if (windows_.size() == 1) SelectWindow(windows_[0]); + + if (!ShouldShowUi()) { + // When there is only one window, we should give feedback to the user. If + // the window is minimized, we should also show it. + if (windows_.size() == 1) + ::wm::AnimateWindow(windows_[0], ::wm::WINDOW_ANIMATION_TYPE_BOUNCE); + return; } DCHECK(static_cast<size_t>(current_index_) < windows_.size()); - current_index_ = GetOffsettedWindowIndex(offset); - if (ShouldShowUi()) { - if (current_index_ > 1) - InitWindowCycleView(); - if (cycle_view_) - cycle_view_->ScrollToWindow(windows_[current_index_]); - } + if (current_index_ > 1) + InitWindowCycleView(); + + if (cycle_view_) + cycle_view_->ScrollToWindow(windows_[current_index_]); } int WindowCycleList::GetOffsettedWindowIndex(int offset) const {
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc index 844910c..0ddba1b 100644 --- a/ash/wm/window_state.cc +++ b/ash/wm/window_state.cc
@@ -145,7 +145,7 @@ float GetCurrentSnappedWidthRatio(aura::Window* window) { gfx::Rect maximized_bounds = screen_util::GetMaximizedWindowBoundsInParent(window); - return static_cast<float>(window->bounds().width()) / + return static_cast<float>(window->GetTargetBounds().width()) / static_cast<float>(maximized_bounds.width()); }
diff --git a/ash/wm/window_state_unittest.cc b/ash/wm/window_state_unittest.cc index cf9953d..38105f7 100644 --- a/ash/wm/window_state_unittest.cc +++ b/ash/wm/window_state_unittest.cc
@@ -11,6 +11,7 @@ #include "ash/public/cpp/shelf_config.h" #include "ash/public/cpp/window_properties.h" #include "ash/test/ash_test_base.h" +#include "ash/test/test_window_builder.h" #include "ash/wm/pip/pip_positioner.h" #include "ash/wm/window_state_util.h" #include "ash/wm/window_util.h" @@ -21,6 +22,7 @@ #include "ui/aura/window.h" #include "ui/base/hit_test.h" #include "ui/compositor/layer.h" +#include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/display/screen.h" #include "ui/events/test/event_generator.h" #include "ui/views/widget/widget.h" @@ -412,6 +414,57 @@ EXPECT_EQ(0.5f, *window_state->snapped_width_ratio()); } +// Tests that dragging and snapping the snapped window update the width ratio +// correctly (crbug.com/1208969). +TEST_F(WindowStateTest, SnapSnappedWindow) { + ui::ScopedAnimationDurationScaleMode test_duration_mode( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + UpdateDisplay("800x600"); + const gfx::Rect kWorkAreaBounds = + display::Screen::GetScreen()->GetPrimaryDisplay().work_area(); + aura::test::TestWindowDelegate delegate; + gfx::Size window_normal_size = gfx::Size(800, 100); + std::unique_ptr<aura::Window> window = + TestWindowBuilder() + .SetBounds(gfx::Rect(window_normal_size)) + .SetDelegate(&delegate) + .AllowAllWindowStates() + .Build(); + delegate.set_window_component(HTCAPTION); + WindowState* window_state = WindowState::Get(window.get()); + const WMEvent cycle_snap_left(WM_EVENT_CYCLE_SNAP_LEFT); + window_state->OnWMEvent(&cycle_snap_left); + + // Snap window to the left. + EXPECT_EQ(WindowStateType::kLeftSnapped, window_state->GetStateType()); + gfx::Rect expected = + gfx::Rect(kWorkAreaBounds.x(), kWorkAreaBounds.y(), + kWorkAreaBounds.width() / 2, kWorkAreaBounds.height()); + // Wait for the snapped animation to complete and test that the window bound + // is left-snapped and the snap width ratio is updated. + window->layer()->GetAnimator()->Step(base::TimeTicks::Now() + + base::TimeDelta::FromSeconds(1)); + EXPECT_EQ(expected, window->GetBoundsInScreen()); + EXPECT_EQ(0.5f, *window_state->snapped_width_ratio()); + + // Drag the window to unsnap but do not release. + ui::test::EventGenerator* generator = GetEventGenerator(); + generator->MoveMouseTo(window->bounds().CenterPoint()); + generator->PressLeftButton(); + generator->MoveMouseBy(5, 0); + // While dragged, the window size should restore to its normal bound. + EXPECT_EQ(window_normal_size, window->bounds().size()); + EXPECT_EQ(1.0f, *window_state->snapped_width_ratio()); + + // Continue dragging the window and snap it back to the same position. + generator->MoveMouseBy(-405, 0); + generator->ReleaseLeftButton(); + + // The snapped ratio should be correct regardless of whether the animation + // is finished or not. + EXPECT_EQ(0.5f, *window_state->snapped_width_ratio()); +} + // Test that snapping left/right preserves the restore bounds. TEST_F(WindowStateTest, RestoreBounds) { std::unique_ptr<aura::Window> window(
diff --git a/base/test/scoped_feature_list.cc b/base/test/scoped_feature_list.cc index 7ada1d5..4b9c09f8 100644 --- a/base/test/scoped_feature_list.cc +++ b/base/test/scoped_feature_list.cc
@@ -136,6 +136,10 @@ ScopedFeatureList::ScopedFeatureList() = default; +ScopedFeatureList::ScopedFeatureList(const Feature& enable_feature) { + InitAndEnableFeature(enable_feature); +} + ScopedFeatureList::~ScopedFeatureList() { Reset(); }
diff --git a/base/test/scoped_feature_list.h b/base/test/scoped_feature_list.h index 6de0305..05f1e98 100644 --- a/base/test/scoped_feature_list.h +++ b/base/test/scoped_feature_list.h
@@ -41,7 +41,12 @@ // initialization in the test harness's constructor. class ScopedFeatureList final { public: + // Constructs the instance in a non-initialized state. ScopedFeatureList(); + + // Shorthand for immediately initializing with InitAndEnableFeature(). + explicit ScopedFeatureList(const Feature& enable_feature); + ~ScopedFeatureList(); struct FeatureAndParams {
diff --git a/build/android/gyp/compile_resources.py b/build/android/gyp/compile_resources.py index 48409de..8a668e7 100755 --- a/build/android/gyp/compile_resources.py +++ b/build/android/gyp/compile_resources.py
@@ -121,6 +121,11 @@ 'must be identical.') input_opts.add_argument( + '--support-zh-hk', + action='store_true', + help='Use zh-rTW resources for zh-rHK.') + + input_opts.add_argument( '--debuggable', action='store_true', help='Whether to add android:debuggable="true".') @@ -283,6 +288,20 @@ yield os.path.join(root, f) +def _DuplicateZhResources(resource_dirs, path_info): + """Duplicate Taiwanese resources into Hong-Kong specific directory.""" + for resource_dir in resource_dirs: + # We use zh-TW resources for zh-HK (if we have zh-TW resources). + for path in _IterFiles(resource_dir): + if 'zh-rTW' in path: + hk_path = path.replace('zh-rTW', 'zh-rHK') + build_utils.MakeDirectory(os.path.dirname(hk_path)) + shutil.copyfile(path, hk_path) + path_info.RegisterRename( + os.path.relpath(path, resource_dir), + os.path.relpath(hk_path, resource_dir)) + + def _RenameLocaleResourceDirs(resource_dirs, path_info): """Rename locale resource directories into standard names when necessary. @@ -338,11 +357,13 @@ os.path.relpath(path2, resource_dir)) -def _ToAndroidLocales(locale_allowlist): +def _ToAndroidLocales(locale_allowlist, support_zh_hk): """Converts the list of Chrome locales to Android config locale qualifiers. Args: locale_allowlist: A list of Chromium locale names. + support_zh_hk: True if we need to support zh-HK by duplicating + the zh-TW strings. Returns: A set of matching Android config locale qualifier names. """ @@ -356,7 +377,14 @@ language = locale.split('-')[0] ret.add(language) - return ret + # We don't actually support zh-HK in Chrome on Android, but we mimic the + # native side behavior where we use zh-TW resources when the locale is set to + # zh-HK. See https://crbug.com/780847. + if support_zh_hk: + assert not any('HK' in l for l in locale_allowlist), ( + 'Remove special logic if zh-HK is now supported (crbug.com/780847).') + ret.add('zh-rHK') + return set(ret) def _MoveImagesToNonMdpiFolders(res_root, path_info): @@ -682,7 +710,8 @@ # list provided by --locale-allowlist. wanted_locales = all_locales if options.locale_allowlist: - wanted_locales = _ToAndroidLocales(options.locale_allowlist) + wanted_locales = _ToAndroidLocales(options.locale_allowlist, + options.support_zh_hk) # Set B: shared resources locales, which is either set A # or the list provided by --shared-resources-allowlist-locales @@ -694,7 +723,7 @@ options.shared_resources_allowlist)) shared_resources_locales = _ToAndroidLocales( - options.shared_resources_allowlist_locales) + options.shared_resources_allowlist_locales, options.support_zh_hk) # Remove any file that belongs to a locale not covered by # either A or B. @@ -754,6 +783,8 @@ logging.debug('Applying locale transformations') path_info = resource_utils.ResourceInfoFile() + if options.support_zh_hk: + _DuplicateZhResources(dep_subdirs, path_info) _RenameLocaleResourceDirs(dep_subdirs, path_info) logging.debug('Applying file-based exclusions')
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 11eb48cd..5fd989b 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -2212,6 +2212,10 @@ # resources to put in the final output, even if aapt_locale_allowlist # is defined to a smaller subset. # + # support_zh_hk: (optional) + # If true, support zh-HK in Chrome on Android by using the resources + # from zh-TW. See https://crbug.com/780847. + # # aapt_locale_allowlist: (optional) # Restrict compiled locale-dependent resources to a specific allowlist. # NOTE: This is a list of Chromium locale names, not Android ones. @@ -2524,6 +2528,10 @@ [ "--values-filter-rules=${invoker.resource_values_filter_rules}" ] } + if (defined(invoker.support_zh_hk) && invoker.support_zh_hk) { + _args += [ "--support-zh-hk" ] + } + if (defined(invoker.include_resource)) { _rebased_include_resources = rebase_path(invoker.include_resource, root_build_dir)
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index d33240d..c65ab979 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -2482,6 +2482,7 @@ "resources_config_paths", "shared_resources", "shared_resources_allowlist_locales", + "support_zh_hk", "uses_split", ]) short_resource_paths = _short_resource_paths @@ -3497,6 +3498,7 @@ "static_library_provider", "static_library_synchronized_proguard", "strip_resource_names", + "support_zh_hk", "target_sdk_version", "testonly", "uncompress_dex", @@ -3624,6 +3626,7 @@ "static_library_provider", "static_library_synchronized_proguard", "strip_resource_names", + "support_zh_hk", "target_sdk_version", "testonly", "uncompress_shared_libraries",
diff --git a/build/config/fuchsia/generate_runner_scripts.gni b/build/config/fuchsia/generate_runner_scripts.gni index d9a67521..3b83f3b 100644 --- a/build/config/fuchsia/generate_runner_scripts.gni +++ b/build/config/fuchsia/generate_runner_scripts.gni
@@ -157,12 +157,8 @@ "${boot_image_root}/qemu/storage-full.blk", "${boot_image_root}/qemu/zircon-a.zbi", "//third_party/qemu-${host_os}-${test_host_cpu}/", + "${aemu_root}/", ] - - # Include AEMU for x64 emulator hosts and for arm64 hosts. - if (test_host_cpu == "x64" || test_host_cpu == "arm64") { - data += [ "${aemu_root}/" ] - } } foreach(fuchsia_additional_boot_image, fuchsia_additional_boot_images) {
diff --git a/build/config/locales.gni b/build/config/locales.gni index 1d57b877..e94e162 100644 --- a/build/config/locales.gni +++ b/build/config/locales.gni
@@ -14,11 +14,26 @@ # |locales_without_pseudolocales|. # The following additional platform specific lists are created: +# - |android_apk_locales| subset for Android based apk builds # - |android_bundle_locales_as_resources| locales formatted for XML output names # - |locales_as_mac_outputs| formated for mac output bundles # - |ios_packed_locales| subset for iOS # - |ios_packed_locales_as_mac_outputs| subset for iOS output +# Android doesn't ship all locales in order to save space (but webview does). +# http://crbug.com/369218 +android_apk_omitted_locales = [ + "bn", + "et", + "gu", + "kn", + "ml", + "mr", + "ms", + "ta", + "te", +] + # Chrome on iOS only ships with a subset of the locales supported by other # version of Chrome as the corresponding locales are not supported by the # operating system (but for simplicity, the corresponding .pak files are @@ -42,6 +57,7 @@ # These list are defined even when not building for Android or iOS for the # sake of build/locale_tool.py. Ensure that GN doesn't complain about them # being unused. +not_needed([ "android_apk_omitted_locales" ]) not_needed([ "ios_unsupported_locales" ]) # Superset of all locales used in Chrome with platform specific changes noted. @@ -167,6 +183,11 @@ if (is_android) { locales = all_chrome_locales + # Android doesn't ship all locales on KitKat in order to save space + # (but webview does). http://crbug.com/369218 + android_apk_locales = all_chrome_locales - android_bundle_only_locales - + android_apk_omitted_locales + # List for Android locale names in .xml exports. Note: needs to stay in sync # with |ToAndroidLocaleName| in build/android/gyp/util/resource_utils.py. # - add r: (e.g. zh-HK -> zh-rHK )
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 896c5554..cb5229fa 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -4.20210527.1.1 +4.20210527.3.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index e204c51..cb5229fa 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -4.20210527.0.1 +4.20210527.3.1
diff --git a/build/locale_tool.py b/build/locale_tool.py index b5729d8..cad51908 100755 --- a/build/locale_tool.py +++ b/build/locale_tool.py
@@ -322,9 +322,10 @@ ########################################################################## # Various list of locales that will be extracted from build/config/locales.gni -# Do not use these directly, use ChromeLocales(), and IosUnsupportedLocales() -# instead to access these lists. +# Do not use these directly, use ChromeLocales(), AndroidAPKOmittedLocales() and +# IosUnsupportedLocales() instead to access these lists. _INTERNAL_CHROME_LOCALES = [] +_INTERNAL_ANDROID_APK_OMITTED_LOCALES = [] _INTERNAL_IOS_UNSUPPORTED_LOCALES = [] @@ -335,6 +336,13 @@ return _INTERNAL_CHROME_LOCALES +def AndroidAPKOmittedLocales(): + """Return the list of locales omitted from Android APKs.""" + if not _INTERNAL_ANDROID_APK_OMITTED_LOCALES: + _ExtractAllChromeLocalesLists() + return _INTERNAL_ANDROID_APK_OMITTED_LOCALES + + def IosUnsupportedLocales(): """Return the list of locales that are unsupported on iOS.""" if not _INTERNAL_IOS_UNSUPPORTED_LOCALES: @@ -396,6 +404,9 @@ # Write the locales lists to files in the output directory. _filename = root_build_dir + "/foo" write_file(_filename + ".locales", locales, "json") +write_file(_filename + ".android_apk_omitted_locales", + android_apk_omitted_locales, + "json") write_file(_filename + ".ios_unsupported_locales", ios_unsupported_locales, "json") @@ -450,6 +461,10 @@ _INTERNAL_CHROME_LOCALES = _ReadJsonList( os.path.join(out_path, 'foo.locales')) + global _INTERNAL_ANDROID_APK_OMITTED_LOCALES + _INTERNAL_ANDROID_APK_OMITTED_LOCALES = _ReadJsonList( + os.path.join(out_path, 'foo.android_apk_omitted_locales')) + global _INTERNAL_IOS_UNSUPPORTED_LOCALES _INTERNAL_IOS_UNSUPPORTED_LOCALES = _ReadJsonList( os.path.join(out_path, 'foo.ios_unsupported_locales')) @@ -1271,8 +1286,9 @@ description = 'List supported Chrome locales' long_description = r''' List locales of interest, by default this prints all locales supported by -Chrome, but `--type=ios_unsupported` can be used for the list of locales -unsupported on iOS. +Chrome, but `--type=android_apk_omitted` can be used to print the list of +locales omitted from Android APKs (but not app bundles), and +`--type=ios_unsupported` for the list of locales unsupported on iOS. These values are extracted directly from build/config/locales.gni. @@ -1283,6 +1299,7 @@ # Maps type argument to a function returning the corresponding locales list. TYPE_MAP = { 'all': ChromeLocales, + 'android_apk_omitted': AndroidAPKOmittedLocales, 'ios_unsupported': IosUnsupportedLocales, }
diff --git a/chrome/VERSION b/chrome/VERSION index e82286f..49264b155 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=93 MINOR=0 -BUILD=4525 +BUILD=4526 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 0988287..93ac6234 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -2004,7 +2004,13 @@ renaming_sources = [] renaming_destinations = [] - foreach(_locale, locales) { + # Only include all Android locales on bundle builds. + if (_is_bundle_module) { + _locales_list = locales + } else { + _locales_list = android_apk_locales + } + foreach(_locale, _locales_list) { renaming_sources += [ "$target_gen_dir/${_variant}_paks/locales/$_locale.pak" ] renaming_destinations += [ "locales/$_locale.pak" ]
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index ca1ae15f..f9c8d98 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -432,7 +432,6 @@ "java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityLifecycleUmaTracker.java", "java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java", "java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java", - "java/src/org/chromium/chrome/browser/customtabs/CustomTabColorProvider.java", "java/src/org/chromium/chrome/browser/customtabs/CustomTabColorProviderImpl.java", "java/src/org/chromium/chrome/browser/customtabs/CustomTabCompositorContentInitializer.java", "java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java",
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni index 1f3e94f..f1cb16b 100644 --- a/chrome/android/chrome_public_apk_tmpl.gni +++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -173,6 +173,11 @@ product_config_java_packages = [ "org.chromium.chrome.browser" ] } + # Use zh-TW strings for zh-HK (https://crbug.com/780847). + if (!defined(support_zh_hk)) { + support_zh_hk = true + } + # Android supports webp transparent resources properly since API level 18, # so this can only be activated for modern ones (which target API >= 21). if (!defined(png_to_webp)) { @@ -185,9 +190,18 @@ short_resource_paths = true if (!defined(aapt_locale_allowlist)) { - # For bundles, only include resource strings files from our full - # locale list, but nothing more. - aapt_locale_allowlist = locales + if (target_type == "android_apk") { + # For APKs, do not include the resource strings files from our + # omitted locale list in order to save size. + aapt_locale_allowlist = android_apk_locales + } else { + # For bundles, only include resource strings files from our full + # locale list, but nothing more. + aapt_locale_allowlist = locales + + # zh_hk is supported in Android bundles. + support_zh_hk = false + } } if (!defined(use_chromium_linker)) { @@ -573,6 +587,13 @@ uncompress_shared_libraries = true } + # Android N+ better supports multiple locales (https://crbug.com/780847). + if (defined(invoker.support_zh_hk)) { + support_zh_hk = invoker.support_zh_hk + } else { + support_zh_hk = false + } + if (_is_bundle_module) { _pak_prefix += "_bundle_module" } else { @@ -623,6 +644,7 @@ "secondary_abi_shared_libraries", "secondary_native_lib_placeholders", "shared_libraries", + "support_zh_hk", "uncompress_shared_libraries", "use_chromium_linker", "use_modern_linker",
diff --git a/chrome/android/features/cablev2_authenticator/native/cablev2_authenticator_android.cc b/chrome/android/features/cablev2_authenticator/native/cablev2_authenticator_android.cc index 64faf63..4f3a773 100644 --- a/chrome/android/features/cablev2_authenticator/native/cablev2_authenticator_android.cc +++ b/chrome/android/features/cablev2_authenticator/native/cablev2_authenticator_android.cc
@@ -574,8 +574,8 @@ return 0; } - DCHECK(event->source != - device::cablev2::authenticator::Registration::Type::LINKING || + DCHECK((event->source == + device::cablev2::authenticator::Registration::Type::LINKING) == event->contact_id.has_value()); GlobalData& global_data = GetGlobalData();
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedStreamViewResizer.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedStreamViewResizer.java new file mode 100644 index 0000000..d468c5e --- /dev/null +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedStreamViewResizer.java
@@ -0,0 +1,110 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.feed; + +import android.app.Activity; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.Rect; +import android.view.View; +import android.view.ViewGroup; + +import androidx.core.view.ViewCompat; + +import org.chromium.chrome.R; +import org.chromium.components.browser_ui.widget.displaystyle.UiConfig; +import org.chromium.components.browser_ui.widget.displaystyle.ViewResizer; + +/** + * Updates the paddings used to display the feed stream when switching to landscape mode. Due to the + * fact that the search bar is floating at the top, the entire feed stream needs to shrink a little + * bit in order to have large image or video preview fit in the viewport. + */ +public class FeedStreamViewResizer extends ViewResizer { + // The aspect ratio of large images or video previews, computed based on 1280:720. + private static final float FEED_IMAGE_OR_VIDEO_ASPECT_RATIO = 1.778f; + + private final Activity mActivity; + + /** + * @param activity The activity displays the view. + * @param view The view that will have its padding resized. + * @param config The UiConfig object to subscribe to. + * @param defaultPaddingPixels Padding to use in {@link HorizontalDisplayStyle#REGULAR}. + * @param minWidePaddingPixels Minimum lateral padding to use in {@link + * HorizontalDisplayStyle#WIDE}. + */ + public FeedStreamViewResizer(Activity activity, View view, UiConfig config, + int defaultPaddingPixels, int minWidePaddingPixels) { + super(view, config, defaultPaddingPixels, minWidePaddingPixels); + mActivity = activity; + } + + /** + * Convenience method to create a new ViewResizer and immediately attach it to a {@link + * UiConfig}. If the {@link UiConfig} can outlive the view, the regular constructor should be + * used, so it can be detached to avoid memory leaks. + * @param activity The activity displays the view. + * @param view The view that will have its padding resized. + * @param config The UiConfig object to subscribe to. + * @param defaultPaddingPixels Padding to use in {@link HorizontalDisplayStyle#REGULAR}. + * @param minWidePaddingPixels Minimum lateral padding to use in {@link + * HorizontalDisplayStyle#WIDE}. + * @return The {@link ViewResizer} that is created and attached. + */ + public static FeedStreamViewResizer createAndAttach(Activity activity, View view, + UiConfig config, int defaultPaddingPixels, int minWidePaddingPixels) { + FeedStreamViewResizer viewResizer = new FeedStreamViewResizer( + activity, view, config, defaultPaddingPixels, minWidePaddingPixels); + viewResizer.attach(); + return viewResizer; + } + + @Override + public void onDisplayStyleChanged(UiConfig.DisplayStyle newDisplayStyle) { + if (mUiConfig.getContext().getResources().getConfiguration().orientation + != Configuration.ORIENTATION_LANDSCAPE) { + super.onDisplayStyleChanged(newDisplayStyle); + return; + } + + updatePaddingForLandscapeMode(); + } + + /** + * In landscape mode, the entire large image or video preview cannot fit in the viewport because + * the floating search bar at the top reduces the user's visible area. To deal with this, we + * add the left and right paddings to all items in the RecyclerView in order to shrink all card + * images a little bit so that they can fit in the viewport. + */ + private void updatePaddingForLandscapeMode() { + ViewGroup contentContainer = mActivity.findViewById(android.R.id.content); + if (contentContainer == null) { + return; + } + View toolbarView = contentContainer.findViewById(R.id.toolbar_container); + if (toolbarView == null) { + return; + } + int toolbarHeight = toolbarView.getHeight(); + + Resources resources = mUiConfig.getContext().getResources(); + float dpToPx = resources.getDisplayMetrics().density; + float screenWidth = resources.getConfiguration().screenWidthDp * dpToPx; + float screenHeight = resources.getConfiguration().screenHeightDp * dpToPx; + + float useableHeight = screenHeight - statusBarHeight() - toolbarHeight; + int padding = (int) ((screenWidth - useableHeight * FEED_IMAGE_OR_VIDEO_ASPECT_RATIO) / 2); + + ViewCompat.setPaddingRelative( + mView, padding, mView.getPaddingTop(), padding, mView.getPaddingBottom()); + } + + private int statusBarHeight() { + Rect visibleContentRect = new Rect(); + mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(visibleContentRect); + return visibleContentRect.top; + } +}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java index 554a072..36c8e6b 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
@@ -115,7 +115,7 @@ private @Nullable NativePageNavigationDelegate mPageNavigationDelegate; private @Nullable FeedSurfaceLifecycleManager mFeedSurfaceLifecycleManager; private @Nullable PersonalizedSigninPromoView mSigninPromoView; - private @Nullable ViewResizer mStreamViewResizer; + private @Nullable FeedStreamViewResizer mStreamViewResizer; // This is the "default"/interest feed stream, not necessarily the current stream. // TODO(chili): Remove the necessity of this. private @Nullable FeedStream mStream; @@ -498,8 +498,8 @@ mRecyclerView.setBackgroundResource(R.color.default_bg_color); mRootView.addView(mRecyclerView); - mStreamViewResizer = ViewResizer.createAndAttach( - mRecyclerView, mUiConfig, mDefaultMarginPixels, mWideMarginPixels); + mStreamViewResizer = FeedStreamViewResizer.createAndAttach( + mActivity, mRecyclerView, mUiConfig, mDefaultMarginPixels, mWideMarginPixels); if (mNtpHeader != null) UiUtils.removeViewFromParent(mNtpHeader); if (mSectionHeaderView != null) UiUtils.removeViewFromParent(mSectionHeaderView);
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedV2NewTabPageTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedV2NewTabPageTest.java index fd99563d..46fb0457 100644 --- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedV2NewTabPageTest.java +++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedV2NewTabPageTest.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.feed; +import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; + import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; @@ -22,6 +24,7 @@ import static org.chromium.chrome.test.util.ViewUtils.VIEW_NULL; import static org.chromium.chrome.test.util.ViewUtils.waitForView; +import android.content.pm.ActivityInfo; import android.support.test.InstrumentationRegistry; import android.view.View; import android.view.ViewGroup; @@ -55,7 +58,9 @@ import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.Restriction; import org.chromium.chrome.R; +import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.feed.v2.FeedV2TestHelper; import org.chromium.chrome.browser.feed.v2.TestFeedServer; import org.chromium.chrome.browser.firstrun.FirstRunUtils; @@ -70,6 +75,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.chrome.test.util.ChromeRenderTestRule; import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.NewTabPageTestUtils; import org.chromium.chrome.test.util.ViewUtils; @@ -83,7 +89,9 @@ import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.net.NetworkChangeNotifier; import org.chromium.net.test.EmbeddedTestServer; +import org.chromium.ui.test.util.UiRestriction; +import java.io.IOException; import java.util.Collections; import java.util.List; @@ -118,6 +126,10 @@ private final ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); + @Rule + public final ChromeRenderTestRule mRenderTestRule = + ChromeRenderTestRule.Builder.withPublicCorpus().build(); + private final AccountManagerTestRule mAccountManagerTestRule = new AccountManagerTestRule(new FakeAccountManagerFacade(null) { @Override @@ -359,6 +371,33 @@ headerStatusView.getText()); } + @Test + @MediumTest + @Feature({"RenderTest"}) + @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) + public void testLoadFeedContent_Landscape() throws IOException { + ChromeTabbedActivity chromeActivity = mActivityTestRule.getActivity(); + chromeActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + CriteriaHelper.pollUiThread(() -> { + Criteria.checkThat(chromeActivity.getResources().getConfiguration().orientation, + is(ORIENTATION_LANDSCAPE)); + }); + + openNewTabPage(); + + CriteriaHelper.pollUiThread(() -> { + Criteria.checkThat(FeedV2TestHelper.getFeedUserActionsHistogramValues(), + Matchers.hasEntry("kOpenedFeedSurface", 1)); + Criteria.checkThat(FeedV2TestHelper.getLoadStreamStatusInitialValues(), + Matchers.hasEntry("kLoadedFromNetwork", 1)); + }); + + RecyclerView recyclerView = getRecyclerView(); + FeedV2TestHelper.waitForRecyclerItems(MIN_ITEMS_AFTER_LOAD, recyclerView); + + mRenderTestRule.render(recyclerView, "feedContent_landscape"); + } + /** * Toggles the header and checks whether the header has the right status. * @param expanded Whether the header should be expanded.
diff --git a/chrome/android/feed/feed_java_sources.gni b/chrome/android/feed/feed_java_sources.gni index 53b6918c..de145734 100644 --- a/chrome/android/feed/feed_java_sources.gni +++ b/chrome/android/feed/feed_java_sources.gni
@@ -20,6 +20,7 @@ ] feed_java_sources = [ + "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedStreamViewResizer.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceLifecycleManager.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java index 3c11685f..7cfc41c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
@@ -444,8 +444,9 @@ @Override public int getActivityThemeColor() { BrowserServicesIntentDataProvider intentDataProvider = getIntentDataProvider(); - if (!intentDataProvider.isOpenedByChrome() && intentDataProvider.hasCustomToolbarColor()) { - return intentDataProvider.getToolbarColor(); + if (!intentDataProvider.isOpenedByChrome() + && intentDataProvider.getColorProvider().hasCustomToolbarColor()) { + return intentDataProvider.getColorProvider().getToolbarColor(); } return TabState.UNSPECIFIED_THEME_COLOR; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index 6ca4b58..729e2b3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -86,7 +86,8 @@ @Override protected Drawable getBackgroundDrawable() { - int initialBackgroundColor = mIntentDataProvider.getInitialBackgroundColor(); + int initialBackgroundColor = + mIntentDataProvider.getColorProvider().getInitialBackgroundColor(); if (mIntentDataProvider.isTrustedIntent() && initialBackgroundColor != Color.TRANSPARENT) { return new ColorDrawable(initialBackgroundColor); } else { @@ -134,7 +135,7 @@ // Setting task title and icon to be null will preserve the client app's title and icon. setTaskDescription(new ActivityManager.TaskDescription( - null, null, mIntentDataProvider.getToolbarColor())); + null, null, mIntentDataProvider.getColorProvider().getToolbarColor())); getComponent().resolveBottomBarDelegate().showBottomBarIfNecessary(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java index 1025324..2a83a89 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java
@@ -151,7 +151,7 @@ if (items.isEmpty()) return; LinearLayout layout = new LinearLayout(mActivity); layout.setId(R.id.custom_tab_bottom_bar_wrapper); - layout.setBackgroundColor(mDataProvider.getBottomBarColor()); + layout.setBackgroundColor(mDataProvider.getColorProvider().getBottomBarColor()); for (CustomButtonParams params : items) { if (params.showOnToolbar()) continue; final PendingIntent pendingIntent = params.getPendingIntent();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabColorProviderImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabColorProviderImpl.java index ed02a78..ddc3b8f2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabColorProviderImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabColorProviderImpl.java
@@ -18,14 +18,15 @@ import org.chromium.base.IntentUtils; import org.chromium.base.Log; +import org.chromium.chrome.browser.browserservices.intents.ColorProvider; import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.ui.util.ColorUtils; /** - * CustomTabColorProvider implementation used for normal profiles, in some cases incognito + * ColorProvider implementation used for normal profiles, in some cases incognito * profiles. */ -public final class CustomTabColorProviderImpl implements CustomTabColorProvider { +public final class CustomTabColorProviderImpl implements ColorProvider { private static final String TAG = "CustomTabColorPrvdr"; private final boolean mHasCustomToolbarColor;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java index 8347175..a939ebb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -39,6 +39,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider; +import org.chromium.chrome.browser.browserservices.intents.ColorProvider; import org.chromium.chrome.browser.browserservices.intents.CustomButtonParams; import org.chromium.chrome.browser.flags.ActivityType; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -248,7 +249,7 @@ private final int[] mGsaExperimentIds; @NonNull - private final CustomTabColorProvider mColorProvider; + private final ColorProvider mColorProvider; /** * Add extras to customize menu items for opening Reader Mode UI custom tab from Chrome. @@ -470,8 +471,8 @@ if (shareState == CustomTabsIntent.SHARE_STATE_ON || shareState == CustomTabsIntent.SHARE_STATE_DEFAULT) { if (mToolbarButtons.isEmpty()) { - mToolbarButtons.add( - CustomButtonParamsImpl.createShareButton(context, getToolbarColor())); + mToolbarButtons.add(CustomButtonParamsImpl.createShareButton( + context, getColorProvider().getToolbarColor())); logShareOptionLocation(ShareOptionLocation.TOOLBAR); } else if (mMenuEntries.isEmpty()) { mShowShareItemInMenu = true; @@ -631,25 +632,8 @@ } @Override - public int getToolbarColor() { - return mColorProvider.getToolbarColor(); - } - - @Override - public boolean hasCustomToolbarColor() { - return mColorProvider.hasCustomToolbarColor(); - } - - @Override - @Nullable - public Integer getNavigationBarColor() { - return mColorProvider.getNavigationBarColor(); - } - - @Override - @Nullable - public Integer getNavigationBarDividerColor() { - return mColorProvider.getNavigationBarDividerColor(); + public ColorProvider getColorProvider() { + return mColorProvider; } @Override @@ -679,11 +663,6 @@ } @Override - public int getBottomBarColor() { - return mColorProvider.getBottomBarColor(); - } - - @Override @Nullable public RemoteViews getBottomBarRemoteViews() { return mRemoteViews; @@ -756,11 +735,6 @@ } @Override - public int getInitialBackgroundColor() { - return mColorProvider.getInitialBackgroundColor(); - } - - @Override public boolean shouldShowStarButton() { return !mDisableStar; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProvider.java index 06f2d7b..842e27d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProvider.java
@@ -56,7 +56,7 @@ case ToolbarColorType.DEFAULT_COLOR: return DEFAULT_STATUS_BAR_COLOR; case ToolbarColorType.INTENT_TOOLBAR_COLOR: - return mIntentDataProvider.getToolbarColor(); + return mIntentDataProvider.getColorProvider().getToolbarColor(); } return DEFAULT_STATUS_BAR_COLOR; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTaskDescriptionHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTaskDescriptionHelper.java index 36b9e470..2f75665 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTaskDescriptionHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTaskDescriptionHelper.java
@@ -96,8 +96,8 @@ mDefaultThemeColor = ApiCompatibilityUtils.getColor( mActivity.getResources(), R.color.default_primary_color); if (webappExtras != null) { - if (mIntentDataProvider.hasCustomToolbarColor()) { - mDefaultThemeColor = mIntentDataProvider.getToolbarColor(); + if (mIntentDataProvider.getColorProvider().hasCustomToolbarColor()) { + mDefaultThemeColor = mIntentDataProvider.getColorProvider().getToolbarColor(); } mForceIcon = webappExtras.icon.bitmap(); mForceTitle = webappExtras.shortName;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabColorProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabColorProvider.java index fe9454e..0d4ab42 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabColorProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabColorProvider.java
@@ -9,13 +9,13 @@ import androidx.annotation.Nullable; +import org.chromium.chrome.browser.browserservices.intents.ColorProvider; import org.chromium.components.browser_ui.styles.ChromeColors; /** - * CustomTabColorProvider implementation used for normal provides, and some times incognito - * profiles. + * ColorProvider implementation used for incognito profiles. */ -public final class IncognitoCustomTabColorProvider implements CustomTabColorProvider { +public final class IncognitoCustomTabColorProvider implements ColorProvider { private final int mToolbarColor; private final int mBottomBarColor; private final int mNavigationBarColor;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabIntentDataProvider.java index 0bfaff4c..4ad4e519 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabIntentDataProvider.java
@@ -28,6 +28,7 @@ import org.chromium.chrome.browser.ChromeApplicationImpl; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider; +import org.chromium.chrome.browser.browserservices.intents.ColorProvider; import org.chromium.chrome.browser.flags.ActivityType; import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -64,7 +65,7 @@ private final CustomTabsSessionToken mSession; private final boolean mIsTrustedIntent; private final Bundle mAnimationBundle; - private final CustomTabColorProvider mColorProvider; + private final ColorProvider mColorProvider; private final int mTitleVisibilityState; private final Drawable mCloseButtonIcon; private final boolean mShowShareItem; @@ -291,13 +292,8 @@ } @Override - public int getToolbarColor() { - return mColorProvider.getToolbarColor(); - } - - @Override - public boolean hasCustomToolbarColor() { - return mColorProvider.hasCustomToolbarColor(); + public ColorProvider getColorProvider() { + return mColorProvider; } @Override @@ -312,27 +308,6 @@ } @Override - public int getBottomBarColor() { - return mColorProvider.getBottomBarColor(); - } - - @Override - public int getInitialBackgroundColor() { - return mColorProvider.getInitialBackgroundColor(); - } - - @Override - public Integer getNavigationBarColor() { - return mColorProvider.getNavigationBarColor(); - } - - @Override - @Nullable - public Integer getNavigationBarDividerColor() { - return mColorProvider.getNavigationBarDividerColor(); - } - - @Override public int getTitleVisibilityState() { return mTitleVisibilityState; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java index 62638b3..832082c2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java
@@ -488,7 +488,7 @@ private void prepareTabBackground(final Tab tab) { if (!CustomTabIntentDataProvider.isTrustedCustomTab(mIntent, mSession)) return; - int backgroundColor = mIntentDataProvider.getInitialBackgroundColor(); + int backgroundColor = mIntentDataProvider.getColorProvider().getInitialBackgroundColor(); if (backgroundColor == Color.TRANSPARENT) return; // Set the background color.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/CustomTabNavigationBarController.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/CustomTabNavigationBarController.java index 636060f1..8e945a6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/CustomTabNavigationBarController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/CustomTabNavigationBarController.java
@@ -27,8 +27,9 @@ */ public static void update(Window window, BrowserServicesIntentDataProvider intentDataProvider, Resources resources) { - Integer navigationBarColor = intentDataProvider.getNavigationBarColor(); - Integer navigationBarDividerColor = intentDataProvider.getNavigationBarDividerColor(); + Integer navigationBarColor = intentDataProvider.getColorProvider().getNavigationBarColor(); + Integer navigationBarDividerColor = + intentDataProvider.getColorProvider().getNavigationBarDividerColor(); int lightBackgroundDividerColor = ApiCompatibilityUtils.getColor( resources, org.chromium.chrome.R.color.black_alpha_12);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java index 09ff4e6c..21d7468 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java
@@ -89,8 +89,9 @@ return ToolbarColorType.THEME_COLOR; } - return intentDataProvider.hasCustomToolbarColor() ? ToolbarColorType.INTENT_TOOLBAR_COLOR - : ToolbarColorType.DEFAULT_COLOR; + return intentDataProvider.getColorProvider().hasCustomToolbarColor() + ? ToolbarColorType.INTENT_TOOLBAR_COLOR + : ToolbarColorType.DEFAULT_COLOR; } /** @@ -170,7 +171,7 @@ case ToolbarColorType.DEFAULT_COLOR: return getDefaultColor(); case ToolbarColorType.INTENT_TOOLBAR_COLOR: - return mIntentDataProvider.getToolbarColor(); + return mIntentDataProvider.getColorProvider().getToolbarColor(); } return getDefaultColor(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java index 8addf21..2d30a61c4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java
@@ -103,7 +103,7 @@ * ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING otherwise. */ public long toolbarColor() { - return hasValidToolbarColor() ? mProvider.getToolbarColor() + return hasValidToolbarColor() ? mProvider.getColorProvider().getToolbarColor() : ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING; } @@ -111,7 +111,7 @@ * Returns whether the toolbar color specified in the Intent is valid. */ public boolean hasValidToolbarColor() { - return mProvider.hasCustomToolbarColor(); + return mProvider.getColorProvider().hasCustomToolbarColor(); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java index ec253b92..464adfd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java
@@ -21,6 +21,7 @@ import org.chromium.base.ContextUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider; +import org.chromium.chrome.browser.browserservices.intents.ColorProvider; import org.chromium.chrome.browser.browserservices.intents.WebApkExtras; import org.chromium.chrome.browser.browserservices.intents.WebDisplayMode; import org.chromium.chrome.browser.browserservices.intents.WebappExtras; @@ -31,8 +32,6 @@ * Stores info about a web app. */ public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider { - private final int mToolbarColor; - private final boolean mHasCustomToolbarColor; private final Drawable mCloseButtonIcon; private final TrustedWebActivityDisplayMode mTwaDisplayMode; private final ShareData mShareData; @@ -40,6 +39,7 @@ private final @Nullable WebApkExtras mWebApkExtras; private final @ActivityType int mActivityType; private final Intent mIntent; + private final ColorProviderImpl mColorProvider; /** * Returns the toolbar color to use if a custom color is not specified by the webapp. @@ -52,8 +52,7 @@ boolean hasCustomToolbarColor, @Nullable ShareData shareData, @NonNull WebappExtras webappExtras, @Nullable WebApkExtras webApkExtras) { mIntent = intent; - mToolbarColor = toolbarColor; - mHasCustomToolbarColor = hasCustomToolbarColor; + mColorProvider = new ColorProviderImpl(toolbarColor, hasCustomToolbarColor); mCloseButtonIcon = TintedDrawable.constructTintedDrawable( ContextUtils.getApplicationContext(), R.drawable.btn_close); mTwaDisplayMode = (webappExtras.displayMode == WebDisplayMode.FULLSCREEN) @@ -92,13 +91,9 @@ } @Override - public int getToolbarColor() { - return mToolbarColor; - } - - @Override - public boolean hasCustomToolbarColor() { - return mHasCustomToolbarColor; + @NonNull + public ColorProvider getColorProvider() { + return mColorProvider; } @Override @@ -159,4 +154,46 @@ public int getDefaultOrientation() { return mWebappExtras.orientation; } + + private static final class ColorProviderImpl implements ColorProvider { + private final int mToolbarColor; + private final boolean mHasCustomToolbarColor; + + ColorProviderImpl(int toolbarColor, boolean hasCustomToolbarColor) { + mToolbarColor = toolbarColor; + mHasCustomToolbarColor = hasCustomToolbarColor; + } + + @Override + public int getToolbarColor() { + return mToolbarColor; + } + + @Override + public boolean hasCustomToolbarColor() { + return mHasCustomToolbarColor; + } + + @Override + @Nullable + public Integer getNavigationBarColor() { + return null; + } + + @Override + @Nullable + public Integer getNavigationBarDividerColor() { + return null; + } + + @Override + public int getBottomBarColor() { + return getToolbarColor(); + } + + @Override + public int getInitialBackgroundColor() { + return Color.TRANSPARENT; + } + } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java index dcbd5c0..7629730 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java
@@ -35,6 +35,7 @@ import org.chromium.base.IntentUtils; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.R; +import org.chromium.chrome.browser.browserservices.intents.ColorProvider; import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.test.util.browser.Features; import org.chromium.device.mojom.ScreenOrientationLockType; @@ -69,10 +70,12 @@ .build() .intent; - CustomTabIntentDataProvider lightProvider = new CustomTabIntentDataProvider( - intent, ApplicationProvider.getApplicationContext(), COLOR_SCHEME_LIGHT); - CustomTabIntentDataProvider darkProvider = new CustomTabIntentDataProvider( - intent, ApplicationProvider.getApplicationContext(), COLOR_SCHEME_DARK); + ColorProvider lightProvider = new CustomTabIntentDataProvider( + intent, ApplicationProvider.getApplicationContext(), COLOR_SCHEME_LIGHT) + .getColorProvider(); + ColorProvider darkProvider = new CustomTabIntentDataProvider( + intent, ApplicationProvider.getApplicationContext(), COLOR_SCHEME_DARK) + .getColorProvider(); assertEquals((int) lightParams.toolbarColor, lightProvider.getToolbarColor()); assertEquals((int) darkParams.toolbarColor, darkProvider.getToolbarColor());
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabNavigationBarControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabNavigationBarControllerTest.java index cd5d7f1e..05aa042 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabNavigationBarControllerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabNavigationBarControllerTest.java
@@ -26,6 +26,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.browserservices.intents.ColorProvider; import org.chromium.chrome.browser.customtabs.features.CustomTabNavigationBarController; import org.chromium.ui.util.ColorUtils; @@ -34,6 +35,8 @@ @Config(manifest = Config.NONE) public class CustomTabNavigationBarControllerTest { @Mock + private ColorProvider mColorProvider; + @Mock private CustomTabIntentDataProvider mCustomTabIntentDataProvider; private Window mWindow; private Resources mResources; @@ -44,11 +47,12 @@ Activity activity = Robolectric.buildActivity(Activity.class).get(); mWindow = spy(activity.getWindow()); mResources = activity.getResources(); + when(mCustomTabIntentDataProvider.getColorProvider()).thenReturn(mColorProvider); } @Test public void doesNotSetBarColorWhenNull() { - when(mCustomTabIntentDataProvider.getNavigationBarColor()).thenReturn(null); + when(mColorProvider.getNavigationBarColor()).thenReturn(null); CustomTabNavigationBarController.update(mWindow, mCustomTabIntentDataProvider, mResources); verify(mWindow, never()).setNavigationBarColor(Mockito.anyInt()); @@ -57,10 +61,10 @@ @Test @Config(sdk = Build.VERSION_CODES.P) // Android P+ (>=28) is needed for setting divider color. public void doesNotSetDividerColorWhenNull() { - when(mCustomTabIntentDataProvider.getNavigationBarDividerColor()).thenReturn(null); + when(mColorProvider.getNavigationBarDividerColor()).thenReturn(null); // Bar color needs to be null. Otherwise the divider color could still be set if // needsDarkButtons is true. - when(mCustomTabIntentDataProvider.getNavigationBarColor()).thenReturn(null); + when(mColorProvider.getNavigationBarColor()).thenReturn(null); CustomTabNavigationBarController.update(mWindow, mCustomTabIntentDataProvider, mResources); verify(mWindow, never()).setNavigationBarDividerColor(Mockito.anyInt()); @@ -70,8 +74,8 @@ @Config(sdk = Build.VERSION_CODES.O_MR1) // Android P+ (>=28) is needed for setting the divider color. public void doesNotSetDividerColorWhenSdkLow() { - when(mCustomTabIntentDataProvider.getNavigationBarDividerColor()).thenReturn(Color.RED); - when(mCustomTabIntentDataProvider.getNavigationBarColor()).thenReturn(Color.GREEN); + when(mColorProvider.getNavigationBarDividerColor()).thenReturn(Color.RED); + when(mColorProvider.getNavigationBarColor()).thenReturn(Color.GREEN); // Make sure calling the line below does not throw an exception, because the method does not // exist in android P+. @@ -81,15 +85,15 @@ @Test @Config(sdk = Build.VERSION_CODES.N_MR1) // SDK 25 is used to trigger supportsDarkButtons=false. public void setsCorrectBarColor() { - when(mCustomTabIntentDataProvider.getNavigationBarDividerColor()).thenReturn(Color.RED); + when(mColorProvider.getNavigationBarDividerColor()).thenReturn(Color.RED); // The case when needsDarkButtons=true. - when(mCustomTabIntentDataProvider.getNavigationBarColor()).thenReturn(Color.WHITE); + when(mColorProvider.getNavigationBarColor()).thenReturn(Color.WHITE); CustomTabNavigationBarController.update(mWindow, mCustomTabIntentDataProvider, mResources); verify(mWindow).setNavigationBarColor(ColorUtils.getDarkenedColorForStatusBar(Color.WHITE)); // The case when needsDarkButtons=false. - when(mCustomTabIntentDataProvider.getNavigationBarColor()).thenReturn(Color.BLACK); + when(mColorProvider.getNavigationBarColor()).thenReturn(Color.BLACK); CustomTabNavigationBarController.update(mWindow, mCustomTabIntentDataProvider, mResources); verify(mWindow).setNavigationBarColor(Color.BLACK); } @@ -97,11 +101,11 @@ @Test @Config(sdk = Build.VERSION_CODES.O) // SDK 26 is used to trigger supportDarkButtons=true. public void setsCorrectBarColorWhenDarkButtonsSupported() { - when(mCustomTabIntentDataProvider.getNavigationBarDividerColor()).thenReturn(Color.RED); - when(mCustomTabIntentDataProvider.getNavigationBarColor()).thenReturn(Color.GREEN); + when(mColorProvider.getNavigationBarDividerColor()).thenReturn(Color.RED); + when(mColorProvider.getNavigationBarColor()).thenReturn(Color.GREEN); // The case when needsDarkButtons=true - when(mCustomTabIntentDataProvider.getNavigationBarColor()).thenReturn(Color.WHITE); + when(mColorProvider.getNavigationBarColor()).thenReturn(Color.WHITE); CustomTabNavigationBarController.update(mWindow, mCustomTabIntentDataProvider, mResources); verify(mWindow).setNavigationBarColor(Color.WHITE); } @@ -110,15 +114,15 @@ @Config(sdk = Build.VERSION_CODES.P) // Android P+ (>=28) needed for setting divider color. public void setsCorrectDividerColor() { // The case when divider color is set explicitly. - when(mCustomTabIntentDataProvider.getNavigationBarDividerColor()).thenReturn(Color.RED); - when(mCustomTabIntentDataProvider.getNavigationBarColor()).thenReturn(Color.BLACK); + when(mColorProvider.getNavigationBarDividerColor()).thenReturn(Color.RED); + when(mColorProvider.getNavigationBarColor()).thenReturn(Color.BLACK); CustomTabNavigationBarController.update(mWindow, mCustomTabIntentDataProvider, mResources); verify(mWindow).setNavigationBarDividerColor(Color.RED); // The case when divider color is set implicitly due to needsDarkButtons=true. - when(mCustomTabIntentDataProvider.getNavigationBarDividerColor()).thenReturn(null); - when(mCustomTabIntentDataProvider.getNavigationBarColor()).thenReturn(Color.WHITE); + when(mColorProvider.getNavigationBarDividerColor()).thenReturn(null); + when(mColorProvider.getNavigationBarColor()).thenReturn(Color.WHITE); CustomTabNavigationBarController.update(mWindow, mCustomTabIntentDataProvider, mResources); verify(mWindow).setNavigationBarDividerColor(ApiCompatibilityUtils.getColor( mResources, org.chromium.chrome.R.color.black_alpha_12));
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProviderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProviderTest.java index ad9edd50..6ed6b39d 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProviderTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProviderTest.java
@@ -21,6 +21,7 @@ import org.robolectric.annotation.Config; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.browserservices.intents.ColorProvider; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.ui.system.StatusBarColorController; @@ -39,17 +40,21 @@ @Mock public StatusBarColorController mStatusBarColorController; @Mock public TabImpl mTab; - private CustomTabStatusBarColorProvider mColorProvider; + private CustomTabStatusBarColorProvider mStatusBarColorProvider; + @Mock + private ColorProvider mColorProvider; @Before public void setUp() { MockitoAnnotations.initMocks(this); - mColorProvider = Mockito.spy(new CustomTabStatusBarColorProvider( + mStatusBarColorProvider = Mockito.spy(new CustomTabStatusBarColorProvider( mCustomTabIntentDataProvider, mStatusBarColorController)); - when(mCustomTabIntentDataProvider.getToolbarColor()).thenReturn(USER_PROVIDED_COLOR); - when(mCustomTabIntentDataProvider.hasCustomToolbarColor()).thenReturn(true); + when(mCustomTabIntentDataProvider.getColorProvider()).thenReturn(mColorProvider); + + when(mColorProvider.getToolbarColor()).thenReturn(USER_PROVIDED_COLOR); + when(mColorProvider.hasCustomToolbarColor()).thenReturn(true); } @Test @@ -61,48 +66,48 @@ @Test public void useTabThemeColor_enable() { - mColorProvider.setUseTabThemeColor(true); + mStatusBarColorProvider.setUseTabThemeColor(true); Assert.assertEquals(UNDEFINED_STATUS_BAR_COLOR, getStatusBarColor(mTab)); verify(mStatusBarColorController).updateStatusBarColor(); } @Test public void useTabThemeColor_enable_nullTab() { - mColorProvider.setUseTabThemeColor(true); + mStatusBarColorProvider.setUseTabThemeColor(true); Assert.assertEquals(USER_PROVIDED_COLOR, getStatusBarColor(null)); - when(mCustomTabIntentDataProvider.hasCustomToolbarColor()).thenReturn(false); + when(mColorProvider.hasCustomToolbarColor()).thenReturn(false); Assert.assertEquals(DEFAULT_STATUS_BAR_COLOR, getStatusBarColor(null)); } @Test public void useTabThemeColor_disable() { - mColorProvider.setUseTabThemeColor(true); + mStatusBarColorProvider.setUseTabThemeColor(true); Assert.assertEquals(UNDEFINED_STATUS_BAR_COLOR, getStatusBarColor(mTab)); verify(mStatusBarColorController).updateStatusBarColor(); - mColorProvider.setUseTabThemeColor(false); + mStatusBarColorProvider.setUseTabThemeColor(false); Assert.assertEquals(USER_PROVIDED_COLOR, getStatusBarColor(mTab)); verify(mStatusBarColorController, times(2)).updateStatusBarColor(); } @Test public void useTabThemeColor_disable_noCustomColor() { - when(mCustomTabIntentDataProvider.hasCustomToolbarColor()).thenReturn(false); - mColorProvider.setUseTabThemeColor(false); + when(mColorProvider.hasCustomToolbarColor()).thenReturn(false); + mStatusBarColorProvider.setUseTabThemeColor(false); Assert.assertEquals(DEFAULT_STATUS_BAR_COLOR, getStatusBarColor(mTab)); } @Test public void useTabThemeColor_idempotent() { - mColorProvider.setUseTabThemeColor(true); - mColorProvider.setUseTabThemeColor(true); + mStatusBarColorProvider.setUseTabThemeColor(true); + mStatusBarColorProvider.setUseTabThemeColor(true); Assert.assertEquals(UNDEFINED_STATUS_BAR_COLOR, getStatusBarColor(mTab)); verify(mStatusBarColorController).updateStatusBarColor(); } private int getStatusBarColor(Tab tab) { - return mColorProvider.getBaseStatusBarColor(tab, FALLBACK_COLOR); + return mStatusBarColorProvider.getBaseStatusBarColor(tab, FALLBACK_COLOR); } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java index 274dca3a..2084793 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java
@@ -33,6 +33,7 @@ import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.app.tab_activity_glue.ReparentingTask; import org.chromium.chrome.browser.app.tabmodel.CustomTabsTabModelOrchestrator; +import org.chromium.chrome.browser.browserservices.intents.ColorProvider; import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.customtabs.CloseButtonNavigator; import org.chromium.chrome.browser.customtabs.CustomTabDelegateFactory; @@ -77,6 +78,7 @@ @Mock public CustomTabDelegateFactory customTabDelegateFactory; @Mock public ChromeActivity activity; @Mock public CustomTabsConnection connection; + @Mock public ColorProvider colorProvider; @Mock public CustomTabIntentDataProvider intentDataProvider; @Mock public TabObserverRegistrar tabObserverRegistrar; @Mock public CompositorViewHolder compositorViewHolder; @@ -143,6 +145,7 @@ when(startupTabPreloader.takeTabIfMatchingOrDestroy(any(), anyInt())).thenReturn(null); when(reparentingTaskProvider.get(any())).thenReturn(reparentingTask); when(activityTabProvider.addObserver(activityTabObserverCaptor.capture())).thenReturn(null); + when(intentDataProvider.getColorProvider()).thenReturn(colorProvider); } @Override
diff --git a/chrome/android/modules/chrome_bundle_tmpl.gni b/chrome/android/modules/chrome_bundle_tmpl.gni index 18233436..8ffac28 100644 --- a/chrome/android/modules/chrome_bundle_tmpl.gni +++ b/chrome/android/modules/chrome_bundle_tmpl.gni
@@ -164,7 +164,7 @@ proguard_enabled = !is_java_debug enable_language_splits = true extra_modules = _extra_modules - system_image_locale_allowlist = locales - android_bundle_only_locales + system_image_locale_allowlist = android_apk_locales is_multi_abi = _is_multi_abi validate_services = _enable_chrome_module
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 63411e7..4f9ad9f 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -4488,6 +4488,8 @@ "nearby_sharing/nearby_receive_manager.h", "nearby_sharing/nearby_share_delegate_impl.cc", "nearby_sharing/nearby_share_delegate_impl.h", + "nearby_sharing/nearby_share_feature_usage_metrics.cc", + "nearby_sharing/nearby_share_feature_usage_metrics.h", "nearby_sharing/nearby_share_metrics_logger.cc", "nearby_sharing/nearby_share_metrics_logger.h", "nearby_sharing/nearby_share_profile_info_provider_impl.cc", @@ -4630,6 +4632,7 @@ "//chrome/services/sharing/public/proto", "//chrome/services/speech:lib", "//chromeos/components/cdm_factory_daemon:cdm_factory_daemon_browser", + "//chromeos/components/feature_usage", "//chromeos/components/quick_answers", "//chromeos/components/sync_wifi", "//chromeos/crosapi/cpp",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index d732a99..edb817a 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -5374,6 +5374,13 @@ FEATURE_VALUE_TYPE(app_list_features::kEnableAssistantSearch)}, #endif // BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(ENABLE_EXTENSIONS) + {"strict-extension-isolation", + flag_descriptions::kStrictExtensionIsolationName, + flag_descriptions::kStrictExtensionIsolationDescription, kOsDesktop, + FEATURE_VALUE_TYPE(extensions_features::kStrictExtensionIsolation)}, +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + {"strict-origin-isolation", flag_descriptions::kStrictOriginIsolationName, flag_descriptions::kStrictOriginIsolationDescription, kOsAll, FEATURE_VALUE_TYPE(features::kStrictOriginIsolation)}, @@ -5506,6 +5513,10 @@ flag_descriptions::kEnableShortcutCustomizationAppName, flag_descriptions::kEnableShortcutCustomizationAppDescription, kOsCrOS, FEATURE_VALUE_TYPE(features::kShortcutCustomizationApp)}, + + {"enhanced-network-voices", flag_descriptions::kEnhancedNetworkVoicesName, + flag_descriptions::kEnhancedNetworkVoicesDescription, kOsCrOS, + FEATURE_VALUE_TYPE(features::kEnhancedNetworkVoices)}, #endif // BUILDFLAG(IS_CHROMEOS_ASH) {"enable-fenced-frames", flag_descriptions::kEnableFencedFramesName, @@ -6390,7 +6401,7 @@ {"conversion-measurement-api", flag_descriptions::kConversionMeasurementApiName, flag_descriptions::kConversionMeasurementApiDescription, kOsAll, - FEATURE_VALUE_TYPE(features::kConversionMeasurement)}, + FEATURE_VALUE_TYPE(blink::features::kConversionMeasurement)}, {"conversion-measurement-debug-mode", flag_descriptions::kConversionMeasurementDebugModeName, flag_descriptions::kConversionMeasurementDebugModeDescription, kOsAll,
diff --git a/chrome/browser/android/browserservices/intents/BUILD.gn b/chrome/browser/android/browserservices/intents/BUILD.gn index a668c3fc..d13d0d5 100644 --- a/chrome/browser/android/browserservices/intents/BUILD.gn +++ b/chrome/browser/android/browserservices/intents/BUILD.gn
@@ -8,6 +8,7 @@ sources = [ "java/src/org/chromium/chrome/browser/browserservices/intents/BitmapHelper.java", "java/src/org/chromium/chrome/browser/browserservices/intents/BrowserServicesIntentDataProvider.java", + "java/src/org/chromium/chrome/browser/browserservices/intents/ColorProvider.java", "java/src/org/chromium/chrome/browser/browserservices/intents/CustomButtonParams.java", "java/src/org/chromium/chrome/browser/browserservices/intents/WebApkExtras.java", "java/src/org/chromium/chrome/browser/browserservices/intents/WebApkShareTarget.java",
diff --git a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/BrowserServicesIntentDataProvider.java b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/BrowserServicesIntentDataProvider.java index df7bf30..07bb9eb4 100644 --- a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/BrowserServicesIntentDataProvider.java +++ b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/BrowserServicesIntentDataProvider.java
@@ -7,11 +7,11 @@ import android.app.PendingIntent; import android.content.ComponentName; import android.content.Intent; -import android.graphics.Color; import android.graphics.drawable.Drawable; import android.widget.RemoteViews; import androidx.annotation.IntDef; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.browser.customtabs.CustomTabsIntent; import androidx.browser.customtabs.CustomTabsSessionToken; @@ -145,35 +145,8 @@ return true; } - /** - * @return The toolbar color. - */ - public int getToolbarColor() { - return Color.WHITE; - } - - /** - * @return Whether the intent specifies a custom toolbar color. - */ - public boolean hasCustomToolbarColor() { - return false; - } - - /** - * @return The navigation bar color specified in the intent, or null if not specified. - */ - @Nullable - public Integer getNavigationBarColor() { - return null; - } - - /** - * @return The navigation bar divider color specified in the intent, or null if not specified. - */ - @Nullable - public Integer getNavigationBarDividerColor() { - return null; - } + @NonNull + public abstract ColorProvider getColorProvider(); /** * @return The drawable of the icon of close button shown in the custom tab toolbar. @@ -212,13 +185,6 @@ } /** - * @return The color of the bottom bar. - */ - public int getBottomBarColor() { - return getToolbarColor(); - } - - /** * @return The {@link RemoteViews} to show on the bottom bar, or null if the extra is not * specified. */ @@ -290,13 +256,6 @@ } /** - * @return Initial RGB background color. - */ - public int getInitialBackgroundColor() { - return Color.TRANSPARENT; - } - - /** * @return Whether there should be a star button in the menu. */ public boolean shouldShowStarButton() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabColorProvider.java b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/ColorProvider.java similarity index 72% rename from chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabColorProvider.java rename to chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/ColorProvider.java index ebe3c9f..05730e48 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabColorProvider.java +++ b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/ColorProvider.java
@@ -1,17 +1,15 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.customtabs; +package org.chromium.chrome.browser.browserservices.intents; import androidx.annotation.Nullable; /** - * Provides the set of colors used by custom tabs. + * Provides the set of colors used by BrowserServicesIntentDataProvider. */ -// TODO(sky): make BrowserServicesIntentDataProvider own this and move methods from -// BrowserServicesIntentDataProvider onto this. -public interface CustomTabColorProvider { +public interface ColorProvider { /** * @return The color of the bottom bar. */
diff --git a/chrome/browser/apps/icon_standardizer.cc b/chrome/browser/apps/icon_standardizer.cc index 68433fcb..4c46b97 100644 --- a/chrome/browser/apps/icon_standardizer.cc +++ b/chrome/browser/apps/icon_standardizer.cc
@@ -21,6 +21,8 @@ constexpr float kBackgroundCircleScale = 176.0f / 192.0f; +constexpr float kMinimumVisibleCircularIconSizeRatio = 0.625f; + // Returns the bounding rect for the opaque part of the icon. gfx::Rect GetVisibleIconBounds(const SkBitmap& bitmap) { const SkPixmap pixmap = bitmap.pixmap(); @@ -152,13 +154,13 @@ preview.eraseColor(SK_ColorTRANSPARENT); // |preview| will be the original icon with all visible pixels colored red. - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - const SkColor* src_color = - reinterpret_cast<SkColor*>(bitmap.getAddr32(0, y)); - SkColor* preview_color = - reinterpret_cast<SkColor*>(preview.getAddr32(0, y)); + for (int y = 0; y < height; y++) { + const SkColor* src_color = + reinterpret_cast<SkColor*>(bitmap.getAddr32(0, y)); + SkColor* preview_color = + reinterpret_cast<SkColor*>(preview.getAddr32(0, y)); + for (int x = 0; x < width; x++) { SkColor target_color; if (SkColorGetA(src_color[x]) < 1) { @@ -172,37 +174,15 @@ } gfx::Rect visible_preview_bounds = GetVisibleIconBounds(preview); - float visible_icon_diagonal = std::sqrt( - visible_preview_bounds.height() * visible_preview_bounds.height() + - visible_preview_bounds.width() * visible_preview_bounds.width()); - float preview_diagonal = std::sqrt(preview.height() * preview.height() + - preview.width() * preview.width()); - - float scale = preview_diagonal / visible_icon_diagonal; - - // If the visible icon requires too large of a scale, then the icon is small - // enough that it should not be considered circular. This also serves as a - // speculative crash fix by setting an upper limit on |scale| in the case it - // is too large. (crbug.com/1162155) - if (scale >= 1.6f) + float visible_icon_size_ratio = + static_cast<float>(visible_preview_bounds.width()) / + static_cast<float>(width); + // If the visible icon is too small then it should not be considered + // circular. + if (visible_icon_size_ratio < kMinimumVisibleCircularIconSizeRatio) return false; - gfx::Size scaled_icon_size = - gfx::ScaleToRoundedSize(rep.pixel_size(), scale); - - // To detect a circle shaped icon of any size, resize and scale |preview| so - // the visible icon bounds match the maximum width and height of the bitmap. - const SkBitmap scaled_preview = skia::ImageOperations::Resize( - preview, skia::ImageOperations::RESIZE_BEST, scaled_icon_size.width(), - scaled_icon_size.height()); - - preview.eraseColor(SK_ColorTRANSPARENT); - SkCanvas canvas1(preview); - canvas1.drawImage(scaled_preview.asImage(), - -visible_preview_bounds.x() * scale, - -visible_preview_bounds.y() * scale); - // Use a canvas to perform XOR and DST_OUT operations, which should // generate a transparent bitmap for |preview| if the original icon is // shaped like a circle. @@ -214,14 +194,15 @@ // XOR operation to remove a circle. paint_circle_mask.setBlendMode(SkBlendMode::kXor); - canvas.drawCircle(SkPoint::Make(width / 2.0f, height / 2.0f), width / 2.0, - paint_circle_mask); + canvas.drawCircle(SkPoint::Make(width / 2.0f, height / 2.0f), + visible_preview_bounds.width() / 2.0f, paint_circle_mask); SkPaint paint_outline; paint_outline.setColor(SK_ColorGREEN); paint_outline.setStyle(SkPaint::kStroke_Style); - const float outline_stroke_width = width * kCircleOutlineStrokeWidthRatio; + const float outline_stroke_width = + visible_preview_bounds.width() * kCircleOutlineStrokeWidthRatio; const float radius_offset = outline_stroke_width / 8.0f; paint_outline.setStrokeWidth(outline_stroke_width); @@ -230,7 +211,8 @@ // DST_OUT operation to remove an extra circle outline. paint_outline.setBlendMode(SkBlendMode::kDstOut); canvas.drawCircle(SkPoint::Make(width / 2.0f, height / 2.0f), - width / 2.0f + radius_offset, paint_outline); + visible_preview_bounds.width() / 2.0f + radius_offset, + paint_outline); // Compute the total pixel difference between the circle mask and the // original icon. @@ -244,7 +226,8 @@ } float percentage_diff_pixels = - static_cast<float>(total_pixel_difference) / (width * height); + static_cast<float>(total_pixel_difference) / + (visible_preview_bounds.width() * visible_preview_bounds.height()); // If the pixel difference between a circle and the original icon is small // enough, then the icon can be considered circle shaped.
diff --git a/chrome/browser/ash/login/ui/captive_portal_window_browsertest.cc b/chrome/browser/ash/login/ui/captive_portal_window_browsertest.cc index c8652d09..710c539 100644 --- a/chrome/browser/ash/login/ui/captive_portal_window_browsertest.cc +++ b/chrome/browser/ash/login/ui/captive_portal_window_browsertest.cc
@@ -215,7 +215,9 @@ DISALLOW_COPY_AND_ASSIGN(CaptivePortalWindowCtorDtorTest); }; -IN_PROC_BROWSER_TEST_F(CaptivePortalWindowCtorDtorTest, OpenPortalDialog) { +// TODO(https://crbug.com/1213549): Flaky on linux-chromeos-rel. +IN_PROC_BROWSER_TEST_F(CaptivePortalWindowCtorDtorTest, + DISABLED_OpenPortalDialog) { LoginDisplayHost* host = LoginDisplayHost::default_host(); ASSERT_TRUE(host); OobeUI* oobe = host->GetOobeUI();
diff --git a/chrome/browser/attribution_reporting/chrome_attribution_browsertest.cc b/chrome/browser/attribution_reporting/chrome_attribution_browsertest.cc index 028ca2939..ec3af52 100644 --- a/chrome/browser/attribution_reporting/chrome_attribution_browsertest.cc +++ b/chrome/browser/attribution_reporting/chrome_attribution_browsertest.cc
@@ -4,14 +4,12 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/page_load_metrics/browser/page_load_metrics_test_waiter.h" #include "content/public/browser/web_contents.h" -#include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" @@ -26,9 +24,7 @@ // content shell. class ChromeAttributionBrowserTest : public InProcessBrowserTest { public: - ChromeAttributionBrowserTest() { - feature_list_.InitAndEnableFeature(features::kConversionMeasurement); - } + ChromeAttributionBrowserTest() = default; void SetUpCommandLine(base::CommandLine* command_line) override { // Sets up the blink runtime feature for ConversionMeasurement. @@ -47,9 +43,6 @@ protected: net::EmbeddedTestServer server_{net::EmbeddedTestServer::TYPE_HTTPS}; - - private: - base::test::ScopedFeatureList feature_list_; }; IN_PROC_BROWSER_TEST_F(ChromeAttributionBrowserTest,
diff --git a/chrome/browser/attribution_reporting/conversions_usage_restriction_trial_browsertest.cc b/chrome/browser/attribution_reporting/conversions_usage_restriction_trial_browsertest.cc index 2fd44aa..d7c8601 100644 --- a/chrome/browser/attribution_reporting/conversions_usage_restriction_trial_browsertest.cc +++ b/chrome/browser/attribution_reporting/conversions_usage_restriction_trial_browsertest.cc
@@ -74,8 +74,7 @@ // Disable the alternative usage feature, this should prevent the OT token // from enabling the API. feature_list_.InitWithFeatures( - {features::kConversionMeasurement}, - {embedder_support::kConversionMeasurementAPIAlternativeUsage}); + {}, {embedder_support::kConversionMeasurementAPIAlternativeUsage}); } private: @@ -100,9 +99,7 @@ // Enable the alternative usage feature, this should allow the OT token to // enable the API. feature_list_.InitWithFeatures( - {features::kConversionMeasurement, - embedder_support::kConversionMeasurementAPIAlternativeUsage}, - {}); + {embedder_support::kConversionMeasurementAPIAlternativeUsage}, {}); } private:
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index e6ba098..c2169a0c 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1963,6 +1963,15 @@ return true; } +size_t ChromeContentBrowserClient::GetProcessCountToIgnoreForLimit() { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeContentBrowserClientExtensionsPart:: + GetProcessCountToIgnoreForLimit(); +#else + return 0; +#endif +} + bool ChromeContentBrowserClient::ShouldTryToUseExistingProcessHost( content::BrowserContext* browser_context, const GURL& url) {
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 8a2e7ea..b0d91a2 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -199,6 +199,7 @@ bool IsSuitableHost(content::RenderProcessHost* process_host, const GURL& site_url) override; bool MayReuseHost(content::RenderProcessHost* process_host) override; + size_t GetProcessCountToIgnoreForLimit() override; bool ShouldTryToUseExistingProcessHost( content::BrowserContext* browser_context, const GURL& url) override;
diff --git a/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc b/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc index 49c40fc..170ba95e 100644 --- a/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc +++ b/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc
@@ -24,6 +24,9 @@ #include "content/public/browser/storage_partition.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" +#include "extensions/browser/api/declarative/rules_registry.h" +#include "extensions/browser/api/declarative/rules_registry_service.h" +#include "extensions/browser/api/declarative_webrequest/webrequest_constants.h" #include "extensions/browser/extension_action.h" #include "extensions/browser/extension_action_manager.h" #include "extensions/browser/extension_registry.h" @@ -1029,6 +1032,52 @@ ExecuteScriptInBackgroundPage(extension->id(), kRemoveTestRule1)); } +// Test that an extension with a RequestContentScript rule in its manifest can +// be loaded. +// Regression for crbug.com/1211316, which could cause this test to flake if +// RulesRegistry::OnExtensionLoaded() was called before +// UserScriptmanager::OnExtensionLoaded(). +IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, RequestContentScriptRule) { + constexpr char kManifest[] = R"( + { + "name": "Declarative Content apitest", + "version": "0.1", + "manifest_version": 2, + "page_action": {}, + "permissions": [ + "declarativeContent" + ], + "event_rules": [{ + "event": "declarativeContent.onPageChanged", + "actions": [{ + "type": "declarativeContent.RequestContentScript", + "js": ["asdf.js"] + }], + "conditions": [{ + "type": "declarativeContent.PageStateMatcher", + "pageUrl": {"hostPrefix": "test1"} + }] + }] + } + )"; + + ext_dir_.WriteManifest(kManifest); + const Extension* extension = LoadExtension(ext_dir_.UnpackedPath()); + ASSERT_TRUE(extension); + + RulesRegistryService* rules_registry_service = + extensions::RulesRegistryService::Get(browser()->profile()); + scoped_refptr<RulesRegistry> rules_registry = + rules_registry_service->GetRulesRegistry( + RulesRegistryService::kDefaultRulesRegistryID, + "declarativeContent.onPageChanged"); + DCHECK(rules_registry); + + std::vector<const api::events::Rule*> rules; + rules_registry->GetAllRules(extension->id(), &rules); + EXPECT_EQ(1u, rules.size()); +} + // TODO(wittman): Once ChromeContentRulesRegistry operates on condition and // action interfaces, add a test that checks that a navigation always evaluates // consistent URL state for all conditions. i.e.: if condition1 evaluates to
diff --git a/chrome/browser/extensions/api/socket/socket_api_unittest.cc b/chrome/browser/extensions/api/socket/socket_api_unittest.cc index 59475e98..d9cba341 100644 --- a/chrome/browser/extensions/api/socket/socket_api_unittest.cc +++ b/chrome/browser/extensions/api/socket/socket_api_unittest.cc
@@ -39,7 +39,6 @@ TEST_F(SocketUnitTest, Create) { // Create SocketCreateFunction and put it on BrowserThread SocketCreateFunction* function = new SocketCreateFunction(); - function->set_work_task_runner(base::SequencedTaskRunnerHandle::Get()); // Run tests std::unique_ptr<base::DictionaryValue> result(
diff --git a/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_api_unittest.cc b/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_api_unittest.cc index 40210ce..066526e 100644 --- a/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_api_unittest.cc +++ b/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_api_unittest.cc
@@ -54,7 +54,6 @@ // Create SocketCreateFunction and put it on BrowserThread SocketsTcpServerCreateFunction* function = new SocketsTcpServerCreateFunction(); - function->set_work_task_runner(base::SequencedTaskRunnerHandle::Get()); // Run tests std::unique_ptr<base::DictionaryValue> result(RunFunctionAndReturnDictionary(
diff --git a/chrome/browser/extensions/chrome_app_sorting.cc b/chrome/browser/extensions/chrome_app_sorting.cc index 4430a8e..12bba92 100644 --- a/chrome/browser/extensions/chrome_app_sorting.cc +++ b/chrome/browser/extensions/chrome_app_sorting.cc
@@ -81,7 +81,14 @@ : browser_context_(browser_context), default_ordinals_created_(false) { ExtensionIdList extensions; - ExtensionPrefs::Get(browser_context_)->GetExtensions(&extensions); + ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_); + std::unique_ptr<extensions::ExtensionPrefs::ExtensionsInfo> extensions_info = + prefs->GetInstalledExtensionsInfo(); + for (size_t i = 0; i < extensions_info->size(); ++i) { + ExtensionInfo* info = extensions_info->at(i).get(); + if (!prefs->IsFromBookmark(info->extension_id)) + extensions.push_back(info->extension_id); + } InitializePageOrdinalMap(extensions); MigrateAppIndex(extensions); } @@ -201,6 +208,16 @@ InitializePageOrdinalMap(web_app_registrar_->GetAppIds()); } +void ChromeAppSorting::SetWebAppRegistrarForTesting( + const web_app::WebAppRegistrar* web_app_registrar) { + web_app_registrar_ = web_app_registrar; +} + +void ChromeAppSorting::SetWebAppSyncBridgeForTesting( + web_app::WebAppSyncBridge* sync_bridge) { + web_app_sync_bridge_ = sync_bridge; +} + void ChromeAppSorting::FixNTPOrdinalCollisions() { for (auto page_it = ntp_ordinal_map_.begin(); page_it != ntp_ordinal_map_.end(); ++page_it) {
diff --git a/chrome/browser/extensions/chrome_app_sorting.h b/chrome/browser/extensions/chrome_app_sorting.h index 7d28ea1..fb574569 100644 --- a/chrome/browser/extensions/chrome_app_sorting.h +++ b/chrome/browser/extensions/chrome_app_sorting.h
@@ -96,6 +96,7 @@ friend class ChromeAppSortingInitializeWithNoApps; friend class ChromeAppSortingPageOrdinalMapping; friend class ChromeAppSortingSetExtensionVisible; + friend class ChromeAppSortingMigratedBookmarkApp; // An enum used by GetMinOrMaxAppLaunchOrdinalsOnPage to specify which // value should be returned. @@ -165,6 +166,13 @@ // Returns the number of items in |m| visible on the new tab page. size_t CountItemsVisibleOnNtp(const AppLaunchOrdinalMap& m) const; + // Sets |web_app_registrar_|. Only for use by tests. + void SetWebAppRegistrarForTesting( + const web_app::WebAppRegistrar* web_app_registrar); + + // Sets |web_app_sync_bridge_|. Only for use by tests. + void SetWebAppSyncBridgeForTesting(web_app::WebAppSyncBridge* sync_bridge); + content::BrowserContext* const browser_context_ = nullptr; const web_app::WebAppRegistrar* web_app_registrar_ = nullptr; web_app::WebAppSyncBridge* web_app_sync_bridge_ = nullptr;
diff --git a/chrome/browser/extensions/chrome_app_sorting_unittest.cc b/chrome/browser/extensions/chrome_app_sorting_unittest.cc index 1a75eec..4526c2e 100644 --- a/chrome/browser/extensions/chrome_app_sorting_unittest.cc +++ b/chrome/browser/extensions/chrome_app_sorting_unittest.cc
@@ -7,6 +7,8 @@ #include <memory> #include "chrome/browser/extensions/extension_prefs_unittest.h" +#include "chrome/browser/web_applications/test/test_web_app_registry_controller.h" +#include "chrome/browser/web_applications/web_app.h" #include "components/crx_file/id_util.h" #include "components/sync/model/string_ordinal.h" #include "extensions/common/constants.h" @@ -938,4 +940,180 @@ ChromeAppSortingSetExtensionVisible) { } +class ChromeAppSortingMigratedBookmarkApp : public ExtensionPrefsTest { + public: + ChromeAppSortingMigratedBookmarkApp() {} + ~ChromeAppSortingMigratedBookmarkApp() override {} + + void Initialize() override { + base::DictionaryValue simple_dict; + std::string error; + + simple_dict.SetString(manifest_keys::kVersion, "1.0.0.0"); + simple_dict.SetInteger(manifest_keys::kManifestVersion, 2); + + // Say that ext1_ is a from_bookmark app that has been migrated to webapp. + // It should not be added to page ordinal map, since bookmark apps migrated + // to webapps are no longer used, but are still present. The web app added + // below will be used instead. + simple_dict.SetString(manifest_keys::kName, "ext1_"); + extension1_ = prefs_.AddExtensionWithManifestAndFlags( + simple_dict, ManifestLocation::kExternalPref, Extension::FROM_BOOKMARK); + + simple_dict.SetString(manifest_keys::kName, "ext2_"); + extension2_ = prefs_.AddExtensionWithManifestAndFlags( + simple_dict, ManifestLocation::kExternalPref, Extension::NO_FLAGS); + + simple_dict.SetString(manifest_keys::kName, "ext3_"); + extension3_ = prefs_.AddExtensionWithManifestAndFlags( + simple_dict, ManifestLocation::kExternalPref, Extension::NO_FLAGS); + + repeated_ordinal_ = syncer::StringOrdinal::CreateInitialOrdinal(); + second_ordinal_ = repeated_ordinal_.CreateAfter(); + third_ordinal_ = second_ordinal_.CreateAfter(); + + // A preference determining the order of which the apps appear on the NTP. + const char kPrefAppLaunchOrdinal[] = "app_launcher_ordinal"; + // A preference determining the page on which an app appears in the NTP. + const char kPrefPageOrdinal[] = "page_ordinal"; + + // Set the pref values for which ordinals the extensions should use. This + // intentionally does not use ChromeAppSorting::SetAppLaunchOrdinal and + // SetPageOrdinal since those also insert entries into ntp_ordinal_map_. + + // Old ordinals still exist for the ext1_ bookmark app that was migrated to + // webapp. These would create a collision with ext2, but should be ignored. + prefs()->UpdateExtensionPref( + extension1_->id(), kPrefAppLaunchOrdinal, + std::make_unique<base::Value>(repeated_ordinal_.ToInternalValue())); + prefs()->UpdateExtensionPref( + extension1_->id(), kPrefPageOrdinal, + std::make_unique<base::Value>(repeated_ordinal_.ToInternalValue())); + + prefs()->UpdateExtensionPref( + extension2_->id(), kPrefAppLaunchOrdinal, + std::make_unique<base::Value>(repeated_ordinal_.ToInternalValue())); + prefs()->UpdateExtensionPref( + extension2_->id(), kPrefPageOrdinal, + std::make_unique<base::Value>(repeated_ordinal_.ToInternalValue())); + + prefs()->UpdateExtensionPref( + extension3_->id(), kPrefAppLaunchOrdinal, + std::make_unique<base::Value>(third_ordinal_.ToInternalValue())); + prefs()->UpdateExtensionPref( + extension3_->id(), kPrefPageOrdinal, + std::make_unique<base::Value>(third_ordinal_.ToInternalValue())); + + // Double check that the prefs set above are read correctly by + // ChromeAppSorting. + EXPECT_TRUE(repeated_ordinal_.Equals( + app_sorting()->GetAppLaunchOrdinal(extension1_->id()))); + EXPECT_TRUE(repeated_ordinal_.Equals( + app_sorting()->GetPageOrdinal(extension1_->id()))); + + EXPECT_TRUE(repeated_ordinal_.Equals( + app_sorting()->GetAppLaunchOrdinal(extension2_->id()))); + EXPECT_TRUE(repeated_ordinal_.Equals( + app_sorting()->GetPageOrdinal(extension2_->id()))); + + EXPECT_TRUE(third_ordinal_.Equals( + app_sorting()->GetAppLaunchOrdinal(extension3_->id()))); + EXPECT_TRUE(third_ordinal_.Equals( + app_sorting()->GetPageOrdinal(extension3_->id()))); + + // Recreate ExtensionPrefs, which recreates app_sorting, which should now + // find the above created extensions and insert them into ntp_ordinal_map_. + prefs_.RecreateExtensionPrefs(); + + // Only two items should be in ordinal map, since ext1_ was ignored. + EXPECT_EQ(2U, CountElementsInOrdinalMap()); + + // Webapps are added to ChromeAppSorting asynchronously sometime after it + // is created. Simulate that now. + test_registry_controller_ = + std::make_unique<web_app::TestWebAppRegistryController>(); + test_registry_controller_->SetUp(prefs_.profile()); + test_registry_controller_->Init(); + + auto web_app = std::make_unique<web_app::WebApp>(extension1_->id()); + web_app->SetName("name1"); + web_app->SetStartUrl(GURL("https://example.com/path")); + web_app->SetDisplayMode(web_app::DisplayMode::kStandalone); + web_app->SetUserDisplayMode(web_app::DisplayMode::kStandalone); + web_app->AddSource(web_app::Source::kSync); + web_app->SetUserLaunchOrdinal(second_ordinal_); + web_app->SetUserPageOrdinal(repeated_ordinal_); + test_registry_controller_->RegisterApp(std::move(web_app)); + + // Emulate app_sorting()->InitializePageOrdinalMapFromWebApps() without + // needing a WebAppProvider: + app_sorting()->SetWebAppRegistrarForTesting( + &test_registry_controller_->registrar()); + app_sorting()->SetWebAppSyncBridgeForTesting( + &test_registry_controller_->sync_bridge()); + app_sorting()->InitializePageOrdinalMap( + test_registry_controller_->registrar().GetAppIds()); + + // Now that the bookmark app that was migrated to a webapp was added, there + // should be three items in ordinal map. + EXPECT_EQ(3U, CountElementsInOrdinalMap()); + + // Now call FixNTPOrdinalCollisions and see what happens. + app_sorting()->FixNTPOrdinalCollisions(); + + // Verification is done here rather than in Verify() since + // ExtensionPrefsTest verifies twice, once after recreating the + // ExtensionPrefs, which won't include the web_app we registered here. + + // The ordinals should be unchanged since old bookmark app ordinals were + // ignored, there were not actually any collisions. + EXPECT_EQ(3U, CountElementsInOrdinalMap()); + EXPECT_TRUE(app_sorting() + ->GetAppLaunchOrdinal(extension1_->id()) + .Equals(second_ordinal_)); + EXPECT_TRUE(app_sorting() + ->GetPageOrdinal(extension1_->id()) + .Equals(repeated_ordinal_)); + EXPECT_TRUE(app_sorting() + ->GetAppLaunchOrdinal(extension2_->id()) + .Equals(repeated_ordinal_)); + EXPECT_TRUE(app_sorting() + ->GetPageOrdinal(extension2_->id()) + .Equals(repeated_ordinal_)); + EXPECT_TRUE(app_sorting() + ->GetAppLaunchOrdinal(extension3_->id()) + .Equals(third_ordinal_)); + EXPECT_TRUE(app_sorting() + ->GetPageOrdinal(extension3_->id()) + .Equals(third_ordinal_)); + } + + void Verify() override { + // Verification is done at the end of Initialize(), see comment there for + // details. + } + + private: + size_t CountElementsInOrdinalMap() { + size_t count = 0; + for (const auto& page : app_sorting()->ntp_ordinal_map_) { + count += page.second.size(); + } + return count; + } + + syncer::StringOrdinal repeated_ordinal_; + syncer::StringOrdinal second_ordinal_; + syncer::StringOrdinal third_ordinal_; + + scoped_refptr<Extension> extension1_; + scoped_refptr<Extension> extension2_; + scoped_refptr<Extension> extension3_; + + std::unique_ptr<web_app::TestWebAppRegistryController> + test_registry_controller_; +}; +TEST_F(ChromeAppSortingMigratedBookmarkApp, + ChromeAppSortingMigratedBookmarkApp) {} + } // namespace extensions
diff --git a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc index f37a1c5..0ef90ac3 100644 --- a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc +++ b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc
@@ -6,6 +6,7 @@ #include <stddef.h> +#include <algorithm> #include <memory> #include <set> #include <string> @@ -13,6 +14,7 @@ #include "base/bind.h" #include "base/command_line.h" +#include "base/feature_list.h" #include "base/metrics/histogram_macros.h" #include "base/strings/string_piece.h" #include "build/chromeos_buildflags.h" @@ -63,6 +65,7 @@ #include "extensions/browser/url_request_util.h" #include "extensions/browser/view_type_utils.h" #include "extensions/common/constants.h" +#include "extensions/common/extension_features.h" #include "extensions/common/extension_urls.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_handlers/app_isolation_info.h" @@ -195,6 +198,26 @@ return script_url == extension->GetResourceURL(sw_script); } +// Returns the number of processes containing extension background pages across +// all profiles. If this is large enough (e.g., at browser startup time), it can +// pose a risk that normal web processes will be overly constrained by the +// browser's process limit. +size_t GetExtensionBackgroundProcessCount() { + std::set<int> process_ids; + + // Go through all profiles to ensure we have total count of extension + // processes containing background pages, otherwise one profile can + // starve the other. See https://crbug.com/98737. + std::vector<Profile*> profiles = + g_browser_process->profile_manager()->GetLoadedProfiles(); + for (Profile* profile : profiles) { + ProcessManager* epm = ProcessManager::Get(profile); + for (ExtensionHost* host : epm->background_hosts()) + process_ids.insert(host->render_process_host()->GetID()); + } + return process_ids.size(); +} + } // namespace ChromeContentBrowserClientExtensionsPart:: @@ -331,6 +354,13 @@ bool ChromeContentBrowserClientExtensionsPart::ShouldLockProcessToSite( content::BrowserContext* browser_context, const GURL& effective_site_url) { + // When strict extension isolation is enabled, all extension processes should + // be locked. + if (base::FeatureList::IsEnabled( + extensions_features::kStrictExtensionIsolation)) { + return true; + } + if (!effective_site_url.SchemeIs(kExtensionScheme)) return true; @@ -472,6 +502,13 @@ bool ChromeContentBrowserClientExtensionsPart::ShouldTryToUseExistingProcessHost( Profile* profile, const GURL& url) { + // When strict extension isolation is enabled, no extensions need to reuse an + // existing process. + if (base::FeatureList::IsEnabled( + extensions_features::kStrictExtensionIsolation)) { + return false; + } + // This function is trying to limit the amount of processes used by extensions // with background pages. It uses a globally set percentage of processes to // run such extensions and if the limit is exceeded, it returns true, to @@ -489,23 +526,34 @@ if (!BackgroundInfo::HasBackgroundPage(extension)) return false; - std::set<int> process_ids; + size_t max_process_count = + content::RenderProcessHost::GetMaxRendererProcessCount(); + return (GetExtensionBackgroundProcessCount() > + (max_process_count * chrome::kMaxShareOfExtensionProcesses)); +} + +size_t +ChromeContentBrowserClientExtensionsPart::GetProcessCountToIgnoreForLimit() { + // If strict extension isolation is enabled, ignore any extension processes + // that are beyond the extension-specific process limit when considering + // whether processes should be reused for other types of pages. + + // If this is a unit test with no profile manager, or if strict extension + // isolation is disabled, there is no need to ignore any processes. + if (!g_browser_process->profile_manager() || + !base::FeatureList::IsEnabled( + extensions_features::kStrictExtensionIsolation)) { + return 0; + } + size_t max_process_count = content::RenderProcessHost::GetMaxRendererProcessCount(); - // Go through all profiles to ensure we have total count of extension - // processes containing background pages, otherwise one profile can - // starve the other. - std::vector<Profile*> profiles = g_browser_process->profile_manager()-> - GetLoadedProfiles(); - for (size_t i = 0; i < profiles.size(); ++i) { - ProcessManager* epm = ProcessManager::Get(profiles[i]); - for (ExtensionHost* host : epm->background_hosts()) - process_ids.insert(host->render_process_host()->GetID()); - } - - return (process_ids.size() > - (max_process_count * chrome::kMaxShareOfExtensionProcesses)); + // Ignore any extension background processes over the extension portion of the + // process limit when deciding whether to reuse other renderer processes. + return std::max(0, static_cast<int>(GetExtensionBackgroundProcessCount() - + (max_process_count * + chrome::kMaxShareOfExtensionProcesses))); } // static
diff --git a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.h b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.h index eefa114..7ed95d5 100644 --- a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.h +++ b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.h
@@ -71,6 +71,7 @@ const GURL& site_url); static bool ShouldTryToUseExistingProcessHost(Profile* profile, const GURL& url); + static size_t GetProcessCountToIgnoreForLimit(); static bool ShouldSubframesTryToReuseExistingProcess( content::RenderFrameHost* main_frame); static bool ShouldSwapBrowsingInstancesForNavigation(
diff --git a/chrome/browser/extensions/navigation_observer_browsertest.cc b/chrome/browser/extensions/navigation_observer_browsertest.cc index b2f4801..8e8bdeb 100644 --- a/chrome/browser/extensions/navigation_observer_browsertest.cc +++ b/chrome/browser/extensions/navigation_observer_browsertest.cc
@@ -4,6 +4,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" +#include "base/feature_list.h" #include "base/run_loop.h" #include "chrome/browser/extensions/chrome_test_extension_loader.h" #include "chrome/browser/extensions/extension_browsertest.h" @@ -11,6 +12,7 @@ #include "chrome/browser/extensions/navigation_observer.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/ui_test_utils.h" +#include "content/public/common/content_features.h" #include "content/public/test/browser_test.h" #include "content/public/test/no_renderer_crashes_assertion.h" #include "content/public/test/test_navigation_observer.h" @@ -18,9 +20,19 @@ #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" +#include "extensions/common/extension_features.h" namespace extensions { +namespace { + +bool IsStrictExtensionIsolationEnabled() { + return base::FeatureList::IsEnabled( + extensions_features::kStrictExtensionIsolation); +} + +} // namespace + // A class for testing various scenarios of disabled extensions. class DisableExtensionBrowserTest : public ExtensionBrowserTest { protected: @@ -184,9 +196,11 @@ scoped_refptr<content::SiteInstance> extension_site_instance = subframe->GetSiteInstance(); - // The extension process shouldn't be locked, since multiple extensions are - // allowed to reuse the same extension process. - EXPECT_FALSE(subframe->GetProcess()->IsProcessLockedToSiteForTesting()); + // The extension process should only be locked if strict extension isolation + // is enabled, since multiple extensions are normally allowed to reuse the + // same extension process. + EXPECT_EQ(IsStrictExtensionIsolationEnabled(), + subframe->GetProcess()->IsProcessLockedToSiteForTesting()); // Disable the extension. extension_service()->DisableExtension(extension->id(), @@ -212,8 +226,10 @@ EXPECT_EQ(subframe->GetSiteInstance()->GetSiteURL(), GURL(chrome::kExtensionInvalidRequestURL)); - // The disabled extension process also shouldn't be locked. - EXPECT_FALSE(subframe->GetProcess()->IsProcessLockedToSiteForTesting()); + // The disabled extension process should only be locked if strict extension + // isolation is enabled. + EXPECT_EQ(IsStrictExtensionIsolationEnabled(), + subframe->GetProcess()->IsProcessLockedToSiteForTesting()); // Re-enable the extension. extension_service()->EnableExtension(extension->id()); @@ -226,7 +242,8 @@ subframe = ChildFrameAt(web_contents->GetMainFrame(), 0); EXPECT_TRUE(subframe->IsRenderFrameLive()); EXPECT_EQ(subframe->GetSiteInstance(), extension_site_instance); - EXPECT_FALSE(subframe->GetProcess()->IsProcessLockedToSiteForTesting()); + EXPECT_EQ(IsStrictExtensionIsolationEnabled(), + subframe->GetProcess()->IsProcessLockedToSiteForTesting()); } IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, NoExtensionsInRefererHeader) {
diff --git a/chrome/browser/extensions/process_management_browsertest.cc b/chrome/browser/extensions/process_management_browsertest.cc index 4a668cb..bebf41b 100644 --- a/chrome/browser/extensions/process_management_browsertest.cc +++ b/chrome/browser/extensions/process_management_browsertest.cc
@@ -4,6 +4,7 @@ #include <stddef.h> +#include "base/feature_list.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" @@ -33,6 +34,7 @@ #include "extensions/browser/extension_host.h" #include "extensions/browser/process_manager.h" #include "extensions/browser/process_map.h" +#include "extensions/common/extension_features.h" #include "extensions/common/manifest_handlers/web_accessible_resources_info.h" #include "extensions/common/switches.h" #include "net/dns/mock_host_resolver.h" @@ -46,9 +48,8 @@ namespace { bool IsExtensionProcessSharingAllowed() { - // TODO(nick): Currently, process sharing is allowed even in - // --site-per-process. Lock this down. https://crbug.com/766267 - return true; + return !base::FeatureList::IsEnabled( + extensions_features::kStrictExtensionIsolation); } class ProcessManagementTest : public ExtensionBrowserTest { @@ -386,6 +387,144 @@ EXPECT_EQ(5u, process_map->size()); } +// Parameterized tests that run with and without StrictExtensionIsolation, to +// ensure we have test coverage for both paths. +class ProcessManagementExtensionIsolationTest + : public ProcessManagementTest, + public ::testing::WithParamInterface<bool> { + public: + ProcessManagementExtensionIsolationTest() { + if (GetParam()) { + feature_list_.InitAndEnableFeature( + extensions_features::kStrictExtensionIsolation); + } else { + feature_list_.InitAndDisableFeature( + extensions_features::kStrictExtensionIsolation); + } + } + + // Provides meaningful param names instead of /0, /1, ... + static std::string DescribeParams( + const testing::TestParamInfo<ParamType>& info) { + return info.param ? "StrictExtensionIsolation" : "ExtensionSharing"; + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +// Test that pushing both extensions and web processes past the limit creates +// the expected number of processes. +// +// Sets the process limit to 3, with 1 expected extension process when sharing +// is allowed between extensions. The test then creates 3 separate extensions, +// 3 same-site web pages, and 1 cross-site web page. +// +// With extension process sharing, there should be 1 process for all extensions, +// 2 processes for the same-site pages, and an extra process for the cross-site +// page due to Site Isolation. +// +// Without extension process sharing, there should be 3 processes for the +// extensions. The web pages should act as if there were only 1 process used by +// the extensions, so there are 2 web processes for the same-site pages, and an +// extra process for the cross-site page due to Site Isolation. +IN_PROC_BROWSER_TEST_P(ProcessManagementExtensionIsolationTest, + ExtensionAndWebProcessOverflow) { + // Set max renderers to 3, to expect a single extension process when sharing + // is allowed. + content::RenderProcessHost::SetMaxRendererProcessCount(3); + + ASSERT_TRUE(embedded_test_server()->Start()); + + // Load 3 extensions with background processes, similar to Chrome startup. + ASSERT_TRUE(LoadExtension( + test_data_dir_.AppendASCII("api_test/browser_action/none"))); + ASSERT_TRUE(LoadExtension( + test_data_dir_.AppendASCII("api_test/browser_action/basics"))); + ASSERT_TRUE(LoadExtension( + test_data_dir_.AppendASCII("api_test/browser_action/add_popup"))); + + // Verify the number of extension processes. + std::set<int> process_ids; + Profile* profile = browser()->profile(); + ProcessManager* epm = ProcessManager::Get(profile); + for (ExtensionHost* host : epm->background_hosts()) { + SCOPED_TRACE(testing::Message() + << "When testing extension: " << host->extension_id()); + // The process should be locked iff process sharing is not allowed. + EXPECT_NE(IsExtensionProcessSharingAllowed(), + host->render_process_host()->IsProcessLockedToSiteForTesting()); + process_ids.insert(host->render_process_host()->GetID()); + } + if (IsExtensionProcessSharingAllowed()) { + // All extensions share a single process, since this is 1/3 the process + // limit. + EXPECT_EQ(1u, process_ids.size()); + } else { + // Each extension is in a locked process, unavailable for sharing. + EXPECT_EQ(3u, process_ids.size()); + } + + // Load 3 same-site tabs after the extensions. + GURL web_url1(embedded_test_server()->GetURL("foo.com", "/title1.html")); + GURL web_url2(embedded_test_server()->GetURL("foo.com", "/title2.html")); + GURL web_url3(embedded_test_server()->GetURL("foo.com", "/title3.html")); + ui_test_utils::NavigateToURLWithDisposition( + browser(), web_url1, WindowOpenDisposition::CURRENT_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + WebContents* web_contents1 = + browser()->tab_strip_model()->GetActiveWebContents(); + ui_test_utils::NavigateToURLWithDisposition( + browser(), web_url2, WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + WebContents* web_contents2 = + browser()->tab_strip_model()->GetActiveWebContents(); + ui_test_utils::NavigateToURLWithDisposition( + browser(), web_url3, WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + WebContents* web_contents3 = + browser()->tab_strip_model()->GetActiveWebContents(); + + // Verify the number of processes across extensions and tabs. + process_ids.insert(web_contents1->GetMainFrame()->GetProcess()->GetID()); + process_ids.insert(web_contents2->GetMainFrame()->GetProcess()->GetID()); + process_ids.insert(web_contents3->GetMainFrame()->GetProcess()->GetID()); + if (IsExtensionProcessSharingAllowed()) { + // The web pages share the 2 remaining processes to stay under the limit. + EXPECT_EQ(3u, process_ids.size()); + } else { + // The web processes still share 2 processes as if there were a single + // extension process (making a total of 5 processes counting the existing 3 + // extension processes). This avoids starving the web pages with a single + // process (if the extensions pushed us past the limit on their own), or + // increasing the process count further (if all extension processes were + // ignored). + EXPECT_EQ(5u, process_ids.size()); + } + + // Add a cross-site web process. + GURL cross_site_url( + embedded_test_server()->GetURL("bar.com", "/title1.html")); + ui_test_utils::NavigateToURLWithDisposition( + browser(), cross_site_url, WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + WebContents* web_contents4 = + browser()->tab_strip_model()->GetActiveWebContents(); + process_ids.insert(web_contents4->GetMainFrame()->GetProcess()->GetID()); + // The cross-site process adds 1 more process to the total, to avoid sharing + // with the existing web renderer processes (due to Site Isolation). + if (IsExtensionProcessSharingAllowed()) + EXPECT_EQ(4u, process_ids.size()); + else + EXPECT_EQ(6u, process_ids.size()); +} + +INSTANTIATE_TEST_SUITE_P( + All, + ProcessManagementExtensionIsolationTest, + testing::Bool(), + ProcessManagementExtensionIsolationTest::DescribeParams); + IN_PROC_BROWSER_TEST_F(ProcessManagementTest, NavigateExtensionTabToWebViaPost) { ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/chrome/browser/extensions/process_manager_browsertest.cc b/chrome/browser/extensions/process_manager_browsertest.cc index 70e35cb0..b31717be 100644 --- a/chrome/browser/extensions/process_manager_browsertest.cc +++ b/chrome/browser/extensions/process_manager_browsertest.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/callback.h" #include "base/containers/contains.h" +#include "base/feature_list.h" #include "base/path_service.h" #include "base/run_loop.h" #include "base/strings/strcat.h" @@ -47,6 +48,7 @@ #include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/app_window_registry.h" #include "extensions/browser/process_manager.h" +#include "extensions/common/extension_features.h" #include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/manifest_handlers/web_accessible_resources_info.h" #include "extensions/common/permissions/permissions_data.h" @@ -66,9 +68,8 @@ namespace { bool IsExtensionProcessSharingAllowed() { - // TODO(nick): Currently, process sharing is allowed even in - // --site-per-process. Lock this down. https://crbug.com/766267 - return true; + return !base::FeatureList::IsEnabled( + extensions_features::kStrictExtensionIsolation); } void AddFrameToSet(std::set<content::RenderFrameHost*>* frames,
diff --git a/chrome/browser/feed/android/BUILD.gn b/chrome/browser/feed/android/BUILD.gn index 6791519..d80acd94 100644 --- a/chrome/browser/feed/android/BUILD.gn +++ b/chrome/browser/feed/android/BUILD.gn
@@ -66,6 +66,7 @@ "java/res/layout/feed_management_activity.xml", "java/res/layout/feed_management_list_item.xml", "java/res/layout/follow_management_activity.xml", + "java/res/layout/follow_management_empty_state.xml", "java/res/layout/follow_management_item.xml", "java/res/layout/radio_button_group_video_previews_preference.xml", "java/res/layout/web_feed_dialog.xml",
diff --git a/chrome/browser/feed/android/java/res/layout/follow_management_activity.xml b/chrome/browser/feed/android/java/res/layout/follow_management_activity.xml index b101dad..0e6899f 100644 --- a/chrome/browser/feed/android/java/res/layout/follow_management_activity.xml +++ b/chrome/browser/feed/android/java/res/layout/follow_management_activity.xml
@@ -40,7 +40,7 @@ <androidx.recyclerview.widget.RecyclerView android:id="@+id/follow_management_list" android:layout_width="match_parent" - android:layout_height="wrap_content" /> + android:layout_height="match_parent" /> <!-- TODO(petewil) - After UXR, show all button -->
diff --git a/chrome/browser/feed/android/java/res/layout/follow_management_empty_state.xml b/chrome/browser/feed/android/java/res/layout/follow_management_empty_state.xml new file mode 100644 index 0000000..a31eb00 --- /dev/null +++ b/chrome/browser/feed/android/java/res/layout/follow_management_empty_state.xml
@@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2021 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. +--> + + +<!-- The empty state will only appear if the recycler view is empty. --> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/follow_management_empty_state" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center" + android:orientation="vertical" > + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:layout_margin="@dimen/follow_empty_margin" + style="@style/TextAppearance.TextMedium.Secondary" + android:padding="@dimen/follow_empty_margin" + android:background="@drawable/hairline_border_card_background" + android:text="@string/follow_manage_following_empty_state" /> + +</LinearLayout>
diff --git a/chrome/browser/feed/android/java/res/values/dimens.xml b/chrome/browser/feed/android/java/res/values/dimens.xml index d144509e..0c6120a9 100644 --- a/chrome/browser/feed/android/java/res/values/dimens.xml +++ b/chrome/browser/feed/android/java/res/values/dimens.xml
@@ -26,4 +26,5 @@ <dimen name="follow_arrow_size">24dp</dimen> <dimen name="follow_margin">16dp</dimen> <dimen name="follow_item_margin">10dp</dimen> + <dimen name="follow_empty_margin">24dp</dimen> </resources>
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementCoordinator.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementCoordinator.java index f7d02d24..3da0e213 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementCoordinator.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementCoordinator.java
@@ -8,6 +8,7 @@ import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; +import android.widget.LinearLayout; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -23,6 +24,7 @@ * https://chromium.googlesource.com/chromium/src/+/HEAD/docs/ui/android/mvc_simple_list_tutorial.md */ public class FollowManagementCoordinator { + private static final String TAG = "FollowMMCoordinator"; private FollowManagementMediator mMediator; private Activity mActivity; private final View mView; @@ -32,9 +34,13 @@ ModelList listItems = new ModelList(); SimpleRecyclerViewAdapter adapter = new SimpleRecyclerViewAdapter(listItems); + // Register types for both the full and empty states. adapter.registerType(FollowManagementItemProperties.DEFAULT_ITEM_TYPE, new LayoutViewBuilder<FollowManagementItemView>(R.layout.follow_management_item), FollowManagementItemViewBinder::bind); + adapter.registerType(FollowManagementItemProperties.EMPTY_ITEM_TYPE, + new LayoutViewBuilder<LinearLayout>(R.layout.follow_management_empty_state), + (unusedModel, unusedView, unusedKey) -> {}); // Inflate the XML for the activity. mView = LayoutInflater.from(activity).inflate(R.layout.follow_management_activity, null);
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementItemProperties.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementItemProperties.java index e074eecd..8952d07 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementItemProperties.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementItemProperties.java
@@ -15,6 +15,7 @@ */ public class FollowManagementItemProperties { public static final int DEFAULT_ITEM_TYPE = 0; + public static final int EMPTY_ITEM_TYPE = 1; public static final WritableObjectPropertyKey<String> TITLE_KEY = new WritableObjectPropertyKey<>();
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementMediator.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementMediator.java index 2750c724..f49f659 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementMediator.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementMediator.java
@@ -166,6 +166,8 @@ private void fillRecyclerView(List<WebFeedMetadata> followedWebFeeds) { String updatesUnavailable = mContext.getResources().getString(R.string.follow_manage_updates_unavailable); + + // Add the list items (if any) to the recycler view. for (WebFeedMetadata page : followedWebFeeds) { String title = page.title; GURL url = page.visitUrl; @@ -195,6 +197,14 @@ // getFavicon is async. We'll get the favicon, then add it to the model. faviconProvider.startFaviconFetch(); } + // If there are no subscribed feeds, show the empty state instead. + if (followedWebFeeds.isEmpty()) { + // Inflate and show the empty state view inside the recycler view. + PropertyModel pageModel = new PropertyModel(); + SimpleRecyclerViewAdapter.ListItem listItem = new SimpleRecyclerViewAdapter.ListItem( + FollowManagementItemProperties.EMPTY_ITEM_TYPE, pageModel); + mModelList.add(listItem); + } } // Generate a list item for the recycler vivew for a followed page.
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 1860175..513222e 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -2739,6 +2739,11 @@ "expiry_milestone": 90 }, { + "name": "enhanced-network-voices", + "owners": ["joelriley@google.com", "leileilei@google.com", "dmazzoni"], + "expiry_milestone": 95 + }, + { "name": "enterprise-realtime-extension-request", "owners": ["zmin", "parastoog"], "expiry_milestone": 98 @@ -4876,6 +4881,14 @@ "expiry_milestone": 90 }, { + "name": "strict-extension-isolation", + "owners": [ "creis" ], + // This prevents extensions from sharing a process with each other. It is + // useful for improving security but launching it will depend on trials that + // will monitor the effect on process count, etc. + "expiry_milestone": 100 + }, + { "name": "strict-origin-isolation", "owners": [ "wjmaclean", "alexmos", "creis" ], // This can be used to opt in to origin isolation which isolates full
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 6db86b1..081e83c5 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -800,6 +800,11 @@ "during the handshake when resuming a connection to a compatible TLS 1.3 " "server."; +const char kEnhancedNetworkVoicesName[] = "Enhanced network voices"; +const char kEnhancedNetworkVoicesDescription[] = + "This option enables high-quality, network-based voices in " + "Select-to-speak."; + const char kPostQuantumCECPQ2Name[] = "TLS Post-Quantum Confidentiality"; const char kPostQuantumCECPQ2Description[] = "This option enables a post-quantum (i.e. resistent to quantum computers) " @@ -2290,6 +2295,11 @@ "Partitions the HTTP Cache by (top-level site, current-frame site) to " "disallow cross-site tracking."; +const char kStrictExtensionIsolationName[] = "Strict Extension Isolation"; +const char kStrictExtensionIsolationDescription[] = + "Experimental security mode that prevents extensions from sharing a " + "process with each other."; + const char kStrictOriginIsolationName[] = "Strict-Origin-Isolation"; const char kStrictOriginIsolationDescription[] = "Experimental security mode that strengthens the site isolation policy. "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index e24aba2c..292b983c 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -479,6 +479,9 @@ extern const char kEnableTLS13EarlyDataName[]; extern const char kEnableTLS13EarlyDataDescription[]; +extern const char kEnhancedNetworkVoicesName[]; +extern const char kEnhancedNetworkVoicesDescription[]; + extern const char kPostQuantumCECPQ2Name[]; extern const char kPostQuantumCECPQ2Description[]; @@ -1324,6 +1327,9 @@ extern const char kStoreHoursAndroidName[]; extern const char kStoreHoursAndroidDescription[]; +extern const char kStrictExtensionIsolationName[]; +extern const char kStrictExtensionIsolationDescription[]; + extern const char kStrictOriginIsolationName[]; extern const char kStrictOriginIsolationDescription[];
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc b/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc index 5735127..51d0397 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc +++ b/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc
@@ -39,6 +39,7 @@ #if BUILDFLAG(ENABLE_EXTENSIONS) #include "extensions/browser/process_manager.h" #include "extensions/common/extension.h" +#include "extensions/common/extension_features.h" #include "extensions/test/background_page_watcher.h" #include "extensions/test/test_extension_dir.h" #endif @@ -663,6 +664,13 @@ #endif IN_PROC_BROWSER_TEST_F(ProcessMemoryMetricsEmitterTest, MAYBE_FetchAndEmitMetricsWithExtensionsAndHostReuse) { + // When strict extension isolation is enabled, there is no process reuse for + // extensions, and this becomes the same as FetchAndEmitMetricsWithExtensions. + if (base::FeatureList::IsEnabled( + extensions_features::kStrictExtensionIsolation)) { + return; + } + // Limit the number of renderer processes to force reuse. content::RenderProcessHost::SetMaxRendererProcessCount(1); const Extension* extension1 = CreateExtension("Extension 1");
diff --git a/chrome/browser/nearby_sharing/nearby_share_feature_usage_metrics.cc b/chrome/browser/nearby_sharing/nearby_share_feature_usage_metrics.cc new file mode 100644 index 0000000..d273f41 --- /dev/null +++ b/chrome/browser/nearby_sharing/nearby_share_feature_usage_metrics.cc
@@ -0,0 +1,63 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/nearby_sharing/nearby_share_feature_usage_metrics.h" +#include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" +#include "chromeos/components/feature_usage/feature_usage_metrics.h" +#include "components/prefs/pref_service.h" + +namespace { +const char kNearbyShareUmaFeatureName[] = "NearbyShare"; +} // namespace + +NearbyShareFeatureUsageMetrics::NearbyShareFeatureUsageMetrics( + PrefService* pref_service) + : pref_service_(pref_service), + feature_usage_metrics_(kNearbyShareUmaFeatureName, this) {} + +NearbyShareFeatureUsageMetrics::~NearbyShareFeatureUsageMetrics() = default; + +NearbyShareFeatureUsageMetrics::NearbyShareEnabledState +NearbyShareFeatureUsageMetrics::GetNearbyShareEnabledState() const { + bool is_enabled = + pref_service_->GetBoolean(prefs::kNearbySharingEnabledPrefName); + bool is_managed = + pref_service_->IsManagedPreference(prefs::kNearbySharingEnabledPrefName); + bool is_onboarded = pref_service_->GetBoolean( + prefs::kNearbySharingOnboardingCompletePrefName); + + if (is_enabled) { + return is_onboarded ? NearbyShareEnabledState::kEnabledAndOnboarded + : NearbyShareEnabledState::kEnabledAndNotOnboarded; + } + + if (is_managed) { + return NearbyShareEnabledState::kDisallowedByPolicy; + } + + return is_onboarded ? NearbyShareEnabledState::kDisabledAndOnboarded + : NearbyShareEnabledState::kDisabledAndNotOnboarded; +} + +void NearbyShareFeatureUsageMetrics::RecordUsage(bool success) { + feature_usage_metrics_.RecordUsage(success); +} + +bool NearbyShareFeatureUsageMetrics::IsEligible() const { + // This class is only created if the Nearby Share service is started, which + // only occurs for eligible users. + return true; +} + +bool NearbyShareFeatureUsageMetrics::IsEnabled() const { + switch (GetNearbyShareEnabledState()) { + case NearbyShareEnabledState::kEnabledAndOnboarded: + case NearbyShareEnabledState::kEnabledAndNotOnboarded: + return true; + case NearbyShareEnabledState::kDisabledAndOnboarded: + case NearbyShareEnabledState::kDisabledAndNotOnboarded: + case NearbyShareEnabledState::kDisallowedByPolicy: + return false; + } +}
diff --git a/chrome/browser/nearby_sharing/nearby_share_feature_usage_metrics.h b/chrome/browser/nearby_sharing/nearby_share_feature_usage_metrics.h new file mode 100644 index 0000000..2d69c5e --- /dev/null +++ b/chrome/browser/nearby_sharing/nearby_share_feature_usage_metrics.h
@@ -0,0 +1,44 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_NEARBY_SHARING_NEARBY_SHARE_FEATURE_USAGE_METRICS_H_ +#define CHROME_BROWSER_NEARBY_SHARING_NEARBY_SHARE_FEATURE_USAGE_METRICS_H_ + +#include "chromeos/components/feature_usage/feature_usage_metrics.h" + +class PrefService; + +// Tracks Nearby Share feature usage for the Standard Feature Usage Logging +// (SFUL) framework. +class NearbyShareFeatureUsageMetrics + : public feature_usage::FeatureUsageMetrics::Delegate { + public: + // These values are persisted to logs. Entries should not be renumbered and + // numeric values should never be reused. If entries are added, kMaxValue + // should be updated. + enum class NearbyShareEnabledState { + kEnabledAndOnboarded = 0, + kEnabledAndNotOnboarded = 1, + kDisabledAndOnboarded = 2, + kDisabledAndNotOnboarded = 3, + kDisallowedByPolicy = 4, + kMaxValue = kDisallowedByPolicy + }; + + explicit NearbyShareFeatureUsageMetrics(PrefService* pref_service); + ~NearbyShareFeatureUsageMetrics() final; + + // feature_usage::FeatureUsageMetrics::Delegate: + bool IsEligible() const final; + bool IsEnabled() const final; + + NearbyShareEnabledState GetNearbyShareEnabledState() const; + void RecordUsage(bool success); + + private: + PrefService* pref_service_; + feature_usage::FeatureUsageMetrics feature_usage_metrics_; +}; + +#endif // CHROME_BROWSER_NEARBY_SHARING_NEARBY_SHARE_FEATURE_USAGE_METRICS_H_
diff --git a/chrome/browser/nearby_sharing/nearby_share_feature_usage_metrics_unittest.cc b/chrome/browser/nearby_sharing/nearby_share_feature_usage_metrics_unittest.cc new file mode 100644 index 0000000..cde8f16 --- /dev/null +++ b/chrome/browser/nearby_sharing/nearby_share_feature_usage_metrics_unittest.cc
@@ -0,0 +1,144 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> + +#include "base/test/metrics/histogram_tester.h" +#include "base/test/task_environment.h" +#include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" +#include "chrome/browser/nearby_sharing/nearby_share_feature_usage_metrics.h" +#include "chromeos/components/feature_usage/feature_usage_metrics.h" +#include "components/prefs/testing_pref_service.h" +#include "testing/gtest/include/gtest/gtest.h" + +class NearbyShareFeatureUsageMetricsTest : public ::testing::Test { + protected: + NearbyShareFeatureUsageMetricsTest() = default; + ~NearbyShareFeatureUsageMetricsTest() override = default; + + void SetUp() override { + RegisterNearbySharingPrefs(pref_service_.registry()); + } + + void SetUnmanagedEnabled(bool is_enabled) { + pref_service_.SetBoolean(prefs::kNearbySharingEnabledPrefName, is_enabled); + } + void SetManagedEnabled(bool is_enabled) { + pref_service_.SetManagedPref(prefs::kNearbySharingEnabledPrefName, + std::make_unique<base::Value>(is_enabled)); + ASSERT_TRUE(pref_service_.IsManagedPreference( + prefs::kNearbySharingEnabledPrefName)); + } + void SetOnboarded(bool is_onboarded) { + pref_service_.SetBoolean(prefs::kNearbySharingOnboardingCompletePrefName, + is_onboarded); + } + + base::test::TaskEnvironment task_environment_; + TestingPrefServiceSimple pref_service_; +}; + +TEST_F(NearbyShareFeatureUsageMetricsTest, Enabled_Unmanaged) { + NearbyShareFeatureUsageMetrics feature_usage_metrics(&pref_service_); + SetUnmanagedEnabled(false); + SetOnboarded(false); + EXPECT_TRUE(feature_usage_metrics.IsEligible()); + EXPECT_FALSE(feature_usage_metrics.IsEnabled()); + EXPECT_EQ(NearbyShareFeatureUsageMetrics::NearbyShareEnabledState:: + kDisabledAndNotOnboarded, + feature_usage_metrics.GetNearbyShareEnabledState()); + + SetUnmanagedEnabled(false); + SetOnboarded(true); + EXPECT_TRUE(feature_usage_metrics.IsEligible()); + EXPECT_FALSE(feature_usage_metrics.IsEnabled()); + EXPECT_EQ(NearbyShareFeatureUsageMetrics::NearbyShareEnabledState:: + kDisabledAndOnboarded, + feature_usage_metrics.GetNearbyShareEnabledState()); + + // Note: This should never happen in practice. + SetUnmanagedEnabled(true); + SetOnboarded(false); + EXPECT_TRUE(feature_usage_metrics.IsEligible()); + EXPECT_TRUE(feature_usage_metrics.IsEnabled()); + EXPECT_EQ(NearbyShareFeatureUsageMetrics::NearbyShareEnabledState:: + kEnabledAndNotOnboarded, + feature_usage_metrics.GetNearbyShareEnabledState()); + + SetUnmanagedEnabled(true); + SetOnboarded(true); + EXPECT_TRUE(feature_usage_metrics.IsEligible()); + EXPECT_TRUE(feature_usage_metrics.IsEnabled()); + EXPECT_EQ(NearbyShareFeatureUsageMetrics::NearbyShareEnabledState:: + kEnabledAndOnboarded, + feature_usage_metrics.GetNearbyShareEnabledState()); +} + +TEST_F(NearbyShareFeatureUsageMetricsTest, Enabled_Managed) { + NearbyShareFeatureUsageMetrics feature_usage_metrics(&pref_service_); + + SetManagedEnabled(false); + SetOnboarded(false); + EXPECT_TRUE(feature_usage_metrics.IsEligible()); + EXPECT_FALSE(feature_usage_metrics.IsEnabled()); + EXPECT_EQ(NearbyShareFeatureUsageMetrics::NearbyShareEnabledState:: + kDisallowedByPolicy, + feature_usage_metrics.GetNearbyShareEnabledState()); + + SetManagedEnabled(false); + SetOnboarded(true); + EXPECT_TRUE(feature_usage_metrics.IsEligible()); + EXPECT_FALSE(feature_usage_metrics.IsEnabled()); + EXPECT_EQ(NearbyShareFeatureUsageMetrics::NearbyShareEnabledState:: + kDisallowedByPolicy, + feature_usage_metrics.GetNearbyShareEnabledState()); + + // Note: This should never happen in practice. + SetManagedEnabled(true); + SetOnboarded(false); + EXPECT_TRUE(feature_usage_metrics.IsEligible()); + EXPECT_TRUE(feature_usage_metrics.IsEnabled()); + EXPECT_EQ(NearbyShareFeatureUsageMetrics::NearbyShareEnabledState:: + kEnabledAndNotOnboarded, + feature_usage_metrics.GetNearbyShareEnabledState()); + + SetManagedEnabled(true); + SetOnboarded(true); + EXPECT_TRUE(feature_usage_metrics.IsEligible()); + EXPECT_TRUE(feature_usage_metrics.IsEnabled()); + EXPECT_EQ(NearbyShareFeatureUsageMetrics::NearbyShareEnabledState:: + kEnabledAndOnboarded, + feature_usage_metrics.GetNearbyShareEnabledState()); +} + +TEST_F(NearbyShareFeatureUsageMetricsTest, RecordUsage) { + // Note: The feature must be enabled to use RecordUsage(). + NearbyShareFeatureUsageMetrics feature_usage_metrics(&pref_service_); + SetUnmanagedEnabled(true); + SetOnboarded(true); + + base::HistogramTester histograms; + histograms.ExpectBucketCount( + "ChromeOS.FeatureUsage.NearbyShare", + feature_usage::FeatureUsageMetrics::Event::kUsedWithSuccess, 0); + histograms.ExpectBucketCount( + "ChromeOS.FeatureUsage.NearbyShare", + feature_usage::FeatureUsageMetrics::Event::kUsedWithFailure, 0); + + feature_usage_metrics.RecordUsage(/*success=*/true); + histograms.ExpectBucketCount( + "ChromeOS.FeatureUsage.NearbyShare", + feature_usage::FeatureUsageMetrics::Event::kUsedWithSuccess, 1); + histograms.ExpectBucketCount( + "ChromeOS.FeatureUsage.NearbyShare", + feature_usage::FeatureUsageMetrics::Event::kUsedWithFailure, 0); + + feature_usage_metrics.RecordUsage(/*success=*/false); + histograms.ExpectBucketCount( + "ChromeOS.FeatureUsage.NearbyShare", + feature_usage::FeatureUsageMetrics::Event::kUsedWithSuccess, 1); + histograms.ExpectBucketCount( + "ChromeOS.FeatureUsage.NearbyShare", + feature_usage::FeatureUsageMetrics::Event::kUsedWithFailure, 1); +}
diff --git a/chrome/browser/nearby_sharing/nearby_share_metrics_logger.cc b/chrome/browser/nearby_sharing/nearby_share_metrics_logger.cc index 21ac976..a2d5c0c 100644 --- a/chrome/browser/nearby_sharing/nearby_share_metrics_logger.cc +++ b/chrome/browser/nearby_sharing/nearby_share_metrics_logger.cc
@@ -6,12 +6,10 @@ #include "base/metrics/histogram_functions.h" #include "base/numerics/safe_conversions.h" -#include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" #include "chromeos/services/nearby/public/mojom/nearby_connections_types.mojom.h" #include "chromeos/services/nearby/public/mojom/nearby_decoder_types.mojom.h" #include "components/policy/core/common/policy_service.h" #include "components/policy/policy_constants.h" -#include "components/prefs/pref_service.h" namespace { @@ -21,18 +19,6 @@ // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. If entries are added, kMaxValue should // be updated. -enum class NearbyShareEnabledState { - kEnabledAndOnboarded = 0, - kEnabledAndNotOnboarded = 1, - kDisabledAndOnboarded = 2, - kDisabledAndNotOnboarded = 3, - kDisallowedByPolicy = 4, - kMaxValue = kDisallowedByPolicy -}; - -// These values are persisted to logs. Entries should not be renumbered and -// numeric values should never be reused. If entries are added, kMaxValue should -// be updated. enum class TransferFinalStatus { kComplete = 0, kUnknown = 1, @@ -362,26 +348,8 @@ } // namespace -void RecordNearbyShareEnabledMetric(const PrefService* pref_service) { - NearbyShareEnabledState state; - - bool is_managed = - pref_service->IsManagedPreference(prefs::kNearbySharingEnabledPrefName); - bool is_enabled = - pref_service->GetBoolean(prefs::kNearbySharingEnabledPrefName); - bool is_onboarded = - pref_service->GetBoolean(prefs::kNearbySharingOnboardingCompletePrefName); - - if (is_enabled) { - state = is_onboarded ? NearbyShareEnabledState::kEnabledAndOnboarded - : NearbyShareEnabledState::kEnabledAndNotOnboarded; - } else if (is_managed) { - state = NearbyShareEnabledState::kDisallowedByPolicy; - } else { // !is_enabled && !is_managed - state = is_onboarded ? NearbyShareEnabledState::kDisabledAndOnboarded - : NearbyShareEnabledState::kDisabledAndNotOnboarded; - } - +void RecordNearbyShareEnabledMetric( + NearbyShareFeatureUsageMetrics::NearbyShareEnabledState state) { base::UmaHistogramEnumeration("Nearby.Share.Enabled", state); } @@ -552,12 +520,26 @@ } void RecordNearbyShareTransferFinalStatusMetric( + NearbyShareFeatureUsageMetrics* feature_usage_metrics, bool is_incoming, nearby_share::mojom::ShareTargetType type, TransferMetadata::Status status, bool is_known) { DCHECK(TransferMetadata::IsFinalStatus(status)); + // Emit success/failure to Standard Feature Usage Logging if there was a + // definitive result. + switch (TransferMetadata::ToResult(status)) { + case TransferMetadata::Result::kSuccess: + feature_usage_metrics->RecordUsage(/*success=*/true); + break; + case TransferMetadata::Result::kFailure: + feature_usage_metrics->RecordUsage(/*success=*/false); + break; + case TransferMetadata::Result::kIndeterminate: + break; + } + base::UmaHistogramBoolean("Nearby.Share.IsKnownContact", is_known); std::string send_or_receive = GetDirectionSubcategoryName(is_incoming);
diff --git a/chrome/browser/nearby_sharing/nearby_share_metrics_logger.h b/chrome/browser/nearby_sharing/nearby_share_metrics_logger.h index 5c19dfb3..83224ca 100644 --- a/chrome/browser/nearby_sharing/nearby_share_metrics_logger.h +++ b/chrome/browser/nearby_sharing/nearby_share_metrics_logger.h
@@ -6,15 +6,15 @@ #define CHROME_BROWSER_NEARBY_SHARING_NEARBY_SHARE_METRICS_LOGGER_H_ #include "base/time/time.h" +#include "chrome/browser/nearby_sharing/nearby_share_feature_usage_metrics.h" #include "chrome/browser/nearby_sharing/transfer_metadata.h" #include "chromeos/services/nearby/public/mojom/nearby_connections_types.mojom.h" #include "chromeos/services/nearby/public/mojom/nearby_decoder_types.mojom.h" #include "chromeos/services/nearby/public/mojom/nearby_share_target_types.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" -class PrefService; - -void RecordNearbyShareEnabledMetric(const PrefService* pref_service); +void RecordNearbyShareEnabledMetric( + NearbyShareFeatureUsageMetrics::NearbyShareEnabledState state); void RecordNearbyShareEstablishConnectionMetrics( bool success, @@ -71,6 +71,7 @@ location::nearby::connections::mojom::Status status); void RecordNearbyShareTransferFinalStatusMetric( + NearbyShareFeatureUsageMetrics* feature_usage_metrics, bool is_incoming, nearby_share::mojom::ShareTargetType type, TransferMetadata::Status status,
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc index 5e70c43b..3fcf3ae 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
@@ -293,6 +293,7 @@ profile->GetPath(), http_client_factory_.get())), settings_(prefs, local_device_data_manager_.get()), + feature_usage_metrics_(prefs), on_network_changed_delay_timer_( FROM_HERE, kProcessNetworkChangeTimerDelay, @@ -303,7 +304,8 @@ DCHECK(nearby_connections_manager_); DCHECK(power_client_); - RecordNearbyShareEnabledMetric(prefs_); + RecordNearbyShareEnabledMetric( + feature_usage_metrics_.GetNearbyShareEnabledState()); auto* session_controller = ash::SessionController::Get(); if (session_controller) { @@ -1143,7 +1145,8 @@ void NearbySharingServiceImpl::OnEnabledChanged(bool enabled) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - RecordNearbyShareEnabledMetric(prefs_); + RecordNearbyShareEnabledMetric( + feature_usage_metrics_.GetNearbyShareEnabledState()); base::UmaHistogramBoolean("Nearby.Share.EnabledStateChanged", enabled); if (enabled) { NS_LOG(VERBOSE) << __func__ << ": Nearby sharing enabled!"; @@ -2733,6 +2736,7 @@ if (metadata.is_final_status()) { RecordNearbyShareTransferFinalStatusMetric( + &feature_usage_metrics_, /*is_incoming=*/true, share_target.type, metadata.status(), share_target.is_known); OnTransferComplete(); @@ -2769,6 +2773,7 @@ if (metadata.is_final_status()) { is_connecting_ = false; RecordNearbyShareTransferFinalStatusMetric( + &feature_usage_metrics_, /*is_incoming=*/false, share_target.type, metadata.status(), share_target.is_known); OnTransferComplete();
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h index 7d22ba38..060db47 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h
@@ -32,6 +32,7 @@ #include "chrome/browser/nearby_sharing/nearby_connections_manager.h" #include "chrome/browser/nearby_sharing/nearby_file_handler.h" #include "chrome/browser/nearby_sharing/nearby_notification_manager.h" +#include "chrome/browser/nearby_sharing/nearby_share_feature_usage_metrics.h" #include "chrome/browser/nearby_sharing/nearby_share_profile_info_provider_impl.h" #include "chrome/browser/nearby_sharing/nearby_share_settings.h" #include "chrome/browser/nearby_sharing/nearby_sharing_service.h" @@ -410,6 +411,7 @@ std::unique_ptr<NearbyShareContactManager> contact_manager_; std::unique_ptr<NearbyShareCertificateManager> certificate_manager_; NearbyShareSettings settings_; + NearbyShareFeatureUsageMetrics feature_usage_metrics_; NearbyFileHandler file_handler_; bool is_screen_locked_ = false; base::OneShotTimer rotate_background_advertisement_timer_;
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc index 434d7bf..2ea70bc 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc
@@ -18,6 +18,7 @@ #include "base/strings/string_number_conversions.h" #include "base/system/sys_info.h" #include "base/test/bind.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/threading/thread_restrictions.h" #include "build/chromeos_buildflags.h" @@ -52,6 +53,7 @@ #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" +#include "chromeos/components/feature_usage/feature_usage_metrics.h" #include "chromeos/services/nearby/public/cpp/mock_nearby_process_manager.h" #include "chromeos/services/nearby/public/cpp/mock_nearby_sharing_decoder.h" #include "chromeos/services/nearby/public/mojom/nearby_connections_types.mojom.h" @@ -836,15 +838,31 @@ auto barrier = base::BarrierClosure(updates.size(), std::move(callback)); auto& expectation = EXPECT_CALL(transfer_callback, OnTransferUpdate).Times(updates.size()); + for (TransferMetadata::Status status : updates) { - expectation.WillOnce(testing::Invoke( - [=](const ShareTarget& share_target, TransferMetadata metadata) { - EXPECT_EQ(target.id, share_target.id); - EXPECT_EQ(status, metadata.status()); - if (new_share_target) - *new_share_target = share_target; - barrier.Run(); - })); + expectation.WillOnce(testing::Invoke([=](const ShareTarget& share_target, + TransferMetadata metadata) { + EXPECT_EQ(target.id, share_target.id); + EXPECT_EQ(status, metadata.status()); + if (new_share_target) + *new_share_target = share_target; + + // Though this is indirect, verify that the highest level + // success/failure metric was logged. We expect transfer updates to + // be a few indeterminate status then only one success or failure + // status. + TransferMetadata::Result result = TransferMetadata::ToResult(status); + histogram_tester_.ExpectBucketCount( + "ChromeOS.FeatureUsage.NearbyShare", + feature_usage::FeatureUsageMetrics::Event::kUsedWithSuccess, + result == TransferMetadata::Result::kSuccess ? 1 : 0); + histogram_tester_.ExpectBucketCount( + "ChromeOS.FeatureUsage.NearbyShare", + feature_usage::FeatureUsageMetrics::Event::kUsedWithFailure, + result == TransferMetadata::Result::kFailure ? 1 : 0); + + barrier.Run(); + })); } } @@ -1046,6 +1064,7 @@ int64_t last_advertising_interval_max_ = 0; chromeos::nearby::NearbyProcessManager::NearbyProcessStoppedCallback process_stopped_callback_; + base::HistogramTester histogram_tester_; }; struct ValidSendSurfaceTestData {
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc index 7904a05..9188fe3 100644 --- a/chrome/browser/net/system_network_context_manager.cc +++ b/chrome/browser/net/system_network_context_manager.cc
@@ -499,23 +499,7 @@ network_service->ConfigureHttpAuthPrefs( CreateHttpAuthDynamicParams(local_state_)); - int max_connections_per_proxy = - local_state_->GetInteger(prefs::kMaxConnectionsPerProxy); - if (max_connections_per_proxy != -1) - network_service->SetMaxConnectionsPerProxy(max_connections_per_proxy); - - network_service_network_context_.reset(); - network_service->CreateNetworkContext( - network_service_network_context_.BindNewPipeAndPassReceiver(), - CreateNetworkContextParams()); - - mojo::PendingRemote<network::mojom::NetworkContextClient> client_remote; - mojo::MakeSelfOwnedReceiver( - std::make_unique<content::NetworkContextClientBase>(), - client_remote.InitWithNewPipeAndPassReceiver()); - network_service_network_context_->SetClient(std::move(client_remote)); - -// Configure the Certificate Transparency logs. + // Configure the Certificate Transparency logs. #if !defined(OS_ANDROID) if (g_enable_certificate_transparency) { std::vector<std::string> operated_by_google_logs = @@ -546,6 +530,22 @@ } #endif + int max_connections_per_proxy = + local_state_->GetInteger(prefs::kMaxConnectionsPerProxy); + if (max_connections_per_proxy != -1) + network_service->SetMaxConnectionsPerProxy(max_connections_per_proxy); + + network_service_network_context_.reset(); + network_service->CreateNetworkContext( + network_service_network_context_.BindNewPipeAndPassReceiver(), + CreateNetworkContextParams()); + + mojo::PendingRemote<network::mojom::NetworkContextClient> client_remote; + mojo::MakeSelfOwnedReceiver( + std::make_unique<content::NetworkContextClientBase>(), + client_remote.InitWithNewPipeAndPassReceiver()); + network_service_network_context_->SetClient(std::move(client_remote)); + // Configure the stub resolver. This must be done after the system // NetworkContext is created, but before anything has the chance to use it. stub_resolver_config_reader_.UpdateNetworkService(true /* record_metrics */);
diff --git a/chrome/browser/optimization_guide/android/BUILD.gn b/chrome/browser/optimization_guide/android/BUILD.gn index 024b5a2..a0f7aab 100644 --- a/chrome/browser/optimization_guide/android/BUILD.gn +++ b/chrome/browser/optimization_guide/android/BUILD.gn
@@ -48,10 +48,12 @@ ":java", "//base:base_java", "//chrome/browser/flags:java", + "//chrome/browser/profiles/android:java", "//components/optimization_guide/proto:optimization_guide_proto_java", "//content/public/android:content_java", "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/junit", + "//third_party/mockito:mockito_java", "//url:gurl_java", ]
diff --git a/chrome/browser/optimization_guide/android/android_push_notification_manager_unittest.cc b/chrome/browser/optimization_guide/android/android_push_notification_manager_unittest.cc index 324eaa5..e5c9e4c3 100644 --- a/chrome/browser/optimization_guide/android/android_push_notification_manager_unittest.cc +++ b/chrome/browser/optimization_guide/android/android_push_notification_manager_unittest.cc
@@ -11,11 +11,17 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/optimization_guide/android/native_j_unittests_jni_headers/OptimizationGuidePushNotificationTestHelper_jni.h" +#include "chrome/browser/optimization_guide/android/optimization_guide_bridge.h" +#include "chrome/browser/optimization_guide/optimization_guide_hints_manager.h" +#include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" +#include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_constants.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" +#include "components/optimization_guide/core/hint_cache.h" #include "components/optimization_guide/core/hints_fetcher.h" #include "components/optimization_guide/core/optimization_guide_features.h" #include "components/optimization_guide/core/optimization_guide_prefs.h" @@ -78,7 +84,9 @@ class AndroidPushNotificationManagerJavaTest : public testing::Test { public: AndroidPushNotificationManagerJavaTest() - : env_(base::android::AttachCurrentThread()), + : j_test_(Java_OptimizationGuidePushNotificationTestHelper_Constructor( + base::android::AttachCurrentThread())), + env_(base::android::AttachCurrentThread()), profile_manager_(TestingBrowserProcess::GetGlobal()) { scoped_feature_list_.InitAndEnableFeature( optimization_guide::features::kPushNotifications); @@ -90,21 +98,52 @@ ASSERT_TRUE(profile_manager_.SetUp(temp_dir_.GetPath())); profile_ = profile_manager_.CreateTestingProfile(chrome::kInitialProfile); - // It takes two session starts for experimental params to be picked up by - // Java, so override it manually. + service_ = static_cast<OptimizationGuideKeyedService*>( + OptimizationGuideKeyedServiceFactory::GetInstance() + ->SetTestingFactoryAndUse( + profile(), + base::BindRepeating(&AndroidPushNotificationManagerJavaTest:: + CreateServiceForProfile, + base::Unretained(this)))); + + Java_OptimizationGuidePushNotificationTestHelper_setUpMocks(env_, j_test_); + + // It takes two session starts for experimental params and feature flags to + // be picked up by Java, so override them manually. Java_OptimizationGuidePushNotificationTestHelper_setOverflowSizeForTesting( env_, kOverflowSize); + Java_OptimizationGuidePushNotificationTestHelper_setFeatureEnabled(env_); } void TearDown() override { Java_OptimizationGuidePushNotificationTestHelper_clearAllCaches(env_); } - JNIEnv* env() { return env_; } + std::unique_ptr<KeyedService> CreateServiceForProfile( + content::BrowserContext* browser_context) { + return std::make_unique<OptimizationGuideKeyedService>( + Profile::FromBrowserContext(browser_context)); + } - Profile* profile() { return profile_; } + void PushNotificationNative( + const proto::HintNotificationPayload& notification) { + std::string encoded_notification; + notification.SerializeToString(&encoded_notification); - PrefService* prefs() { return profile()->GetPrefs(); } + OptimizationGuideBridge bridge(service()); + bridge.OnNewPushNotification( + env_, base::android::ToJavaByteArray(env_, encoded_notification)); + } + + bool PushNotificationJava( + const proto::HintNotificationPayload& notification) { + std::string encoded_notification; + if (!notification.SerializeToString(&encoded_notification)) + return false; + + return Java_OptimizationGuidePushNotificationTestHelper_pushNotification( + env_, base::android::ToJavaByteArray(env_, encoded_notification)); + } void CauseOverflow(proto::OptimizationType opt_type) { for (int i = 0; i < kOverflowSize + 1; i++) { @@ -126,15 +165,6 @@ env_, base::android::ToJavaByteArray(env_, encoded_notification)); } - bool PushNotification(const proto::HintNotificationPayload& notification) { - std::string encoded_notification; - if (!notification.SerializeToString(&encoded_notification)) - return false; - - return Java_OptimizationGuidePushNotificationTestHelper_pushNotification( - env_, base::android::ToJavaByteArray(env_, encoded_notification)); - } - bool DidOverflow(proto::OptimizationType opt_type) { return Java_OptimizationGuidePushNotificationTestHelper_didOverflow( env_, static_cast<int>(opt_type)); @@ -145,12 +175,26 @@ env_, static_cast<int>(opt_type)); } + OptimizationGuideKeyedService* service() { return service_; } + + OptimizationGuideHintsManager* hints_manager() { + return service()->GetHintsManager(); + } + + JNIEnv* env() { return env_; } + + TestingProfile* profile() { return profile_; } + + PrefService* prefs() { return profile()->GetPrefs(); } + private: content::BrowserTaskEnvironment task_environment_{ base::test::TaskEnvironment::MainThreadType::UI}; + base::android::ScopedJavaGlobalRef<jobject> j_test_; JNIEnv* env_; TestingProfileManager profile_manager_; TestingProfile* profile_; + OptimizationGuideKeyedService* service_; base::ScopedTempDir temp_dir_; base::test::ScopedFeatureList scoped_feature_list_; }; @@ -191,7 +235,7 @@ } TEST_F(AndroidPushNotificationManagerJavaTest, - SingleCachedNotification_FailedCallback) { + Cached_SingleNotification_FailedCallback) { base::HistogramTester histogram_tester; TestDelegate delegate; delegate.SetRunSuccessCallbacks(false); @@ -270,7 +314,7 @@ true, 2); } -TEST_F(AndroidPushNotificationManagerJavaTest, Overflow_HandledSuccess) { +TEST_F(AndroidPushNotificationManagerJavaTest, Cached_Overflow_HandledSuccess) { base::HistogramTester histogram_tester; TestDelegate delegate; delegate.SetRunSuccessCallbacks(true); @@ -296,7 +340,7 @@ 0); } -TEST_F(AndroidPushNotificationManagerJavaTest, Overflow_HandledFailure) { +TEST_F(AndroidPushNotificationManagerJavaTest, Cached_Overflow_HandledFailure) { TestDelegate delegate; delegate.SetRunSuccessCallbacks(false); @@ -312,7 +356,7 @@ EXPECT_TRUE(DidOverflow(proto::OptimizationType::PERFORMANCE_HINTS)); } -TEST_F(AndroidPushNotificationManagerJavaTest, OverflowPurgesAllTypes) { +TEST_F(AndroidPushNotificationManagerJavaTest, Cached_OverflowPurgesAllTypes) { base::HistogramTester histogram_tester; TestDelegate delegate; delegate.SetRunSuccessCallbacks(true); @@ -430,7 +474,8 @@ "OptimizationGuide.PushNotifications.GotPushNotification", true, 1); } -TEST_F(AndroidPushNotificationManagerJavaTest, MultipleKeyRepresentations) { +TEST_F(AndroidPushNotificationManagerJavaTest, + Cached_MultipleKeyRepresentations) { base::HistogramTester histogram_tester; TestDelegate delegate; delegate.SetRunSuccessCallbacks(true); @@ -481,5 +526,318 @@ true, 1); } +TEST_F(AndroidPushNotificationManagerJavaTest, Pushed_URL_SuccessCase) { + // Pre-populate the store with some hints. + int cache_duration_in_secs = 60; + GURL url("https://host.com/r/cats"); + + std::unique_ptr<proto::GetHintsResponse> get_hints_response = + std::make_unique<proto::GetHintsResponse>(); + + proto::Hint* hint = get_hints_response->add_hints(); + hint->set_key(url.spec()); + hint->set_key_representation(proto::FULL_URL); + hint->mutable_max_cache_duration()->set_seconds(cache_duration_in_secs); + proto::PageHint* page_hint = hint->add_page_hints(); + page_hint->add_whitelisted_optimizations()->set_optimization_type( + proto::PERFORMANCE_HINTS); + page_hint->set_page_pattern("whatever/*"); + + hint = get_hints_response->add_hints(); + hint->set_key_representation(proto::HOST); + hint->set_key(url.host()); + page_hint = hint->add_page_hints(); + page_hint->set_page_pattern("page/*"); + + std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); + hints_manager()->hint_cache()->UpdateFetchedHints( + std::move(get_hints_response), base::Time().Now(), {url.host()}, {url}, + run_loop->QuitClosure()); + run_loop->Run(); + + EXPECT_TRUE(hints_manager()->hint_cache()->HasHint(url.host())); + EXPECT_TRUE(hints_manager()->hint_cache()->HasURLKeyedEntryForURL(url)); + + proto::HintNotificationPayload notification; + notification.set_optimization_type( + proto::OptimizationType::PERFORMANCE_HINTS); + notification.set_key_representation(proto::KeyRepresentation::FULL_URL); + notification.set_hint_key(url.spec()); + + PushNotificationNative(notification); + base::RunLoop().RunUntilIdle(); + + EXPECT_FALSE(hints_manager()->hint_cache()->HasHint(url.host())); + EXPECT_FALSE(hints_manager()->hint_cache()->HasURLKeyedEntryForURL(url)); +} + +TEST_F(AndroidPushNotificationManagerJavaTest, Pushed_Host_SuccessCase) { + // Pre-populate the store with some hints. + int cache_duration_in_secs = 60; + GURL url("https://host.com/r/cats"); + + std::unique_ptr<proto::GetHintsResponse> get_hints_response = + std::make_unique<proto::GetHintsResponse>(); + + proto::Hint* hint = get_hints_response->add_hints(); + hint->set_key(url.spec()); + hint->set_key_representation(proto::FULL_URL); + hint->mutable_max_cache_duration()->set_seconds(cache_duration_in_secs); + proto::PageHint* page_hint = hint->add_page_hints(); + page_hint->add_whitelisted_optimizations()->set_optimization_type( + proto::PERFORMANCE_HINTS); + page_hint->set_page_pattern("whatever/*"); + + hint = get_hints_response->add_hints(); + hint->set_key_representation(proto::HOST); + hint->set_key(url.host()); + page_hint = hint->add_page_hints(); + page_hint->set_page_pattern("page/*"); + + std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); + hints_manager()->hint_cache()->UpdateFetchedHints( + std::move(get_hints_response), base::Time().Now(), {url.host()}, {url}, + run_loop->QuitClosure()); + run_loop->Run(); + + EXPECT_TRUE(hints_manager()->hint_cache()->HasHint(url.host())); + EXPECT_TRUE(hints_manager()->hint_cache()->HasURLKeyedEntryForURL(url)); + + proto::HintNotificationPayload notification; + notification.set_optimization_type( + proto::OptimizationType::PERFORMANCE_HINTS); + notification.set_key_representation(proto::KeyRepresentation::HOST); + notification.set_hint_key(url.host()); + + PushNotificationNative(notification); + base::RunLoop().RunUntilIdle(); + + EXPECT_FALSE(hints_manager()->hint_cache()->HasHint(url.host())); + EXPECT_TRUE(hints_manager()->hint_cache()->HasURLKeyedEntryForURL(url)); +} + +TEST_F(AndroidPushNotificationManagerJavaTest, PushedJava_URL_SuccessCase) { + // Pre-populate the store with some hints. + int cache_duration_in_secs = 60; + GURL url("https://host.com/r/cats"); + + std::unique_ptr<proto::GetHintsResponse> get_hints_response = + std::make_unique<proto::GetHintsResponse>(); + + proto::Hint* hint = get_hints_response->add_hints(); + hint->set_key(url.spec()); + hint->set_key_representation(proto::FULL_URL); + hint->mutable_max_cache_duration()->set_seconds(cache_duration_in_secs); + proto::PageHint* page_hint = hint->add_page_hints(); + page_hint->add_whitelisted_optimizations()->set_optimization_type( + proto::PERFORMANCE_HINTS); + page_hint->set_page_pattern("whatever/*"); + + hint = get_hints_response->add_hints(); + hint->set_key_representation(proto::HOST); + hint->set_key(url.host()); + page_hint = hint->add_page_hints(); + page_hint->set_page_pattern("page/*"); + + std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); + hints_manager()->hint_cache()->UpdateFetchedHints( + std::move(get_hints_response), base::Time().Now(), {url.host()}, {url}, + run_loop->QuitClosure()); + run_loop->Run(); + + EXPECT_TRUE(hints_manager()->hint_cache()->HasHint(url.host())); + EXPECT_TRUE(hints_manager()->hint_cache()->HasURLKeyedEntryForURL(url)); + + proto::HintNotificationPayload notification; + notification.set_optimization_type( + proto::OptimizationType::PERFORMANCE_HINTS); + notification.set_key_representation(proto::KeyRepresentation::FULL_URL); + notification.set_hint_key(url.spec()); + + PushNotificationJava(notification); + base::RunLoop().RunUntilIdle(); + + EXPECT_FALSE(hints_manager()->hint_cache()->HasHint(url.host())); + EXPECT_FALSE(hints_manager()->hint_cache()->HasURLKeyedEntryForURL(url)); +} + +TEST_F(AndroidPushNotificationManagerJavaTest, PushedJava_Host_SuccessCase) { + // Pre-populate the store with some hints. + int cache_duration_in_secs = 60; + GURL url("https://host.com/r/cats"); + + std::unique_ptr<proto::GetHintsResponse> get_hints_response = + std::make_unique<proto::GetHintsResponse>(); + + proto::Hint* hint = get_hints_response->add_hints(); + hint->set_key(url.spec()); + hint->set_key_representation(proto::FULL_URL); + hint->mutable_max_cache_duration()->set_seconds(cache_duration_in_secs); + proto::PageHint* page_hint = hint->add_page_hints(); + page_hint->add_whitelisted_optimizations()->set_optimization_type( + proto::PERFORMANCE_HINTS); + page_hint->set_page_pattern("whatever/*"); + + hint = get_hints_response->add_hints(); + hint->set_key_representation(proto::HOST); + hint->set_key(url.host()); + page_hint = hint->add_page_hints(); + page_hint->set_page_pattern("page/*"); + + std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); + hints_manager()->hint_cache()->UpdateFetchedHints( + std::move(get_hints_response), base::Time().Now(), {url.host()}, {url}, + run_loop->QuitClosure()); + run_loop->Run(); + + EXPECT_TRUE(hints_manager()->hint_cache()->HasHint(url.host())); + EXPECT_TRUE(hints_manager()->hint_cache()->HasURLKeyedEntryForURL(url)); + + proto::HintNotificationPayload notification; + notification.set_optimization_type( + proto::OptimizationType::PERFORMANCE_HINTS); + notification.set_key_representation(proto::KeyRepresentation::HOST); + notification.set_hint_key(url.host()); + + PushNotificationJava(notification); + base::RunLoop().RunUntilIdle(); + + EXPECT_FALSE(hints_manager()->hint_cache()->HasHint(url.host())); + EXPECT_TRUE(hints_manager()->hint_cache()->HasURLKeyedEntryForURL(url)); +} + +TEST_F(AndroidPushNotificationManagerJavaTest, + Pushed_KeyRepresentationRequired) { + // Pre-populate the store with some hints. + int cache_duration_in_secs = 60; + GURL url("https://host.com/r/cats"); + + std::unique_ptr<proto::GetHintsResponse> get_hints_response = + std::make_unique<proto::GetHintsResponse>(); + + proto::Hint* hint = get_hints_response->add_hints(); + hint->set_key(url.spec()); + hint->set_key_representation(proto::FULL_URL); + hint->mutable_max_cache_duration()->set_seconds(cache_duration_in_secs); + proto::PageHint* page_hint = hint->add_page_hints(); + page_hint->add_whitelisted_optimizations()->set_optimization_type( + proto::PERFORMANCE_HINTS); + page_hint->set_page_pattern("whatever/*"); + + hint = get_hints_response->add_hints(); + hint->set_key_representation(proto::HOST); + hint->set_key(url.host()); + page_hint = hint->add_page_hints(); + page_hint->set_page_pattern("page/*"); + + std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); + hints_manager()->hint_cache()->UpdateFetchedHints( + std::move(get_hints_response), base::Time().Now(), {url.host()}, {url}, + run_loop->QuitClosure()); + run_loop->Run(); + + EXPECT_TRUE(hints_manager()->hint_cache()->HasHint(url.host())); + EXPECT_TRUE(hints_manager()->hint_cache()->HasURLKeyedEntryForURL(url)); + + proto::HintNotificationPayload notification; + notification.set_optimization_type( + proto::OptimizationType::PERFORMANCE_HINTS); + notification.set_hint_key(url.spec()); + + PushNotificationNative(notification); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(hints_manager()->hint_cache()->HasHint(url.host())); + EXPECT_TRUE(hints_manager()->hint_cache()->HasURLKeyedEntryForURL(url)); +} + +TEST_F(AndroidPushNotificationManagerJavaTest, + Pushed_OptimizationTypeNotRequired) { + // Pre-populate the store with some hints. + int cache_duration_in_secs = 60; + GURL url("https://host.com/r/cats"); + + std::unique_ptr<proto::GetHintsResponse> get_hints_response = + std::make_unique<proto::GetHintsResponse>(); + + proto::Hint* hint = get_hints_response->add_hints(); + hint->set_key(url.spec()); + hint->set_key_representation(proto::FULL_URL); + hint->mutable_max_cache_duration()->set_seconds(cache_duration_in_secs); + proto::PageHint* page_hint = hint->add_page_hints(); + page_hint->add_whitelisted_optimizations()->set_optimization_type( + proto::PERFORMANCE_HINTS); + page_hint->set_page_pattern("whatever/*"); + + hint = get_hints_response->add_hints(); + hint->set_key_representation(proto::HOST); + hint->set_key(url.host()); + page_hint = hint->add_page_hints(); + page_hint->set_page_pattern("page/*"); + + std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); + hints_manager()->hint_cache()->UpdateFetchedHints( + std::move(get_hints_response), base::Time().Now(), {url.host()}, {url}, + run_loop->QuitClosure()); + run_loop->Run(); + + EXPECT_TRUE(hints_manager()->hint_cache()->HasHint(url.host())); + EXPECT_TRUE(hints_manager()->hint_cache()->HasURLKeyedEntryForURL(url)); + + proto::HintNotificationPayload notification; + notification.set_key_representation(proto::KeyRepresentation::FULL_URL); + notification.set_hint_key(url.spec()); + + PushNotificationNative(notification); + base::RunLoop().RunUntilIdle(); + + EXPECT_FALSE(hints_manager()->hint_cache()->HasHint(url.host())); + EXPECT_FALSE(hints_manager()->hint_cache()->HasURLKeyedEntryForURL(url)); +} + +TEST_F(AndroidPushNotificationManagerJavaTest, Pushed_HintKeyRequired) { + // Pre-populate the store with some hints. + int cache_duration_in_secs = 60; + GURL url("https://host.com/r/cats"); + + std::unique_ptr<proto::GetHintsResponse> get_hints_response = + std::make_unique<proto::GetHintsResponse>(); + + proto::Hint* hint = get_hints_response->add_hints(); + hint->set_key(url.spec()); + hint->set_key_representation(proto::FULL_URL); + hint->mutable_max_cache_duration()->set_seconds(cache_duration_in_secs); + proto::PageHint* page_hint = hint->add_page_hints(); + page_hint->add_whitelisted_optimizations()->set_optimization_type( + proto::PERFORMANCE_HINTS); + page_hint->set_page_pattern("whatever/*"); + + hint = get_hints_response->add_hints(); + hint->set_key_representation(proto::HOST); + hint->set_key(url.host()); + page_hint = hint->add_page_hints(); + page_hint->set_page_pattern("page/*"); + + std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); + hints_manager()->hint_cache()->UpdateFetchedHints( + std::move(get_hints_response), base::Time().Now(), {url.host()}, {url}, + run_loop->QuitClosure()); + run_loop->Run(); + + EXPECT_TRUE(hints_manager()->hint_cache()->HasHint(url.host())); + EXPECT_TRUE(hints_manager()->hint_cache()->HasURLKeyedEntryForURL(url)); + + proto::HintNotificationPayload notification; + notification.set_optimization_type( + proto::OptimizationType::PERFORMANCE_HINTS); + notification.set_key_representation(proto::KeyRepresentation::FULL_URL); + + PushNotificationNative(notification); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(hints_manager()->hint_cache()->HasHint(url.host())); + EXPECT_TRUE(hints_manager()->hint_cache()->HasURLKeyedEntryForURL(url)); +} + } // namespace android } // namespace optimization_guide
diff --git a/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridge.java b/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridge.java index f0ba493b..08789e2 100644 --- a/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridge.java +++ b/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridge.java
@@ -116,6 +116,17 @@ mNativeOptimizationGuideBridge, url, optimizationType.getNumber(), callback); } + public void onNewPushNotification(HintNotificationPayload notification) { + ThreadUtils.assertOnUiThread(); + if (mNativeOptimizationGuideBridge == 0) { + OptimizationGuidePushNotificationManager.onPushNotificationNotHandledByNative( + notification); + return; + } + OptimizationGuideBridgeJni.get().onNewPushNotification( + mNativeOptimizationGuideBridge, notification.toByteArray()); + } + @CalledByNative private static void onOptimizationGuideDecision(OptimizationGuideCallback callback, @OptimizationGuideDecision int optimizationGuideDecision,
diff --git a/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeFactory.java b/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeFactory.java index f7bec5e8..1c90ce04 100644 --- a/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeFactory.java +++ b/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeFactory.java
@@ -10,6 +10,7 @@ import org.chromium.chrome.browser.profiles.ProfileManager; import org.chromium.components.optimization_guide.proto.HintsProto; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -25,6 +26,13 @@ private ProfileManager.Observer mProfileManagerObserver; /** + * Creates an instance of this class with no observed optimization types. + */ + public OptimizationGuideBridgeFactory() { + this(new ArrayList<HintsProto.OptimizationType>()); + } + + /** * @param optimizationTypes list of {@link HintsProto.OptimizationType} the {@link * OptimizationGuideBridge} is initialized with. */ @@ -56,7 +64,9 @@ mProfileToOptimizationGuideBridgeMap.get(profile); if (optimizationGuideBridge == null) { optimizationGuideBridge = new OptimizationGuideBridge(); - optimizationGuideBridge.registerOptimizationTypes(mOptimizationTypes); + if (mOptimizationTypes.size() > 0) { + optimizationGuideBridge.registerOptimizationTypes(mOptimizationTypes); + } mProfileToOptimizationGuideBridgeMap.put(profile, optimizationGuideBridge); } return optimizationGuideBridge;
diff --git a/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManager.java b/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManager.java index cc1a276..99c2d8a 100644 --- a/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManager.java +++ b/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManager.java
@@ -29,6 +29,7 @@ */ public class OptimizationGuidePushNotificationManager { private static Boolean sNativeIsInitialized; + private static OptimizationGuideBridgeFactory sBridgeFactory; // All logic here is static, so no instances of this class are needed. private OptimizationGuidePushNotificationManager() {} @@ -54,7 +55,10 @@ } if (nativeIsInitialized()) { - // TODO(crbug/1199123): Push the notification to native. + if (sBridgeFactory == null) { + sBridgeFactory = new OptimizationGuideBridgeFactory(); + } + sBridgeFactory.create().onNewPushNotification(payload); return; }
diff --git a/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationTestHelper.java b/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationTestHelper.java index 8b33e78..9e444ab 100644 --- a/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationTestHelper.java +++ b/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationTestHelper.java
@@ -4,7 +4,13 @@ package org.chromium.chrome.browser.optimization_guide; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + import org.chromium.base.annotations.CalledByNative; +import org.chromium.chrome.browser.flags.CachedFeatureFlags; +import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.components.optimization_guide.proto.HintsProto.OptimizationType; import org.chromium.components.optimization_guide.proto.PushNotificationProto.HintNotificationPayload; @@ -12,6 +18,18 @@ * Unit test helper for OptimizationGuidePushNotificationManager. */ public class OptimizationGuidePushNotificationTestHelper { + @Mock + private Profile mProfile; + + @CalledByNative + private OptimizationGuidePushNotificationTestHelper() {} + + @CalledByNative + public void setUpMocks() { + MockitoAnnotations.initMocks(this); + Profile.setLastUsedProfileForTesting(mProfile); + } + @CalledByNative public static boolean cacheNotification(byte[] encodedNotification) { HintNotificationPayload notification; @@ -27,18 +45,6 @@ } @CalledByNative - public static boolean pushNotification(byte[] encodedNotification) { - HintNotificationPayload notification; - try { - notification = HintNotificationPayload.parseFrom(encodedNotification); - OptimizationGuidePushNotificationManager.onPushNotification(notification); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - return false; - } - return true; - } - - @CalledByNative public static int countCachedNotifications(int optType) { HintNotificationPayload[] payloads = OptimizationGuidePushNotificationManager.getNotificationCacheForOptimizationType( @@ -62,4 +68,23 @@ public static void clearAllCaches() { OptimizationGuidePushNotificationManager.clearCacheForAllTypes(); } + + @CalledByNative + public static void setFeatureEnabled() { + CachedFeatureFlags.setForTesting( + ChromeFeatureList.OPTIMIZATION_GUIDE_PUSH_NOTIFICATIONS, true); + } + + @CalledByNative + public static boolean pushNotification(byte[] encodedNotification) { + HintNotificationPayload notification; + try { + notification = HintNotificationPayload.parseFrom(encodedNotification); + OptimizationGuidePushNotificationManager.onPushNotification(notification); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + return false; + } + + return true; + } }
diff --git a/chrome/browser/optimization_guide/android/javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManagerUnitTest.java b/chrome/browser/optimization_guide/android/javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManagerUnitTest.java index 222fca8..acc5661 100644 --- a/chrome/browser/optimization_guide/android/javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManagerUnitTest.java +++ b/chrome/browser/optimization_guide/android/javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManagerUnitTest.java
@@ -4,6 +4,12 @@ package org.chromium.chrome.browser.optimization_guide; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import androidx.test.filters.SmallTest; import com.google.protobuf.ByteString; @@ -11,14 +17,20 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import org.chromium.base.FeatureList; import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.base.test.UiThreadTest; import org.chromium.base.test.util.Batch; +import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.components.optimization_guide.proto.CommonTypesProto.Any; import org.chromium.components.optimization_guide.proto.HintsProto.KeyRepresentation; import org.chromium.components.optimization_guide.proto.HintsProto.OptimizationType; @@ -34,6 +46,15 @@ // Batch this per class since the test is setting global feature state. @Batch(Batch.PER_CLASS) public class OptimizationGuidePushNotificationManagerUnitTest { + @Rule + public JniMocker mocker = new JniMocker(); + + @Mock + private Profile mProfile; + + @Mock + OptimizationGuideBridge.Natives mOptimizationGuideBridgeJniMock; + private static final String TEST_URL = "https://testurl.com/"; private static final HintNotificationPayload NOTIFICATION_WITH_PAYLOAD = @@ -60,8 +81,22 @@ } @Before + public void setUp() { + resetFeatureFlags(); + + MockitoAnnotations.initMocks(this); + mocker.mock(OptimizationGuideBridgeJni.TEST_HOOKS, mOptimizationGuideBridgeJniMock); + when(mOptimizationGuideBridgeJniMock.init()).thenReturn(1L); + + Profile.setLastUsedProfileForTesting(mProfile); + } + @After - public void reset() { + public void tearDown() { + resetFeatureFlags(); + } + + public void resetFeatureFlags() { CachedFeatureFlags.resetFlagsForTesting(); OptimizationGuidePushNotificationManager.clearCacheForAllTypes(); OptimizationGuidePushNotificationManager.setNativeIsInitializedForTesting(null); @@ -102,6 +137,25 @@ @Test @SmallTest + @UiThreadTest + public void testNativeCalled() { + setFeatureStatusForTest(true); + OptimizationGuidePushNotificationManager.setNativeIsInitializedForTesting(true); + + OptimizationGuidePushNotificationManager.onPushNotification(NOTIFICATION_WITHOUT_PAYLOAD); + + HintNotificationPayload[] cached = + OptimizationGuidePushNotificationManager.getNotificationCacheForOptimizationType( + OptimizationType.PERFORMANCE_HINTS); + Assert.assertNotNull(cached); + Assert.assertEquals(0, cached.length); + + verify(mOptimizationGuideBridgeJniMock, times(1)) + .onNewPushNotification(anyLong(), eq(NOTIFICATION_WITHOUT_PAYLOAD.toByteArray())); + } + + @Test + @SmallTest public void testFeatureDisabled() { setFeatureStatusForTest(false); OptimizationGuidePushNotificationManager.setNativeIsInitializedForTesting(false);
diff --git a/chrome/browser/optimization_guide/android/optimization_guide_bridge.cc b/chrome/browser/optimization_guide/android/optimization_guide_bridge.cc index 11df0e72..32afba97 100644 --- a/chrome/browser/optimization_guide/android/optimization_guide_bridge.cc +++ b/chrome/browser/optimization_guide/android/optimization_guide_bridge.cc
@@ -191,7 +191,7 @@ void OptimizationGuideBridge::OnNewPushNotification( JNIEnv* env, - const JavaParamRef<jbyteArray>& j_encoded_notification) { + const JavaRef<jbyteArray>& j_encoded_notification) { if (!j_encoded_notification) return;
diff --git a/chrome/browser/optimization_guide/android/optimization_guide_bridge.h b/chrome/browser/optimization_guide/android/optimization_guide_bridge.h index 6bdd53e6..4fa5e7f3 100644 --- a/chrome/browser/optimization_guide/android/optimization_guide_bridge.h +++ b/chrome/browser/optimization_guide/android/optimization_guide_bridge.h
@@ -43,7 +43,7 @@ const base::android::JavaParamRef<jobject>& java_callback); void OnNewPushNotification( JNIEnv* env, - const base::android::JavaParamRef<jbyteArray>& j_encoded_notification); + const base::android::JavaRef<jbyteArray>& j_encoded_notification); private: OptimizationGuideKeyedService* optimization_guide_keyed_service_;
diff --git a/chrome/browser/optimization_guide/optimization_guide_keyed_service.h b/chrome/browser/optimization_guide/optimization_guide_keyed_service.h index 0c42266..2ef9d45a7 100644 --- a/chrome/browser/optimization_guide/optimization_guide_keyed_service.h +++ b/chrome/browser/optimization_guide/optimization_guide_keyed_service.h
@@ -26,6 +26,7 @@ namespace optimization_guide { namespace android { +class AndroidPushNotificationManagerJavaTest; class OptimizationGuideBridge; } // namespace android class OptimizationGuideStore; @@ -114,6 +115,8 @@ friend class OptimizationGuideWebContentsObserver; friend class optimization_guide::PredictionModelDownloadClient; friend class optimization_guide::PredictionManagerBrowserTestBase; + friend class optimization_guide::android:: + AndroidPushNotificationManagerJavaTest; friend class optimization_guide::android::OptimizationGuideBridge; // Initializes |this|.
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_browsertest.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_browsertest.cc index 8b99606..760ac73 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_browsertest.cc +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_browsertest.cc
@@ -45,7 +45,8 @@ public: PrivacySandboxSettingsBrowserTest() { feature_list()->InitWithFeatures( - {features::kPrivacySandboxSettings, features::kConversionMeasurement, + {features::kPrivacySandboxSettings, + blink::features::kConversionMeasurement, blink::features::kInterestCohortAPIOriginTrial}, {}); }
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc index b854027..08d0ceec 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc
@@ -161,7 +161,8 @@ feature_list()->Reset(); if (privacy_sandbox_available) { feature_list()->InitWithFeatures( - {features::kPrivacySandboxSettings, features::kConversionMeasurement, + {features::kPrivacySandboxSettings, + blink::features::kConversionMeasurement, blink::features::kInterestCohortAPIOriginTrial}, {}); } else { @@ -198,7 +199,7 @@ TEST_F(PrivacySandboxSettingsTest, PrivacySandboxSettingsFunctional) { feature_list()->InitWithFeatures( - {features::kConversionMeasurement, + {blink::features::kConversionMeasurement, blink::features::kInterestCohortAPIOriginTrial}, {features::kPrivacySandboxSettings}); EXPECT_FALSE(privacy_sandbox_settings()->PrivacySandboxSettingsFunctional()); @@ -206,7 +207,7 @@ feature_list()->InitWithFeatures( {features::kPrivacySandboxSettings}, - {features::kConversionMeasurement, + {blink::features::kConversionMeasurement, blink::features::kInterestCohortAPIOriginTrial}); EXPECT_TRUE(privacy_sandbox_settings()->PrivacySandboxSettingsFunctional()); }
diff --git a/chrome/browser/resources/chromeos/accessibility/switch_access/item_scan_manager.js b/chrome/browser/resources/chromeos/accessibility/switch_access/item_scan_manager.js index 9af930f6..9b7df388 100644 --- a/chrome/browser/resources/chromeos/accessibility/switch_access/item_scan_manager.js +++ b/chrome/browser/resources/chromeos/accessibility/switch_access/item_scan_manager.js
@@ -255,6 +255,7 @@ // Clearing the focus rings avoids having them re-animate to the same // position. FocusRingManager.clearAll(); + this.history_.save(new FocusData(this.group_, this.node_)); this.loadFromData_(this.suspendedGroup_); } }
diff --git a/chrome/browser/resources/download_shelf/BUILD.gn b/chrome/browser/resources/download_shelf/BUILD.gn index 7761ea3..0e63e05 100644 --- a/chrome/browser/resources/download_shelf/BUILD.gn +++ b/chrome/browser/resources/download_shelf/BUILD.gn
@@ -164,6 +164,7 @@ "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m", "//ui/webui/resources/js:custom_element", "//ui/webui/resources/js:icon.m", + "//ui/webui/resources/js:load_time_data.m", ] }
diff --git a/chrome/browser/resources/download_shelf/app.html b/chrome/browser/resources/download_shelf/app.html index e0f6226..c96bea3d 100644 --- a/chrome/browser/resources/download_shelf/app.html +++ b/chrome/browser/resources/download_shelf/app.html
@@ -23,7 +23,6 @@ </style> <download-list></download-list> -<cr-button id="show-all-button">$i18n{showAll}</cr-button> -<cr-icon-button id="close-button" iron-icon="cr:close" - aria-label="$i18n{close}"> +<cr-button id="show-all-button"></cr-button> +<cr-icon-button id="close-button" iron-icon="cr:close"> </cr-icon-button>
diff --git a/chrome/browser/resources/download_shelf/app.js b/chrome/browser/resources/download_shelf/app.js index 7dbf78e..81489e8 100644 --- a/chrome/browser/resources/download_shelf/app.js +++ b/chrome/browser/resources/download_shelf/app.js
@@ -11,6 +11,7 @@ import './strings.m.js'; import {CustomElement} from 'chrome://resources/js/custom_element.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {DownloadShelfApiProxy, DownloadShelfApiProxyImpl} from './download_shelf_api_proxy.js'; export class DownloadShelfAppElement extends CustomElement { @@ -24,9 +25,13 @@ /** @private {!DownloadShelfApiProxy} */ this.apiProxy_ = DownloadShelfApiProxyImpl.getInstance(); - this.$('#show-all-button') - .addEventListener('click', e => this.onShowAll_()); - this.$('#close-button').addEventListener('click', e => this.onClose_()); + const showAllButton = this.$('#show-all-button'); + showAllButton.innerText = loadTimeData.getString('showAll'); + showAllButton.addEventListener('click', e => this.onShowAll_()); + + const closeButton = this.$('#close-button'); + closeButton.setAttribute('aria-label', loadTimeData.getString('close')); + closeButton.addEventListener('click', e => this.onClose_()); } /** @private */
diff --git a/chrome/browser/resources/new_tab_page/realbox/realbox_match.html b/chrome/browser/resources/new_tab_page/realbox/realbox_match.html index 4dd4fa5c..65e2d091 100644 --- a/chrome/browser/resources/new_tab_page/realbox/realbox_match.html +++ b/chrome/browser/resources/new_tab_page/realbox/realbox_match.html
@@ -78,6 +78,7 @@ --cr-icon-button-margin-end: 0; --cr-icon-button-margin-start: 0; --cr-icon-button-size: 24px; + margin-inline-end: 1px; opacity: 0; /* Hides the button while keeping it in tab order. */ }
diff --git a/chrome/browser/resources/settings/a11y_page/captions_subpage.html b/chrome/browser/resources/settings/a11y_page/captions_subpage.html index a9076161..86ef0284 100644 --- a/chrome/browser/resources/settings/a11y_page/captions_subpage.html +++ b/chrome/browser/resources/settings/a11y_page/captions_subpage.html
@@ -1,7 +1,11 @@ <style include="cr-shared-style settings-shared"> + .cr-row-no-top-gap { + margin-bottom: var(--cr-section-vertical-margin); + min-height: auto; + } .preview-box { - all: initial; align-items: center; + all: initial; background-image: url(chrome://theme/IDR_ACCESSIBILITY_CAPTIONS_PREVIEW_BACKGROUND); background-position: center; @@ -21,7 +25,7 @@ <div class="cr-row"> <h2 class="start">$i18n{captionsPreferencesTitle}</h2> </div> - <div class="cr-row first"> + <div class="cr-row first cr-row-no-top-gap"> <div class="start">$i18n{captionsPreferencesSubtitle}</div> </div> <div class="preview-box">
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.html b/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.html index 5fc0a9a..f226563d 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.html +++ b/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.html
@@ -43,7 +43,7 @@ <div class="settings-box two-line no-padding"> <div actionable$="[[isItemActionable_(activeNetworkState, deviceState, networkStateList)]]" - class="flex layout horizontal center link-wrapper" + class="flex layout horizontal center link-wrapper" on-click="onShowDetailsTap_"> <div id="details" no-flex$="[[showSimInfo_(deviceState)]]" aria-hidden="true">
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.js b/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.js index a244b9a..d52d266 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.js +++ b/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.js
@@ -478,10 +478,10 @@ return true; } // When network type is Cellular and |updatedCellularActivationUi| is - // enabled, always show "Mobile data" subpage, when eSim is available - // or multiple pSimSlots are available + // enabled, always show "Mobile data" subpage, when at least one eSIM + // or pSIM slot is available const {pSimSlots, eSimSlots} = getSimSlotCount(deviceState); - if (eSimSlots > 0 || pSimSlots > 1) { + if (eSimSlots > 0 || pSimSlots > 0) { return true; } } else if (this.simLockedOrAbsent_(deviceState)) {
diff --git a/chrome/browser/sharing_hub/sharing_hub_model.cc b/chrome/browser/sharing_hub/sharing_hub_model.cc index 26cd1fb..0436df32 100644 --- a/chrome/browser/sharing_hub/sharing_hub_model.cc +++ b/chrome/browser/sharing_hub/sharing_hub_model.cc
@@ -4,15 +4,20 @@ #include "chrome/browser/sharing_hub/sharing_hub_model.h" +#include "base/strings/utf_string_conversions.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/send_tab_to_self/send_tab_to_self_util.h" +#include "chrome/browser/ui/browser_navigator.h" +#include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/qrcode_generator/qrcode_generator_bubble_controller.h" #include "chrome/grit/generated_resources.h" #include "components/vector_icons/vector_icons.h" #include "content/public/browser/browser_context.h" +#include "ui/base/l10n/l10n_util.h" +#include "url/gurl.h" namespace sharing_hub { @@ -24,9 +29,10 @@ SharingHubModel::~SharingHubModel() = default; -void SharingHubModel::GetActionList(content::WebContents* web_contents, - std::vector<SharingHubAction>* list) { - for (const auto& action : action_list_) { +void SharingHubModel::GetFirstPartyActionList( + content::WebContents* web_contents, + std::vector<SharingHubAction>* list) { + for (const auto& action : first_party_action_list_) { if (action.command_id == IDC_SEND_TAB_TO_SELF) { if (DoShowSendTabToSelfForWebContents(web_contents)) { list->push_back(action); @@ -42,29 +48,66 @@ } } +void SharingHubModel::GetThirdPartyActionList( + content::WebContents* web_contents, + std::vector<SharingHubAction>* list) { + for (const auto& action : third_party_action_list_) { + list->push_back(action); + } +} + +void SharingHubModel::ExecuteThirdPartyAction(Profile* profile, int id) { + auto url_it = third_party_action_urls_.find(id); + if (url_it == third_party_action_urls_.end()) + return; + + NavigateParams params(profile, url_it->second, ui::PAGE_TRANSITION_LINK); + params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; + params.tabstrip_add_types = TabStripModel::ADD_ACTIVE; + Navigate(¶ms); +} + void SharingHubModel::PopulateFirstPartyActions() { - action_list_.push_back( - {IDC_COPY_URL, IDS_SHARING_HUB_COPY_LINK_LABEL, kCopyIcon, true}); + first_party_action_list_.push_back( + {IDC_COPY_URL, l10n_util::GetStringUTF16(IDS_SHARING_HUB_COPY_LINK_LABEL), + kCopyIcon, true}); - action_list_.push_back({IDC_QRCODE_GENERATOR, - IDS_OMNIBOX_QRCODE_GENERATOR_ICON_LABEL, - kQrcodeGeneratorIcon, true}); + first_party_action_list_.push_back( + {IDC_QRCODE_GENERATOR, + l10n_util::GetStringUTF16(IDS_OMNIBOX_QRCODE_GENERATOR_ICON_LABEL), + kQrcodeGeneratorIcon, true}); - action_list_.push_back({IDC_SEND_TAB_TO_SELF, - IDS_CONTEXT_MENU_SEND_TAB_TO_SELF, kSendTabToSelfIcon, - true}); + first_party_action_list_.push_back( + {IDC_SEND_TAB_TO_SELF, + l10n_util::GetStringUTF16(IDS_CONTEXT_MENU_SEND_TAB_TO_SELF), + kSendTabToSelfIcon, true}); - action_list_.push_back( - {IDC_SAVE_PAGE, IDS_SHARING_HUB_SAVE_PAGE_LABEL, kSavePageIcon, true}); + first_party_action_list_.push_back( + {IDC_SAVE_PAGE, + l10n_util::GetStringUTF16(IDS_SHARING_HUB_SAVE_PAGE_LABEL), + kSavePageIcon, true}); if (media_router::MediaRouterEnabled(context_)) { - action_list_.push_back({IDC_ROUTE_MEDIA, IDS_SHARING_HUB_MEDIA_ROUTER_LABEL, - vector_icons::kMediaRouterIdleIcon, true}); + first_party_action_list_.push_back( + {IDC_ROUTE_MEDIA, + l10n_util::GetStringUTF16(IDS_SHARING_HUB_MEDIA_ROUTER_LABEL), + vector_icons::kMediaRouterIdleIcon, true}); } } void SharingHubModel::PopulateThirdPartyActions() { - // TODO(1186833): add third party actions + // Note: The third party action id must be greater than 0, otherwise the + // action will be disabled in the app menu. + // TODO(1186833): Replace with actual 3P data. + std::string title = "title"; + third_party_action_list_.push_back( + {1, base::ASCIIToUTF16(title), kQrcodeGeneratorIcon, false}); + third_party_action_urls_[1] = GURL(u"https://www.google.com"); + + std::string title2 = "title2"; + third_party_action_list_.push_back( + {2, base::ASCIIToUTF16(title2), kQrcodeGeneratorIcon, false}); + third_party_action_urls_[2] = GURL(u"https://www.twitter.com"); } bool SharingHubModel::DoShowSendTabToSelfForWebContents(
diff --git a/chrome/browser/sharing_hub/sharing_hub_model.h b/chrome/browser/sharing_hub/sharing_hub_model.h index b2792d2..76bfbf0 100644 --- a/chrome/browser/sharing_hub/sharing_hub_model.h +++ b/chrome/browser/sharing_hub/sharing_hub_model.h
@@ -5,10 +5,15 @@ #ifndef CHROME_BROWSER_SHARING_HUB_SHARING_HUB_MODEL_H_ #define CHROME_BROWSER_SHARING_HUB_SHARING_HUB_MODEL_H_ +#include <map> +#include <string> #include <vector> #include "base/macros.h" +class GURL; +class Profile; + namespace content { class BrowserContext; class WebContents; @@ -22,7 +27,7 @@ struct SharingHubAction { int command_id; - int title; + std::u16string title; const gfx::VectorIcon& icon; bool is_first_party; }; @@ -35,11 +40,19 @@ explicit SharingHubModel(content::BrowserContext* context); ~SharingHubModel(); - // Populates the vector with Sharing Hub actions, ordered by appearance in the - // dialog. Some actions (i.e. send tab to self) may not be shown for some - // URLs. - void GetActionList(content::WebContents* web_contents, - std::vector<SharingHubAction>* list); + // Populates the vector with first party Sharing Hub actions, ordered by + // appearance in the dialog. Some actions (i.e. send tab to self) may not be + // shown for some URLs. + void GetFirstPartyActionList(content::WebContents* web_contents, + std::vector<SharingHubAction>* list); + // Populates the vector with third party Sharing Hub actions, ordered by + // appearance in the dialog. + void GetThirdPartyActionList(content::WebContents* web_contents, + std::vector<SharingHubAction>* list); + + // Executes the third party action indicated by |id|, i.e. opens a new tab to + // the corresponding webpage. + void ExecuteThirdPartyAction(Profile* profile, int id); private: void PopulateFirstPartyActions(); @@ -47,8 +60,13 @@ bool DoShowSendTabToSelfForWebContents(content::WebContents* web_contents); - // A list of Sharing Hub actions in order in which they appear. - std::vector<SharingHubAction> action_list_; + // A list of Sharing Hub first party actions in order in which they appear. + std::vector<SharingHubAction> first_party_action_list_; + // A list of Sharing Hub third party actions in order in which they appear. + std::vector<SharingHubAction> third_party_action_list_; + + // A list of third party action URLs mapped to action id. + std::map<int, GURL> third_party_action_urls_; content::BrowserContext* context_;
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 75416271..b3d44cde 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -2846,6 +2846,9 @@ <message name="IDS_FOLLOW_MANAGE_FOLLOWING" desc="Header for Following Management activity."> Following </message> + <message name="IDS_FOLLOW_MANAGE_FOLLOWING_EMPTY_STATE" desc="Message for Following Management activity when there are no followed sites to show."> + You'll find sites you follow here + </message> <message name="IDS_FOLLOW_MANAGE_UPDATES_UNAVAILABLE" desc="Label this web feed source as unavailable so the user will not expect updates from it."> Updates Unavailable </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_FOLLOW_MANAGE_FOLLOWING_EMPTY_STATE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_FOLLOW_MANAGE_FOLLOWING_EMPTY_STATE.png.sha1 new file mode 100644 index 0000000..6b33c43 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_FOLLOW_MANAGE_FOLLOWING_EMPTY_STATE.png.sha1
@@ -0,0 +1 @@ +3de06623921cbf71a9d4feaf3f1683194560599f \ No newline at end of file
diff --git a/chrome/browser/ui/ash/assistant/device_actions.cc b/chrome/browser/ui/ash/assistant/device_actions.cc index 91d7f8e..ca21860 100644 --- a/chrome/browser/ui/ash/assistant/device_actions.cc +++ b/chrome/browser/ui/ash/assistant/device_actions.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chromeos/dbus/power/power_manager_client.h" #include "chromeos/dbus/power_manager/backlight.pb.h" +#include "chromeos/network/network_event_log.h" #include "chromeos/network/network_state_handler.h" #include "components/arc/arc_service_manager.h" #include "components/arc/mojom/intent_helper.mojom.h" @@ -112,6 +113,7 @@ DeviceActions::~DeviceActions() = default; void DeviceActions::SetWifiEnabled(bool enabled) { + NET_LOG(USER) << __func__ << ":" << enabled; NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled( NetworkTypePattern::WiFi(), enabled, chromeos::network_handler::ErrorCallback());
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc index af88603..4e37311 100644 --- a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc +++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc
@@ -117,15 +117,24 @@ return true; } -std::vector<SharingHubAction> SharingHubBubbleController::GetActions() const { - SharingHubService* const service = - SharingHubServiceFactory::GetForProfile(GetProfile()); - SharingHubModel* const model = - service ? service->GetSharingHubModel() : nullptr; - +std::vector<SharingHubAction> +SharingHubBubbleController::GetFirstPartyActions() { std::vector<SharingHubAction> actions; + + SharingHubModel* model = GetSharingHubModel(); if (model) - model->GetActionList(web_contents_, &actions); + model->GetFirstPartyActionList(web_contents_, &actions); + + return actions; +} + +std::vector<SharingHubAction> +SharingHubBubbleController::GetThirdPartyActions() { + std::vector<SharingHubAction> actions; + + SharingHubModel* model = GetSharingHubModel(); + if (model) + model->GetThirdPartyActionList(web_contents_, &actions); return actions; } @@ -140,7 +149,9 @@ if (is_first_party) { chrome::ExecuteCommand(browser, command_id); } else { - // TODO(1186833): execute 3p action + SharingHubModel* model = GetSharingHubModel(); + DCHECK(model); + model->ExecuteThirdPartyAction(GetProfile(), command_id); } } @@ -148,6 +159,17 @@ sharing_hub_bubble_view_ = nullptr; } +SharingHubModel* SharingHubBubbleController::GetSharingHubModel() { + if (!sharing_hub_model_) { + SharingHubService* const service = + SharingHubServiceFactory::GetForProfile(GetProfile()); + if (!service) + return nullptr; + sharing_hub_model_ = service->GetSharingHubModel(); + } + return sharing_hub_model_; +} + #if BUILDFLAG(IS_CHROMEOS_ASH) void SharingHubBubbleController::ShowSharesheet() { if (!base::FeatureList::IsEnabled(features::kSharesheet) ||
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h index 215a1de..149f592 100644 --- a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h +++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h
@@ -17,6 +17,7 @@ namespace sharing_hub { class SharingHubBubbleView; +class SharingHubModel; struct SharingHubAction; // Controller component of the Sharing Hub dialog bubble. @@ -43,8 +44,10 @@ // Returns true if the omnibox icon should be shown. bool ShouldOfferOmniboxIcon(); - // Returns the list of Sharing Hub actions. - virtual std::vector<SharingHubAction> GetActions() const; + // Returns the list of Sharing Hub first party actions. + virtual std::vector<SharingHubAction> GetFirstPartyActions(); + // Returns the list of Sharing Hub third party actions. + virtual std::vector<SharingHubAction> GetThirdPartyActions(); // Handles when the user clicks on a Sharing Hub action. If this is a first // party action, executes the appropriate browser command. If this is a third @@ -60,6 +63,8 @@ private: friend class content::WebContentsUserData<SharingHubBubbleController>; + SharingHubModel* GetSharingHubModel(); + #if BUILDFLAG(IS_CHROMEOS_ASH) void ShowSharesheet(); void OnSharesheetShown(sharesheet::SharesheetResult result); @@ -69,6 +74,8 @@ content::WebContents* web_contents_; // Weak reference. Will be nullptr if no bubble is currently shown. SharingHubBubbleView* sharing_hub_bubble_view_ = nullptr; + // Cached reference to the model. + SharingHubModel* sharing_hub_model_ = nullptr; WEB_CONTENTS_USER_DATA_KEY_DECL();
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_sub_menu_model.cc b/chrome/browser/ui/sharing_hub/sharing_hub_sub_menu_model.cc index cb35d31..b0e331d6 100644 --- a/chrome/browser/ui/sharing_hub/sharing_hub_sub_menu_model.cc +++ b/chrome/browser/ui/sharing_hub/sharing_hub_sub_menu_model.cc
@@ -21,33 +21,70 @@ namespace sharing_hub { -SharingHubSubMenuModel::SharingHubSubMenuModel( - ui::SimpleMenuModel::Delegate* delegate, - content::WebContents* web_contents) - : SimpleMenuModel(delegate) { - Build(web_contents); +SharingHubSubMenuModel::SharingHubSubMenuModel(Browser* browser) + : SimpleMenuModel(this), browser_(browser) { + Build(browser_->tab_strip_model()->GetActiveWebContents()); +} + +SharingHubSubMenuModel::~SharingHubSubMenuModel() = default; + +bool SharingHubSubMenuModel::IsCommandIdEnabled(int command_id) const { + return true; +} + +void SharingHubSubMenuModel::ExecuteCommand(int command_id, int event_flags) { + if (IsThirdPartyAction(command_id)) { + SharingHubModel* const model = GetSharingHubModel(); + if (!model) + return; + model->ExecuteThirdPartyAction(browser_->profile(), command_id); + } else { + GlobalError* error = + GlobalErrorServiceFactory::GetForProfile(browser_->profile()) + ->GetGlobalErrorByMenuItemCommandID(command_id); + if (error) { + error->ExecuteMenuItem(browser_); + return; + } + // TODO crbug.com/1186848 Log metrics per command_id; + chrome::ExecuteCommand(browser_, command_id); + } +} + +SharingHubModel* SharingHubSubMenuModel::GetSharingHubModel() const { + SharingHubService* const service = + SharingHubServiceFactory::GetForProfile(browser_->profile()); + return service ? service->GetSharingHubModel() : nullptr; } void SharingHubSubMenuModel::Build(content::WebContents* web_contents) { if (!web_contents) return; - Profile* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); - SharingHubService* const service = - SharingHubServiceFactory::GetForProfile(profile); - SharingHubModel* const model = - service ? service->GetSharingHubModel() : nullptr; - std::vector<SharingHubAction> actions; - if (model) { - model->GetActionList(web_contents, &actions); + SharingHubModel* const model = GetSharingHubModel(); + if (!model) + return; - for (std::vector<SharingHubAction>::const_iterator it = actions.begin(); - it != actions.end(); ++it) { - AddItemWithStringId(it->command_id, it->title); - } + std::vector<SharingHubAction> first_party_actions; + std::vector<SharingHubAction> third_party_actions; + model->GetFirstPartyActionList(web_contents, &first_party_actions); + model->GetThirdPartyActionList(web_contents, &third_party_actions); + + for (auto action : first_party_actions) { + AddItem(action.command_id, action.title); } AddSeparator(ui::NORMAL_SEPARATOR); + for (auto action : third_party_actions) { + AddItemWithIcon(action.command_id, action.title, + ui::ImageModel::FromVectorIcon(action.icon)); + third_party_action_ids_.push_back(action.command_id); + } +} + +bool SharingHubSubMenuModel::IsThirdPartyAction(int id) { + return std::find(third_party_action_ids_.begin(), + third_party_action_ids_.end(), + id) != third_party_action_ids_.end(); } } // namespace sharing_hub
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_sub_menu_model.h b/chrome/browser/ui/sharing_hub/sharing_hub_sub_menu_model.h index 5a505e9..c8b3cff 100644 --- a/chrome/browser/ui/sharing_hub/sharing_hub_sub_menu_model.h +++ b/chrome/browser/ui/sharing_hub/sharing_hub_sub_menu_model.h
@@ -8,15 +8,29 @@ #include "content/public/browser/web_contents.h" #include "ui/base/models/simple_menu_model.h" +class Browser; + namespace sharing_hub { -class SharingHubSubMenuModel : public ui::SimpleMenuModel { +class SharingHubModel; + +class SharingHubSubMenuModel : public ui::SimpleMenuModel, + public ui::SimpleMenuModel::Delegate { public: - SharingHubSubMenuModel(ui::SimpleMenuModel::Delegate* delegate, - content::WebContents* web_contents); + explicit SharingHubSubMenuModel(Browser* browser); + ~SharingHubSubMenuModel() override; + + // Overridden from ui::SimpleMenuModel::Delegate: + bool IsCommandIdEnabled(int command_id) const override; + void ExecuteCommand(int command_id, int event_flags) override; private: + SharingHubModel* GetSharingHubModel() const; void Build(content::WebContents* web_contents); + bool IsThirdPartyAction(int id); + + Browser* browser_; + std::vector<int> third_party_action_ids_; DISALLOW_COPY_AND_ASSIGN(SharingHubSubMenuModel); };
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc index 77d8373..075abaf 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.cc +++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -826,8 +826,8 @@ AddSeparator(ui::UPPER_SEPARATOR); if (base::FeatureList::IsEnabled(sharing_hub::kSharingHubDesktopAppMenu)) { - sub_menus_.push_back(std::make_unique<sharing_hub::SharingHubSubMenuModel>( - this, browser_->tab_strip_model()->GetActiveWebContents())); + sub_menus_.push_back( + std::make_unique<sharing_hub::SharingHubSubMenuModel>(browser_)); AddSubMenuWithStringId(IDC_SHARING_HUB_MENU, IDS_SHARING_HUB_TITLE, sub_menus_.back().get()); }
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index 7305203..cbfa041 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -1669,7 +1669,12 @@ views::LabelButton* button = bookmark_buttons_[index]; bookmark_buttons_.erase(bookmark_buttons_.cbegin() + index); - delete button; + // Set not visible before removing to advance focus if needed. See + // crbug.com/1183980. TODO(crbug.com/1189729): remove this workaround if + // FocusManager behavior is changed. + button->SetVisible(false); + RemoveChildViewT(button); + return true; }
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index bfa6016a..cad9e986 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -3307,6 +3307,7 @@ // Toggle fullscreen mode; move the window between displays as needed. // TODO(crbug.com/1034783): Implement at lower layers to avoid transitions. + bool entering_cross_screen_fullscreen = false; if (fullscreen && display_id != display::kInvalidDisplayId) { display::Screen* screen = display::Screen::GetScreen(); display::Display display; @@ -3335,19 +3336,23 @@ } else { frame_->SetFullscreen(false); } + entering_cross_screen_fullscreen = true; frame_->SetBounds({display.work_area().origin(), frame_->GetWindowBoundsInScreen().size()}); } } +#if defined(OS_MAC) + // On Mac, the fullscreen state change must be requested with a delay after + // moving the window to the target display; see http://crbug.com/1210548 + frame_->SetFullscreen(fullscreen, entering_cross_screen_fullscreen); +#else // OS_MAC frame_->SetFullscreen(fullscreen); - -#if !defined(OS_MAC) // On Mac, the pre-fullscreen bounds must be restored after an asynchronous // transition out of the fullscreen workspace; see http://crbug.com/1039874 if (!fullscreen && restore_pre_fullscreen_bounds_callback_) std::move(restore_pre_fullscreen_bounds_callback_).Run(); -#endif // !OS_MAC +#endif // OS_MAC // Enable immersive before the browser refreshes its list of enabled commands. const bool should_stay_in_immersive =
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 6b777fd..17968cd 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -228,6 +228,10 @@ // Accessor for the contents WebView. views::WebView* contents_web_view() { return contents_web_view_; } + base::WeakPtr<BrowserView> GetAsWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); + } + // Accessor for the BrowserView's TabSearchButton instance. TabSearchButton* GetTabSearchButton();
diff --git a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_action_button.cc b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_action_button.cc index e8587f5..eebf2e56 100644 --- a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_action_button.cc +++ b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_action_button.cc
@@ -36,7 +36,7 @@ base::Unretained(bubble), base::Unretained(this)), CreateIcon(action_info.icon), - l10n_util::GetStringUTF16(action_info.title)) { + action_info.title) { action_command_id_ = action_info.command_id; action_is_first_party_ = action_info.is_first_party; SetEnabled(true);
diff --git a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc index f682597..3d04cda 100644 --- a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc +++ b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc
@@ -111,23 +111,27 @@ scroll_view_ = AddChildView(std::make_unique<views::ScrollView>()); scroll_view_->ClipHeightTo(0, kActionButtonHeight * kMaximumButtons); - PopulateScrollView(controller_->GetActions()); + PopulateScrollView(controller_->GetFirstPartyActions(), + controller_->GetThirdPartyActions()); } void SharingHubBubbleViewImpl::PopulateScrollView( - const std::vector<SharingHubAction>& actions) { + const std::vector<SharingHubAction>& first_party_actions, + const std::vector<SharingHubAction>& third_party_actions) { auto* action_list_view = scroll_view_->SetContents(std::make_unique<views::View>()); action_list_view->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical)); - bool separator_added = false; - for (const auto& action : actions) { - if (!separator_added && !action.is_first_party) { - action_list_view->AddChildView(GetSeparator()); - separator_added = true; - } + for (const auto& action : first_party_actions) { + auto* view = action_list_view->AddChildView( + std::make_unique<SharingHubBubbleActionButton>(this, action)); + view->SetGroup(kActionButtonGroup); + } + action_list_view->AddChildView(GetSeparator()); + + for (const auto& action : third_party_actions) { auto* view = action_list_view->AddChildView( std::make_unique<SharingHubBubbleActionButton>(this, action)); view->SetGroup(kActionButtonGroup);
diff --git a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h index 4302a440..e3bcee5 100644 --- a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h +++ b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h
@@ -61,7 +61,9 @@ void CreateScrollView(); // Populates the scroll view containing sharing actions. - void PopulateScrollView(const std::vector<SharingHubAction>& actions); + void PopulateScrollView( + const std::vector<SharingHubAction>& first_party_actions, + const std::vector<SharingHubAction>& third_party_actions); // Resizes and potentially moves the bubble to fit the content's preferred // size.
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc index fbda064f7..14e0f078 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -1488,6 +1488,12 @@ ? views::Widget::MoveLoopEscapeBehavior::kHide : views::Widget::MoveLoopEscapeBehavior::kDontHide; + // This code isn't set up to handle nested run loops. Nested run loops may + // lead to all sorts of interesting crashes, and generally indicate a bug + // lower in the stack. This is a CHECK() as there may be security + // implications to attempting a nested run loop. + CHECK(!in_move_loop_); + in_move_loop_ = true; views::Widget::MoveLoopResult result = move_loop_widget_->RunMoveLoop( drag_offset, move_loop_source, escape_behavior); content::NotificationService::current()->Notify( @@ -1498,10 +1504,8 @@ if (!ref) return; - if (move_loop_widget_ && - widget_observation_.IsObservingSource(move_loop_widget_)) { - widget_observation_.Reset(); - } + in_move_loop_ = false; + widget_observation_.Reset(); move_loop_widget_ = nullptr; if (current_state_ == DragState::kDraggingWindow) {
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.h b/chrome/browser/ui/views/tabs/tab_drag_controller.h index ef8d13d..6cbf15f 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.h +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.h
@@ -718,6 +718,9 @@ base::ScopedObservation<views::Widget, views::WidgetObserver> widget_observation_{this}; + // True while RunMoveLoop() has been called on a widget. + bool in_move_loop_ = false; + base::WeakPtrFactory<TabDragController> weak_factory_{this}; };
diff --git a/chrome/browser/ui/views/toolbar/chrome_labs_button.cc b/chrome/browser/ui/views/toolbar/chrome_labs_button.cc index 05be16f..c17e709 100644 --- a/chrome/browser/ui/views/toolbar/chrome_labs_button.cc +++ b/chrome/browser/ui/views/toolbar/chrome_labs_button.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/about_flags.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.h" #include "chrome/browser/ui/webui/flags/flags_ui.h" #include "chrome/common/channel_info.h" @@ -26,11 +27,11 @@ #include "chrome/browser/ash/settings/owner_flags_storage.h" #endif -ChromeLabsButton::ChromeLabsButton(Browser* browser, +ChromeLabsButton::ChromeLabsButton(BrowserView* browser_view, const ChromeLabsBubbleViewModel* model) : ToolbarButton(base::BindRepeating(&ChromeLabsButton::ButtonPressed, base::Unretained(this))), - browser_(browser), + browser_view_(browser_view), model_(model) { SetVectorIcons(kChromeLabsIcon, kChromeLabsTouchIcon); SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_CHROMELABS_BUTTON)); @@ -47,6 +48,14 @@ } void ChromeLabsButton::ButtonPressed() { + // On Chrome OS if we are still waiting for IsOwnerAsync to return abort + // button clicks. +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (is_waiting_to_show) { + return; + } +#endif + if (ChromeLabsBubbleView::IsShowing()) { ChromeLabsBubbleView::Hide(); return; @@ -60,20 +69,31 @@ // Reset timer. ash_owner_check_timer_ = nullptr; // Bypass possible incognito profile same as chrome://flags does. - Profile* original_profile = browser_->profile()->GetOriginalProfile(); - if (base::SysInfo::IsRunningOnChromeOS() && + Profile* original_profile = + browser_view_->browser()->profile()->GetOriginalProfile(); + if ((base::SysInfo::IsRunningOnChromeOS() || + should_circumvent_device_check_for_testing_) && ash::OwnerSettingsServiceAshFactory::GetForBrowserContext( original_profile)) { ash::OwnerSettingsServiceAsh* service = ash::OwnerSettingsServiceAshFactory::GetForBrowserContext( original_profile); ash_owner_check_timer_ = std::make_unique<base::ElapsedTimer>(); - service->IsOwnerAsync( - base::BindOnce(&ChromeLabsBubbleView::Show, this, browser_, model_)); + is_waiting_to_show = true; + service->IsOwnerAsync(base::BindOnce( + [](ChromeLabsButton* button, base::WeakPtr<BrowserView> browser_view, + const ChromeLabsBubbleViewModel* model, bool is_owner) { + if (!browser_view) + return; + ChromeLabsBubbleView::Show(button, browser_view->browser(), model, + is_owner); + button->is_waiting_to_show = false; + }, + this, browser_view_->GetAsWeakPtr(), model_)); return; } #endif - ChromeLabsBubbleView::Show(this, browser_, model_, + ChromeLabsBubbleView::Show(this, browser_view_->browser(), model_, /*user_is_chromeos_owner=*/false); }
diff --git a/chrome/browser/ui/views/toolbar/chrome_labs_button.h b/chrome/browser/ui/views/toolbar/chrome_labs_button.h index 285c248..40c440c 100644 --- a/chrome/browser/ui/views/toolbar/chrome_labs_button.h +++ b/chrome/browser/ui/views/toolbar/chrome_labs_button.h
@@ -13,13 +13,13 @@ class ElapsedTimer; } -class Browser; +class BrowserView; class Profile; class ChromeLabsButton : public ToolbarButton { public: METADATA_HEADER(ChromeLabsButton); - explicit ChromeLabsButton(Browser* browser, + explicit ChromeLabsButton(BrowserView* browser_view, const ChromeLabsBubbleViewModel* model); ChromeLabsButton(const ChromeLabsButton&) = delete; ChromeLabsButton& operator=(const ChromeLabsButton&) = delete; @@ -32,6 +32,10 @@ base::ElapsedTimer* GetAshOwnerCheckTimer() { return ash_owner_check_timer_.get(); } + + void SetShouldCircumventDeviceCheckForTesting(bool should_circumvent) { + should_circumvent_device_check_for_testing_ = should_circumvent; + } #endif private: @@ -44,7 +48,13 @@ std::unique_ptr<base::ElapsedTimer> ash_owner_check_timer_; #endif - Browser* browser_; + BrowserView* browser_view_; + +#if BUILDFLAG(IS_CHROMEOS_ASH) + bool is_waiting_to_show = false; + // Used to circumvent the IsRunningOnChromeOS() check in ash-chrome tests. + bool should_circumvent_device_check_for_testing_ = false; +#endif const ChromeLabsBubbleViewModel* model_; };
diff --git a/chrome/browser/ui/views/toolbar/chrome_labs_button_unittest.cc b/chrome/browser/ui/views/toolbar/chrome_labs_button_unittest.cc index 82d7853..0a8e798a 100644 --- a/chrome/browser/ui/views/toolbar/chrome_labs_button_unittest.cc +++ b/chrome/browser/ui/views/toolbar/chrome_labs_button_unittest.cc
@@ -22,6 +22,8 @@ #include "base/command_line.h" #include "base/memory/ptr_util.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" +#include "chrome/browser/ash/ownership/owner_settings_service_ash.h" +#include "chrome/browser/ash/ownership/owner_settings_service_ash_factory.h" #include "chrome/common/pref_names.h" #include "components/user_manager/scoped_user_manager.h" #endif @@ -89,12 +91,23 @@ TEST_F(ChromeLabsButtonTest, ShowAndHideChromeLabsBubbleOnPress) { ChromeLabsButton* labs_button = browser_view()->toolbar()->chrome_labs_button(); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + ash::OwnerSettingsServiceAsh* service_ = + ash::OwnerSettingsServiceAshFactory::GetForBrowserContext(GetProfile()); + labs_button->SetShouldCircumventDeviceCheckForTesting(true); +#endif + EXPECT_FALSE(ChromeLabsBubbleView::IsShowing()); ui::MouseEvent e(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), 0, 0); views::test::ButtonTestApi test_api(labs_button); test_api.NotifyClick(e); +#if BUILDFLAG(IS_CHROMEOS_ASH) + service_->RunPendingIsOwnerCallbacksForTesting(/*is_owner=*/false); +#endif EXPECT_TRUE(ChromeLabsBubbleView::IsShowing()); + views::test::WidgetDestroyedWaiter destroyed_waiter( ChromeLabsBubbleView::GetChromeLabsBubbleViewForTesting()->GetWidget()); test_api.NotifyClick(e);
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc index 2c5c301..1ebaac5d 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -312,7 +312,7 @@ if (ChromeLabsButton::ShouldShowButton(chrome_labs_model_.get(), browser_->profile())) { chrome_labs_button_ = AddChildView(std::make_unique<ChromeLabsButton>( - browser_, chrome_labs_model_.get())); + browser_view_, chrome_labs_model_.get())); show_chrome_labs_button_.Init( chrome_labs_prefs::kBrowserLabsEnabled,
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest.cc b/chrome/browser/ui/web_applications/web_app_browsertest.cc index 2ed89371..e85f0f5 100644 --- a/chrome/browser/ui/web_applications/web_app_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_browsertest.cc
@@ -186,13 +186,11 @@ // line switch to enable manifest parsing. class WebAppBrowserTest_WindowControlsOverlay : public WebAppBrowserTest { public: - WebAppBrowserTest_WindowControlsOverlay() { - scoped_feature_list_.InitWithFeatures( - {features::kWebAppWindowControlsOverlay}, {}); - } + WebAppBrowserTest_WindowControlsOverlay() = default; private: - base::test::ScopedFeatureList scoped_feature_list_; + base::test::ScopedFeatureList scoped_feature_list_{ + features::kWebAppWindowControlsOverlay}; }; using WebAppTabRestoreBrowserTest = WebAppBrowserTest; @@ -1145,12 +1143,11 @@ class WebAppBrowserTest_HideOrigin : public WebAppBrowserTest { public: - WebAppBrowserTest_HideOrigin() { - scoped_feature_list_.InitAndEnableFeature(features::kHideWebAppOriginText); - } + WebAppBrowserTest_HideOrigin() = default; private: - base::test::ScopedFeatureList scoped_feature_list_; + base::test::ScopedFeatureList scoped_feature_list_{ + features::kHideWebAppOriginText}; }; // WebApps should not have origin text with this feature on. @@ -1163,13 +1160,11 @@ class WebAppBrowserTest_AppNameInsteadOfOrigin : public WebAppBrowserTest { public: - WebAppBrowserTest_AppNameInsteadOfOrigin() { - scoped_feature_list_.InitAndEnableFeature( - features::kDesktopPWAsFlashAppNameInsteadOfOrigin); - } + WebAppBrowserTest_AppNameInsteadOfOrigin() = default; private: - base::test::ScopedFeatureList scoped_feature_list_; + base::test::ScopedFeatureList scoped_feature_list_{ + features::kDesktopPWAsFlashAppNameInsteadOfOrigin}; }; // Web apps should flash the app name with this feature on. @@ -1316,13 +1311,11 @@ class WebAppBrowserTest_RemoveStatusBar : public WebAppBrowserTest { public: - WebAppBrowserTest_RemoveStatusBar() { - scoped_feature_list_.InitAndEnableFeature( - features::kRemoveStatusBarInWebApps); - } + WebAppBrowserTest_RemoveStatusBar() = default; private: - base::test::ScopedFeatureList scoped_feature_list_; + base::test::ScopedFeatureList scoped_feature_list_{ + features::kRemoveStatusBarInWebApps}; }; IN_PROC_BROWSER_TEST_F(WebAppBrowserTest_RemoveStatusBar, RemoveStatusBar) {
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc index 132d2d6..98c96b29 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
@@ -32,7 +32,8 @@ #include "chrome/browser/usb/usb_chooser_context.h" #include "chrome/browser/usb/usb_chooser_context_factory.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" -#include "chrome/browser/web_applications/test/test_app_registrar.h" +#include "chrome/browser/web_applications/test/test_web_app_registry_controller.h" +#include "chrome/browser/web_applications/web_app.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "chrome/test/base/browser_with_test_window_test.h" @@ -106,10 +107,6 @@ {{"http://127.0.0.1", "location"}, {true, ""}}, // Localhost is secure. {{"http://[::1]", "location"}, {true, ""}}}; -std::string GenerateFakeAppId(const GURL& url) { - return web_app::GenerateAppIdFromURL(url); -} - } // namespace namespace settings { @@ -171,8 +168,13 @@ } void SetUp() override { + test_registry_controller_ = + std::make_unique<web_app::TestWebAppRegistryController>(); + test_registry_controller_->SetUp(profile()); + controller().Init(); + handler_ = - std::make_unique<SiteSettingsHandler>(profile_.get(), app_registrar_); + std::make_unique<SiteSettingsHandler>(profile_.get(), app_registrar()); handler()->set_web_ui(web_ui()); handler()->AllowJavascript(); // AllowJavascript() adds a callback to create leveldb_env::ChromiumEnv @@ -193,9 +195,26 @@ } } + std::unique_ptr<web_app::WebApp> CreateWebApp() { + const GURL app_url = GURL("http://abc.example.com/path"); + const web_app::AppId app_id = web_app::GenerateAppIdFromURL(app_url); + + auto web_app = std::make_unique<web_app::WebApp>(app_id); + web_app->AddSource(web_app::Source::kSync); + web_app->SetDisplayMode(web_app::DisplayMode::kStandalone); + web_app->SetUserDisplayMode(web_app::DisplayMode::kStandalone); + web_app->SetName("Name"); + web_app->SetStartUrl(app_url); + + return web_app; + } + + web_app::TestWebAppRegistryController& controller() { + return *test_registry_controller_; + } + web_app::WebAppRegistrar& app_registrar() { return controller().registrar(); } TestingProfile* profile() { return profile_.get(); } TestingProfile* incognito_profile() { return incognito_profile_; } - web_app::TestAppRegistrar& app_registrar() { return app_registrar_; } content::TestWebUI* web_ui() { return &web_ui_; } SiteSettingsHandler* handler() { return handler_.get(); } @@ -487,7 +506,8 @@ content::BrowserTaskEnvironment task_environment_; std::unique_ptr<TestingProfile> profile_; TestingProfile* incognito_profile_; - web_app::TestAppRegistrar app_registrar_; + std::unique_ptr<web_app::TestWebAppRegistryController> + test_registry_controller_; content::TestWebUI web_ui_; std::unique_ptr<SiteSettingsHandler> handler_; #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -906,9 +926,8 @@ } TEST_F(SiteSettingsHandlerTest, InstalledApps) { - web_app::TestAppRegistrar& registrar = app_registrar(); - const GURL url("http://abc.example.com/"); - registrar.AddExternalApp(GenerateFakeAppId(url), {url}); + auto web_app = CreateWebApp(); + controller().RegisterApp(std::move(web_app)); SetUpCookiesTreeModel(); @@ -1533,7 +1552,13 @@ const SiteSettingsHandlerInfobarTest&) = delete; void SetUp() override { BrowserWithTestWindowTest::SetUp(); - handler_ = std::make_unique<SiteSettingsHandler>(profile(), app_registrar_); + + test_registry_controller_ = + std::make_unique<web_app::TestWebAppRegistryController>(); + test_registry_controller_->SetUp(profile()); + + handler_ = + std::make_unique<SiteSettingsHandler>(profile(), app_registrar()); handler()->set_web_ui(web_ui()); handler()->AllowJavascript(); web_ui()->ClearTrackedCalls(); @@ -1547,6 +1572,9 @@ extensions::ExtensionSystem::Get(profile())); extension_system->CreateExtensionService( base::CommandLine::ForCurrentProcess(), base::FilePath(), false); + + // Wait for the sync bridge to be ready synchronously. + controller().Init(); } void TearDown() override { @@ -1577,10 +1605,17 @@ Browser* browser2() { return browser2_.get(); } + web_app::TestWebAppRegistryController& controller() { + return *test_registry_controller_; + } + + web_app::WebAppRegistrar& app_registrar() { return controller().registrar(); } + const std::string kNotifications; private: - web_app::TestAppRegistrar app_registrar_; + std::unique_ptr<web_app::TestWebAppRegistryController> + test_registry_controller_; content::TestWebUI web_ui_; std::unique_ptr<SiteSettingsHandler> handler_; std::unique_ptr<BrowserWindow> window2_;
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.cc b/chrome/browser/webauthn/authenticator_request_dialog_model.cc index 2e515843..1bb8956 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model.cc +++ b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
@@ -843,6 +843,12 @@ if (cable_ui_type_) { switch (*cable_ui_type_) { + case AuthenticatorRequestDialogModel::CableUIType::CABLE_V2_2ND_FACTOR: + if (!base::FeatureList::IsEnabled(device::kWebAuthPhoneSupport)) { + break; + } + [[fallthrough]]; + case AuthenticatorRequestDialogModel::CableUIType::CABLE_V2_SERVER_LINK: transports_to_list_if_active.push_back( AuthenticatorTransport::kAndroidAccessory); @@ -854,16 +860,14 @@ if (base::Contains(transport_availability_.available_transports, cable)) { transports_to_list_if_active.push_back(cable); - DCHECK(is_get_assertion); + DCHECK(is_get_assertion || + base::FeatureList::IsEnabled(device::kWebAuthPhoneSupport)); if (!priority_transport) { priority_transport = cable; } } break; } - - case AuthenticatorRequestDialogModel::CableUIType::CABLE_V2_2ND_FACTOR: - break; } }
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index aeafbb9..7d868a7 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-master-1622115746-16aae4983a3b79f0983927a7f29da7d36068f03d.profdata +chrome-win64-master-1622159822-454cea1e0e4715322c0a3ea42d011f3c9a700300.profdata
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index c3bb583..6fd5f654 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -5612,6 +5612,7 @@ "../browser/nearby_sharing/nearby_notification_manager_unittest.cc", "../browser/nearby_sharing/nearby_per_session_discovery_manager_unittest.cc", "../browser/nearby_sharing/nearby_receive_manager_unittest.cc", + "../browser/nearby_sharing/nearby_share_feature_usage_metrics_unittest.cc", "../browser/nearby_sharing/nearby_share_profile_info_provider_impl_unittest.cc", "../browser/nearby_sharing/nearby_share_settings_unittest.cc", "../browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc",
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 a7554d1..0944530 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/routine_section_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/routine_section_test.js
@@ -226,6 +226,15 @@ return flushTasks(); } + /** + * @param {boolean} isActive + * @return {!Promise} + */ + function setIsActive(isActive) { + routineSectionElement.isActive = isActive; + return flushTasks(); + } + test('ElementRenders', () => { return initializeRoutineSection([]).then(() => { // Verify the element rendered. @@ -850,4 +859,38 @@ resetMockTime(); }); }); + + test('PageChangeStopsRunningTest', () => { + /** @type {!Array<!RoutineType>} */ + const routines = [RoutineType.kMemory]; + + routineController.setFakeStandardRoutineResult( + RoutineType.kMemory, StandardRoutineResult.kTestPassed); + return initializeRoutineSection(routines) + .then(() => clickRunTestsButton()) + .then(() => { + // Badge is visible with test running. + assertFalse(getStatusBadge().hidden); + assertEquals(getStatusBadge().badgeType, BadgeType.RUNNING); + dx_utils.assertTextContains( + getStatusBadge().value, loadTimeData.getString('testRunning')); + + // Text is visible describing which test is being run. + assertFalse(getStatusTextElement().hidden); + dx_utils.assertElementContainsText( + getStatusTextElement(), + loadTimeData.getString('memoryRoutineText').toLowerCase()); + + // Simulate a navigation page change event. + return setIsActive(false); + }) + .then(() => flushTasks()) + .then(() => { + // Result list is no longer visible. + assertFalse(isVisible(getResultList())); + // Memory routine should be cancelled. + assertEquals( + ExecutionProgress.kCancelled, getEntries()[0].item.progress); + }); + }); }
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_update_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_update_page_test.js index ea9536ff..553c8d8 100644 --- a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_update_page_test.js +++ b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_update_page_test.js
@@ -54,9 +54,10 @@ /** * @return {!Promise} */ - function clickCheckUpdateBtn() { - const checkUpdateBtn = component.shadowRoot.querySelector('#checkUpdate'); - checkUpdateBtn.click(); + function clickCheckUpdateButton() { + const checkUpdateButton = + component.shadowRoot.querySelector('#checkUpdate'); + checkUpdateButton.click(); return flushTasks(); } @@ -67,9 +68,9 @@ return initializeUpdatePage(version, update).then(() => { const versionComponent = component.shadowRoot.querySelector('#versionInfo'); - const updateBtn = component.shadowRoot.querySelector('#performUpdate'); + const updateButton = component.shadowRoot.querySelector('#performUpdate'); assertTrue(versionComponent.textContent.trim().indexOf(version) !== -1); - assertTrue(updateBtn.hidden); + assertTrue(updateButton.hidden); }); }); @@ -85,11 +86,11 @@ .then(() => { const networkUnavailable = component.shadowRoot.querySelector('#networkUnavailable'); - const checkUpdateBtn = + const checkUpdateButton = component.shadowRoot.querySelector('#checkUpdate'); assertFalse(networkUnavailable.hidden); - assertTrue(checkUpdateBtn.hidden); + assertTrue(checkUpdateButton.hidden); }); }); @@ -102,7 +103,7 @@ component.networkAvailable = true; return flushTasks(); }) - .then(() => clickCheckUpdateBtn()) + .then(() => clickCheckUpdateButton()) .then(() => { const versionComponent = component.shadowRoot.querySelector('#versionInfo'); @@ -122,7 +123,7 @@ component.networkAvailable = true; return flushTasks(); }) - .then(() => clickCheckUpdateBtn()) + .then(() => clickCheckUpdateButton()) .then(() => { const versionComponent = component.shadowRoot.querySelector('#versionInfo'); @@ -132,9 +133,9 @@ versionComponent.textContent.trim().indexOf(uptoDateMsg) !== -1); }) .then(() => { - const updateBtn = + const updateButton = component.shadowRoot.querySelector('#performUpdate'); - assertFalse(updateBtn.hidden); + assertFalse(updateButton.hidden); }); }); }
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js index 2a98864..8ee6018 100644 --- a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js +++ b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js
@@ -6,7 +6,7 @@ import {fakeChromeVersion, fakeStates} from 'chrome://shimless-rma/fake_data.js'; import {FakeShimlessRmaService} from 'chrome://shimless-rma/fake_shimless_rma_service.js'; import {setShimlessRmaServiceForTesting} from 'chrome://shimless-rma/mojo_interface_provider.js'; -import {BtnState, ShimlessRmaElement} from 'chrome://shimless-rma/shimless_rma.js'; +import {ButtonState, ShimlessRmaElement} from 'chrome://shimless-rma/shimless_rma.js'; import {RmaState, State} from 'chrome://shimless-rma/shimless_rma_types.js'; import {assertFalse, assertTrue} from '../../chai_assert.js'; @@ -56,15 +56,15 @@ /** * Utility function to assert navigation buttons - * TODO(joonbug): expand to cover assertion of BtnState + * TODO(joonbug): expand to cover assertion of ButtonState */ function assertNavButtons() { - const nextBtn = component.shadowRoot.querySelector('#back'); - const prevBtn = component.shadowRoot.querySelector('#cancel'); - const backBtn = component.shadowRoot.querySelector('#next'); - assertTrue(!!nextBtn); - assertTrue(!!prevBtn); - assertTrue(!!backBtn); + const nextButton = component.shadowRoot.querySelector('#back'); + const prevButton = component.shadowRoot.querySelector('#cancel'); + const backButton = component.shadowRoot.querySelector('#next'); + assertTrue(!!nextButton); + assertTrue(!!prevButton); + assertTrue(!!backButton); } /** @@ -72,8 +72,8 @@ * @return {Promise} */ function clickNext() { - const nextBtn = component.shadowRoot.querySelector('#next'); - nextBtn.click(); + const nextButton = component.shadowRoot.querySelector('#next'); + nextButton.click(); return flushTasks(); } @@ -100,8 +100,8 @@ assertTrue(!!initialPage); assertTrue(initialPage.hidden); - const prevBtn = component.shadowRoot.querySelector('#back'); - prevBtn.click(); + const prevButton = component.shadowRoot.querySelector('#back'); + prevButton.click(); await flushTasks(); // components page should not be destroyed. @@ -117,15 +117,15 @@ component.shadowRoot.querySelector('onboarding-landing-page'); await clickNext(); - const cancelBtn = component.shadowRoot.querySelector('#cancel'); - cancelBtn.click(); + const cancelButton = component.shadowRoot.querySelector('#cancel'); + cancelButton.click(); await flushTasks(); // back to initial page assertFalse(initialPage.hidden); }); - test('NextBtnClickedOnReady', async () => { + test('NextButtonClickedOnReady', async () => { await initializeShimlessRMAApp(fakeStates, fakeChromeVersion[0]); const initialPage = @@ -133,7 +133,7 @@ assertTrue(!!initialPage); const resolver = new PromiseResolver(); - initialPage.onNextBtnClick = () => resolver.promise; + initialPage.onNextButtonClick = () => resolver.promise; await clickNext(); assertFalse(initialPage.hidden); @@ -148,7 +148,7 @@ assertTrue(initialPage.hidden); }); - test('NextBtnClickedOnNotReady', async () => { + test('NextButtonClickedOnNotReady', async () => { await initializeShimlessRMAApp(fakeStates, fakeChromeVersion[0]); const initialPage = @@ -156,7 +156,7 @@ assertTrue(!!initialPage); const resolver = new PromiseResolver(); - initialPage.onNextBtnClick = () => resolver.promise; + initialPage.onNextButtonClick = () => resolver.promise; await clickNext(); assertFalse(initialPage.hidden); @@ -170,13 +170,13 @@ test('UpdateButtonState', async () => { await initializeShimlessRMAApp(fakeStates, fakeChromeVersion[0]); - const backBtn = component.shadowRoot.querySelector('#back'); - assertTrue(!!backBtn); - assertTrue(backBtn.hidden); + const backButton = component.shadowRoot.querySelector('#back'); + assertTrue(!!backButton); + assertTrue(backButton.hidden); - component.updateBtnState('btnBack', BtnState.VISIBLE); + component.updateButtonState('buttonBack', ButtonState.VISIBLE); await flushTasks(); - assertFalse(backBtn.hidden); + assertFalse(backButton.hidden); }); }
diff --git a/chrome/test/data/webui/settings/chromeos/network_summary_item_test.js b/chrome/test/data/webui/settings/chromeos/network_summary_item_test.js index a69da17b..1ca11ab 100644 --- a/chrome/test/data/webui/settings/chromeos/network_summary_item_test.js +++ b/chrome/test/data/webui/settings/chromeos/network_summary_item_test.js
@@ -6,6 +6,7 @@ // #import 'chrome://os-settings/chromeos/os_settings.js'; // #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +// #import {eventToPromise} from 'chrome://test/test_util.m.js'; // clang-format on suite('NetworkSummaryItem', function() { @@ -285,4 +286,39 @@ netSummaryItem.$$('#networkState').classList.contains('network-state')); }); + test( + 'Show networks list when only 1 pSIM network is available', + async function() { + const mojom = chromeos.networkConfig.mojom; + + const showNetworksFiredPromise = + test_util.eventToPromise('show-networks', netSummaryItem); + + // Simulate a device which has a single pSIM slot and no eSIM slots. + const simInfos = [{slotId: 1, iccid: '000', isPrimary: true, eid: ''}]; + + netSummaryItem.setProperties({ + isUpdatedCellularUiEnabled_: true, + deviceState: { + deviceState: mojom.DeviceStateType.kEnabled, + type: mojom.NetworkType.kCellular, + simAbsent: false, + inhibitReason: mojom.InhibitReason.kNotInhibited, + simLockStatus: {lockEnabled: false}, + simInfos: simInfos, + }, + activeNetworkState: { + connectionState: mojom.ConnectionStateType.kNotConnected, + guid: '', + type: mojom.NetworkType.kCellular, + typeState: {cellular: {networkTechnology: ''}} + }, + }); + Polymer.dom.flush(); + const networkState = netSummaryItem.$$('#networkState'); + assertTrue(!!networkState); + networkState.click(); + Polymer.dom.flush(); + await showNetworksFiredPromise; + }); });
diff --git a/chrome/test/data/webui/settings/privacy_sandbox_browsertest.js b/chrome/test/data/webui/settings/privacy_sandbox_browsertest.js index ae53c20..be6bfd3 100644 --- a/chrome/test/data/webui/settings/privacy_sandbox_browsertest.js +++ b/chrome/test/data/webui/settings/privacy_sandbox_browsertest.js
@@ -24,7 +24,7 @@ return { enabled: [ 'blink::features::kInterestCohortAPIOriginTrial', - 'features::kConversionMeasurement', + 'blink::features::kConversionMeasurement', 'features::kPrivacySandboxSettings', ] };
diff --git a/chromecast/cast_core/BUILD.gn b/chromecast/cast_core/BUILD.gn index 4547ee7..5b0abbb 100644 --- a/chromecast/cast_core/BUILD.gn +++ b/chromecast/cast_core/BUILD.gn
@@ -4,20 +4,35 @@ import("//chromecast/chromecast.gni") +cast_source_set("renderer") { + sources = [ + "cast_runtime_content_renderer_client.cc", + "cast_runtime_content_renderer_client.h", + ] + + deps = [ + "//base", + "//chromecast/renderer", + "//components/cast_streaming/renderer", + "//content/public/renderer", + "//media", + ] +} + cast_source_set("cast_core") { sources = [ "cast_runtime_service.cc", "cast_runtime_service.h", ] - - if (!enable_cast_media_runtime) { - sources += [ "cast_runtime_service_simple.cc" ] - } - deps = [ "//base", "//chromecast/service", ] - public_deps = [ "//chromecast/media/cma/backend/proxy:headers" ] + + if (!enable_cast_media_runtime) { + sources += [ "cast_runtime_service_simple.cc" ] + } else { + deps += [ ":renderer" ] + } }
diff --git a/chromecast/cast_core/DEPS b/chromecast/cast_core/DEPS index b5becb8..207af01 100644 --- a/chromecast/cast_core/DEPS +++ b/chromecast/cast_core/DEPS
@@ -1,4 +1,8 @@ include_rules = [ "+chromecast/media", + "+chromecast/renderer", '+chromecast/service', + '+components/cast_streaming', + "+content/public", + "+media/base", ]
diff --git a/chromecast/cast_core/cast_runtime_content_renderer_client.cc b/chromecast/cast_core/cast_runtime_content_renderer_client.cc new file mode 100644 index 0000000..d9e898f --- /dev/null +++ b/chromecast/cast_core/cast_runtime_content_renderer_client.cc
@@ -0,0 +1,43 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromecast/cast_core/cast_runtime_content_renderer_client.h" + +#include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_frame_media_playback_options.h" +#include "media/base/demuxer.h" + +namespace chromecast { + +// static +std::unique_ptr<shell::CastContentRendererClient> +shell::CastContentRendererClient::Create() { + return std::make_unique<CastRuntimeContentRendererClient>(); +} + +CastRuntimeContentRendererClient::CastRuntimeContentRendererClient() = default; + +CastRuntimeContentRendererClient::~CastRuntimeContentRendererClient() = default; + +void CastRuntimeContentRendererClient::RenderFrameCreated( + content::RenderFrame* render_frame) { + CastContentRendererClient::RenderFrameCreated(render_frame); + cast_streaming_renderer_client_.RenderFrameCreated(render_frame); +} + +std::unique_ptr<::media::Demuxer> +CastRuntimeContentRendererClient::OverrideDemuxerForUrl( + content::RenderFrame* render_frame, + const GURL& url, + scoped_refptr<base::SingleThreadTaskRunner> media_task_runner) { + if (!render_frame->GetRenderFrameMediaPlaybackOptions() + .is_remoting_renderer_enabled()) { + return nullptr; + } + + return cast_streaming_renderer_client_.OverrideDemuxerForUrl( + render_frame, url, std::move(media_task_runner)); +} + +} // namespace chromecast
diff --git a/chromecast/cast_core/cast_runtime_content_renderer_client.h b/chromecast/cast_core/cast_runtime_content_renderer_client.h new file mode 100644 index 0000000..1c16508 --- /dev/null +++ b/chromecast/cast_core/cast_runtime_content_renderer_client.h
@@ -0,0 +1,47 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMECAST_CAST_CORE_CAST_RUNTIME_CONTENT_RENDERER_CLIENT_H_ +#define CHROMECAST_CAST_CORE_CAST_RUNTIME_CONTENT_RENDERER_CLIENT_H_ + +#include <memory> + +#include "chromecast/renderer/cast_content_renderer_client.h" +#include "components/cast_streaming/renderer/public/cast_streaming_content_renderer_client.h" + +namespace media { +class Demuxer; +} + +namespace chromecast { + +class CastRuntimeContentRendererClient + : public shell::CastContentRendererClient { + public: + CastRuntimeContentRendererClient(); + CastRuntimeContentRendererClient(const CastRuntimeContentRendererClient&) = + delete; + CastRuntimeContentRendererClient(CastRuntimeContentRendererClient&&) = delete; + ~CastRuntimeContentRendererClient() override; + + CastRuntimeContentRendererClient& operator=( + const CastRuntimeContentRendererClient&) = delete; + CastRuntimeContentRendererClient& operator=( + CastRuntimeContentRendererClient&&) = delete; + + // content::ContentRendererClient overrides. + void RenderFrameCreated(content::RenderFrame* render_frame) override; + std::unique_ptr<::media::Demuxer> OverrideDemuxerForUrl( + content::RenderFrame* render_frame, + const GURL& url, + scoped_refptr<base::SingleThreadTaskRunner> media_task_runner) override; + + private: + cast_streaming::CastStreamingContentRendererClient + cast_streaming_renderer_client_; +}; + +} // namespace chromecast + +#endif // CHROMECAST_CAST_CORE_CAST_RUNTIME_CONTENT_RENDERER_CLIENT_H_
diff --git a/chromecast/renderer/BUILD.gn b/chromecast/renderer/BUILD.gn index 53141dfb..96b9a256 100644 --- a/chromecast/renderer/BUILD.gn +++ b/chromecast/renderer/BUILD.gn
@@ -26,6 +26,10 @@ group("renderer") { public_deps = [ ":renderer_base" ] + + if (chromecast_branding == "public" && !enable_cast_media_runtime) { + public_deps += [ ":simple_client" ] + } } cast_source_set("renderer_base") {
diff --git a/chromeos/components/diagnostics_ui/resources/battery_status_card.html b/chromeos/components/diagnostics_ui/resources/battery_status_card.html index 8a2f1f2..981368e 100644 --- a/chromeos/components/diagnostics_ui/resources/battery_status_card.html +++ b/chromeos/components/diagnostics_ui/resources/battery_status_card.html
@@ -46,6 +46,7 @@ additional-message="[[getRunTestsAdditionalMessage( batteryChargeStatus_.chargeNowMilliampHours, batteryHealth_.chargeFullNowMilliampHours)]]" - learn-more-link-section="battery"> + learn-more-link-section="battery" + is-active="[[isActive]]"> </routine-section> </diagnostics-card>
diff --git a/chromeos/components/diagnostics_ui/resources/battery_status_card.js b/chromeos/components/diagnostics_ui/resources/battery_status_card.js index ac46315..631333e 100644 --- a/chromeos/components/diagnostics_ui/resources/battery_status_card.js +++ b/chromeos/components/diagnostics_ui/resources/battery_status_card.js
@@ -102,6 +102,11 @@ type: String, computed: 'updateIconClassList_(batteryChargeStatus_.powerAdapterStatus)', }, + + /** @type {boolean} */ + isActive: { + type: Boolean, + }, }, /** @override */
diff --git a/chromeos/components/diagnostics_ui/resources/connectivity_card.html b/chromeos/components/diagnostics_ui/resources/connectivity_card.html index 09407be..94420755 100644 --- a/chromeos/components/diagnostics_ui/resources/connectivity_card.html +++ b/chromeos/components/diagnostics_ui/resources/connectivity_card.html
@@ -8,6 +8,7 @@ <routine-section slot="routines" routines="[[routines_]]" is-test-running="{{isTestRunning}}" run-tests-button-text="Run Network test" - routine-runtime="{{getEstimateRuntimeInMinutes_(routines_)}}"> + routine-runtime="{{getEstimateRuntimeInMinutes_(routines_)}}" + is-active="[[isActive]]"> </routine-section> </diagnostics-card>
diff --git a/chromeos/components/diagnostics_ui/resources/connectivity_card.js b/chromeos/components/diagnostics_ui/resources/connectivity_card.js index fda60db..5370f0b 100644 --- a/chromeos/components/diagnostics_ui/resources/connectivity_card.js +++ b/chromeos/components/diagnostics_ui/resources/connectivity_card.js
@@ -52,6 +52,11 @@ type: String, value: '', }, + + /** @type {boolean} */ + isActive: { + type: Boolean, + }, }, /** @protected */
diff --git a/chromeos/components/diagnostics_ui/resources/cpu_card.html b/chromeos/components/diagnostics_ui/resources/cpu_card.html index ba72256..016a9d7 100644 --- a/chromeos/components/diagnostics_ui/resources/cpu_card.html +++ b/chromeos/components/diagnostics_ui/resources/cpu_card.html
@@ -33,6 +33,7 @@ is-test-running="{{isTestRunning}}" run-tests-button-text="[[i18n('runCpuTestText')]]" should-show-caution-banner="true" - learn-more-link-section="cpu"> + learn-more-link-section="cpu" + is-active="[[isActive]]"> </routine-section> </diagnostics-card>
diff --git a/chromeos/components/diagnostics_ui/resources/cpu_card.js b/chromeos/components/diagnostics_ui/resources/cpu_card.js index 3c072a7b..165950e 100644 --- a/chromeos/components/diagnostics_ui/resources/cpu_card.js +++ b/chromeos/components/diagnostics_ui/resources/cpu_card.js
@@ -71,6 +71,11 @@ value: false, notify: true, }, + + /** @type {boolean} */ + isActive: { + type: Boolean, + }, }, /** @override */
diff --git a/chromeos/components/diagnostics_ui/resources/memory_card.html b/chromeos/components/diagnostics_ui/resources/memory_card.html index 29c67c8..d577101 100644 --- a/chromeos/components/diagnostics_ui/resources/memory_card.html +++ b/chromeos/components/diagnostics_ui/resources/memory_card.html
@@ -13,6 +13,7 @@ routine-runtime="{{getEstimateRuntimeInMinutes_(routines_, memoryUsage_)}}" is-test-running="{{isTestRunning}}" run-tests-button-text="[[i18n('runMemoryTestText')]]" - learn-more-link-section="memory"> + learn-more-link-section="memory" + is-active="[[isActive]]"> </routine-section> </diagnostics-card>
diff --git a/chromeos/components/diagnostics_ui/resources/memory_card.js b/chromeos/components/diagnostics_ui/resources/memory_card.js index 7ed887b..64d1f18 100644 --- a/chromeos/components/diagnostics_ui/resources/memory_card.js +++ b/chromeos/components/diagnostics_ui/resources/memory_card.js
@@ -63,7 +63,12 @@ type: Boolean, value: false, notify: true, - } + }, + + /** @type {boolean} */ + isActive: { + type: Boolean, + }, }, /** @override */
diff --git a/chromeos/components/diagnostics_ui/resources/network_list.html b/chromeos/components/diagnostics_ui/resources/network_list.html index 2cd8a3f..39ffa346 100644 --- a/chromeos/components/diagnostics_ui/resources/network_list.html +++ b/chromeos/components/diagnostics_ui/resources/network_list.html
@@ -4,7 +4,8 @@ <div id="networkListContainer" class="diagnostics-cards-container"> <div class="diagnostics-cards-container"> <connectivity-card class="card-width" active-guid="[[activeGuid_]]" - is-test-running="{{isTestRunning}}"> + is-test-running="{{isTestRunning}}" + is-active="[[isActive]]"> </connectivity-card> </div> <dom-repeat id="networkCardList" items="[[otherNetworkGuids_]]" as="guid">
diff --git a/chromeos/components/diagnostics_ui/resources/network_list.js b/chromeos/components/diagnostics_ui/resources/network_list.js index 81ef5e9..61bf01b 100644 --- a/chromeos/components/diagnostics_ui/resources/network_list.js +++ b/chromeos/components/diagnostics_ui/resources/network_list.js
@@ -46,6 +46,12 @@ type: String, value: '', }, + + /** @type {boolean} */ + isActive: { + type: Boolean, + value: true, + }, }, /** @override */ @@ -72,4 +78,14 @@ guid => guid !== networkGuidInfo.activeGuid); this.activeGuid_ = networkGuidInfo.activeGuid || ''; }, + + /** + * 'navigation-view-panel' is responsible for calling this function when + * the active page changes. + * @param {{isActive: boolean}} isActive + * @public + */ + onNavigationPageChanged({isActive}) { + this.isActive = isActive; + }, });
diff --git a/chromeos/components/diagnostics_ui/resources/routine_section.js b/chromeos/components/diagnostics_ui/resources/routine_section.js index a2b5a8a..3c03a0b 100644 --- a/chromeos/components/diagnostics_ui/resources/routine_section.js +++ b/chromeos/components/diagnostics_ui/resources/routine_section.js
@@ -160,13 +160,39 @@ type: Boolean, value: false, }, + + /** @type {boolean} */ + isActive: { + type: Boolean, + }, + + /** + * Used to reset run button text to its initial state + * when a navigation page change event occurs. + * @private {string} + */ + initialButtonText_: { + type: String, + value: '', + computed: 'getInitialButtonText_(runTestsButtonText)', + }, }, observers: [ 'routineStatusChanged_(executionStatus_, currentTestName_,' + 'additionalMessage)', + 'onActivePageChanged_(isActive)', ], + /** + * @param {string} buttonText + * @return {string} + * @private + */ + getInitialButtonText_(buttonText) { + return this.initialButtonText_ || buttonText; + }, + /** @private */ getResultListElem_() { return /** @type {!RoutineResultListElement} */ ( @@ -450,6 +476,26 @@ 'dismiss-caution-banner', {bubbles: true, composed: true})); }, + /** @private */ + resetRoutineState_() { + this.setBadgeAndStatusText_(BadgeType.QUEUED, '', ''); + this.runTestsButtonText = this.initialButtonText_; + this.hasTestFailure_ = false; + this.currentTestName_ = ''; + this.executionStatus_ = ExecutionProgress.kNotStarted; + this.$.collapse.hide(); + }, + + /** + * Stop any running tests and reset to initial routine state + * when the active navigation page changes. + * @private + */ + onActivePageChanged_() { + this.stopTests_(); + this.resetRoutineState_(); + }, + /** @override */ detached() { this.cleanUp_();
diff --git a/chromeos/components/diagnostics_ui/resources/system_page.html b/chromeos/components/diagnostics_ui/resources/system_page.html index b7f0bcd..48788f2 100644 --- a/chromeos/components/diagnostics_ui/resources/system_page.html +++ b/chromeos/components/diagnostics_ui/resources/system_page.html
@@ -77,18 +77,24 @@ <template is="dom-if" if="[[showBatteryStatusCard_]]" restamp> <div class="card-width"> <battery-status-card id="batteryStatusCard" - is-test-running="{{isTestRunning}}"> + is-test-running="{{isTestRunning}}" + is-active="[[isActive]]" + > </battery-status-card> </div> </template> <div class="card-width"> <cpu-card id="cpuCard" - is-test-running="{{isTestRunning}}"> + is-test-running="{{isTestRunning}}" + is-active="[[isActive]]" + > </cpu-card> </div> <div class="card-width"> <memory-card id="memoryCard" - is-test-running="{{isTestRunning}}"> + is-test-running="{{isTestRunning}}" + is-active="[[isActive]]" + > </memory-card> </div> </div>
diff --git a/chromeos/components/diagnostics_ui/resources/system_page.js b/chromeos/components/diagnostics_ui/resources/system_page.js index 5dbb894..c7be4a2 100644 --- a/chromeos/components/diagnostics_ui/resources/system_page.js +++ b/chromeos/components/diagnostics_ui/resources/system_page.js
@@ -93,6 +93,12 @@ type: Number, value: -1, }, + + /** @type {boolean} */ + isActive: { + type: Boolean, + value: true, + }, }, /** @override */ @@ -171,4 +177,14 @@ window.setTimeout(() => this.scrollingClass_ = '', 300); }); }, + + /** + * 'navigation-view-panel' is responsible for calling this function when + * the active page changes. + * @param {{isActive: boolean}} isActive + * @public + */ + onNavigationPageChanged({isActive}) { + this.isActive = isActive; + }, });
diff --git a/chromeos/network/cellular_esim_uninstall_handler.cc b/chromeos/network/cellular_esim_uninstall_handler.cc index 326f33c..9df59734 100644 --- a/chromeos/network/cellular_esim_uninstall_handler.cc +++ b/chromeos/network/cellular_esim_uninstall_handler.cc
@@ -262,32 +262,8 @@ void CellularESimUninstallHandler::AttemptDisableProfile() { DCHECK_EQ(state_, UninstallState::kDisablingProfile); - - const dbus::ObjectPath& esim_profile_path = - *uninstall_requests_.front()->esim_profile_path; - HermesProfileClient::Properties* esim_profile_properties = - HermesProfileClient::Get()->GetProperties(esim_profile_path); - - if (!esim_profile_properties) { - NET_LOG(ERROR) << "eSIM profile not exposed by Hermes. ICCID: " - << GetIccidForCurrentRequest(); - CompleteCurrentRequest(/*success=*/false); - return; - } - - if (esim_profile_properties->state().value() != - hermes::profile::State::kActive) { - NET_LOG(EVENT) << "eSIM profile with ICCID " << GetIccidForCurrentRequest() - << "is not active and does " - << "not need to be disabled. State: " - << esim_profile_properties->state().value(); - TransitionToUninstallState(UninstallState::kUninstallingProfile); - AttemptUninstallProfile(); - return; - } - HermesProfileClient::Get()->DisableCarrierProfile( - esim_profile_path, + *uninstall_requests_.front()->esim_profile_path, base::BindOnce(&CellularESimUninstallHandler::OnDisableProfile, weak_ptr_factory_.GetWeakPtr())); }
diff --git a/chromeos/network/network_connect.cc b/chromeos/network/network_connect.cc index df6e643d8..bc3fcb8 100644 --- a/chromeos/network/network_connect.cc +++ b/chromeos/network/network_connect.cc
@@ -393,8 +393,9 @@ void NetworkConnectImpl::SetTechnologyEnabled( const NetworkTypePattern& technology, bool enabled_state) { + const std::string technology_string = technology.ToDebugString(); std::string log_string = base::StringPrintf( - "technology %s, target state: %s", technology.ToDebugString().c_str(), + "technology %s, target state: %s", technology_string.c_str(), (enabled_state ? "ENABLED" : "DISABLED")); NET_LOG(USER) << "SetTechnologyEnabled: " << log_string; NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); @@ -405,6 +406,7 @@ } if (enabled) { // User requested to disable the technology. + NET_LOG(USER) << __func__ << " " << technology_string << ":" << false; handler->SetTechnologyEnabled(technology, false, network_handler::ErrorCallback()); return; @@ -434,6 +436,7 @@ return; } } + NET_LOG(USER) << __func__ << " " << technology_string << ":" << true; handler->SetTechnologyEnabled(technology, true, network_handler::ErrorCallback()); }
diff --git a/chromeos/services/BUILD.gn b/chromeos/services/BUILD.gn index 26fa2c0..e42d1a0 100644 --- a/chromeos/services/BUILD.gn +++ b/chromeos/services/BUILD.gn
@@ -23,6 +23,7 @@ "//chromeos/services/cellular_setup:unit_tests", "//chromeos/services/cros_healthd/public/cpp:unit_tests", "//chromeos/services/device_sync:unit_tests", + "//chromeos/services/federated/public/cpp:unit_tests", "//chromeos/services/ime:services_unittests", "//chromeos/services/ime:unit_tests", "//chromeos/services/machine_learning/public/cpp:unit_tests",
diff --git a/chromeos/services/cellular_setup/euicc.cc b/chromeos/services/cellular_setup/euicc.cc index 1e8afe6..d0eefef1 100644 --- a/chromeos/services/cellular_setup/euicc.cc +++ b/chromeos/services/cellular_setup/euicc.cc
@@ -62,14 +62,14 @@ Euicc::RequestPendingProfilesCallback callback) { return base::BindOnce( [](Euicc::RequestPendingProfilesCallback callback, - base::Time installation_start_time, + base::Time refresh_profile_start_time, mojom::ESimOperationResult result) -> void { std::move(callback).Run(result); if (result != mojom::ESimOperationResult::kSuccess) return; UMA_HISTOGRAM_MEDIUM_TIMES( "Network.Cellular.ESim.ProfileDiscovery.Latency", - base::Time::Now() - installation_start_time); + base::Time::Now() - refresh_profile_start_time); }, std::move(callback), base::Time::Now()); } @@ -140,9 +140,13 @@ } void Euicc::RequestPendingProfiles(RequestPendingProfilesCallback callback) { - NET_LOG(EVENT) << "Requesting Pending profiles"; - esim_manager_->cellular_inhibitor()->InhibitCellularScanning( - CellularInhibitor::InhibitReason::kRefreshingProfileList, + // Before requesting pending profiles, we also request installed profiles. + // This ensures that if an error occurs and Chrome's installed profile cache + // goes out of sync with Hermes, we re-sync at this point. See b/187459880 for + // details. + NET_LOG(EVENT) << "Requesting installed and pending profiles"; + esim_manager_->cellular_esim_profile_handler()->RefreshProfileList( + path_, base::BindOnce( &Euicc::PerformRequestPendingProfiles, weak_ptr_factory_.GetWeakPtr(), CreateTimedRequestPendingProfilesCallback(std::move(callback)))); @@ -346,11 +350,13 @@ RequestPendingProfilesCallback callback, std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock) { if (!inhibit_lock) { - NET_LOG(ERROR) << "Error inhibiting cellular device"; + NET_LOG(ERROR) << "Error requesting installed profiles. Path: " + << path_.value(); std::move(callback).Run(mojom::ESimOperationResult::kFailure); return; } + NET_LOG(EVENT) << "Requesting pending profiles"; HermesEuiccClient::Get()->RequestPendingProfiles( path_, /*root_smds=*/std::string(), base::BindOnce(&Euicc::OnRequestPendingProfilesResult,
diff --git a/chromeos/services/cellular_setup/euicc_unittest.cc b/chromeos/services/cellular_setup/euicc_unittest.cc index d574fd9..0a04274 100644 --- a/chromeos/services/cellular_setup/euicc_unittest.cc +++ b/chromeos/services/cellular_setup/euicc_unittest.cc
@@ -241,18 +241,20 @@ base::HistogramTester histogram_tester; - const uint64_t profile_discovery_latency = 3000; + constexpr base::TimeDelta kHermesInteractiveDelay = + base::TimeDelta::FromMilliseconds(3000); HermesEuiccClient::Get()->GetTestInterface()->SetInteractiveDelay( - base::TimeDelta::FromMilliseconds(profile_discovery_latency)); + kHermesInteractiveDelay); // Verify that successful request returns correct status code. EXPECT_EQ(mojom::ESimOperationResult::kSuccess, RequestPendingProfiles(euicc)); + // Before requesting pending profiles, we request installed profiles, so we + // expect that there will be 2 delays (one for installed, one for pending). histogram_tester.ExpectTimeBucketCount( "Network.Cellular.ESim.ProfileDiscovery.Latency", - base::TimeDelta::FromMilliseconds(profile_discovery_latency), 1); - + 2 * kHermesInteractiveDelay, 1); histogram_tester.ExpectTotalCount( "Network.Cellular.ESim.ProfileDiscovery.Latency", 1); }
diff --git a/chromeos/services/federated/DEPS b/chromeos/services/federated/DEPS new file mode 100644 index 0000000..2e2e8d99 --- /dev/null +++ b/chromeos/services/federated/DEPS
@@ -0,0 +1,5 @@ +include_rules = [ + "+chromeos/dbus", + "+mojo/core/embedder", + "+mojo/public", +]
diff --git a/chromeos/services/federated/OWNERS b/chromeos/services/federated/OWNERS new file mode 100644 index 0000000..e48073a8 --- /dev/null +++ b/chromeos/services/federated/OWNERS
@@ -0,0 +1,3 @@ +alanlxl@chromium.org +amoylan@chromium.org +martis@chromium.org
diff --git a/chromeos/services/federated/public/cpp/BUILD.gn b/chromeos/services/federated/public/cpp/BUILD.gn new file mode 100644 index 0000000..55d96ae --- /dev/null +++ b/chromeos/services/federated/public/cpp/BUILD.gn
@@ -0,0 +1,48 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos") + +source_set("cpp") { + sources = [ + "federated_example_util.cc", + "federated_example_util.h", + "service_connection.cc", + "service_connection.h", + ] + deps = [ + "//base", + "//chromeos/dbus/federated", + "//chromeos/services/federated/public/mojom", + ] +} + +source_set("test_support") { + testonly = true + sources = [ + "fake_service_connection.cc", + "fake_service_connection.h", + ] + deps = [ + ":cpp", + "//base", + "//chromeos/services/federated/public/mojom", + "//mojo/public/cpp/bindings", + ] +} + +source_set("unit_tests") { + testonly = true + sources = [ "service_connection_unittest.cc" ] + deps = [ + ":cpp", + ":test_support", + "//base/test:test_support", + "//chromeos/dbus/federated", + "//chromeos/services/federated/public/mojom", + "//mojo/core/embedder", + "//mojo/public/cpp/bindings", + "//testing/gtest", + ] +}
diff --git a/chromeos/services/federated/public/cpp/fake_service_connection.cc b/chromeos/services/federated/public/cpp/fake_service_connection.cc new file mode 100644 index 0000000..6027764 --- /dev/null +++ b/chromeos/services/federated/public/cpp/fake_service_connection.cc
@@ -0,0 +1,30 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/services/federated/public/cpp/fake_service_connection.h" + +namespace chromeos { +namespace federated { + +FakeServiceConnectionImpl::FakeServiceConnectionImpl() = default; +FakeServiceConnectionImpl::~FakeServiceConnectionImpl() = default; + +void FakeServiceConnectionImpl::BindReceiver( + mojo::PendingReceiver<mojom::FederatedService> receiver) { + Clone(std::move(receiver)); +} + +void FakeServiceConnectionImpl::Clone( + mojo::PendingReceiver<mojom::FederatedService> receiver) { + receivers_.Add(this, std::move(receiver)); +} + +void FakeServiceConnectionImpl::ReportExample(const std::string& client_name, + mojom::ExamplePtr example) { + LOG(INFO) << "In FakeServiceConnectionImpl::ReportExample, does nothing"; + return; +} + +} // namespace federated +} // namespace chromeos
diff --git a/chromeos/services/federated/public/cpp/fake_service_connection.h b/chromeos/services/federated/public/cpp/fake_service_connection.h new file mode 100644 index 0000000..3db4aa3 --- /dev/null +++ b/chromeos/services/federated/public/cpp/fake_service_connection.h
@@ -0,0 +1,48 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_SERVICES_FEDERATED_PUBLIC_CPP_FAKE_SERVICE_CONNECTION_H_ +#define CHROMEOS_SERVICES_FEDERATED_PUBLIC_CPP_FAKE_SERVICE_CONNECTION_H_ + +#include <string> + +#include "base/macros.h" +#include "chromeos/services/federated/public/cpp/service_connection.h" +#include "chromeos/services/federated/public/mojom/example.mojom.h" +#include "chromeos/services/federated/public/mojom/federated_service.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver_set.h" + +namespace chromeos { +namespace federated { + +// Fake implementation of chromeos::federated::ServiceConnection. +// Handles BindReceiver by binding the receiver to itself. +// For use with ServiceConnection::UseFakeServiceConnectionForTesting(). +class FakeServiceConnectionImpl : public ServiceConnection, + public mojom::FederatedService { + public: + FakeServiceConnectionImpl(); + FakeServiceConnectionImpl(const FakeServiceConnectionImpl&) = delete; + FakeServiceConnectionImpl& operator=(const FakeServiceConnectionImpl&) = + delete; + ~FakeServiceConnectionImpl() override; + + // ServiceConnection: + void BindReceiver( + mojo::PendingReceiver<mojom::FederatedService> receiver) override; + + // mojom::FederatedService: + void Clone(mojo::PendingReceiver<mojom::FederatedService> receiver) override; + void ReportExample(const std::string& client_name, + mojom::ExamplePtr example) override; + + private: + mojo::ReceiverSet<mojom::FederatedService> receivers_; +}; + +} // namespace federated +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_FEDERATED_PUBLIC_CPP_FAKE_SERVICE_CONNECTION_H_
diff --git a/chromeos/services/federated/public/cpp/federated_example_util.cc b/chromeos/services/federated/public/cpp/federated_example_util.cc new file mode 100644 index 0000000..a46318bf --- /dev/null +++ b/chromeos/services/federated/public/cpp/federated_example_util.cc
@@ -0,0 +1,32 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/services/federated/public/cpp/federated_example_util.h" + +namespace chromeos { +namespace federated { + +mojom::ValueListPtr CreateInt64List(const std::vector<int64_t>& values) { + mojom::ValueListPtr value_list = mojom::ValueList::New(); + value_list->set_int64_list(mojom::Int64List::New()); + value_list->get_int64_list()->value = values; + return value_list; +} + +mojom::ValueListPtr CreateFloatList(const std::vector<double>& values) { + mojom::ValueListPtr value_list = mojom::ValueList::New(); + value_list->set_float_list(mojom::FloatList::New()); + value_list->get_float_list()->value = values; + return value_list; +} + +mojom::ValueListPtr CreateStringList(const std::vector<std::string>& values) { + mojom::ValueListPtr value_list = mojom::ValueList::New(); + value_list->set_string_list(mojom::StringList::New()); + value_list->get_string_list()->value = values; + return value_list; +} + +} // namespace federated +} // namespace chromeos
diff --git a/chromeos/services/federated/public/cpp/federated_example_util.h b/chromeos/services/federated/public/cpp/federated_example_util.h new file mode 100644 index 0000000..cafb218 --- /dev/null +++ b/chromeos/services/federated/public/cpp/federated_example_util.h
@@ -0,0 +1,24 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_SERVICES_FEDERATED_PUBLIC_CPP_FEDERATED_EXAMPLE_UTIL_H_ +#define CHROMEOS_SERVICES_FEDERATED_PUBLIC_CPP_FEDERATED_EXAMPLE_UTIL_H_ + +#include <string> +#include <vector> + +#include "chromeos/services/federated/public/mojom/example.mojom.h" + +namespace chromeos { +namespace federated { + +// Helper functions for creating different ValueList. +mojom::ValueListPtr CreateInt64List(const std::vector<int64_t>& values); +mojom::ValueListPtr CreateFloatList(const std::vector<double>& values); +mojom::ValueListPtr CreateStringList(const std::vector<std::string>& values); + +} // namespace federated +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_FEDERATED_PUBLIC_CPP_FEDERATED_EXAMPLE_UTIL_H_
diff --git a/chromeos/services/federated/public/cpp/service_connection.cc b/chromeos/services/federated/public/cpp/service_connection.cc new file mode 100644 index 0000000..505f0112 --- /dev/null +++ b/chromeos/services/federated/public/cpp/service_connection.cc
@@ -0,0 +1,135 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/services/federated/public/cpp/service_connection.h" + +#include "base/bind.h" +#include "base/macros.h" +#include "base/no_destructor.h" +#include "base/sequence_checker.h" +#include "chromeos/dbus/federated/federated_client.h" +#include "chromeos/services/federated/public/mojom/federated_service.mojom.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "mojo/public/cpp/platform/platform_channel.h" +#include "mojo/public/cpp/system/invitation.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace chromeos { +namespace federated { + +namespace { + +ServiceConnection* g_fake_service_connection_for_testing = nullptr; + +// Real Impl of ServiceConnection +class ServiceConnectionImpl : public ServiceConnection { + public: + ServiceConnectionImpl(); + ServiceConnectionImpl(const ServiceConnectionImpl&) = delete; + ServiceConnectionImpl& operator=(const ServiceConnectionImpl&) = delete; + ~ServiceConnectionImpl() override = default; + + // ServiceConnection: + void BindReceiver( + mojo::PendingReceiver<mojom::FederatedService> receiver) override; + + private: + // Binds the top level interface |federated_service_| to an + // implementation in the Federated Service daemon, if it is not already bound. + // The binding is accomplished via D-Bus bootstrap. + void BindFederatedServiceIfNeeded(); + + // Mojo disconnect handler. Resets |federated_service_|, which + // will be reconnected upon next use. + void OnMojoDisconnect(); + + // Response callback for FederatedClient::BootstrapMojoConnection. + void OnBootstrapMojoConnectionResponse(bool success); + + mojo::Remote<mojom::FederatedService> federated_service_; + + SEQUENCE_CHECKER(sequence_checker_); +}; + +ServiceConnectionImpl::ServiceConnectionImpl() { + DETACH_FROM_SEQUENCE(sequence_checker_); +} + +void ServiceConnectionImpl::BindReceiver( + mojo::PendingReceiver<mojom::FederatedService> receiver) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + BindFederatedServiceIfNeeded(); + federated_service_->Clone(std::move(receiver)); +} + +void ServiceConnectionImpl::BindFederatedServiceIfNeeded() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (federated_service_) { + return; + } + + mojo::PlatformChannel platform_channel; + + // Prepare a Mojo invitation to send through |platform_channel|. + mojo::OutgoingInvitation invitation; + // Include an initial Mojo pipe in the invitation. + mojo::ScopedMessagePipeHandle pipe = invitation.AttachMessagePipe( + ::federated::kBootstrapMojoConnectionChannelToken); + mojo::OutgoingInvitation::Send(std::move(invitation), + base::kNullProcessHandle, + platform_channel.TakeLocalEndpoint()); + + // Bind our end of |pipe| to our mojo::Remote<FederatedService>. The daemon + // should bind its end to a FederatedService implementation. + federated_service_.Bind(mojo::PendingRemote<mojom::FederatedService>( + std::move(pipe), 0u /* version */)); + federated_service_.set_disconnect_handler(base::BindOnce( + &ServiceConnectionImpl::OnMojoDisconnect, base::Unretained(this))); + + // Send the file descriptor for the other end of |platform_channel| to the + // Federated service daemon over D-Bus. + FederatedClient::Get()->BootstrapMojoConnection( + platform_channel.TakeRemoteEndpoint().TakePlatformHandle().TakeFD(), + base::BindOnce(&ServiceConnectionImpl::OnBootstrapMojoConnectionResponse, + base::Unretained(this))); +} + +void ServiceConnectionImpl::OnMojoDisconnect() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Connection errors are not expected so log a warning. + LOG(WARNING) << "Federated Service Mojo connection closed"; + federated_service_.reset(); +} + +void ServiceConnectionImpl::OnBootstrapMojoConnectionResponse( + const bool success) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!success) { + LOG(WARNING) << "BootstrapMojoConnection D-Bus call failed"; + federated_service_.reset(); + } +} + +} // namespace + +ServiceConnection* ServiceConnection::GetInstance() { + if (g_fake_service_connection_for_testing) { + return g_fake_service_connection_for_testing; + } + static base::NoDestructor<ServiceConnectionImpl> service_connection; + return service_connection.get(); +} + +ScopedFakeServiceConnectionForTest::ScopedFakeServiceConnectionForTest( + ServiceConnection* fake_service_connection) { + DCHECK(!g_fake_service_connection_for_testing); + g_fake_service_connection_for_testing = fake_service_connection; +} + +ScopedFakeServiceConnectionForTest::~ScopedFakeServiceConnectionForTest() { + g_fake_service_connection_for_testing = nullptr; +} + +} // namespace federated +} // namespace chromeos
diff --git a/chromeos/services/federated/public/cpp/service_connection.h b/chromeos/services/federated/public/cpp/service_connection.h new file mode 100644 index 0000000..4f3c1b0b --- /dev/null +++ b/chromeos/services/federated/public/cpp/service_connection.h
@@ -0,0 +1,59 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_SERVICES_FEDERATED_PUBLIC_CPP_SERVICE_CONNECTION_H_ +#define CHROMEOS_SERVICES_FEDERATED_PUBLIC_CPP_SERVICE_CONNECTION_H_ + +#include "chromeos/services/federated/public/mojom/federated_service.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" + +namespace chromeos { +namespace federated { + +// Encapsulates a connection to the Chrome OS Federated Service daemon via its +// Mojo interface. Usage: +// mojo::Remote<FederatedService> federated_service; +// chromeos::federated::ServiceConnection::GetInstance()->BindReceiver( +// federated_service.BindNewPipeAndPassReceiver()); +// if (federated_service) { +// chromeos::federated::mojom::ExamplePtr example = ...; +// const std::string client_name = ...; +// federated_service->ReportExample(client_name, std::move(example)); +// } else { +// // error handler +// } +// +// Sequencing: Must be used on a single sequence (may be created on another). +class ServiceConnection { + public: + static ServiceConnection* GetInstance(); + + // Binds the receiver to the implementation in the Federated Service daemon. + virtual void BindReceiver( + mojo::PendingReceiver<mojom::FederatedService> receiver) = 0; + + protected: + ServiceConnection() = default; + virtual ~ServiceConnection() = default; +}; + +// Helper class that sets a global fake service_connection pointer and +// automatically clean up when it goes out of the scope. +// Used in unit_test only to inject fake to ServiceConnection::GetInstance(). +class ScopedFakeServiceConnectionForTest { + public: + explicit ScopedFakeServiceConnectionForTest( + ServiceConnection* fake_service_connection); + ScopedFakeServiceConnectionForTest( + const ScopedFakeServiceConnectionForTest&) = delete; + ScopedFakeServiceConnectionForTest& operator=( + const ScopedFakeServiceConnectionForTest&) = delete; + + ~ScopedFakeServiceConnectionForTest(); +}; + +} // namespace federated +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_FEDERATED_PUBLIC_CPP_SERVICE_CONNECTION_H_
diff --git a/chromeos/services/federated/public/cpp/service_connection_unittest.cc b/chromeos/services/federated/public/cpp/service_connection_unittest.cc new file mode 100644 index 0000000..432466e --- /dev/null +++ b/chromeos/services/federated/public/cpp/service_connection_unittest.cc
@@ -0,0 +1,86 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/services/federated/public/cpp/service_connection.h" + +#include <vector> + +#include "base/macros.h" +#include "base/run_loop.h" +#include "base/test/task_environment.h" +#include "base/threading/thread.h" +#include "chromeos/dbus/federated/federated_client.h" +#include "chromeos/services/federated/public/cpp/fake_service_connection.h" +#include "chromeos/services/federated/public/cpp/federated_example_util.h" +#include "chromeos/services/federated/public/mojom/example.mojom.h" +#include "mojo/core/embedder/scoped_ipc_support.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { +namespace federated { +namespace { + +using chromeos::federated::mojom::Example; +using chromeos::federated::mojom::ExamplePtr; +using chromeos::federated::mojom::Features; + +// Create an ExamplePtr for testing. It must contain real value to avoid +// VALIDATION_ERROR_UNEXPECTED_NULL_POINTER failure in dry run. +ExamplePtr CreateExample() { + ExamplePtr example = Example::New(); + example->features = Features::New(); + auto& feature_map = example->features->feature; + feature_map["int_feature1"] = CreateInt64List({1, 2, 3, 4, 5}); + feature_map["int_feature2"] = CreateInt64List({10, 20, 30, 40, 50}); + + return example; +} + +class FederatedServiceConnectionTest : public testing::Test { + public: + FederatedServiceConnectionTest() = default; + FederatedServiceConnectionTest(const FederatedServiceConnectionTest&) = + delete; + FederatedServiceConnectionTest& operator=( + const FederatedServiceConnectionTest&) = delete; + + // testing::Test: + void SetUp() override { FederatedClient::InitializeFake(); } + + void TearDown() override { FederatedClient::Shutdown(); } + + private: + base::test::TaskEnvironment task_environment_; + mojo::core::ScopedIPCSupport ipc_support_{ + task_environment_.GetMainThreadTaskRunner(), + mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN}; +}; + +// Tests that BindReceiver runs OK (no crash) in a basic Mojo environment. +TEST_F(FederatedServiceConnectionTest, ReportExample) { + mojo::Remote<mojom::FederatedService> federated_service; + chromeos::federated::ServiceConnection::GetInstance()->BindReceiver( + federated_service.BindNewPipeAndPassReceiver()); +} + +// Tests that FakeServiceConnection can handle BindReceiver and the bound +// receiver can call ReportExample successfully. +TEST_F(FederatedServiceConnectionTest, FakeServiceConnection) { + FakeServiceConnectionImpl fake_service_connection; + ScopedFakeServiceConnectionForTest scoped_fake_for_test( + &fake_service_connection); + + mojo::Remote<mojom::FederatedService> federated_service; + chromeos::federated::ServiceConnection::GetInstance()->BindReceiver( + federated_service.BindNewPipeAndPassReceiver()); + EXPECT_TRUE(federated_service.is_bound()); + EXPECT_TRUE(federated_service.is_connected()); + + federated_service->ReportExample("test_client", CreateExample()); + base::RunLoop().RunUntilIdle(); +} + +} // namespace +} // namespace federated +} // namespace chromeos
diff --git a/chromeos/services/machine_learning/public/mojom/soda.mojom b/chromeos/services/machine_learning/public/mojom/soda.mojom index c134078..f501923 100644 --- a/chromeos/services/machine_learning/public/mojom/soda.mojom +++ b/chromeos/services/machine_learning/public/mojom/soda.mojom
@@ -13,11 +13,22 @@ // clients (Chromium, other downstream repos) later. // Use //chromeos/services/machine_learning/public/mojom/roll_mojom.sh to help // replicate Chrome OS-side changes over to Chromium. - +// Versions list: +// Version 0: Initial +// Version 1: Include HypothesisPart Info in Final result. +// Version 2: Include enable formatting in request config. module chromeos.machine_learning.mojom; import "mojo/public/mojom/base/time.mojom"; +// Augments a bool to include an 'unknown' value. +[Stable, Extensible] +enum OptionalBool { + [Default] kUnknown = 0, + kFalse, + kTrue, +}; + // The configuration used to load Soda recognizer. [Stable] struct SodaConfig { @@ -31,6 +42,9 @@ string library_dlc_path; // Path to already-installed SODA language pack to use. string language_dlc_path; + // Whether to enable automated punctuation. Defaults to true as this + // is the default in the underlying protocol buffer. + [MinVersion=2] OptionalBool enable_formatting = kTrue; }; // From the endpointer, What kind of endpointer event to record.
diff --git a/chromeos/services/network_config/cros_network_config.cc b/chromeos/services/network_config/cros_network_config.cc index c9bc907..9ae3bb3 100644 --- a/chromeos/services/network_config/cros_network_config.cc +++ b/chromeos/services/network_config/cros_network_config.cc
@@ -22,6 +22,7 @@ #include "chromeos/network/managed_network_configuration_handler.h" #include "chromeos/network/network_connection_handler.h" #include "chromeos/network/network_device_handler.h" +#include "chromeos/network/network_event_log.h" #include "chromeos/network/network_handler.h" #include "chromeos/network/network_metadata_store.h" #include "chromeos/network/network_name_util.h" @@ -432,36 +433,14 @@ return sim_info_mojos; } -bool IsCellularConnecting(NetworkStateHandler* network_state_handler) { - NetworkStateHandler::NetworkStateList cellular_networks; - network_state_handler->GetVisibleNetworkListByType( - NetworkTypePattern::Cellular(), &cellular_networks); - auto iter = std::find_if(cellular_networks.begin(), cellular_networks.end(), - [](const NetworkState* network_state) { - return network_state->IsConnectingState(); - }); - return iter != cellular_networks.end(); -} - -mojom::InhibitReason GetInhibitReason( - NetworkStateHandler* network_state_handler, - CellularInhibitor* cellular_inhibitor) { +mojom::InhibitReason GetInhibitReason(CellularInhibitor* cellular_inhibitor) { if (!cellular_inhibitor) return mojom::InhibitReason::kNotInhibited; absl::optional<CellularInhibitor::InhibitReason> inhibit_reason = cellular_inhibitor->GetInhibitReason(); - if (!inhibit_reason) { - // For devices with EUICC, the UI should be inhibited when a cellular - // network connection is in progress to prevent additional requests. This is - // due to complexity in switching slots. - if (!chromeos::HermesManagerClient::Get()->GetAvailableEuiccs().empty() && - IsCellularConnecting(network_state_handler)) { - return mojom::InhibitReason::kConnectingToProfile; - } - + if (!inhibit_reason) return mojom::InhibitReason::kNotInhibited; - } switch (*inhibit_reason) { case CellularInhibitor::InhibitReason::kInstallingProfile: @@ -479,7 +458,6 @@ mojom::DeviceStatePropertiesPtr DeviceStateToMojo( const DeviceState* device, - NetworkStateHandler* network_state_handler, CellularInhibitor* cellular_inhibitor, mojom::DeviceStateType technology_state) { mojom::NetworkType type = ShillTypeToMojo(device->type()); @@ -525,8 +503,7 @@ } if (type == mojom::NetworkType::kCellular) { result->sim_infos = CellularSIMInfosToMojo(device); - result->inhibit_reason = - GetInhibitReason(network_state_handler, cellular_inhibitor); + result->inhibit_reason = GetInhibitReason(cellular_inhibitor); } return result; } @@ -1981,8 +1958,8 @@ NET_LOG(ERROR) << "Device state unavailable: " << device->name(); continue; } - mojom::DeviceStatePropertiesPtr mojo_device = DeviceStateToMojo( - device, network_state_handler_, cellular_inhibitor_, technology_state); + mojom::DeviceStatePropertiesPtr mojo_device = + DeviceStateToMojo(device, cellular_inhibitor_, technology_state); if (mojo_device) result.emplace_back(std::move(mojo_device)); } @@ -2369,6 +2346,9 @@ std::move(callback).Run(false); return; } + + NET_LOG(USER) << __func__ << " " << type << ":" << enabled; + // Set the technology enabled state and return true. The call to Shill does // not have a 'success' callback (and errors are already logged). network_state_handler_->SetTechnologyEnabled(
diff --git a/chromeos/services/network_config/cros_network_config_unittest.cc b/chromeos/services/network_config/cros_network_config_unittest.cc index 6b3046d..acc1de0b 100644 --- a/chromeos/services/network_config/cros_network_config_unittest.cc +++ b/chromeos/services/network_config/cros_network_config_unittest.cc
@@ -1344,39 +1344,6 @@ EXPECT_EQ(mojom::InhibitReason::kInstallingProfile, cellular->inhibit_reason); } -TEST_F(CrosNetworkConfigTest, CellularInhibitState_Connecting) { - const char kTestEuiccPath[] = "euicc_path"; - mojom::DeviceStatePropertiesPtr cellular = - GetDeviceStateFromList(mojom::NetworkType::kCellular); - ASSERT_TRUE(cellular); - EXPECT_EQ(mojom::DeviceStateType::kEnabled, cellular->device_state); - EXPECT_EQ(mojom::InhibitReason::kNotInhibited, cellular->inhibit_reason); - - // Set connect requested on cellular network. - NetworkStateHandler* network_state_handler = - NetworkHandler::Get()->network_state_handler(); - const NetworkState* network_state = - network_state_handler->GetNetworkStateFromGuid("cellular_guid"); - network_state_handler->SetNetworkConnectRequested(network_state->path(), - true); - - // Verify the inhibit state is not set when connecting if there are no EUICC. - cellular = GetDeviceStateFromList(mojom::NetworkType::kCellular); - ASSERT_TRUE(cellular); - EXPECT_EQ(mojom::DeviceStateType::kEnabled, cellular->device_state); - EXPECT_EQ(mojom::InhibitReason::kNotInhibited, cellular->inhibit_reason); - - // Verify the adding EUICC sets the inhibit reason correctly. - helper()->hermes_manager_test()->AddEuicc(dbus::ObjectPath(kTestEuiccPath), - "eid", /*is_active=*/true, - /*physical_slot=*/0); - cellular = GetDeviceStateFromList(mojom::NetworkType::kCellular); - ASSERT_TRUE(cellular); - EXPECT_EQ(mojom::DeviceStateType::kEnabled, cellular->device_state); - EXPECT_EQ(mojom::InhibitReason::kConnectingToProfile, - cellular->inhibit_reason); -} - TEST_F(CrosNetworkConfigTest, SetCellularSimState) { // Assert initial state. mojom::DeviceStatePropertiesPtr cellular =
diff --git a/components/arc/net/arc_net_host_impl.cc b/components/arc/net/arc_net_host_impl.cc index d71698f..d91861b 100644 --- a/components/arc/net/arc_net_host_impl.cc +++ b/components/arc/net/arc_net_host_impl.cc
@@ -18,6 +18,7 @@ #include "chromeos/network/managed_network_configuration_handler.h" #include "chromeos/network/network_configuration_handler.h" #include "chromeos/network/network_connection_handler.h" +#include "chromeos/network/network_event_log.h" #include "chromeos/network/network_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" @@ -646,6 +647,7 @@ return; } + NET_LOG(USER) << __func__ << ":" << is_enabled; GetStateHandler()->SetTechnologyEnabled( chromeos::NetworkTypePattern::WiFi(), is_enabled, chromeos::network_handler::ErrorCallback());
diff --git a/components/autofill_payments_strings.grdp b/components/autofill_payments_strings.grdp index 8c72cf4..1684adc 100644 --- a/components/autofill_payments_strings.grdp +++ b/components/autofill_payments_strings.grdp
@@ -93,6 +93,9 @@ <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_CONFIRM" desc="Text to show for the Autofill upload save credit card prompt accept button when more information (e.g., CVC) was needed in order to save the card and was entered." formatter_data="android_java"> Confirm </message> + <message name="IDS_AUTOFILL_MOBILE_SAVE_CARD_TO_CLOUD_CONFIRMATION_DIALOG_TITLE" desc="This message appears as the title of a confirmation dialog in which the user can view/edit the information that will be saved to Google Payments, and only appears after the user has expressed interest in uploading the card."> + Save to Google Account + </message> </if> <if expr="is_ios"> <then>
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_MOBILE_SAVE_CARD_TO_CLOUD_CONFIRMATION_DIALOG_TITLE.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_MOBILE_SAVE_CARD_TO_CLOUD_CONFIRMATION_DIALOG_TITLE.png.sha1 new file mode 100644 index 0000000..76813da --- /dev/null +++ b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_MOBILE_SAVE_CARD_TO_CLOUD_CONFIRMATION_DIALOG_TITLE.png.sha1
@@ -0,0 +1 @@ +37c8c340a5db76c7b4183c3bf42f84a3b948074a \ No newline at end of file
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/displaystyle/ViewResizer.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/displaystyle/ViewResizer.java index 67c5ab9b..7fa6d82 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/displaystyle/ViewResizer.java +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/displaystyle/ViewResizer.java
@@ -21,9 +21,9 @@ private int mDefaultPaddingPixels; /** The minimum wide display value used for the lateral padding. */ private int mMinWidePaddingPixels; - private final View mView; + protected final View mView; private final DisplayStyleObserverAdapter mDisplayStyleObserver; - private final UiConfig mUiConfig; + protected final UiConfig mUiConfig; @HorizontalDisplayStyle private int mCurrentDisplayStyle;
diff --git a/components/chromeos_camera/fake_mjpeg_decode_accelerator.cc b/components/chromeos_camera/fake_mjpeg_decode_accelerator.cc index 9445e15..19b47a37 100644 --- a/components/chromeos_camera/fake_mjpeg_decode_accelerator.cc +++ b/components/chromeos_camera/fake_mjpeg_decode_accelerator.cc
@@ -10,6 +10,7 @@ #include "base/logging.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" +#include "media/base/bind_to_current_loop.h" #include "media/base/unaligned_shared_memory.h" #include "media/base/video_frame.h" #include "media/base/video_types.h" @@ -26,18 +27,32 @@ DCHECK(client_task_runner_->BelongsToCurrentThread()); } -bool FakeMjpegDecodeAccelerator::Initialize( - MjpegDecodeAccelerator::Client* client) { +void FakeMjpegDecodeAccelerator::InitializeOnTaskRunner( + MjpegDecodeAccelerator::Client* client, + InitCB init_cb) { DCHECK(client_task_runner_->BelongsToCurrentThread()); client_ = client; if (!decoder_thread_.Start()) { DLOG(ERROR) << "Failed to start decoding thread."; - return false; + std::move(init_cb).Run(false); + return; } - decoder_task_runner_ = decoder_thread_.task_runner(); - return true; + decoder_task_runner_ = decoder_thread_.task_runner(); + std::move(init_cb).Run(true); +} + +void FakeMjpegDecodeAccelerator::InitializeAsync( + MjpegDecodeAccelerator::Client* client, + InitCB init_cb) { + DCHECK(client_task_runner_->BelongsToCurrentThread()); + + client_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&FakeMjpegDecodeAccelerator::InitializeOnTaskRunner, + weak_factory_.GetWeakPtr(), client, + media::BindToCurrentLoop(std::move(init_cb)))); } void FakeMjpegDecodeAccelerator::Decode(
diff --git a/components/chromeos_camera/fake_mjpeg_decode_accelerator.h b/components/chromeos_camera/fake_mjpeg_decode_accelerator.h index ea51eb55..c1a71c7 100644 --- a/components/chromeos_camera/fake_mjpeg_decode_accelerator.h +++ b/components/chromeos_camera/fake_mjpeg_decode_accelerator.h
@@ -31,7 +31,8 @@ ~FakeMjpegDecodeAccelerator() override; // MjpegDecodeAccelerator implementation. - bool Initialize(MjpegDecodeAccelerator::Client* client) override; + void InitializeAsync(chromeos_camera::MjpegDecodeAccelerator::Client* client, + InitCB init_cb) override; void Decode(media::BitstreamBuffer bitstream_buffer, scoped_refptr<media::VideoFrame> video_frame) override; void Decode(int32_t task_id, @@ -50,6 +51,10 @@ void NotifyErrorOnClientThread(int32_t task_id, Error error); void OnDecodeDoneOnClientThread(int32_t task_id); + void InitializeOnTaskRunner( + chromeos_camera::MjpegDecodeAccelerator::Client* client, + InitCB init_cb); + // Task runner for calls to |client_|. const scoped_refptr<base::SingleThreadTaskRunner> client_task_runner_;
diff --git a/components/chromeos_camera/mjpeg_decode_accelerator.h b/components/chromeos_camera/mjpeg_decode_accelerator.h index 58890e8..aee32513 100644 --- a/components/chromeos_camera/mjpeg_decode_accelerator.h +++ b/components/chromeos_camera/mjpeg_decode_accelerator.h
@@ -91,16 +91,14 @@ virtual ~MjpegDecodeAccelerator() = 0; // Initializes the MJPEG decoder. Should be called once per decoder - // construction. This call is synchronous and returns true iff initialization - // is successful. - // Parameters: + // construction. This call is asynchronous and executes |init_cb| upon + // completion. Parameters: // |client| is the Client interface for decode callback. The provided // pointer must be valid until destructor is called. - virtual bool Initialize(Client* client) = 0; - - // TODO(c.padhi): Remove the sync version and rename this to Initialize. - // Async version of above Initialize(..) function. Executes the |init_cb| - // upon completion. + // |init_cb| is the MJPEG decoder initialization status report callback. + // + // |init_cb| is called on the same thread as InitializeAsync() and can + // potentially be called even after the MjpegDecodeAccelerator destructor. virtual void InitializeAsync(Client* client, InitCB init_cb) {} // Decodes the given bitstream buffer that contains one JPEG frame. It
diff --git a/components/chromeos_camera/mjpeg_decode_accelerator_unittest.cc b/components/chromeos_camera/mjpeg_decode_accelerator_unittest.cc index b550641..2a7f60d 100644 --- a/components/chromeos_camera/mjpeg_decode_accelerator_unittest.cc +++ b/components/chromeos_camera/mjpeg_decode_accelerator_unittest.cc
@@ -533,6 +533,7 @@ FRIEND_TEST_ALL_PREFIXES(JpegClientTest, GetMeanAbsoluteDifference); void SetState(ClientState new_state); + void OnInitialize(bool initialize_result); // Save a video frame that contains a decoded JPEG. The output is a PNG file. // The suffix will be added before the .png extension. @@ -582,6 +583,8 @@ std::vector<base::TimeDelta> decode_times_; std::vector<base::TimeDelta> decode_map_times_; + base::WeakPtrFactory<JpegClient> weak_factory_{this}; + DISALLOW_COPY_AND_ASSIGN(JpegClient); }; @@ -621,12 +624,18 @@ return; } - if (!decoder_->Initialize(this)) { - LOG(ERROR) << "MjpegDecodeAccelerator::Initialize() failed"; - SetState(CS_ERROR); + decoder_->InitializeAsync(this, base::BindOnce(&JpegClient::OnInitialize, + weak_factory_.GetWeakPtr())); +} + +void JpegClient::OnInitialize(bool initialize_result) { + if (initialize_result) { + SetState(CS_INITIALIZED); return; } - SetState(CS_INITIALIZED); + + LOG(ERROR) << "MjpegDecodeAccelerator::InitializeAsync() failed"; + SetState(CS_ERROR); } void JpegClient::VideoFrameReady(int32_t task_id) {
diff --git a/components/chromeos_camera/mojo_mjpeg_decode_accelerator.cc b/components/chromeos_camera/mojo_mjpeg_decode_accelerator.cc index bb62c48..d2c959d 100644 --- a/components/chromeos_camera/mojo_mjpeg_decode_accelerator.cc +++ b/components/chromeos_camera/mojo_mjpeg_decode_accelerator.cc
@@ -26,12 +26,6 @@ DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); } -bool MojoMjpegDecodeAccelerator::Initialize( - MjpegDecodeAccelerator::Client* /*client*/) { - NOTIMPLEMENTED(); - return false; -} - void MojoMjpegDecodeAccelerator::InitializeAsync(Client* client, InitCB init_cb) { DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
diff --git a/components/chromeos_camera/mojo_mjpeg_decode_accelerator.h b/components/chromeos_camera/mojo_mjpeg_decode_accelerator.h index 0dfb85ee..d2e16ca8 100644 --- a/components/chromeos_camera/mojo_mjpeg_decode_accelerator.h +++ b/components/chromeos_camera/mojo_mjpeg_decode_accelerator.h
@@ -33,7 +33,6 @@ // MjpegDecodeAccelerator implementation. // |client| is called on the IO thread, but is never called into after the // MojoMjpegDecodeAccelerator is destroyed. - bool Initialize(Client* client) override; void InitializeAsync(Client* client, InitCB init_cb) override; void Decode(media::BitstreamBuffer bitstream_buffer, scoped_refptr<media::VideoFrame> video_frame) override;
diff --git a/components/chromeos_camera/mojo_mjpeg_decode_accelerator_service.cc b/components/chromeos_camera/mojo_mjpeg_decode_accelerator_service.cc index 9366ab0..592683b 100644 --- a/components/chromeos_camera/mojo_mjpeg_decode_accelerator_service.cc +++ b/components/chromeos_camera/mojo_mjpeg_decode_accelerator_service.cc
@@ -71,11 +71,11 @@ } MojoMjpegDecodeAcceleratorService::MojoMjpegDecodeAcceleratorService() - : accelerator_factory_functions_( - GpuMjpegDecodeAcceleratorFactory::GetAcceleratorFactories()) {} + : accelerator_initialized_(false), weak_this_factory_(this) {} MojoMjpegDecodeAcceleratorService::~MojoMjpegDecodeAcceleratorService() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + accelerator_.reset(); } void MojoMjpegDecodeAcceleratorService::VideoFrameReady( @@ -93,6 +93,32 @@ NotifyDecodeStatus(bitstream_buffer_id, error); } +void MojoMjpegDecodeAcceleratorService::InitializeInternal( + std::vector<GpuMjpegDecodeAcceleratorFactory::CreateAcceleratorCB> + remaining_accelerator_factory_functions, + InitializeCallback init_cb) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + if (remaining_accelerator_factory_functions.empty()) { + DLOG(ERROR) << "All JPEG accelerators failed to initialize"; + std::move(init_cb).Run(false); + return; + } + accelerator_ = std::move(remaining_accelerator_factory_functions.front()) + .Run(base::ThreadTaskRunnerHandle::Get()); + remaining_accelerator_factory_functions.erase( + remaining_accelerator_factory_functions.begin()); + if (!accelerator_) { + OnInitialize(std::move(remaining_accelerator_factory_functions), + std::move(init_cb), /*last_initialize_result=*/false); + return; + } + accelerator_->InitializeAsync( + this, base::BindOnce(&MojoMjpegDecodeAcceleratorService::OnInitialize, + weak_this_factory_.GetWeakPtr(), + std::move(remaining_accelerator_factory_functions), + std::move(init_cb))); +} + void MojoMjpegDecodeAcceleratorService::Initialize( InitializeCallback callback) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -100,24 +126,33 @@ // When adding non-chromeos platforms, VideoCaptureGpuJpegDecoder::Initialize // needs to be updated. - std::unique_ptr<::chromeos_camera::MjpegDecodeAccelerator> accelerator; - for (auto& create_jda_function : accelerator_factory_functions_) { - std::unique_ptr<::chromeos_camera::MjpegDecodeAccelerator> tmp_accelerator = - std::move(create_jda_function).Run(base::ThreadTaskRunnerHandle::Get()); - if (tmp_accelerator && tmp_accelerator->Initialize(this)) { - accelerator = std::move(tmp_accelerator); - break; - } - } + InitializeInternal( + GpuMjpegDecodeAcceleratorFactory::GetAcceleratorFactories(), + std::move(callback)); +} - if (!accelerator) { - DLOG(ERROR) << "JPEG accelerator initialization failed"; - std::move(callback).Run(false); +void MojoMjpegDecodeAcceleratorService::OnInitialize( + std::vector<GpuMjpegDecodeAcceleratorFactory::CreateAcceleratorCB> + remaining_accelerator_factory_functions, + InitializeCallback init_cb, + bool last_initialize_result) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + if (last_initialize_result) { + accelerator_initialized_ = true; + std::move(init_cb).Run(true); return; } - - accelerator_ = std::move(accelerator); - std::move(callback).Run(true); + // Note that we can't call InitializeInternal() directly. The reason is that + // InitializeInternal() may destroy |accelerator_| which could cause a + // use-after-free if |accelerator_| needs to do more stuff after calling + // OnInitialize(). + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&MojoMjpegDecodeAcceleratorService::InitializeInternal, + weak_this_factory_.GetWeakPtr(), + std::move(remaining_accelerator_factory_functions), + std::move(init_cb))); } void MojoMjpegDecodeAcceleratorService::Decode( @@ -183,6 +218,12 @@ frame->BackWithOwnedSharedMemory(std::move(output_region), std::move(mapping)); + if (!accelerator_initialized_) { + NotifyDecodeStatus( + input_buffer.id(), + ::chromeos_camera::MjpegDecodeAccelerator::Error::PLATFORM_FAILURE); + return; + } DCHECK(accelerator_); accelerator_->Decode(std::move(input_buffer), frame); } @@ -226,6 +267,12 @@ DCHECK_EQ(mojo_cb_map_.count(task_id), 0u); mojo_cb_map_[task_id] = std::move(callback); + if (!accelerator_initialized_) { + NotifyDecodeStatus( + task_id, + ::chromeos_camera::MjpegDecodeAccelerator::Error::PLATFORM_FAILURE); + return; + } DCHECK(accelerator_); accelerator_->Decode(task_id, src_handle.TakeFD(), base::strict_cast<size_t>(src_size),
diff --git a/components/chromeos_camera/mojo_mjpeg_decode_accelerator_service.h b/components/chromeos_camera/mojo_mjpeg_decode_accelerator_service.h index add89c9..11f99699 100644 --- a/components/chromeos_camera/mojo_mjpeg_decode_accelerator_service.h +++ b/components/chromeos_camera/mojo_mjpeg_decode_accelerator_service.h
@@ -65,20 +65,32 @@ DecodeWithDmaBufCallback callback) override; void Uninitialize() override; + void OnInitialize( + std::vector<GpuMjpegDecodeAcceleratorFactory::CreateAcceleratorCB> + remaining_accelerator_factory_functions, + InitializeCallback init_cb, + bool last_initialize_result); + + void InitializeInternal( + std::vector<GpuMjpegDecodeAcceleratorFactory::CreateAcceleratorCB> + remaining_accelerator_factory_functions, + InitializeCallback init_cb); + void NotifyDecodeStatus( int32_t bitstream_buffer_id, ::chromeos_camera::MjpegDecodeAccelerator::Error error); - std::vector<GpuMjpegDecodeAcceleratorFactory::CreateAcceleratorCB> - accelerator_factory_functions_; - // A map from |task_id| to MojoCallback. MojoCallbackMap mojo_cb_map_; + bool accelerator_initialized_; + std::unique_ptr<::chromeos_camera::MjpegDecodeAccelerator> accelerator_; THREAD_CHECKER(thread_checker_); + base::WeakPtrFactory<MojoMjpegDecodeAcceleratorService> weak_this_factory_; + DISALLOW_COPY_AND_ASSIGN(MojoMjpegDecodeAcceleratorService); };
diff --git a/components/feed/core/v2/BUILD.gn b/components/feed/core/v2/BUILD.gn index 1d36927..960c770 100644 --- a/components/feed/core/v2/BUILD.gn +++ b/components/feed/core/v2/BUILD.gn
@@ -94,7 +94,7 @@ "wire_response_translator.h", ] deps = [ - ":common", + "public:common", "//components/feed:feature_list", "//components/feed/core/shared_prefs:feed_shared_prefs", "//components/history/core/browser", @@ -150,11 +150,6 @@ ] } -source_set("common") { - sources = [ "common_enums.h" ] - deps = [] -} - source_set("test_helpers") { testonly = true sources = [ @@ -201,10 +196,10 @@ public_deps = [ ":test_helpers" ] deps = [ - ":common", ":feed_core_base_unit_tests", ":feed_core_v2", ":unit_tests_bundle_data", + "public:common", "//base", "//base/test:test_support", "//build:chromeos_buildflags", @@ -270,8 +265,8 @@ if (is_android) { java_cpp_enum("feedv2_enums_java") { sources = [ - "common_enums.h", "enums.h", + "public/common_enums.h", "public/types.h", ] }
diff --git a/components/feed/core/v2/metrics_reporter.cc b/components/feed/core/v2/metrics_reporter.cc index 04da533f..1db3d822 100644 --- a/components/feed/core/v2/metrics_reporter.cc +++ b/components/feed/core/v2/metrics_reporter.cc
@@ -11,8 +11,8 @@ #include "base/metrics/user_metrics.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" -#include "components/feed/core/v2/common_enums.h" #include "components/feed/core/v2/prefs.h" +#include "components/feed/core/v2/public/common_enums.h" #include "components/feed/core/v2/public/feed_api.h" namespace feed {
diff --git a/components/feed/core/v2/metrics_reporter.h b/components/feed/core/v2/metrics_reporter.h index b14839c..3582b309 100644 --- a/components/feed/core/v2/metrics_reporter.h +++ b/components/feed/core/v2/metrics_reporter.h
@@ -10,8 +10,8 @@ #include "base/memory/weak_ptr.h" #include "base/time/time.h" -#include "components/feed/core/v2/common_enums.h" #include "components/feed/core/v2/enums.h" +#include "components/feed/core/v2/public/common_enums.h" #include "components/feed/core/v2/public/stream_type.h" #include "components/feed/core/v2/public/web_feed_subscriptions.h" #include "components/feed/core/v2/types.h"
diff --git a/components/feed/core/v2/metrics_reporter_unittest.cc b/components/feed/core/v2/metrics_reporter_unittest.cc index b3f2c4b3..bd25cd2 100644 --- a/components/feed/core/v2/metrics_reporter_unittest.cc +++ b/components/feed/core/v2/metrics_reporter_unittest.cc
@@ -12,7 +12,7 @@ #include "base/test/task_environment.h" #include "components/feed/core/common/pref_names.h" #include "components/feed/core/shared_prefs/pref_names.h" -#include "components/feed/core/v2/common_enums.h" +#include "components/feed/core/v2/public/common_enums.h" #include "components/feed/core/v2/public/feed_api.h" #include "components/prefs/testing_pref_service.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/feed/core/v2/public/BUILD.gn b/components/feed/core/v2/public/BUILD.gn new file mode 100644 index 0000000..e88d46a --- /dev/null +++ b/components/feed/core/v2/public/BUILD.gn
@@ -0,0 +1,5 @@ +# TODO(crbug.com/1213474): Move public targets here. + +source_set("common") { + sources = [ "common_enums.h" ] +}
diff --git a/components/feed/core/v2/common_enums.h b/components/feed/core/v2/public/common_enums.h similarity index 95% rename from components/feed/core/v2/common_enums.h rename to components/feed/core/v2/public/common_enums.h index 9fa23ff..6db9875 100644 --- a/components/feed/core/v2/common_enums.h +++ b/components/feed/core/v2/public/common_enums.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 COMPONENTS_FEED_CORE_V2_COMMON_ENUMS_H_ -#define COMPONENTS_FEED_CORE_V2_COMMON_ENUMS_H_ +#ifndef COMPONENTS_FEED_CORE_V2_PUBLIC_COMMON_ENUMS_H_ +#define COMPONENTS_FEED_CORE_V2_PUBLIC_COMMON_ENUMS_H_ // Unlike most code from feed/core, these enums are used by both iOS and // Android. @@ -96,4 +96,4 @@ } // namespace feed -#endif // COMPONENTS_FEED_CORE_V2_COMMON_ENUMS_H_ +#endif // COMPONENTS_FEED_CORE_V2_PUBLIC_COMMON_ENUMS_H_
diff --git a/components/feed/core/v2/public/feed_api.h b/components/feed/core/v2/public/feed_api.h index 981df1c..4f26768 100644 --- a/components/feed/core/v2/public/feed_api.h +++ b/components/feed/core/v2/public/feed_api.h
@@ -12,7 +12,7 @@ #include "base/observer_list_types.h" #include "base/strings/string_piece_forward.h" #include "base/time/time.h" -#include "components/feed/core/v2/common_enums.h" +#include "components/feed/core/v2/public/common_enums.h" #include "components/feed/core/v2/public/refresh_task_scheduler.h" #include "components/feed/core/v2/public/stream_type.h" #include "components/feed/core/v2/public/types.h"
diff --git a/components/feed/core/v2/public/ios/BUILD.gn b/components/feed/core/v2/public/ios/BUILD.gn new file mode 100644 index 0000000..f261eef --- /dev/null +++ b/components/feed/core/v2/public/ios/BUILD.gn
@@ -0,0 +1,19 @@ +source_set("feed_ios_public") { + sources = [ + "notice_card_tracker.h", + "pref_names.cc", + "pref_names.h", + "prefs.cc", + "prefs.h", + ] + public_deps = [ + "//components/feed/core/common:feed_core_common", + "//components/feed/core/shared_prefs:feed_shared_prefs", + ] + deps = [ + "//base", + "//components/feed:feature_list", + "//components/feed/core/v2:feed_core_base", + "//components/prefs", + ] +}
diff --git a/components/feed/core/v2/public/ios/README.md b/components/feed/core/v2/public/ios/README.md new file mode 100644 index 0000000..bf9101b6 --- /dev/null +++ b/components/feed/core/v2/public/ios/README.md
@@ -0,0 +1,2 @@ +APIs provided specifically for the Feed on iOS. Modifying these APIs may break +the internal iOS build.
diff --git a/components/feed/core/v2/public/ios/notice_card_tracker.h b/components/feed/core/v2/public/ios/notice_card_tracker.h new file mode 100644 index 0000000..f7c6122 --- /dev/null +++ b/components/feed/core/v2/public/ios/notice_card_tracker.h
@@ -0,0 +1,15 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_FEED_CORE_V2_PUBLIC_IOS_NOTICE_CARD_TRACKER_H_ +#define COMPONENTS_FEED_CORE_V2_PUBLIC_IOS_NOTICE_CARD_TRACKER_H_ + +#include "components/feed/core/v2/notice_card_tracker.h" + +namespace ios_feed { +// TODO(crbug.com/1213474): Fork this class. +using feed::NoticeCardTracker; +} // namespace ios_feed + +#endif // COMPONENTS_FEED_CORE_V2_PUBLIC_IOS_NOTICE_CARD_TRACKER_H_
diff --git a/components/feed/core/v2/public/ios/pref_names.cc b/components/feed/core/v2/public/ios/pref_names.cc new file mode 100644 index 0000000..2e86c72 --- /dev/null +++ b/components/feed/core/v2/public/ios/pref_names.cc
@@ -0,0 +1,17 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/feed/core/v2/public/ios/pref_names.h" + +#include "components/feed/core/common/pref_names.h" +#include "components/feed/core/shared_prefs/pref_names.h" + +namespace ios_feed { + +void RegisterProfilePrefs(PrefRegistrySimple* registry) { + feed::RegisterProfilePrefs(registry); + feed::prefs::RegisterFeedSharedProfilePrefs(registry); +} + +} // namespace ios_feed
diff --git a/components/feed/core/v2/public/ios/pref_names.h b/components/feed/core/v2/public/ios/pref_names.h new file mode 100644 index 0000000..1eecbad --- /dev/null +++ b/components/feed/core/v2/public/ios/pref_names.h
@@ -0,0 +1,18 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_FEED_CORE_V2_PUBLIC_IOS_PREF_NAMES_H_ +#define COMPONENTS_FEED_CORE_V2_PUBLIC_IOS_PREF_NAMES_H_ + +// TODO(crbug.com/1213474): Include only prefs needed for iOS. +#include "components/feed/core/common/pref_names.h" +#include "components/feed/core/shared_prefs/pref_names.h" + +class PrefRegistrySimple; + +namespace ios_feed { +void RegisterProfilePrefs(PrefRegistrySimple* registry); +} + +#endif // COMPONENTS_FEED_CORE_V2_PUBLIC_IOS_PREF_NAMES_H_
diff --git a/components/feed/core/v2/public/ios/prefs.cc b/components/feed/core/v2/public/ios/prefs.cc new file mode 100644 index 0000000..b4030535 --- /dev/null +++ b/components/feed/core/v2/public/ios/prefs.cc
@@ -0,0 +1,34 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/feed/core/v2/public/ios/prefs.h" + +#include "components/feed/core/v2/public/ios/pref_names.h" +#include "components/prefs/pref_service.h" + +namespace ios_feed { +namespace prefs { + +void SetLastFetchHadNoticeCard(PrefService& pref_service, bool value) { + pref_service.SetBoolean(feed::prefs::kLastFetchHadNoticeCard, value); +} + +bool GetLastFetchHadNoticeCard(const PrefService& pref_service) { + return pref_service.GetBoolean(feed::prefs::kLastFetchHadNoticeCard); +} + +void SetHasReachedClickAndViewActionsUploadConditions(PrefService& pref_service, + bool value) { + pref_service.SetBoolean( + feed::prefs::kHasReachedClickAndViewActionsUploadConditions, value); +} + +bool GetHasReachedClickAndViewActionsUploadConditions( + const PrefService& pref_service) { + return pref_service.GetBoolean( + feed::prefs::kHasReachedClickAndViewActionsUploadConditions); +} + +} // namespace prefs +} // namespace ios_feed
diff --git a/components/feed/core/v2/public/ios/prefs.h b/components/feed/core/v2/public/ios/prefs.h new file mode 100644 index 0000000..8f10abac --- /dev/null +++ b/components/feed/core/v2/public/ios/prefs.h
@@ -0,0 +1,23 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_FEED_CORE_V2_PUBLIC_IOS_PREFS_H_ +#define COMPONENTS_FEED_CORE_V2_PUBLIC_IOS_PREFS_H_ + +class PrefService; + +namespace ios_feed { +namespace prefs { + +void SetLastFetchHadNoticeCard(PrefService& pref_service, bool value); +bool GetLastFetchHadNoticeCard(const PrefService& pref_service); +void SetHasReachedClickAndViewActionsUploadConditions(PrefService& pref_service, + bool value); +bool GetHasReachedClickAndViewActionsUploadConditions( + const PrefService& pref_service); + +} // namespace prefs +} // namespace ios_feed + +#endif // COMPONENTS_FEED_CORE_V2_PUBLIC_IOS_PREFS_H_
diff --git a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/AutocompleteResult.java b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/AutocompleteResult.java index aa45fdd..e5cdd9f0 100644 --- a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/AutocompleteResult.java +++ b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/AutocompleteResult.java
@@ -78,7 +78,7 @@ // Note that the mNativeResult might change at any point during the lifecycle of this object // to reflect relocation or destruction of the native object, so we cache this information // separately. - mIsFromCachedResult = nativeResult != 0; + mIsFromCachedResult = nativeResult == 0; mNativeAutocompleteResult = nativeResult; mSuggestions = suggestions != null ? suggestions : new ArrayList<>(); mGroupsDetails = groupsDetails != null ? groupsDetails : new SparseArray<>();
diff --git a/components/omnibox/browser/clipboard_provider.cc b/components/omnibox/browser/clipboard_provider.cc index c889cd38..c38879ed 100644 --- a/components/omnibox/browser/clipboard_provider.cc +++ b/components/omnibox/browser/clipboard_provider.cc
@@ -680,8 +680,7 @@ search_args, url_service->search_terms_data())); match->destination_url = result; - match->contents.assign(l10n_util::GetStringFUTF16( - IDS_COPIED_TEXT_FROM_CLIPBOARD, AutocompleteMatch::SanitizeString(text))); + match->contents.assign(AutocompleteMatch::SanitizeString(text)); if (!match->contents.empty()) match->contents_class.push_back({0, ACMatchClassification::NONE});
diff --git a/components/omnibox/browser/clipboard_provider_unittest.cc b/components/omnibox/browser/clipboard_provider_unittest.cc index 58eb0b2..ab59596 100644 --- a/components/omnibox/browser/clipboard_provider_unittest.cc +++ b/components/omnibox/browser/clipboard_provider_unittest.cc
@@ -37,7 +37,6 @@ const char kCurrentURL[] = "http://example.com/current"; const char kClipboardURL[] = "http://example.com/clipboard"; const char16_t kClipboardText[] = u"Search for me"; -const char16_t kClipboardTitleText[] = u"\"Search for me\""; class CreateMatchWithContentCallbackWaiter { public: @@ -188,7 +187,7 @@ SetClipboardText(kClipboardText); provider_->Start(CreateAutocompleteInput(OmniboxFocusType::ON_FOCUS), false); ASSERT_GE(provider_->matches().size(), 1U); - EXPECT_EQ(kClipboardTitleText, provider_->matches().back().contents); + EXPECT_EQ(kClipboardText, provider_->matches().back().contents); EXPECT_EQ(kClipboardText, provider_->matches().back().fill_into_edit); EXPECT_EQ(AutocompleteMatchType::CLIPBOARD_TEXT, provider_->matches().back().type); @@ -305,7 +304,7 @@ CreateMatchWithContentCallbackWaiter waiter(provider_, &match); waiter.WaitForMatchUpdated(); - EXPECT_EQ(kClipboardTitleText, match.contents); + EXPECT_EQ(kClipboardText, match.contents); EXPECT_EQ(kClipboardText, match.fill_into_edit); EXPECT_EQ(AutocompleteMatchType::CLIPBOARD_TEXT, match.type); }
diff --git a/components/omnibox_strings.grdp b/components/omnibox_strings.grdp index 8cfc5dc..ef78aca 100644 --- a/components/omnibox_strings.grdp +++ b/components/omnibox_strings.grdp
@@ -29,9 +29,6 @@ Image you copied </message> </if> - <message name="IDS_COPIED_TEXT_FROM_CLIPBOARD" desc="The actual text the user copied, surrounded by quotation marks."> - "<ph name="TEXT">$1<ex>search string</ex></ph>" - </message> <message name="IDS_SECURE_CONNECTION_EV" desc="Short text shown in the location bar when the connection is secure with an EV cert."> <ph name="ORGANIZATION">$1<ex>Paypal Inc.</ex></ph> [<ph name="COUNTRY">$2<ex>US</ex></ph>] </message>
diff --git a/components/omnibox_strings_grdp/IDS_COPIED_TEXT_FROM_CLIPBOARD.png.sha1 b/components/omnibox_strings_grdp/IDS_COPIED_TEXT_FROM_CLIPBOARD.png.sha1 deleted file mode 100644 index 25160b9b..0000000 --- a/components/omnibox_strings_grdp/IDS_COPIED_TEXT_FROM_CLIPBOARD.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -b015bfd93d7d6b6c87e140f9e31796dad1d20a3c \ No newline at end of file
diff --git a/components/ownership/owner_settings_service.cc b/components/ownership/owner_settings_service.cc index 90be5e8..ccffed65 100644 --- a/components/ownership/owner_settings_service.cc +++ b/components/ownership/owner_settings_service.cc
@@ -140,6 +140,13 @@ return Set(setting, in_value); } +void OwnerSettingsService::RunPendingIsOwnerCallbacksForTesting(bool is_owner) { + std::vector<IsOwnerCallback> is_owner_callbacks; + is_owner_callbacks.swap(pending_is_owner_callbacks_); + for (auto& callback : is_owner_callbacks) + std::move(callback).Run(is_owner); +} + bool OwnerSettingsService::SetString(const std::string& setting, const std::string& value) { DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/components/ownership/owner_settings_service.h b/components/ownership/owner_settings_service.h index b573f987..57b4913 100644 --- a/components/ownership/owner_settings_service.h +++ b/components/ownership/owner_settings_service.h
@@ -119,6 +119,10 @@ bool SetDouble(const std::string& setting, double value); bool SetString(const std::string& setting, const std::string& value); + // Run callbacks in test setting. Mocks ownership when full device setup is + // not needed. + void RunPendingIsOwnerCallbacksForTesting(bool is_owner); + protected: void ReloadKeypair();
diff --git a/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc b/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc index 62967f68..449c44c 100644 --- a/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc +++ b/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc
@@ -209,6 +209,7 @@ WebFeature::kSerialPortOpen, WebFeature::kHidRequestDevice, WebFeature::kHidDeviceOpen, + WebFeature::kCrossOriginWasmModuleSharing, })); return *opt_in_features; }
diff --git a/components/resources/BUILD.gn b/components/resources/BUILD.gn index fb82ba643..9b87aa1 100644 --- a/components/resources/BUILD.gn +++ b/components/resources/BUILD.gn
@@ -3,7 +3,6 @@ # found in the LICENSE file. import("//build/config/android/config.gni") -import("//build/config/python.gni") import("//components/safe_browsing/buildflags.gni") import("//printing/buildflags/buildflags.gni") import("//tools/grit/grit_rule.gni") @@ -84,8 +83,7 @@ output_dir = "$root_gen_dir/components" } -# TODO(crbug.com/1112471): Get this to run cleanly under Python 3. -python2_action("about_credits") { +action("about_credits") { script = "//tools/licenses.py" depfile = "$target_gen_dir/$target_name.d"
diff --git a/components/safe_browsing/content/password_protection/password_protection_request_content.cc b/components/safe_browsing/content/password_protection/password_protection_request_content.cc index 7434396d..4e3eeb1a 100644 --- a/components/safe_browsing/content/password_protection/password_protection_request_content.cc +++ b/components/safe_browsing/content/password_protection/password_protection_request_content.cc
@@ -55,6 +55,24 @@ } #endif // BUILDFLAG(SAFE_BROWSING_AVAILABLE) +int GetMinWidthForVisualFeatures() { + if (base::FeatureList::IsEnabled(kVisualFeaturesSizes)) { + return base::GetFieldTrialParamByFeatureAsInt( + kVisualFeaturesSizes, "min_width", kMinWidthForVisualFeatures); + } + + return kMinWidthForVisualFeatures; +} + +int GetMinHeightForVisualFeatures() { + if (base::FeatureList::IsEnabled(kVisualFeaturesSizes)) { + return base::GetFieldTrialParamByFeatureAsInt( + kVisualFeaturesSizes, "min_height", kMinHeightForVisualFeatures); + } + + return kMinHeightForVisualFeatures; +} + } // namespace PasswordProtectionRequestContent::PasswordProtectionRequestContent( @@ -262,8 +280,8 @@ trigger_type() == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE && password_protection_service()->IsExtendedReporting() && !password_protection_service()->IsIncognito() && - request_proto_->content_area_width() >= kMinWidthForVisualFeatures && - request_proto_->content_area_height() >= kMinHeightForVisualFeatures; + request_proto_->content_area_width() >= GetMinWidthForVisualFeatures() && + request_proto_->content_area_height() >= GetMinHeightForVisualFeatures(); #if !defined(OS_ANDROID) can_collect_visual_features &= zoom::ZoomController::GetZoomLevelForWebContents(web_contents_) <=
diff --git a/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.cc b/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.cc index dce3b8f..85d1292 100644 --- a/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.cc +++ b/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.cc
@@ -85,6 +85,11 @@ hash->data()->size()); } +void RecordScorerCreationStatus(ScorerCreationStatus status) { + UMA_HISTOGRAM_ENUMERATION("SBClientPhishing.FlatBufferScorer.CreationStatus", + status, SCORER_STATUS_MAX); +} + } // namespace FlatBufferModelScorer::FlatBufferModelScorer() = default;
diff --git a/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.cc b/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.cc index e5553d6..3e68aa9 100644 --- a/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.cc +++ b/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.cc
@@ -69,6 +69,12 @@ return request; } + +void RecordScorerCreationStatus(ScorerCreationStatus status) { + UMA_HISTOGRAM_ENUMERATION("SBClientPhishing.ProtobufScorer.CreationStatus", + status, SCORER_STATUS_MAX); +} + } // namespace ProtobufModelScorer::ProtobufModelScorer() = default;
diff --git a/components/safe_browsing/content/renderer/phishing_classifier/scorer.h b/components/safe_browsing/content/renderer/phishing_classifier/scorer.h index 7f8cf0f..3aea6442 100644 --- a/components/safe_browsing/content/renderer/phishing_classifier/scorer.h +++ b/components/safe_browsing/content/renderer/phishing_classifier/scorer.h
@@ -126,11 +126,6 @@ Scorer(const Scorer&) = delete; Scorer& operator=(const Scorer&) = delete; - static void RecordScorerCreationStatus(ScorerCreationStatus status) { - UMA_HISTOGRAM_ENUMERATION("SBClientPhishing.ScorerCreationStatus", status, - SCORER_STATUS_MAX); - } - protected: // Helper function which converts log odds to a probability in the range // [0.0,1.0].
diff --git a/components/safe_browsing/core/common/visual_utils.cc b/components/safe_browsing/core/common/visual_utils.cc index 6a708ee..547043ef 100644 --- a/components/safe_browsing/core/common/visual_utils.cc +++ b/components/safe_browsing/core/common/visual_utils.cc
@@ -8,8 +8,10 @@ #include <vector> #include "base/check_op.h" +#include "base/feature_list.h" #include "base/numerics/checked_math.h" #include "base/trace_event/trace_event.h" +#include "components/safe_browsing/core/features.h" #include "components/safe_browsing/core/proto/client_model.pb.h" #include "components/safe_browsing/core/proto/csd.pb.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -130,6 +132,24 @@ } } +int GetPHashDownsampleWidth() { + if (base::FeatureList::IsEnabled(kVisualFeaturesSizes)) { + return base::GetFieldTrialParamByFeatureAsInt( + kVisualFeaturesSizes, "phash_width", kPHashDownsampleWidth); + } + + return kPHashDownsampleWidth; +} + +int GetPHashDownsampleHeight() { + if (base::FeatureList::IsEnabled(kVisualFeaturesSizes)) { + return base::GetFieldTrialParamByFeatureAsInt( + kVisualFeaturesSizes, "phash_height", kPHashDownsampleHeight); + } + + return kPHashDownsampleHeight; +} + } // namespace // A QuantizedColor takes the highest 3 bits of R, G, and B, and concatenates @@ -240,9 +260,9 @@ // average to be consistent with the backend. // TODO(drubery): Investigate whether this is necessary for performance or // not. - SkImageInfo downsampled_info = - SkImageInfo::MakeN32(kPHashDownsampleWidth, kPHashDownsampleHeight, - SkAlphaType::kUnpremul_SkAlphaType, rec2020); + SkImageInfo downsampled_info = SkImageInfo::MakeN32( + GetPHashDownsampleWidth(), GetPHashDownsampleHeight(), + SkAlphaType::kUnpremul_SkAlphaType, rec2020); SkBitmap downsampled; if (!downsampled.tryAllocPixels(downsampled_info)) return false;
diff --git a/components/safe_browsing/core/features.cc b/components/safe_browsing/core/features.cc index be2f5bc..b43c72b 100644 --- a/components/safe_browsing/core/features.cc +++ b/components/safe_browsing/core/features.cc
@@ -141,6 +141,9 @@ "VisualFeaturesInPasswordProtectionAndroid", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kVisualFeaturesSizes{"VisualFeaturesSizes", + base::FEATURE_DISABLED_BY_DEFAULT}; + namespace { // List of Safe Browsing features. Boolean value for each list member should be // set to true if the experiment state should be listed on
diff --git a/components/safe_browsing/core/features.h b/components/safe_browsing/core/features.h index 814c572..1e3e252 100644 --- a/components/safe_browsing/core/features.h +++ b/components/safe_browsing/core/features.h
@@ -143,6 +143,11 @@ // Android. extern const base::Feature kVisualFeaturesInPasswordProtectionAndroid; +// Controls the behavior of visual features in CSD pings. This feature is +// checked for the final size of the visual features and the minimum size of +// the screen. +extern const base::Feature kVisualFeaturesSizes; + // Controls whether the delayed warning experiment is enabled. extern const base::Feature kDelayedWarnings; // True if mouse clicks should undelay the warnings immediately when delayed
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc index 63099e27..b8709d17 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc
@@ -194,13 +194,16 @@ NavigateAndCommit(GURL("https://example.first")); - // Initialize the ruleset dealer. + // Initialize the ruleset dealer. Allowlisted URLs must also match a + // disallowed rule in order to work correctly. std::vector<proto::UrlRule> rules; rules.push_back(testing::CreateAllowlistRuleForDocument( "allowlist.com", proto::ACTIVATION_TYPE_DOCUMENT, {"page-with-activation.com"})); + rules.push_back(testing::CreateRuleForDocument( + "allowlist.com", proto::ACTIVATION_TYPE_DOCUMENT, + {"page-with-activation.com"})); - // Allowlist rules must prefix a disallowed rule in order to work correctly. rules.push_back(testing::CreateAllowlistSuffixRule("not_disallowed.html")); rules.push_back(testing::CreateSuffixRule("disallowed.html")); ASSERT_NO_FATAL_FAILURE(test_ruleset_creator_.CreateRulesetWithRules(
diff --git a/components/subresource_filter/core/common/test_ruleset_utils.cc b/components/subresource_filter/core/common/test_ruleset_utils.cc index 4771f494..b6e3bc7 100644 --- a/components/subresource_filter/core/common/test_ruleset_utils.cc +++ b/components/subresource_filter/core/common/test_ruleset_utils.cc
@@ -13,62 +13,72 @@ namespace proto = url_pattern_index::proto; -proto::UrlRule CreateSubstringRule(base::StringPiece substring) { +namespace { + +proto::UrlRule CreateRuleImpl(base::StringPiece substring, + bool is_allowlist_rule, + bool is_suffix_rule) { proto::UrlRule rule; - rule.set_semantics(proto::RULE_SEMANTICS_BLOCKLIST); + rule.set_semantics(is_allowlist_rule ? proto::RULE_SEMANTICS_ALLOWLIST + : proto::RULE_SEMANTICS_BLOCKLIST); rule.set_source_type(proto::SOURCE_TYPE_ANY); rule.set_element_types(proto::ELEMENT_TYPE_ALL); rule.set_url_pattern_type(proto::URL_PATTERN_TYPE_SUBSTRING); rule.set_anchor_left(proto::ANCHOR_TYPE_NONE); - rule.set_anchor_right(proto::ANCHOR_TYPE_NONE); + rule.set_anchor_right(is_suffix_rule ? proto::ANCHOR_TYPE_BOUNDARY + : proto::ANCHOR_TYPE_NONE); rule.set_url_pattern(std::string(substring)); return rule; } -proto::UrlRule CreateSuffixRule(base::StringPiece suffix) { - proto::UrlRule rule; - rule.set_semantics(proto::RULE_SEMANTICS_BLOCKLIST); - rule.set_source_type(proto::SOURCE_TYPE_ANY); - rule.set_element_types(proto::ELEMENT_TYPE_ALL); - rule.set_url_pattern_type(proto::URL_PATTERN_TYPE_SUBSTRING); - rule.set_anchor_left(proto::ANCHOR_TYPE_NONE); - rule.set_anchor_right(proto::ANCHOR_TYPE_BOUNDARY); - rule.set_url_pattern(std::string(suffix)); +proto::UrlRule CreateRuleForDocumentImpl(base::StringPiece substring, + int32_t activation_types, + std::vector<std::string> domains, + bool is_allowlist_rule, + bool is_suffix_rule) { + proto::UrlRule rule = + CreateRuleImpl(substring, is_allowlist_rule, is_suffix_rule); + rule.set_activation_types(activation_types); + for (std::string& domain : domains) { + rule.add_domains()->set_domain(std::move(domain)); + } return rule; } +} // namespace + +proto::UrlRule CreateSubstringRule(base::StringPiece substring) { + return CreateRuleImpl(substring, /*is_allowlist_rule=*/false, + /*is_suffix_rule=*/false); +} + +proto::UrlRule CreateSuffixRule(base::StringPiece suffix) { + return CreateRuleImpl(suffix, /*is_allowlist_rule=*/false, + /*is_suffix_rule=*/true); +} + proto::UrlRule CreateAllowlistSuffixRule(base::StringPiece suffix) { - proto::UrlRule rule; - rule.set_semantics(proto::RULE_SEMANTICS_ALLOWLIST); - rule.set_source_type(proto::SOURCE_TYPE_ANY); - rule.set_element_types(proto::ELEMENT_TYPE_ALL); - rule.set_url_pattern_type(proto::URL_PATTERN_TYPE_SUBSTRING); - rule.set_anchor_left(proto::ANCHOR_TYPE_NONE); - rule.set_anchor_right(proto::ANCHOR_TYPE_BOUNDARY); - rule.set_url_pattern(std::string(suffix)); - return rule; + return CreateRuleImpl(suffix, /*is_allowlist_rule=*/true, + /*is_suffix_rule=*/true); +} + +proto::UrlRule CreateRuleForDocument(base::StringPiece pattern, + int32_t activation_types, + std::vector<std::string> domains) { + return CreateRuleForDocumentImpl(pattern, activation_types, domains, + /*is_allowlist_rule=*/false, + /*is_suffix_rule=*/false); } proto::UrlRule CreateAllowlistRuleForDocument( base::StringPiece pattern, int32_t activation_types, std::vector<std::string> domains) { - proto::UrlRule rule; - rule.set_semantics(proto::RULE_SEMANTICS_ALLOWLIST); - rule.set_source_type(proto::SOURCE_TYPE_ANY); - rule.set_activation_types(activation_types); - - for (std::string& domain : domains) { - rule.add_domains()->set_domain(std::move(domain)); - } - - rule.set_url_pattern_type(proto::URL_PATTERN_TYPE_SUBSTRING); - rule.set_anchor_left(proto::ANCHOR_TYPE_NONE); - rule.set_anchor_right(proto::ANCHOR_TYPE_NONE); - rule.set_url_pattern(std::string(pattern)); - return rule; + return CreateRuleForDocumentImpl(pattern, activation_types, domains, + /*is_allowlist_rule=*/true, + /*is_suffix_rule=*/false); } } // namespace testing
diff --git a/components/subresource_filter/core/common/test_ruleset_utils.h b/components/subresource_filter/core/common/test_ruleset_utils.h index 2fbfc96..61af431 100644 --- a/components/subresource_filter/core/common/test_ruleset_utils.h +++ b/components/subresource_filter/core/common/test_ruleset_utils.h
@@ -24,16 +24,28 @@ // that the resource URL ends with |suffix|. url_pattern_index::proto::UrlRule CreateSuffixRule(base::StringPiece suffix); -// Creates a white URL rule which targets subresources of any type such that -// the resource URL ends with |suffix|. +// Creates an allowlisted URL rule which targets subresources of any type such +// that the resource URL ends with `suffix`. Note that a URL must match both an +// allowlist rule and a blocklist rule to be correctly considered allowlisted. url_pattern_index::proto::UrlRule CreateAllowlistSuffixRule( base::StringPiece suffix); -// Same as CreateUrlRule(pattern, proto::URL_PATTERN_TYPE_WILDCARDED), but the -// rule applies to the specified |activation_types|, and to no element types. -// Additionally, it is restricted to a set of |domains| (if provided). +// Creates a blocklisted URL rule which targets subresources of the specified +// `activation_types` and a URL containing the given `substring`. Additionally, +// it is restricted to a set of `domains`, if provided. +url_pattern_index::proto::UrlRule CreateRuleForDocument( + base::StringPiece substring, + int32_t activation_types = + url_pattern_index::proto::ACTIVATION_TYPE_DOCUMENT, + std::vector<std::string> domains = std::vector<std::string>()); + +// Creates an allowlisted URL rule which targets subresources of the specified +// `activation_types` and a URL containing the given `substring`. Additionally, +// it is restricted to a set of `domains`, if provided. Note that a URL must +// match both an allowlist rule and a blocklist rule to be correctly considered +// allowlisted. url_pattern_index::proto::UrlRule CreateAllowlistRuleForDocument( - base::StringPiece pattern, + base::StringPiece substring, int32_t activation_types = url_pattern_index::proto::ACTIVATION_TYPE_DOCUMENT, std::vector<std::string> domains = std::vector<std::string>());
diff --git a/content/browser/conversions/conversion_host_unittest.cc b/content/browser/conversions/conversion_host_unittest.cc index 619a735..849b0532 100644 --- a/content/browser/conversions/conversion_host_unittest.cc +++ b/content/browser/conversions/conversion_host_unittest.cc
@@ -11,7 +11,6 @@ #include "content/browser/conversions/conversion_test_utils.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/common/content_client.h" -#include "content/public/common/content_features.h" #include "content/public/test/test_renderer_host.h" #include "content/test/fake_mojo_message_dispatch_context.h" #include "content/test/navigation_simulator_impl.h"
diff --git a/content/browser/conversions/conversion_network_sender_impl_unittest.cc b/content/browser/conversions/conversion_network_sender_impl_unittest.cc index 6e73fc9..4b715e5e 100644 --- a/content/browser/conversions/conversion_network_sender_impl_unittest.cc +++ b/content/browser/conversions/conversion_network_sender_impl_unittest.cc
@@ -20,7 +20,6 @@ #include "content/browser/storage_partition_impl.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition.h" -#include "content/public/common/content_features.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_browser_context.h" #include "net/base/load_flags.h"
diff --git a/content/browser/conversions/conversion_registration_browsertest.cc b/content/browser/conversions/conversion_registration_browsertest.cc index 2f83daf..ebdf33a6 100644 --- a/content/browser/conversions/conversion_registration_browsertest.cc +++ b/content/browser/conversions/conversion_registration_browsertest.cc
@@ -6,11 +6,9 @@ #include <memory> #include "base/bind.h" -#include "base/test/scoped_feature_list.h" #include "content/browser/conversions/conversion_host.h" #include "content/browser/conversions/conversion_manager_impl.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" @@ -88,7 +86,6 @@ public: ConversionDisabledBrowserTest() { ConversionManagerImpl::RunInMemoryForTesting(); - feature_list_.InitAndEnableFeature(features::kConversionMeasurement); } void SetUpOnMainThread() override { @@ -112,9 +109,6 @@ net::EmbeddedTestServer* https_server() { return https_server_.get(); } - protected: - base::test::ScopedFeatureList feature_list_; - private: std::unique_ptr<net::EmbeddedTestServer> https_server_; };
diff --git a/content/browser/conversions/conversions_browsertest.cc b/content/browser/conversions/conversions_browsertest.cc index 492cbd9c..c673348 100644 --- a/content/browser/conversions/conversions_browsertest.cc +++ b/content/browser/conversions/conversions_browsertest.cc
@@ -7,12 +7,10 @@ #include "base/command_line.h" #include "base/sequenced_task_runner.h" #include "base/strings/strcat.h" -#include "base/test/scoped_feature_list.h" #include "base/threading/sequenced_task_runner_handle.h" #include "content/browser/conversions/conversion_manager_impl.h" #include "content/browser/conversions/conversion_test_utils.h" #include "content/public/common/content_client.h" -#include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" @@ -91,7 +89,6 @@ class ConversionsBrowserTest : public ContentBrowserTest { public: ConversionsBrowserTest() { - feature_list_.InitAndEnableFeature(features::kConversionMeasurement); ConversionManagerImpl::RunInMemoryForTesting(); } @@ -122,7 +119,6 @@ ConversionDisallowingContentBrowserClient disallowed_browser_client_; private: - base::test::ScopedFeatureList feature_list_; std::unique_ptr<net::EmbeddedTestServer> https_server_; };
diff --git a/content/browser/conversions/conversions_origin_trial_browsertest.cc b/content/browser/conversions/conversions_origin_trial_browsertest.cc index 96c90f2..875410e1 100644 --- a/content/browser/conversions/conversions_origin_trial_browsertest.cc +++ b/content/browser/conversions/conversions_origin_trial_browsertest.cc
@@ -16,7 +16,6 @@ #include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" -#include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" @@ -27,6 +26,7 @@ #include "content/shell/browser/shell.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" #include "url/gurl.h" namespace content { @@ -35,9 +35,9 @@ constexpr char kBaseDataDir[] = "content/test/data/conversions/"; } -class ConversionsOriginTrialBrowserTestBase : public ContentBrowserTest { +class ConversionsOriginTrialBrowserTest : public ContentBrowserTest { public: - ConversionsOriginTrialBrowserTestBase() = default; + ConversionsOriginTrialBrowserTest() = default; void SetUpOnMainThread() override { ContentBrowserTest::SetUpOnMainThread(); @@ -64,17 +64,6 @@ std::unique_ptr<URLLoaderInterceptor> url_loader_interceptor_; }; -class ConversionsOriginTrialBrowserTest - : public ConversionsOriginTrialBrowserTestBase { - public: - ConversionsOriginTrialBrowserTest() { - feature_list_.InitAndEnableFeature(features::kConversionMeasurement); - } - - private: - base::test::ScopedFeatureList feature_list_; -}; - IN_PROC_BROWSER_TEST_F(ConversionsOriginTrialBrowserTest, OriginTrialEnabled_FeatureDetected) { EXPECT_TRUE(NavigateToURL( @@ -132,10 +121,11 @@ // UrlLoadInterceptor cannot properly redirect the conversion pings. class ConversionsOriginTrialNoBrowserFeatureBrowserTest - : public ConversionsOriginTrialBrowserTestBase { + : public ConversionsOriginTrialBrowserTest { public: ConversionsOriginTrialNoBrowserFeatureBrowserTest() { - feature_list_.InitAndDisableFeature(features::kConversionMeasurement); + feature_list_.InitAndDisableFeature( + blink::features::kConversionMeasurement); } private:
diff --git a/content/browser/conversions/impression_declaration_browsertest.cc b/content/browser/conversions/impression_declaration_browsertest.cc index 2bdc45d..c1555e9 100644 --- a/content/browser/conversions/impression_declaration_browsertest.cc +++ b/content/browser/conversions/impression_declaration_browsertest.cc
@@ -8,14 +8,12 @@ #include "base/bind.h" #include "base/run_loop.h" #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "base/time/time.h" #include "build/build_config.h" #include "content/browser/conversions/conversion_host.h" #include "content/browser/conversions/conversion_manager_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/navigation_handle.h" -#include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" @@ -140,7 +138,6 @@ class ImpressionDisabledBrowserTest : public ContentBrowserTest { public: ImpressionDisabledBrowserTest() { - feature_list_.InitAndEnableFeature(features::kConversionMeasurement); ConversionManagerImpl::RunInMemoryForTesting(); } @@ -168,7 +165,6 @@ net::EmbeddedTestServer* https_server() { return https_server_.get(); } private: - base::test::ScopedFeatureList feature_list_; std::unique_ptr<net::EmbeddedTestServer> https_server_; };
diff --git a/content/browser/devtools/devtools_conversion_browsertest.cc b/content/browser/devtools/devtools_conversion_browsertest.cc index bb5c5cb..a13d9fcc 100644 --- a/content/browser/devtools/devtools_conversion_browsertest.cc +++ b/content/browser/devtools/devtools_conversion_browsertest.cc
@@ -4,10 +4,8 @@ #include <iostream> -#include "base/test/scoped_feature_list.h" #include "content/browser/conversions/conversion_manager_impl.h" #include "content/browser/devtools/protocol/devtools_protocol_test_support.h" -#include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" #include "content/public/test/content_browser_test_utils.h" @@ -24,7 +22,6 @@ public: DevToolsConversionBrowserTest() { ConversionManagerImpl::RunInMemoryForTesting(); - feature_list_.InitAndEnableFeature(features::kConversionMeasurement); } void SetUpCommandLine(base::CommandLine* command_line) override { @@ -53,9 +50,6 @@ WebContents* web_contents() { return shell()->web_contents(); } net::EmbeddedTestServer* https_server() { return https_server_.get(); } - protected: - base::test::ScopedFeatureList feature_list_; - private: std::unique_ptr<net::EmbeddedTestServer> https_server_; };
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc index 0e32577..0ee5e24 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host.cc +++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -435,6 +435,9 @@ void RenderFrameDevToolsAgentHost::DidFinishNavigation( NavigationHandle* navigation_handle) { NavigationRequest* request = NavigationRequest::From(navigation_handle); + // If we opt for retaning self within the conditional block below, do so + // till the end of the function, as we require |this| after the conditional. + scoped_refptr<RenderFrameDevToolsAgentHost> protect; if (request->frame_tree_node() == frame_tree_node_) { navigation_requests_.erase(request); if (request->HasCommitted()) @@ -444,7 +447,7 @@ UpdateRawHeadersAccess(frame_tree_node_->current_frame_host()); } // UpdateFrameHost may destruct |this|. - scoped_refptr<RenderFrameDevToolsAgentHost> protect(this); + protect = this; UpdateFrameHost(frame_tree_node_->current_frame_host()); if (navigation_requests_.empty()) {
diff --git a/content/browser/media/session/media_session_controllers_manager_unittest.cc b/content/browser/media/session/media_session_controllers_manager_unittest.cc index 34b5b06..075e2c63 100644 --- a/content/browser/media/session/media_session_controllers_manager_unittest.cc +++ b/content/browser/media/session/media_session_controllers_manager_unittest.cc
@@ -52,8 +52,6 @@ static const int kIsAudioFocusEnabled = 1; void SetUp() override { - RenderViewHostImplTestHarness::SetUp(); - std::vector<base::Feature> enabled_features; std::vector<base::Feature> disabled_features; @@ -79,6 +77,8 @@ scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features); + RenderViewHostImplTestHarness::SetUp(); + GlobalFrameRoutingId frame_routing_id = contents()->GetMainFrame()->GetGlobalFrameRoutingId(); media_player_id_ = MediaPlayerId(frame_routing_id, 1);
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 2821b23..17a6fd15 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -603,7 +603,7 @@ // got too many processes. See also ShouldTryToUseExistingProcessHost in // this file. if (RenderProcessHost::run_renderer_in_process() || - GetAllHosts().size() >= + RenderProcessHostImpl::GetProcessCountForLimit() >= RenderProcessHostImpl::GetMaxRendererProcessCount()) return; @@ -703,7 +703,7 @@ // If the spare shouldn't be kept around, then discard it as soon as we // find that the current spare was mismatched. CleanupSpareRenderProcessHost(); - } else if (GetAllHosts().size() >= + } else if (RenderProcessHostImpl::GetProcessCountForLimit() >= RenderProcessHostImpl::GetMaxRendererProcessCount()) { // Drop the spare if we are at a process limit and the spare wasn't taken. // This helps avoid process reuse. @@ -4256,6 +4256,17 @@ } // static +size_t RenderProcessHostImpl::GetProcessCountForLimit() { + // Let the embedder specify a number of processes to ignore when checking + // against the process limit, to avoid forcing normal pages to reuse processes + // too soon. + size_t process_count_to_ignore = + GetContentClient()->browser()->GetProcessCountToIgnoreForLimit(); + CHECK_LE(process_count_to_ignore, GetAllHosts().size()); + return GetAllHosts().size() - process_count_to_ignore; +} + +// static bool RenderProcessHost::ShouldTryToUseExistingProcessHost( BrowserContext* browser_context, const GURL& url) { @@ -4267,11 +4278,11 @@ // a renderer process for a browser context that has no existing // renderers. This is OK in moderation, since the // GetMaxRendererProcessCount() is conservative. - if (GetAllHosts().size() >= GetMaxRendererProcessCount()) { + size_t process_count = RenderProcessHostImpl::GetProcessCountForLimit(); + if (process_count >= GetMaxRendererProcessCount()) { MAYBEVLOG(4) << __func__ - << ": GetAllHosts().size() >= GetMaxRendererProcessCount() (" - << GetAllHosts().size() - << " >= " << GetMaxRendererProcessCount() + << ": process_count >= GetMaxRendererProcessCount() (" + << process_count << " >= " << GetMaxRendererProcessCount() << ") - will try to reuse an existing process"; return true; }
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index a7108cc3..59ee682 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -335,6 +335,11 @@ // Implementation of FilterURL below that can be shared with the mock class. static void FilterURL(RenderProcessHost* rph, bool empty_allowed, GURL* url); + // Returns the current process count for comparisons against + // GetMaxRendererProcessCount, taking into account any processes the embedder + // wants to ignore via ContentBrowserClient::GetProcessCountToIgnoreForLimit. + static size_t GetProcessCountForLimit(); + // Returns true if |host| is suitable for rendering a page in the given // |isolation_context|, where the page would utilize |site_info.site_url()| as // its SiteInstance site URL, and its process would be locked to
diff --git a/content/browser/speech/speech_recognition_engine.cc b/content/browser/speech/speech_recognition_engine.cc index 92b878f1..9bae55c 100644 --- a/content/browser/speech/speech_recognition_engine.cc +++ b/content/browser/speech/speech_recognition_engine.cc
@@ -10,6 +10,7 @@ #include "base/big_endian.h" #include "base/bind.h" +#include "base/metrics/histogram_functions.h" #include "base/rand_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -18,6 +19,7 @@ #include "content/browser/speech/audio_buffer.h" #include "content/public/browser/google_streaming_api.pb.h" #include "google_apis/google_api_keys.h" +#include "media/base/audio_timestamp_helper.h" #include "mojo/public/c/system/types.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "net/base/escape.h" @@ -35,6 +37,8 @@ const char kDownstreamUrl[] = "/down?"; const char kUpstreamUrl[] = "/up?"; +constexpr char kWebSpeechAudioDuration[] = "Accessibility.WebSpeech.Duration"; + // Used to override |kWebServiceBaseUrl| when non-null, only set in tests. const char* web_service_base_url_for_tests = nullptr; @@ -115,11 +119,15 @@ } void SpeechRecognitionEngine::StartRecognition() { + upstream_audio_duration_ = base::TimeDelta(); FSMEventArgs event_args(EVENT_START_RECOGNITION); DispatchEvent(event_args); } void SpeechRecognitionEngine::EndRecognition() { + base::UmaHistogramLongTimes100(kWebSpeechAudioDuration, + upstream_audio_duration_); + FSMEventArgs event_args(EVENT_END_RECOGNITION); DispatchEvent(event_args); } @@ -495,6 +503,10 @@ DCHECK(event_args.audio_data.get()); const AudioChunk& audio = *(event_args.audio_data.get()); + base::TimeDelta duration = media::AudioTimestampHelper::FramesToTime( + audio.NumSamples(), config_.audio_sample_rate); + upstream_audio_duration_ += duration; + DCHECK_EQ(audio.bytes_per_sample(), config_.audio_num_bits_per_sample / 8); encoder_->Encode(audio); scoped_refptr<AudioChunk> encoded_data(encoder_->GetEncodedDataAndClear());
diff --git a/content/browser/speech/speech_recognition_engine.h b/content/browser/speech/speech_recognition_engine.h index e9f2f8b..87131194 100644 --- a/content/browser/speech/speech_recognition_engine.h +++ b/content/browser/speech/speech_recognition_engine.h
@@ -27,6 +27,10 @@ #include "third_party/blink/public/mojom/speech/speech_recognition_grammar.mojom.h" #include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h" +namespace base { +class TimeDelta; +} + namespace network { class SharedURLLoaderFactory; } @@ -210,6 +214,9 @@ // upload formats, and uses the appropriate one. void UploadAudioChunk(const std::string& data, FrameType type, bool is_final); + // The total audio duration of the upstream request. + base::TimeDelta upstream_audio_duration_; + Config config_; std::unique_ptr<speech::UpstreamLoader> upstream_loader_; std::unique_ptr<speech::DownstreamLoader> downstream_loader_;
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index 143f571..fed97ca 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -1296,7 +1296,7 @@ // The Conversion Measurement API is not available in Incognito mode. if (!is_in_memory_ && - base::FeatureList::IsEnabled(features::kConversionMeasurement)) { + base::FeatureList::IsEnabled(blink::features::kConversionMeasurement)) { conversion_manager_ = std::make_unique<ConversionManagerImpl>( this, path, special_storage_policy_); }
diff --git a/content/browser/storage_partition_impl_unittest.cc b/content/browser/storage_partition_impl_unittest.cc index b0dcc28..ab16fbf 100644 --- a/content/browser/storage_partition_impl_unittest.cc +++ b/content/browser/storage_partition_impl_unittest.cc
@@ -820,11 +820,10 @@ StoragePartitionImplTest() : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP), browser_context_(new TestBrowserContext()) { - // Configures the Conversion API to run in memory to speed up it's + // Configures the Conversion API to run in memory to speed up its // initialization and avoid timeouts. See https://crbug.com/1080764. ConversionManagerImpl::RunInMemoryForTesting(); - feature_list_.InitWithFeatures({features::kConversionMeasurement, - blink::features::kFledgeInterestGroups}, + feature_list_.InitWithFeatures({blink::features::kFledgeInterestGroups}, {}); }
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index df03885..3ce2828 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -926,7 +926,7 @@ // ConversionHost takes a weak ref on |this|, so it must be created outside of // the initializer list. - if (base::FeatureList::IsEnabled(features::kConversionMeasurement)) { + if (base::FeatureList::IsEnabled(blink::features::kConversionMeasurement)) { ConversionHost::CreateForWebContents(this); } }
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index bb7c815..04cdd66e 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -227,8 +227,6 @@ {wf::EnableClickPointerEvent, features::kClickPointerEvent}, {wf::EnableCompositeBGColorAnimation, features::kCompositeBGColorAnimation}, {wf::EnableConsolidatedMovementXY, features::kConsolidatedMovementXY}, - {wf::EnableConversionMeasurementInfraSupport, - features::kConversionMeasurement}, {wf::EnableCookiesWithoutSameSiteMustBeSecure, net::features::kCookiesWithoutSameSiteMustBeSecure}, {wf::EnableCooperativeScheduling, features::kCooperativeScheduling},
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index ffb6f3a..53de48c 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -241,6 +241,10 @@ return true; } +size_t ContentBrowserClient::GetProcessCountToIgnoreForLimit() { + return 0; +} + bool ContentBrowserClient::ShouldTryToUseExistingProcessHost( BrowserContext* browser_context, const GURL& url) {
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index f83b53c..4b1479f6 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -527,6 +527,13 @@ // given |process_host|. virtual bool MayReuseHost(RenderProcessHost* process_host); + // Returns a number of processes to ignore when deciding whether to reuse + // processes when over the process limit. This is useful for embedders that + // may want to partly delay when normal pages start reusing processes (e.g., + // if another process type has a large number of processes). Defaults to 0. + // Must be less than or equal to the total number of RenderProcessHosts. + virtual size_t GetProcessCountToIgnoreForLimit(); + // Returns whether a new process should be created or an existing one should // be reused based on the URL we want to load. This should return false, // unless there is a good reason otherwise.
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 75cc0124b..c0ac9feb 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -183,10 +183,6 @@ const base::Feature kConsolidatedMovementXY{"ConsolidatedMovementXY", base::FEATURE_ENABLED_BY_DEFAULT}; -// Controls whether the Conversion Measurement API infrastructure is enabled. -const base::Feature kConversionMeasurement{"ConversionMeasurement", - base::FEATURE_ENABLED_BY_DEFAULT}; - // Enables Blink cooperative scheduling. const base::Feature kCooperativeScheduling{"CooperativeScheduling", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index b71e4cd..fca527ac 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -47,7 +47,6 @@ CONTENT_EXPORT extern const base::Feature kCompositeBGColorAnimation; CONTENT_EXPORT extern const base::Feature kCodeCacheDeletionWithoutFilter; CONTENT_EXPORT extern const base::Feature kConsolidatedMovementXY; -CONTENT_EXPORT extern const base::Feature kConversionMeasurement; CONTENT_EXPORT extern const base::Feature kCooperativeScheduling; CONTENT_EXPORT extern const base::Feature kCrashReporting; CONTENT_EXPORT extern const base::Feature kCriticalClientHint;
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt index 74bc9fcc..36b23e4a 100644 --- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -397,6 +397,11 @@ crbug.com/1213657 [ linux skia-renderer-vulkan ] Pixel_WebGPUImport2DCanvas [ Skip ] crbug.com/1213657 [ linux skia-renderer-vulkan ] Pixel_WebGPUImportUnaccelerated2DCanvas [ Skip ] +# WebGPU experimentalImportTexture pixel tests fail on Win10+SkiaRenderer+Dawn. +crbug.com/1213920 [ win10 skia-renderer-dawn ] Pixel_WebGPUImportWebGLCanvas [ Failure ] +crbug.com/1213920 [ win10 skia-renderer-dawn ] Pixel_WebGPUImport2DCanvas [ Failure ] +crbug.com/1213920 [ win10 skia-renderer-dawn ] Pixel_WebGPUImportUnaccelerated2DCanvas [ Failure ] + # WebGPU is only supported on Win10, Mac, and Linux+SkiaRenderer+Vulkan. crbug.com/976495 [ linux skia-renderer-gl ] Pixel_WebGPUImportWebGLCanvas [ Skip ] crbug.com/976495 [ linux skia-renderer-gl ] Pixel_WebGPUImport2DCanvas [ Skip ]
diff --git a/device/fido/cable/v2_registration.cc b/device/fido/cable/v2_registration.cc index 34c5a1f..44201f9 100644 --- a/device/fido/cable/v2_registration.cc +++ b/device/fido/cable/v2_registration.cc
@@ -116,7 +116,9 @@ return; } - event.value()->contact_id = contact_id(); + if (type_ == Type::LINKING) { + event.value()->contact_id = contact_id(); + } event_callback_.Run(std::move(*event)); } @@ -296,6 +298,9 @@ } if (CBS_len(&cbs) > 0) { + if (e->source == Type::SYNC) { + return nullptr; + } e->contact_id.emplace(CBS_data(&cbs), CBS_data(&cbs) + CBS_len(&cbs)); }
diff --git a/extensions/browser/api/networking_private/networking_private_chromeos.cc b/extensions/browser/api/networking_private/networking_private_chromeos.cc index c2b8e8d..6de14f9 100644 --- a/extensions/browser/api/networking_private/networking_private_chromeos.cc +++ b/extensions/browser/api/networking_private/networking_private_chromeos.cc
@@ -758,6 +758,7 @@ NetworkTypePattern pattern = chromeos::onc::NetworkTypePatternFromOncType(type); + NET_LOG(USER) << __func__ << ":" << type; GetStateHandler()->SetTechnologyEnabled( pattern, true, chromeos::network_handler::ErrorCallback()); @@ -768,6 +769,7 @@ NetworkTypePattern pattern = chromeos::onc::NetworkTypePatternFromOncType(type); + NET_LOG(USER) << __func__ << ":" << type; GetStateHandler()->SetTechnologyEnabled( pattern, false, chromeos::network_handler::ErrorCallback());
diff --git a/extensions/browser/api/socket/socket.h b/extensions/browser/api/socket/socket.h index 086f2ff..da6e240 100644 --- a/extensions/browser/api/socket/socket.h +++ b/extensions/browser/api/socket/socket.h
@@ -64,6 +64,9 @@ // we need to manage it in the context of an extension. class Socket : public ApiResource { public: + static const content::BrowserThread::ID kThreadId = + content::BrowserThread::UI; + enum SocketType { TYPE_TCP, TYPE_UDP, TYPE_TLS }; ~Socket() override; @@ -80,9 +83,7 @@ void set_hostname(const std::string& hostname) { hostname_ = hostname; } #if BUILDFLAG(IS_CHROMEOS_ASH) - void set_firewall_hole( - std::unique_ptr<AppFirewallHole, content::BrowserThread::DeleteOnUIThread> - firewall_hole) { + void set_firewall_hole(std::unique_ptr<AppFirewallHole> firewall_hole) { firewall_hole_ = std::move(firewall_hole); } #endif // BUILDFLAG(IS_CHROMEOS_ASH) @@ -175,8 +176,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) // Represents a hole punched in the system firewall for this socket. - std::unique_ptr<AppFirewallHole, content::BrowserThread::DeleteOnUIThread> - firewall_hole_; + std::unique_ptr<AppFirewallHole> firewall_hole_; #endif // BUILDFLAG(IS_CHROMEOS_ASH) };
diff --git a/extensions/browser/api/socket/socket_api.cc b/extensions/browser/api/socket/socket_api.cc index 0bcb92e..7ad313fc 100644 --- a/extensions/browser/api/socket/socket_api.cc +++ b/extensions/browser/api/socket/socket_api.cc
@@ -79,12 +79,52 @@ SocketAsyncApiFunction::~SocketAsyncApiFunction() {} -bool SocketAsyncApiFunction::PrePrepare() { +ExtensionFunction::ResponseAction SocketAsyncApiFunction::Run() { manager_ = CreateSocketResourceManager(); - return manager_->SetBrowserContext(browser_context()); + manager_->SetBrowserContext(browser_context()); + if (!PrePrepare() || !Prepare()) { + DCHECK(!results_); + DCHECK(!error_.empty()); + return RespondNow(Error(error_)); + } + AsyncWorkStart(); + return did_respond() ? AlreadyResponded() : RespondLater(); } -bool SocketAsyncApiFunction::Respond() { return error_.empty(); } +bool SocketAsyncApiFunction::PrePrepare() { + return true; +} + +bool SocketAsyncApiFunction::Prepare() { + return true; +} + +void SocketAsyncApiFunction::Work() {} + +void SocketAsyncApiFunction::AsyncWorkStart() { + Work(); + AsyncWorkCompleted(); +} + +ExtensionFunction::ResponseValue SocketAsyncApiFunction::GetResponseValue() { + ResponseValue response; + if (error_.empty()) { + response = ArgumentList(std::move(results_)); + } else { + response = results_ ? ErrorWithArguments(std::move(results_), error_) + : Error(error_); + } + return response; +} + +void SocketAsyncApiFunction::AsyncWorkCompleted() { + Respond(GetResponseValue()); +} + +void SocketAsyncApiFunction::SetResult(std::unique_ptr<base::Value> result) { + results_ = std::make_unique<base::ListValue>(); + results_->Append(std::move(result)); +} std::unique_ptr<SocketResourceManagerInterface> SocketAsyncApiFunction::CreateSocketResourceManager() { @@ -92,6 +132,12 @@ new SocketResourceManager<Socket>()); } +// static +bool SocketAsyncApiFunction::ValidationFailure( + SocketAsyncApiFunction* function) { + return false; +} + int SocketAsyncApiFunction::AddSocket(Socket* socket) { return manager_->Add(socket); } @@ -116,6 +162,7 @@ void SocketAsyncApiFunction::OpenFirewallHole(const std::string& address, int socket_id, Socket* socket) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); #if BUILDFLAG(IS_CHROMEOS_ASH) if (!net::HostStringIsLocalhost(address)) { net::IPEndPoint local_address; @@ -131,57 +178,32 @@ ? AppFirewallHole::PortType::TCP : AppFirewallHole::PortType::UDP; - content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce(&SocketAsyncApiFunction::OpenFirewallHoleOnUIThread, - this, type, local_address.port(), socket_id)); - return; + AppFirewallHoleManager* manager = + AppFirewallHoleManager::Get(browser_context()); + std::unique_ptr<AppFirewallHole> hole( + manager->Open(type, local_address.port(), extension_id()).release()); + + if (!hole) { + error_ = kFirewallFailure; + SetResult(std::make_unique<base::Value>(-1)); + AsyncWorkCompleted(); + return; + } + + Socket* socket = GetSocket(socket_id); + if (!socket) { + error_ = kSocketNotFoundError; + SetResult(std::make_unique<base::Value>(-1)); + AsyncWorkCompleted(); + return; + } + + socket->set_firewall_hole(std::move(hole)); } #endif AsyncWorkCompleted(); } -#if BUILDFLAG(IS_CHROMEOS_ASH) - -void SocketAsyncApiFunction::OpenFirewallHoleOnUIThread( - AppFirewallHole::PortType type, - uint16_t port, - int socket_id) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - AppFirewallHoleManager* manager = - AppFirewallHoleManager::Get(browser_context()); - std::unique_ptr<AppFirewallHole, BrowserThread::DeleteOnUIThread> hole( - manager->Open(type, port, extension_id()).release()); - content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&SocketAsyncApiFunction::OnFirewallHoleOpened, - this, socket_id, std::move(hole))); -} - -void SocketAsyncApiFunction::OnFirewallHoleOpened( - int socket_id, - std::unique_ptr<AppFirewallHole, BrowserThread::DeleteOnUIThread> hole) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!hole) { - error_ = kFirewallFailure; - SetResult(std::make_unique<base::Value>(-1)); - AsyncWorkCompleted(); - return; - } - - Socket* socket = GetSocket(socket_id); - if (!socket) { - error_ = kSocketNotFoundError; - SetResult(std::make_unique<base::Value>(-1)); - AsyncWorkCompleted(); - return; - } - - socket->set_firewall_hole(std::move(hole)); - AsyncWorkCompleted(); -} - -#endif // IS_CHROMEOS_ASH - SocketExtensionWithDnsLookupFunction::SocketExtensionWithDnsLookupFunction() = default; @@ -244,8 +266,6 @@ params_ = api::socket::Create::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params_.get()); - browser_context_ = browser_context(); - switch (params_->type) { case extensions::api::socket::SOCKET_TYPE_TCP: socket_type_ = kSocketTypeTCP; @@ -256,7 +276,8 @@ mojo::PendingRemote<network::mojom::UDPSocketListener> listener_remote; socket_listener_receiver_ = listener_remote.InitWithNewPipeAndPassReceiver(); - browser_context_->GetDefaultStoragePartition() + browser_context() + ->GetDefaultStoragePartition() ->GetNetworkContext() ->CreateUDPSocket(socket_.InitWithNewPipeAndPassReceiver(), std::move(listener_remote)); @@ -273,10 +294,7 @@ void SocketCreateFunction::Work() { Socket* socket = nullptr; if (socket_type_ == kSocketTypeTCP) { - // TODO(crbug.com/1191472): |browser_context_| is unsafe to access when - // DestroyProfileOnBrowserClose is enabled, since it could've been deleted - // by now. Fix this by creating the TCPSocket on the UI thread instead. - socket = new TCPSocket(browser_context_, extension_->id()); + socket = new TCPSocket(browser_context(), extension_->id()); } else if (socket_type_ == kSocketTypeUDP) { socket = new UDPSocket(std::move(socket_), std::move(socket_listener_receiver_), @@ -1121,7 +1139,7 @@ // Override the regular implementation, which would call AsyncWorkCompleted // immediately after Work(). void SocketSecureFunction::AsyncWorkStart() { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); Socket* socket = GetSocket(params_->socket_id); if (!socket) {
diff --git a/extensions/browser/api/socket/socket_api.h b/extensions/browser/api/socket/socket_api.h index 4af9e81..60d0d3b 100644 --- a/extensions/browser/api/socket/socket_api.h +++ b/extensions/browser/api/socket/socket_api.h
@@ -113,16 +113,38 @@ ApiResourceManager<T>* manager_; }; -class SocketAsyncApiFunction : public AsyncApiFunction { +// TODO(crbug.com/1200440): Stop using an AsyncApiFunction-like API to avoid +// confusion. Use plain ExtensionFunction::Run() and re-write each function so +// they don't split Prepare/Work/AsyncWorkStart. +class SocketAsyncApiFunction : public ExtensionFunction { public: SocketAsyncApiFunction(); protected: ~SocketAsyncApiFunction() override; - // AsyncApiFunction: - bool PrePrepare() override; - bool Respond() override; + // ExtensionFunction: + ResponseAction Run() override; + + // These 3 override-able function are run in sequence. Return false to abort + // with an error. + virtual bool PrePrepare(); + virtual bool Prepare(); + virtual void AsyncWorkStart(); + + // The default AsyncWorkStart() calls Work() followed by AsyncWorkCompleted(). + virtual void Work(); + + // Notify that the ExtensionFunction is done running. Subclasses only need to + // call this if they override AsyncWorkStart(). + void AsyncWorkCompleted(); + + // Sets a single Value as the results of the function. + void SetResult(std::unique_ptr<base::Value> result); + + // ValidationFailure override to match RunAsync(). This lets us use the + // EXTENSION_FUNCTION_VALIDATE() macro. + static bool ValidationFailure(SocketAsyncApiFunction* function); virtual std::unique_ptr<SocketResourceManagerInterface> CreateSocketResourceManager(); @@ -138,16 +160,11 @@ int socket_id, Socket* socket); + std::string error_; + std::unique_ptr<base::ListValue> results_; + private: -#if BUILDFLAG(IS_CHROMEOS_ASH) - void OpenFirewallHoleOnUIThread(AppFirewallHole::PortType type, - uint16_t port, - int socket_id); - void OnFirewallHoleOpened( - int socket_id, - std::unique_ptr<AppFirewallHole, content::BrowserThread::DeleteOnUIThread> - hole); -#endif // IS_CHROMEOS_ASH + ResponseValue GetResponseValue(); std::unique_ptr<SocketResourceManagerInterface> manager_; }; @@ -206,8 +223,6 @@ std::unique_ptr<api::socket::Create::Params> params_; SocketType socket_type_; - - content::BrowserContext* browser_context_ = nullptr; }; class SocketDestroyFunction : public SocketAsyncApiFunction {
diff --git a/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc b/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc index 64fdb9f7..498fc22 100644 --- a/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc +++ b/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc
@@ -124,17 +124,13 @@ bool SocketsTcpCreateFunction::Prepare() { params_ = sockets_tcp::Create::Params::Create(*args_); - browser_context_ = browser_context(); EXTENSION_FUNCTION_VALIDATE(params_.get()); return true; } void SocketsTcpCreateFunction::Work() { - // TODO(crbug.com/1191472): |browser_context_| is unsafe to access when - // DestroyProfileOnBrowserClose is enabled, since it could've been deleted by - // now. Fix this by creating the TCPSocket on the UI thread instead. ResumableTCPSocket* socket = - new ResumableTCPSocket(browser_context_, extension_->id()); + new ResumableTCPSocket(browser_context(), extension_->id()); sockets_tcp::SocketProperties* properties = params_->properties.get(); if (properties) { @@ -502,7 +498,7 @@ // Override the regular implementation, which would call AsyncWorkCompleted // immediately after Work(). void SocketsTcpSecureFunction::AsyncWorkStart() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id); if (!socket) {
diff --git a/extensions/browser/api/sockets_tcp/sockets_tcp_api.h b/extensions/browser/api/sockets_tcp/sockets_tcp_api.h index a1cfaa6c..cec877f 100644 --- a/extensions/browser/api/sockets_tcp/sockets_tcp_api.h +++ b/extensions/browser/api/sockets_tcp/sockets_tcp_api.h
@@ -62,8 +62,6 @@ private: FRIEND_TEST_ALL_PREFIXES(SocketsTcpUnitTest, Create); std::unique_ptr<sockets_tcp::Create::Params> params_; - - content::BrowserContext* browser_context_ = nullptr; }; class SocketsTcpUpdateFunction : public TCPSocketAsyncApiFunction {
diff --git a/extensions/browser/api/sockets_tcp/sockets_tcp_api_unittest.cc b/extensions/browser/api/sockets_tcp/sockets_tcp_api_unittest.cc index 4d861ee0..df57170 100644 --- a/extensions/browser/api/sockets_tcp/sockets_tcp_api_unittest.cc +++ b/extensions/browser/api/sockets_tcp/sockets_tcp_api_unittest.cc
@@ -39,7 +39,6 @@ TEST_F(SocketsTcpUnitTest, Create) { // Create SocketCreateFunction and put it on BrowserThread SocketsTcpCreateFunction* function = new SocketsTcpCreateFunction(); - function->set_work_task_runner(base::SequencedTaskRunnerHandle::Get()); // Run tests std::unique_ptr<base::DictionaryValue> result(RunFunctionAndReturnDictionary(
diff --git a/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc b/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc index d4c1b05..953e35ee 100644 --- a/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc +++ b/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc
@@ -84,17 +84,13 @@ bool SocketsTcpServerCreateFunction::Prepare() { params_ = sockets_tcp_server::Create::Params::Create(*args_); - browser_context_ = browser_context(); EXTENSION_FUNCTION_VALIDATE(params_.get()); return true; } void SocketsTcpServerCreateFunction::Work() { - // TODO(crbug.com/1191472): |browser_context_| is unsafe to access when - // DestroyProfileOnBrowserClose is enabled, since it could've been deleted by - // now. Fix this by creating the TCPSocket on the UI thread instead. auto* socket = - new ResumableTCPServerSocket(browser_context_, extension_->id()); + new ResumableTCPServerSocket(browser_context(), extension_->id()); sockets_tcp_server::SocketProperties* properties = params_->properties.get(); if (properties) {
diff --git a/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.h b/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.h index 1bab117..96ed487 100644 --- a/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.h +++ b/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.h
@@ -46,8 +46,6 @@ private: FRIEND_TEST_ALL_PREFIXES(SocketsTcpServerUnitTest, Create); std::unique_ptr<sockets_tcp_server::Create::Params> params_; - - content::BrowserContext* browser_context_ = nullptr; }; class SocketsTcpServerUpdateFunction : public TCPServerSocketAsyncApiFunction {
diff --git a/extensions/browser/api/sockets_udp/sockets_udp_api_unittest.cc b/extensions/browser/api/sockets_udp/sockets_udp_api_unittest.cc index 2f2cac7..ce6d8c6 100644 --- a/extensions/browser/api/sockets_udp/sockets_udp_api_unittest.cc +++ b/extensions/browser/api/sockets_udp/sockets_udp_api_unittest.cc
@@ -38,7 +38,6 @@ TEST_F(SocketsUdpUnitTest, Create) { // Create SocketCreateFunction and put it on BrowserThread SocketsUdpCreateFunction* function = new SocketsUdpCreateFunction(); - function->set_work_task_runner(base::SequencedTaskRunnerHandle::Get()); // Run tests std::unique_ptr<base::DictionaryValue> result(RunFunctionAndReturnDictionary(
diff --git a/extensions/browser/user_script_manager.cc b/extensions/browser/user_script_manager.cc index cb3c05b..e415c03d 100644 --- a/extensions/browser/user_script_manager.cc +++ b/extensions/browser/user_script_manager.cc
@@ -4,7 +4,9 @@ #include "extensions/browser/user_script_manager.h" +#include "base/containers/contains.h" #include "content/public/browser/browser_context.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_util.h" #include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/user_script_loader.h" @@ -33,10 +35,15 @@ ExtensionUserScriptLoader* UserScriptManager::GetUserScriptLoaderForExtension( const ExtensionId& extension_id) { - auto it = extension_script_loaders_.find(extension_id); - DCHECK(it != extension_script_loaders_.end()); + const Extension* extension = ExtensionRegistry::Get(browser_context_) + ->enabled_extensions() + .GetByID(extension_id); + DCHECK(extension); - return it->second.get(); + auto it = extension_script_loaders_.find(extension->id()); + return (it == extension_script_loaders_.end()) + ? CreateExtensionUserScriptLoader(extension) + : it->second.get(); } WebUIUserScriptLoader* UserScriptManager::GetUserScriptLoaderForWebUI( @@ -50,12 +57,7 @@ content::BrowserContext* browser_context, const Extension* extension) { ExtensionUserScriptLoader* loader = - extension_script_loaders_ - .emplace(extension->id(), - std::make_unique<ExtensionUserScriptLoader>( - browser_context_, *extension, - true /* listen_for_extension_system_loaded */)) - .first->second.get(); + GetUserScriptLoaderForExtension(extension->id()); std::unique_ptr<UserScriptList> scripts = GetManifestScriptsMetadata(extension); @@ -114,8 +116,24 @@ return script_vector; } +ExtensionUserScriptLoader* UserScriptManager::CreateExtensionUserScriptLoader( + const Extension* extension) { + DCHECK(!base::Contains(extension_script_loaders_, extension->id())); + // Inserts a new ExtensionUserScriptLoader and returns a ptr to it. + ExtensionUserScriptLoader* loader = + extension_script_loaders_ + .emplace(extension->id(), + std::make_unique<ExtensionUserScriptLoader>( + browser_context_, *extension, + true /* listen_for_extension_system_loaded */)) + .first->second.get(); + + return loader; +} + WebUIUserScriptLoader* UserScriptManager::CreateWebUIUserScriptLoader( const GURL& url) { + DCHECK(!base::Contains(webui_script_loaders_, url)); // Inserts a new WebUIUserScriptLoader and returns a ptr to it. WebUIUserScriptLoader* loader = webui_script_loaders_
diff --git a/extensions/browser/user_script_manager.h b/extensions/browser/user_script_manager.h index a28d077..f873763 100644 --- a/extensions/browser/user_script_manager.h +++ b/extensions/browser/user_script_manager.h
@@ -66,6 +66,10 @@ std::unique_ptr<UserScriptList> GetManifestScriptsMetadata( const Extension* extension); + // Creates a ExtensionUserScriptLoader object. + ExtensionUserScriptLoader* CreateExtensionUserScriptLoader( + const Extension* extension); + // Creates a WebUIUserScriptLoader object. WebUIUserScriptLoader* CreateWebUIUserScriptLoader(const GURL& url);
diff --git a/extensions/common/extension_features.cc b/extensions/common/extension_features.cc index 42b4360..425d9f5 100644 --- a/extensions/common/extension_features.cc +++ b/extensions/common/extension_features.cc
@@ -83,4 +83,9 @@ const base::Feature kReportKeepaliveUkm{"ReportKeepaliveUkm", base::FEATURE_ENABLED_BY_DEFAULT}; +// Controls whether every extension will require a locked process, preventing +// process sharing between extensions. See https://crbug.com/1209417. +const base::Feature kStrictExtensionIsolation{ + "StrictExtensionIsolation", base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace extensions_features
diff --git a/extensions/common/extension_features.h b/extensions/common/extension_features.h index 3d4c1ea..a51676c 100644 --- a/extensions/common/extension_features.h +++ b/extensions/common/extension_features.h
@@ -35,6 +35,8 @@ extern const base::Feature kReportKeepaliveUkm; +extern const base::Feature kStrictExtensionIsolation; + } // namespace extensions_features #endif // EXTENSIONS_COMMON_EXTENSION_FEATURES_H_
diff --git a/infra/config/generated/commit-queue.cfg b/infra/config/generated/commit-queue.cfg index 07c6a99..86060518f 100644 --- a/infra/config/generated/commit-queue.cfg +++ b/infra/config/generated/commit-queue.cfg
@@ -666,6 +666,10 @@ includable_only: true } builders { + name: "chromium/try/fuchsia-fyi-arm64-femu" + includable_only: true + } + builders { name: "chromium/try/fuchsia-fyi-arm64-rel" includable_only: true }
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index 806c2c7..70b4caf 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -24484,6 +24484,72 @@ } } builders { + name: "fuchsia-fyi-arm64-femu" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.ci" + dimensions: "ssd:0" + recipe { + name: "chromium" + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/master" + properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true}" + properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" + properties_j: "$recipe_engine/isolated:{\"server\":\"https://isolateserver.appspot.com\"}" + properties_j: "$recipe_engine/resultdb/test_presentation:{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]}" + properties_j: "builder_group:\"chromium.fyi\"" + } + execution_timeout_secs: 36000 + build_numbers: YES + service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + experiments { + key: "chromium.resultdb.result_sink" + value: 100 + } + experiments { + key: "chromium.resultdb.result_sink.gtests_local" + value: 100 + } + experiments { + key: "chromium.resultdb.result_sink.junit_tests" + value: 100 + } + experiments { + key: "luci.buildbucket.use_bbagent" + value: 20 + } + experiments { + key: "luci.use_realms" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "ci_test_results" + test_results {} + } + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "gpu_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "fuchsia-fyi-arm64-rel" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -43191,6 +43257,75 @@ } } builders { + name: "fuchsia-fyi-arm64-femu" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:0" + recipe { + name: "chromium_trybot" + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/master" + properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true}" + properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" + properties_j: "$recipe_engine/isolated:{\"server\":\"https://isolateserver.appspot.com\"}" + properties_j: "$recipe_engine/resultdb/test_presentation:{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]}" + properties_j: "builder_group:\"tryserver.chromium.linux\"" + } + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + caches { + name: "win_toolchain" + path: "win_toolchain" + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "chromium.resultdb.result_sink" + value: 100 + } + experiments { + key: "chromium.resultdb.result_sink.junit_tests" + value: 100 + } + experiments { + key: "luci.use_realms" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "fuchsia-fyi-arm64-rel" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper"
diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg index c8cfc402..5bec738 100644 --- a/infra/config/generated/luci-milo.cfg +++ b/infra/config/generated/luci-milo.cfg
@@ -6118,6 +6118,11 @@ short_name: "dbg" } builders { + name: "buildbucket/luci.chromium.ci/fuchsia-fyi-arm64-femu" + category: "fuchsia|a64" + short_name: "femu" + } + builders { name: "buildbucket/luci.chromium.ci/fuchsia-fyi-arm64-rel" category: "fuchsia|a64" short_name: "rel" @@ -13444,6 +13449,9 @@ name: "buildbucket/luci.chromium.try/fuchsia-fyi-arm64-dbg" } builders { + name: "buildbucket/luci.chromium.try/fuchsia-fyi-arm64-femu" + } + builders { name: "buildbucket/luci.chromium.try/fuchsia-fyi-arm64-rel" } builders { @@ -14646,6 +14654,9 @@ name: "buildbucket/luci.chromium.try/fuchsia-fyi-arm64-dbg" } builders { + name: "buildbucket/luci.chromium.try/fuchsia-fyi-arm64-femu" + } + builders { name: "buildbucket/luci.chromium.try/fuchsia-fyi-arm64-rel" } builders {
diff --git a/infra/config/generated/luci-notify.cfg b/infra/config/generated/luci-notify.cfg index 03fde7ae..f0f5c083 100644 --- a/infra/config/generated/luci-notify.cfg +++ b/infra/config/generated/luci-notify.cfg
@@ -2732,6 +2732,20 @@ } builders { bucket: "ci" + name: "fuchsia-fyi-arm64-femu" + repository: "https://chromium.googlesource.com/chromium/src" + } +} +notifiers { + notifications { + on_change: true + email { + recipients: "cr-fuchsia+bot@chromium.org" + recipients: "chrome-fuchsia-gardener@grotations.appspotmail.com" + } + } + builders { + bucket: "ci" name: "fuchsia-fyi-arm64-rel" repository: "https://chromium.googlesource.com/chromium/src" }
diff --git a/infra/config/generated/luci-scheduler.cfg b/infra/config/generated/luci-scheduler.cfg index 65e9c8aa..a5ac84e 100644 --- a/infra/config/generated/luci-scheduler.cfg +++ b/infra/config/generated/luci-scheduler.cfg
@@ -5050,6 +5050,16 @@ } } job { + id: "fuchsia-fyi-arm64-femu" + realm: "ci" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "fuchsia-fyi-arm64-femu" + } +} +job { id: "fuchsia-fyi-arm64-rel" realm: "ci" acl_sets: "ci" @@ -7102,6 +7112,7 @@ triggers: "fuchsia-angle-builder" triggers: "fuchsia-arm64-cast" triggers: "fuchsia-fyi-arm64-dbg" + triggers: "fuchsia-fyi-arm64-femu" triggers: "fuchsia-fyi-arm64-rel" triggers: "fuchsia-fyi-x64-dbg" triggers: "fuchsia-fyi-x64-rel"
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star index 0e134ed0..8f29d1d 100644 --- a/infra/config/subprojects/chromium/ci.star +++ b/infra/config/subprojects/chromium/ci.star
@@ -3107,6 +3107,18 @@ ) ci.fyi_builder( + name = "fuchsia-fyi-arm64-femu", + console_view_entry = [ + consoles.console_view_entry( + category = "fuchsia|a64", + short_name = "femu", + ), + ], + notifies = ["cr-fuchsia"], + os = os.LINUX_BIONIC_REMOVE, +) + +ci.fyi_builder( name = "fuchsia-fyi-arm64-rel", console_view_entry = [ consoles.console_view_entry(
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star index 79ff4860..18ac6c9da 100644 --- a/infra/config/subprojects/chromium/try.star +++ b/infra/config/subprojects/chromium/try.star
@@ -1099,6 +1099,10 @@ ) try_.chromium_linux_builder( + name = "fuchsia-fyi-arm64-femu", +) + +try_.chromium_linux_builder( name = "fuchsia-fyi-arm64-rel", )
diff --git a/ios/chrome/browser/DEPS b/ios/chrome/browser/DEPS index 2b900979..7b7a431 100644 --- a/ios/chrome/browser/DEPS +++ b/ios/chrome/browser/DEPS
@@ -25,7 +25,8 @@ "+components/favicon/ios", "+components/favicon_base", "+components/feature_engagement", - "+components/feed", + "+components/feed/core/v2/public", + "+components/feed/feed_feature_list.h", "+components/flags_ui", "+components/gcm_driver", "+components/google/core", @@ -53,7 +54,6 @@ "+components/network_session_configurator", "+components/network_time", "+components/ntp_snippets", - "+components/feed/core/shared_prefs", "+components/ntp_tiles", "+components/omnibox/browser", "+components/omnibox/common",
diff --git a/ios/chrome/browser/infobars/OWNERS b/ios/chrome/browser/infobars/OWNERS index 23b84a8..db73a55 100644 --- a/ios/chrome/browser/infobars/OWNERS +++ b/ios/chrome/browser/infobars/OWNERS
@@ -1,2 +1,3 @@ +thegreenfrog@chromium.org rohitrao@chromium.org sczs@chromium.org
diff --git a/ios/chrome/browser/infobars/infobar_metrics_recorder.mm b/ios/chrome/browser/infobars/infobar_metrics_recorder.mm index 35853312..37e4d31 100644 --- a/ios/chrome/browser/infobars/infobar_metrics_recorder.mm +++ b/ios/chrome/browser/infobars/infobar_metrics_recorder.mm
@@ -123,6 +123,8 @@ UMA_HISTOGRAM_ENUMERATION(kInfobarTranslateBannerEventHistogram, event); break; case InfobarType::kInfobarTypeSaveAutofillAddressProfile: + // TODO(crbug.com/1195978): Add metrics. + case InfobarType::kInfobarTypeAddToReadingList: // TODO(crbug.com/1167062): Add metrics. break; } @@ -151,6 +153,7 @@ dismissType); break; case InfobarType::kInfobarTypeSaveAutofillAddressProfile: + case InfobarType::kInfobarTypeAddToReadingList: // TODO(crbug.com/1167062): Add metrics. break; } @@ -180,6 +183,7 @@ UMA_HISTOGRAM_ENUMERATION(kInfobarTranslateModalEventHistogram, event); break; case InfobarType::kInfobarTypeSaveAutofillAddressProfile: + case InfobarType::kInfobarTypeAddToReadingList: // TODO(crbug.com/1167062): Add metrics. break; } @@ -205,6 +209,7 @@ UMA_HISTOGRAM_ENUMERATION(kInfobarTranslateBadgeTappedHistogram, state); break; case InfobarType::kInfobarTypeSaveAutofillAddressProfile: + case InfobarType::kInfobarTypeAddToReadingList: // TODO(crbug.com/1167062): Add metrics. break; }
diff --git a/ios/chrome/browser/infobars/infobar_type.h b/ios/chrome/browser/infobars/infobar_type.h index 98ade2c..9352e05 100644 --- a/ios/chrome/browser/infobars/infobar_type.h +++ b/ios/chrome/browser/infobars/infobar_type.h
@@ -20,6 +20,8 @@ kInfobarTypeTranslate = 4, // Message Infobar for Saving an address profile. kInfobarTypeSaveAutofillAddressProfile = 5, + // Message Infobar for Adding to Reading List. + kInfobarTypeAddToReadingList = 6, }; // Message "Confirm Infobars" types, these are the generic kInfobarTypeConfirm
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn b/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn index 9fe9e111..ed15cdd 100644 --- a/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn +++ b/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn
@@ -4,6 +4,8 @@ source_set("infobar_banner") { sources = [ + "add_to_reading_list_infobar_banner_overlay_request_config.h", + "add_to_reading_list_infobar_banner_overlay_request_config.mm", "confirm_infobar_banner_overlay_request_config.h", "confirm_infobar_banner_overlay_request_config.mm", "infobar_banner_overlay_responses.cc", @@ -38,6 +40,7 @@ "//ios/chrome/browser/passwords:infobar_delegates", "//ios/chrome/browser/ui/authentication", "//ios/chrome/browser/ui/infobars:infobars_ui", + "//ios/chrome/browser/ui/reading_list:infobar", "//ui/base", ] }
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/add_to_reading_list_infobar_banner_overlay_request_config.h b/ios/chrome/browser/overlays/public/infobar_banner/add_to_reading_list_infobar_banner_overlay_request_config.h new file mode 100644 index 0000000..3682e39 --- /dev/null +++ b/ios/chrome/browser/overlays/public/infobar_banner/add_to_reading_list_infobar_banner_overlay_request_config.h
@@ -0,0 +1,50 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_ADD_TO_READING_LIST_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ +#define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_ADD_TO_READING_LIST_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ + +#include "ios/chrome/browser/overlays/public/overlay_request_config.h" +#include "ios/chrome/browser/overlays/public/overlay_user_data.h" + +namespace infobars { +class InfoBar; +} + +namespace reading_list_infobar_overlay { + +// Configuration object for OverlayRequests for the banner UI for an Infobar +// with a IOSAddToReadingListInfobarDelegate. +class ReadingListBannerRequestConfig + : public OverlayRequestConfig<ReadingListBannerRequestConfig> { + public: + ~ReadingListBannerRequestConfig() override; + + // The title text. + NSString* title_text() const { return title_text_; } + + // The message text. + NSString* message_text() const { return message_text_; } + + // The button text. + NSString* button_text() const { return button_text_; } + + private: + OVERLAY_USER_DATA_SETUP(ReadingListBannerRequestConfig); + explicit ReadingListBannerRequestConfig(infobars::InfoBar* infobar); + + // OverlayUserData: + void CreateAuxiliaryData(base::SupportsUserData* user_data) override; + + NSString* title_text_; + NSString* message_text_; + NSString* button_text_; + + // The InfoBar causing this banner. + infobars::InfoBar* infobar_ = nullptr; +}; + +} // namespace reading_list_infobar_overlay + +#endif // IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_ADD_TO_READING_LIST_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/add_to_reading_list_infobar_banner_overlay_request_config.mm b/ios/chrome/browser/overlays/public/infobar_banner/add_to_reading_list_infobar_banner_overlay_request_config.mm new file mode 100644 index 0000000..36bdaf73 --- /dev/null +++ b/ios/chrome/browser/overlays/public/infobar_banner/add_to_reading_list_infobar_banner_overlay_request_config.mm
@@ -0,0 +1,45 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/overlays/public/infobar_banner/add_to_reading_list_infobar_banner_overlay_request_config.h" + +#include "components/infobars/core/infobar.h" +#include "ios/chrome/browser/infobars/infobar_ios.h" +#import "ios/chrome/browser/infobars/overlays/infobar_overlay_type.h" +#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h" +#import "ios/chrome/browser/ui/reading_list/ios_add_to_reading_list_infobar_delegate.h" +#include "url/gurl.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +using infobars::InfoBar; + +namespace reading_list_infobar_overlay { + +OVERLAY_USER_DATA_SETUP_IMPL(ReadingListBannerRequestConfig); + +ReadingListBannerRequestConfig::ReadingListBannerRequestConfig(InfoBar* infobar) + : infobar_(infobar) { + DCHECK(infobar_); + IOSAddToReadingListInfobarDelegate* delegate = + static_cast<IOSAddToReadingListInfobarDelegate*>(infobar_->delegate()); + int time_to_read = delegate->time_to_read(); + // TODO(crbug.com/1195978): Use localized strings. + message_text_ = [NSString stringWithFormat:@"%i minute read", time_to_read]; + title_text_ = [NSString stringWithFormat:@"Add to Reading List for Later?"]; + button_text_ = @"Add"; +} + +ReadingListBannerRequestConfig::~ReadingListBannerRequestConfig() = default; + +void ReadingListBannerRequestConfig::CreateAuxiliaryData( + base::SupportsUserData* user_data) { + InfobarOverlayRequestConfig::CreateForUserData( + user_data, static_cast<InfoBarIOS*>(infobar_), + InfobarOverlayType::kBanner, false); +} + +} // namespace reading_list_infobar_overlay
diff --git a/ios/chrome/browser/prefs/BUILD.gn b/ios/chrome/browser/prefs/BUILD.gn index ccd71e1d..c7e17c2 100644 --- a/ios/chrome/browser/prefs/BUILD.gn +++ b/ios/chrome/browser/prefs/BUILD.gn
@@ -37,8 +37,7 @@ "//components/content_settings/core/browser", "//components/dom_distiller/core", "//components/enterprise", - "//components/feed/core/common:feed_core_common", - "//components/feed/core/shared_prefs:feed_shared_prefs", + "//components/feed/core/v2/public/ios:feed_ios_public", "//components/flags_ui", "//components/gcm_driver", "//components/handoff",
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm index f22d914..ae6e4b43 100644 --- a/ios/chrome/browser/prefs/browser_prefs.mm +++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -10,8 +10,7 @@ #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/dom_distiller/core/distilled_page_prefs.h" #include "components/enterprise/browser/reporting/common_pref_names.h" -#include "components/feed/core/common/pref_names.h" -#include "components/feed/core/shared_prefs/pref_names.h" +#include "components/feed/core/v2/public/ios/pref_names.h" #include "components/flags_ui/pref_service_flags_storage.h" #import "components/handoff/handoff_manager.h" #include "components/history/core/common/pref_names.h" @@ -177,8 +176,7 @@ void RegisterBrowserStatePrefs(user_prefs::PrefRegistrySyncable* registry) { autofill::prefs::RegisterProfilePrefs(registry); dom_distiller::DistilledPagePrefs::RegisterProfilePrefs(registry); - feed::prefs::RegisterFeedSharedProfilePrefs(registry); - feed::RegisterProfilePrefs(registry); + ios_feed::RegisterProfilePrefs(registry); FirstRun::RegisterProfilePrefs(registry); FontSizeTabHelper::RegisterBrowserStatePrefs(registry); HostContentSettingsMap::RegisterProfilePrefs(registry);
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn index d8c79c9..11e88ed 100644 --- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -40,6 +40,7 @@ "//components/favicon/ios", "//components/feature_engagement/public", "//components/feed/core/shared_prefs:feed_shared_prefs", + "//components/feed/core/v2/public/ios:feed_ios_public", "//components/ntp_snippets", "//components/ntp_tiles", "//components/pref_registry", @@ -207,7 +208,7 @@ deps = [ ":feature_flags", "//base", - "//components/feed/core/v2:common", + "//components/feed/core/v2/public:common", ] configs += [ "//build/config/compiler:enable_arc" ] } @@ -323,6 +324,7 @@ "//base", "//base/test:test_support", "//components/feed/core/shared_prefs:feed_shared_prefs", + "//components/feed/core/v2/public/ios:feed_ios_public", "//components/strings", "//ios/chrome/app/strings", "//ios/chrome/browser:pref_names",
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 7083bb1..29a3b63f 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
@@ -12,7 +12,7 @@ #include "base/strings/sys_string_conversions.h" #import "components/feature_engagement/public/event_constants.h" #import "components/feature_engagement/public/tracker.h" -#include "components/feed/core/shared_prefs/pref_names.h" +#include "components/feed/core/v2/public/ios/pref_names.h" #include "components/ntp_snippets/content_suggestions_service.h" #include "components/ntp_snippets/pref_names.h" #include "components/ntp_snippets/remote/remote_suggestions_scheduler.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/discover_feed_metrics_recorder.mm b/ios/chrome/browser/ui/content_suggestions/discover_feed_metrics_recorder.mm index bbb10925..a712cc8 100644 --- a/ios/chrome/browser/ui/content_suggestions/discover_feed_metrics_recorder.mm +++ b/ios/chrome/browser/ui/content_suggestions/discover_feed_metrics_recorder.mm
@@ -9,7 +9,7 @@ #import "base/metrics/histogram_macros.h" #import "base/metrics/user_metrics.h" #import "base/metrics/user_metrics_action.h" -#import "components/feed/core/v2/common_enums.h" +#import "components/feed/core/v2/public/common_enums.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm index 0c7457e..c583ae0 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
@@ -6,7 +6,7 @@ #include "base/ios/ios_util.h" #include "base/mac/foundation_util.h" #include "base/strings/sys_string_conversions.h" -#include "components/feed/core/shared_prefs/pref_names.h" +#include "components/feed/core/v2/public/ios/pref_names.h" #include "components/strings/grit/components_strings.h" #include "ios/chrome/browser/chrome_switches.h" #import "ios/chrome/browser/pref_names.h"
diff --git a/ios/chrome/browser/ui/ntp/BUILD.gn b/ios/chrome/browser/ui/ntp/BUILD.gn index 20b77988..8b16a2d 100644 --- a/ios/chrome/browser/ui/ntp/BUILD.gn +++ b/ios/chrome/browser/ui/ntp/BUILD.gn
@@ -37,7 +37,7 @@ ":feature_flags", ":ntp", ":ntp_internal", - "//components/feed/core/shared_prefs:feed_shared_prefs", + "//components/feed/core/v2/public/ios:feed_ios_public", "//components/pref_registry", "//components/prefs", "//components/prefs/ios",
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 48d586d..a7673f9 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -7,7 +7,7 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" -#include "components/feed/core/shared_prefs/pref_names.h" +#include "components/feed/core/v2/public/ios/pref_names.h" #import "components/pref_registry/pref_registry_syncable.h" #import "components/prefs/ios/pref_observer_bridge.h" #import "components/prefs/pref_change_registrar.h"
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm b/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm index 38b27ee..083a762 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm
@@ -738,9 +738,7 @@ // Returns the popup row containing the |url| as suggestion. id<GREYMatcher> textYouCopiedMatch = grey_allOf(grey_kindOfClassName(@"OmniboxPopupRowCell"), - grey_descendant(grey_accessibilityLabel( - [NSString stringWithFormat:@"\"%@\"", copiedText])), - nil); + grey_descendant(grey_accessibilityLabel(copiedText)), nil); [[EarlGrey selectElementWithMatcher:textYouCopiedMatch] assertWithMatcher:grey_notNil()]; }
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn b/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn index f03ffccd..12bba23 100644 --- a/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn +++ b/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn
@@ -35,6 +35,7 @@ "//ios/chrome/browser/ui/overlays/infobar_banner/autofill_address_profile", "//ios/chrome/browser/ui/overlays/infobar_banner/confirm", "//ios/chrome/browser/ui/overlays/infobar_banner/passwords", + "//ios/chrome/browser/ui/overlays/infobar_banner/reading_list", "//ios/chrome/browser/ui/overlays/infobar_banner/save_card", "//ios/chrome/browser/ui/overlays/infobar_banner/translate:mediators", "//ios/chrome/browser/ui/util",
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm index 2732a3d..ae964bd8 100644 --- a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm +++ b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm
@@ -21,6 +21,7 @@ #import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h" #import "ios/chrome/browser/ui/overlays/infobar_banner/passwords/save_password_infobar_banner_overlay_mediator.h" #import "ios/chrome/browser/ui/overlays/infobar_banner/passwords/update_password_infobar_banner_overlay_mediator.h" +#import "ios/chrome/browser/ui/overlays/infobar_banner/reading_list/reading_list_infobar_banner_overlay_mediator.h" #import "ios/chrome/browser/ui/overlays/infobar_banner/save_card/save_card_infobar_banner_overlay_mediator.h" #import "ios/chrome/browser/ui/overlays/infobar_banner/translate/translate_infobar_banner_overlay_mediator.h" #import "ios/chrome/browser/ui/overlays/overlay_request_coordinator+subclassing.h" @@ -54,6 +55,7 @@ [TranslateInfobarBannerOverlayMediator class], [SaveCardInfobarBannerOverlayMediator class], [SaveAddressProfileInfobarBannerOverlayMediator class], + [AddToReadingListInfobarBannerOverlayMediator class], ]; }
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/reading_list/BUILD.gn b/ios/chrome/browser/ui/overlays/infobar_banner/reading_list/BUILD.gn new file mode 100644 index 0000000..ab13a22 --- /dev/null +++ b/ios/chrome/browser/ui/overlays/infobar_banner/reading_list/BUILD.gn
@@ -0,0 +1,20 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("reading_list") { + sources = [ + "reading_list_infobar_banner_overlay_mediator.h", + "reading_list_infobar_banner_overlay_mediator.mm", + ] + + configs += [ "//build/config/compiler:enable_arc" ] + + deps = [ + "//ios/chrome/browser/overlays", + "//ios/chrome/browser/overlays/public/infobar_banner", + "//ios/chrome/browser/ui/infobars/banners", + "//ios/chrome/browser/ui/overlays:coordinators", + "//ios/chrome/browser/ui/overlays/infobar_banner:mediators", + ] +}
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/reading_list/reading_list_infobar_banner_overlay_mediator.h b/ios/chrome/browser/ui/overlays/infobar_banner/reading_list/reading_list_infobar_banner_overlay_mediator.h new file mode 100644 index 0000000..c7ef25bd --- /dev/null +++ b/ios/chrome/browser/ui/overlays/infobar_banner/reading_list/reading_list_infobar_banner_overlay_mediator.h
@@ -0,0 +1,15 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_READING_LIST_READING_LIST_INFOBAR_BANNER_OVERLAY_MEDIATOR_H_ +#define IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_READING_LIST_READING_LIST_INFOBAR_BANNER_OVERLAY_MEDIATOR_H_ + +#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h" + +// Mediator that configures an infobar banner for a add to reading list infobar. +@interface AddToReadingListInfobarBannerOverlayMediator + : InfobarBannerOverlayMediator +@end + +#endif // IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_READING_LIST_READING_LIST_INFOBAR_BANNER_OVERLAY_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/reading_list/reading_list_infobar_banner_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/infobar_banner/reading_list/reading_list_infobar_banner_overlay_mediator.mm new file mode 100644 index 0000000..e25a911 --- /dev/null +++ b/ios/chrome/browser/ui/overlays/infobar_banner/reading_list/reading_list_infobar_banner_overlay_mediator.mm
@@ -0,0 +1,53 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/overlays/infobar_banner/reading_list/reading_list_infobar_banner_overlay_mediator.h" + +#import "ios/chrome/browser/overlays/public/infobar_banner/add_to_reading_list_infobar_banner_overlay_request_config.h" +#import "ios/chrome/browser/ui/infobars/banners/infobar_banner_consumer.h" +#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator+consumer_support.h" +#import "ios/chrome/browser/ui/overlays/overlay_request_mediator+subclassing.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +using reading_list_infobar_overlay::ReadingListBannerRequestConfig; + +@interface AddToReadingListInfobarBannerOverlayMediator () +// The add to reading list banner config from the request. +@property(nonatomic, readonly) ReadingListBannerRequestConfig* config; +@end + +@implementation AddToReadingListInfobarBannerOverlayMediator + +#pragma mark - Accessors + +- (ReadingListBannerRequestConfig*)config { + return self.request + ? self.request->GetConfig<ReadingListBannerRequestConfig>() + : nullptr; +} + +#pragma mark - OverlayRequestMediator + ++ (const OverlayRequestSupport*)requestSupport { + return ReadingListBannerRequestConfig::RequestSupport(); +} + +@end + +@implementation AddToReadingListInfobarBannerOverlayMediator (ConsumerSupport) + +- (void)configureConsumer { + ReadingListBannerRequestConfig* config = self.config; + if (!self.consumer || !config) + return; + + [self.consumer setTitleText:config->title_text()]; + [self.consumer setSubtitleText:config->message_text()]; + [self.consumer setButtonText:config->button_text()]; +} + +@end
diff --git a/media/audio/audio_debug_recording_manager.h b/media/audio/audio_debug_recording_manager.h index 19af6454..cef0a5e 100644 --- a/media/audio/audio_debug_recording_manager.h +++ b/media/audio/audio_debug_recording_manager.h
@@ -7,7 +7,6 @@ #include <map> #include <memory> -#include <string> #include <utility> #include "base/callback.h"
diff --git a/media/audio/audio_output_delegate.h b/media/audio/audio_output_delegate.h index ab14a28c..7cb5e00 100644 --- a/media/audio/audio_output_delegate.h +++ b/media/audio/audio_output_delegate.h
@@ -6,7 +6,6 @@ #define MEDIA_AUDIO_AUDIO_OUTPUT_DELEGATE_H_ #include <memory> -#include <string> #include "base/macros.h" #include "base/memory/ref_counted.h"
diff --git a/media/base/android/android_util.h b/media/base/android/android_util.h index 39026177..b70b6495 100644 --- a/media/base/android/android_util.h +++ b/media/base/android/android_util.h
@@ -6,7 +6,6 @@ #define MEDIA_BASE_ANDROID_ANDROID_UTIL_H_ #include <memory> -#include <string> #include "base/android/scoped_java_ref.h"
diff --git a/media/base/audio_renderer_mixer.h b/media/base/audio_renderer_mixer.h index 3891986..f8293130 100644 --- a/media/base/audio_renderer_mixer.h +++ b/media/base/audio_renderer_mixer.h
@@ -9,7 +9,6 @@ #include <map> #include <memory> -#include <string> #include "base/containers/flat_map.h" #include "base/containers/flat_set.h"
diff --git a/media/base/media_client.h b/media/base/media_client.h index db1d309..8931490 100644 --- a/media/base/media_client.h +++ b/media/base/media_client.h
@@ -6,7 +6,6 @@ #define MEDIA_BASE_MEDIA_CLIENT_H_ #include <memory> -#include <string> #include <vector> #include "media/base/audio_codecs.h"
diff --git a/media/base/media_tracks.h b/media/base/media_tracks.h index 900c3b1..36fbd2b 100644 --- a/media/base/media_tracks.h +++ b/media/base/media_tracks.h
@@ -7,7 +7,6 @@ #include <map> #include <memory> -#include <string> #include <vector> #include "base/macros.h"
diff --git a/media/base/scoped_async_trace.h b/media/base/scoped_async_trace.h index b82df2e..e448689 100644 --- a/media/base/scoped_async_trace.h +++ b/media/base/scoped_async_trace.h
@@ -6,7 +6,6 @@ #define MEDIA_BASE_SCOPED_ASYNC_TRACE_H_ #include <memory> -#include <string> #include "base/macros.h" #include "media/base/media_export.h"
diff --git a/media/base/stream_parser.h b/media/base/stream_parser.h index 43d788e..a7de9bc 100644 --- a/media/base/stream_parser.h +++ b/media/base/stream_parser.h
@@ -10,7 +10,6 @@ #include <map> #include <memory> -#include <string> #include <vector> #include "base/callback_forward.h"
diff --git a/media/base/video_frame_layout.h b/media/base/video_frame_layout.h index 73b106e..b1f40ea 100644 --- a/media/base/video_frame_layout.h +++ b/media/base/video_frame_layout.h
@@ -9,7 +9,6 @@ #include <stdint.h> #include <ostream> -#include <string> #include <utility> #include <vector>
diff --git a/media/blink/learning_experiment_helper.h b/media/blink/learning_experiment_helper.h index 907bacf..4b0e14f 100644 --- a/media/blink/learning_experiment_helper.h +++ b/media/blink/learning_experiment_helper.h
@@ -6,7 +6,6 @@ #define MEDIA_BLINK_LEARNING_EXPERIMENT_HELPER_H_ #include <memory> -#include <string> #include "base/macros.h" #include "media/blink/media_blink_export.h"
diff --git a/media/blink/multibuffer_data_source.h b/media/blink/multibuffer_data_source.h index 37be059f..1ee69446 100644 --- a/media/blink/multibuffer_data_source.h +++ b/media/blink/multibuffer_data_source.h
@@ -8,7 +8,6 @@ #include <stdint.h> #include <memory> -#include <string> #include <vector> #include "base/callback.h"
diff --git a/media/blink/watch_time_reporter_unittest.cc b/media/blink/watch_time_reporter_unittest.cc index 7111207..2bf7871 100644 --- a/media/blink/watch_time_reporter_unittest.cc +++ b/media/blink/watch_time_reporter_unittest.cc
@@ -276,6 +276,8 @@ void SetContainerName( container_names::MediaContainerName container_name) override {} void SetRendererType(RendererType renderer_type) override {} + void SetKeySystem(const std::string& key_system) override {} + void SetIsHardwareSecure() override {} void SetHasPlayed() override {} void SetHaveEnough() override {} void SetHasAudio(AudioCodec audio_codec) override {}
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index 1427d22..09f81a8 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -1551,6 +1551,10 @@ cdm_config_ = web_cdm->GetCdmConfig(); key_system_ = web_cdm->GetKeySystem(); DCHECK(!key_system_.empty()); + + media_metrics_provider_->SetKeySystem(key_system_); + if (cdm_config_->use_hw_secure_codecs) + media_metrics_provider_->SetIsHardwareSecure(); CreateVideoDecodeStatsReporter(); CdmContext* cdm_context = cdm_context_ref->GetCdmContext();
diff --git a/media/blink/webmediasource_impl.h b/media/blink/webmediasource_impl.h index e9c4a35..94fdb6e 100644 --- a/media/blink/webmediasource_impl.h +++ b/media/blink/webmediasource_impl.h
@@ -5,7 +5,6 @@ #ifndef MEDIA_BLINK_WEBMEDIASOURCE_IMPL_H_ #define MEDIA_BLINK_WEBMEDIASOURCE_IMPL_H_ -#include <string> #include <vector> #include "base/macros.h"
diff --git a/media/capture/video/android/photo_capabilities.h b/media/capture/video/android/photo_capabilities.h index 49e7115..d2c47f1 100644 --- a/media/capture/video/android/photo_capabilities.h +++ b/media/capture/video/android/photo_capabilities.h
@@ -6,7 +6,6 @@ #define MEDIA_CAPTURE_VIDEO_ANDROID_PHOTO_CAPABILITIES_H_ #include <jni.h> -#include <string> #include <vector> #include "base/android/scoped_java_ref.h"
diff --git a/media/capture/video/fake_video_capture_device.h b/media/capture/video/fake_video_capture_device.h index 3f1c237..a393717 100644 --- a/media/capture/video/fake_video_capture_device.h +++ b/media/capture/video/fake_video_capture_device.h
@@ -8,7 +8,6 @@ #include <stdint.h> #include <memory> -#include <string> #include <vector> #include "base/threading/thread_checker.h"
diff --git a/media/capture/video/file_video_capture_device.h b/media/capture/video/file_video_capture_device.h index a08187a..7862676 100644 --- a/media/capture/video/file_video_capture_device.h +++ b/media/capture/video/file_video_capture_device.h
@@ -8,7 +8,6 @@ #include <stdint.h> #include <memory> -#include <string> #include "base/containers/queue.h" #include "base/files/file.h"
diff --git a/media/capture/video/linux/video_capture_device_linux.h b/media/capture/video/linux/video_capture_device_linux.h index 073b511..88e9263 100644 --- a/media/capture/video/linux/video_capture_device_linux.h +++ b/media/capture/video/linux/video_capture_device_linux.h
@@ -13,7 +13,6 @@ #include <stdint.h> #include <memory> -#include <string> #include <vector> #include "base/files/file_util.h"
diff --git a/media/cast/net/cast_transport_defines.h b/media/cast/net/cast_transport_defines.h index 7c11de2d..3eac16ea 100644 --- a/media/cast/net/cast_transport_defines.h +++ b/media/cast/net/cast_transport_defines.h
@@ -10,7 +10,6 @@ #include <map> #include <set> -#include <string> #include <vector> #include "base/macros.h"
diff --git a/media/filters/dav1d_video_decoder.h b/media/filters/dav1d_video_decoder.h index 938ec76..3cdc5184 100644 --- a/media/filters/dav1d_video_decoder.h +++ b/media/filters/dav1d_video_decoder.h
@@ -5,8 +5,6 @@ #ifndef MEDIA_FILTERS_DAV1D_VIDEO_DECODER_H_ #define MEDIA_FILTERS_DAV1D_VIDEO_DECODER_H_ -#include <string> - #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/ref_counted_memory.h"
diff --git a/media/filters/gav1_video_decoder.h b/media/filters/gav1_video_decoder.h index 3f815625..b9ba0eb 100644 --- a/media/filters/gav1_video_decoder.h +++ b/media/filters/gav1_video_decoder.h
@@ -7,7 +7,6 @@ #include <memory> #include <queue> -#include <string> #include <vector> #include "base/containers/queue.h"
diff --git a/media/gpu/android/codec_wrapper.h b/media/gpu/android/codec_wrapper.h index 53ec972..5a12ed3 100644 --- a/media/gpu/android/codec_wrapper.h +++ b/media/gpu/android/codec_wrapper.h
@@ -9,7 +9,6 @@ #include <stdint.h> #include <memory> -#include <string> #include <vector> #include "base/memory/ref_counted.h"
diff --git a/media/gpu/chromeos/gpu_buffer_layout.h b/media/gpu/chromeos/gpu_buffer_layout.h index 833c182..3e415a04 100644 --- a/media/gpu/chromeos/gpu_buffer_layout.h +++ b/media/gpu/chromeos/gpu_buffer_layout.h
@@ -6,7 +6,6 @@ #define MEDIA_GPU_CHROMEOS_GPU_BUFFER_LAYOUT_H_ #include <ostream> -#include <string> #include <vector> #include "media/base/color_plane_layout.h"
diff --git a/media/gpu/test/image_processor/image_processor_client.h b/media/gpu/test/image_processor/image_processor_client.h index 61b50d7..0e09b0e5 100644 --- a/media/gpu/test/image_processor/image_processor_client.h +++ b/media/gpu/test/image_processor/image_processor_client.h
@@ -6,7 +6,6 @@ #define MEDIA_GPU_TEST_IMAGE_PROCESSOR_IMAGE_PROCESSOR_CLIENT_H_ #include <memory> -#include <string> #include <vector> #include "base/atomicops.h"
diff --git a/media/gpu/test/video_player/test_vda_video_decoder.h b/media/gpu/test/video_player/test_vda_video_decoder.h index a556a52..2d0de12 100644 --- a/media/gpu/test/video_player/test_vda_video_decoder.h +++ b/media/gpu/test/video_player/test_vda_video_decoder.h
@@ -8,7 +8,6 @@ #include <stdint.h> #include <map> #include <memory> -#include <string> #include "base/containers/mru_cache.h" #include "base/macros.h"
diff --git a/media/gpu/v4l2/v4l2_mjpeg_decode_accelerator.cc b/media/gpu/v4l2/v4l2_mjpeg_decode_accelerator.cc index b129903..7e14f49 100644 --- a/media/gpu/v4l2/v4l2_mjpeg_decode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_mjpeg_decode_accelerator.cc
@@ -21,6 +21,7 @@ #include "base/memory/page_size.h" #include "base/numerics/safe_conversions.h" #include "base/threading/thread_task_runner_handle.h" +#include "media/base/bind_to_current_loop.h" #include "media/base/bitstream_buffer.h" #include "media/base/unaligned_shared_memory.h" #include "media/base/video_frame.h" @@ -313,13 +314,14 @@ weak_ptr_, task_id, error)); } -bool V4L2MjpegDecodeAccelerator::Initialize( - chromeos_camera::MjpegDecodeAccelerator::Client* client) { +void V4L2MjpegDecodeAccelerator::InitializeOnTaskRunner( + chromeos_camera::MjpegDecodeAccelerator::Client* client, + chromeos_camera::MjpegDecodeAccelerator::InitCB init_cb) { DCHECK(child_task_runner_->BelongsToCurrentThread()); - if (!device_->Open(V4L2Device::Type::kJpegDecoder, V4L2_PIX_FMT_JPEG)) { VLOGF(1) << "Failed to open device"; - return false; + std::move(init_cb).Run(false); + return; } // Capabilities check. @@ -328,12 +330,14 @@ memset(&caps, 0, sizeof(caps)); if (device_->Ioctl(VIDIOC_QUERYCAP, &caps) != 0) { VPLOGF(1) << "ioctl() failed: VIDIOC_QUERYCAP"; - return false; + std::move(init_cb).Run(false); + return; } if ((caps.capabilities & kCapsRequired) != kCapsRequired) { VLOGF(1) << "VIDIOC_QUERYCAP, caps check failed: 0x" << std::hex << caps.capabilities; - return false; + std::move(init_cb).Run(false); + return; } // Subscribe to the source change event. @@ -342,12 +346,14 @@ sub.type = V4L2_EVENT_SOURCE_CHANGE; if (device_->Ioctl(VIDIOC_SUBSCRIBE_EVENT, &sub) != 0) { VPLOGF(1) << "ioctl() failed: VIDIOC_SUBSCRIBE_EVENT"; - return false; + std::move(init_cb).Run(false); + return; } if (!decoder_thread_.Start()) { VLOGF(1) << "decoder thread failed to start"; - return false; + std::move(init_cb).Run(false); + return; } client_ = client; decoder_task_runner_ = decoder_thread_.task_runner(); @@ -357,7 +363,21 @@ base::Unretained(this))); VLOGF(2) << "V4L2MjpegDecodeAccelerator initialized."; - return true; + std::move(init_cb).Run(true); +} + +void V4L2MjpegDecodeAccelerator::InitializeAsync( + chromeos_camera::MjpegDecodeAccelerator::Client* client, + chromeos_camera::MjpegDecodeAccelerator::InitCB init_cb) { + DCHECK(child_task_runner_->BelongsToCurrentThread()); + + // To guarantee that the caller receives an asynchronous call after the + // return path, we are making use of InitializeOnTaskRunner. + child_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&V4L2MjpegDecodeAccelerator::InitializeOnTaskRunner, + weak_factory_.GetWeakPtr(), client, + BindToCurrentLoop(std::move(init_cb)))); } void V4L2MjpegDecodeAccelerator::Decode(BitstreamBuffer bitstream_buffer,
diff --git a/media/gpu/v4l2/v4l2_mjpeg_decode_accelerator.h b/media/gpu/v4l2/v4l2_mjpeg_decode_accelerator.h index 76ee0afd9..a8bf30e8 100644 --- a/media/gpu/v4l2/v4l2_mjpeg_decode_accelerator.h +++ b/media/gpu/v4l2/v4l2_mjpeg_decode_accelerator.h
@@ -42,8 +42,9 @@ ~V4L2MjpegDecodeAccelerator() override; // MjpegDecodeAccelerator implementation. - bool Initialize( - chromeos_camera::MjpegDecodeAccelerator::Client* client) override; + void InitializeAsync( + chromeos_camera::MjpegDecodeAccelerator::Client* client, + chromeos_camera::MjpegDecodeAccelerator::InitCB init_cb) override; void Decode(BitstreamBuffer bitstream_buffer, scoped_refptr<VideoFrame> video_frame) override; void Decode(int32_t task_id, @@ -75,6 +76,10 @@ void DestroyInputBuffers(); void DestroyOutputBuffers(); + void InitializeOnTaskRunner( + chromeos_camera::MjpegDecodeAccelerator::Client* client, + InitCB init_cb); + // Convert |output_buffer| to |dst_frame|. The function supports the following // formats: // - All formats that libyuv::ConvertToI420 can handle.
diff --git a/media/gpu/v4l2/v4l2_video_decoder.h b/media/gpu/v4l2/v4l2_video_decoder.h index 9d96b5b..8f28cab 100644 --- a/media/gpu/v4l2/v4l2_video_decoder.h +++ b/media/gpu/v4l2/v4l2_video_decoder.h
@@ -9,7 +9,6 @@ #include <map> #include <memory> -#include <string> #include <utility> #include <vector>
diff --git a/media/gpu/vaapi/vaapi_mjpeg_decode_accelerator.cc b/media/gpu/vaapi/vaapi_mjpeg_decode_accelerator.cc index 3b0d6580..f436784 100644 --- a/media/gpu/vaapi/vaapi_mjpeg_decode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_mjpeg_decode_accelerator.cc
@@ -25,6 +25,7 @@ #include "base/trace_event/trace_event.h" #include "gpu/ipc/common/gpu_memory_buffer_impl.h" #include "gpu/ipc/common/gpu_memory_buffer_support.h" +#include "media/base/bind_to_current_loop.h" #include "media/base/bitstream_buffer.h" #include "media/base/format_utils.h" #include "media/base/unaligned_shared_memory.h" @@ -118,25 +119,40 @@ decoder_thread_("VaapiMjpegDecoderThread"), weak_this_factory_(this) {} +// Destroy |decoder_| and |vpp_vaapi_wrapper_| on |decoder_thread_|. +void VaapiMjpegDecodeAccelerator::CleanUpOnDecoderThread() { + DCHECK(decoder_task_runner_->BelongsToCurrentThread()); + DCHECK(vpp_vaapi_wrapper_->HasOneRef()); + vpp_vaapi_wrapper_.reset(); + decoder_.reset(); +} + VaapiMjpegDecodeAccelerator::~VaapiMjpegDecodeAccelerator() { DCHECK(task_runner_->BelongsToCurrentThread()); VLOGF(2) << "Destroying VaapiMjpegDecodeAccelerator"; - weak_this_factory_.InvalidateWeakPtrs(); + + if (decoder_task_runner_) { + // base::Unretained() is fine here because we control |decoder_task_runner_| + // lifetime. + decoder_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&VaapiMjpegDecodeAccelerator::CleanUpOnDecoderThread, + base::Unretained(this))); + } decoder_thread_.Stop(); } -bool VaapiMjpegDecodeAccelerator::Initialize( - chromeos_camera::MjpegDecodeAccelerator::Client* client) { - VLOGF(2); - DCHECK(task_runner_->BelongsToCurrentThread()); +void VaapiMjpegDecodeAccelerator::InitializeOnDecoderTaskRunner( + chromeos_camera::MjpegDecodeAccelerator::InitCB init_cb) { + DCHECK(decoder_task_runner_->BelongsToCurrentThread()); - client_ = client; - - if (!decoder_.Initialize(base::BindRepeating( + decoder_ = std::make_unique<media::VaapiJpegDecoder>(); + if (!decoder_->Initialize(base::BindRepeating( &ReportVaapiErrorToUMA, "Media.VaapiMjpegDecodeAccelerator.VAAPIError"))) { - return false; + VLOGF(1) << "Failed initializing |decoder_|"; + std::move(init_cb).Run(false); } vpp_vaapi_wrapper_ = VaapiWrapper::Create( @@ -146,24 +162,53 @@ "Media.VaapiMjpegDecodeAccelerator.Vpp.VAAPIError")); if (!vpp_vaapi_wrapper_) { VLOGF(1) << "Failed initializing VAAPI for VPP"; - return false; + std::move(init_cb).Run(false); } // Size is irrelevant for a VPP context. if (!vpp_vaapi_wrapper_->CreateContext(gfx::Size())) { VLOGF(1) << "Failed to create context for VPP"; - return false; + std::move(init_cb).Run(false); } - gpu_memory_buffer_support_ = std::make_unique<gpu::GpuMemoryBufferSupport>(); + std::move(init_cb).Run(true); +} + +void VaapiMjpegDecodeAccelerator::InitializeOnTaskRunner( + chromeos_camera::MjpegDecodeAccelerator::Client* client, + chromeos_camera::MjpegDecodeAccelerator::InitCB init_cb) { + DCHECK(task_runner_->BelongsToCurrentThread()); + client_ = client; if (!decoder_thread_.Start()) { VLOGF(1) << "Failed to start decoding thread."; - return false; + std::move(init_cb).Run(false); } decoder_task_runner_ = decoder_thread_.task_runner(); + gpu_memory_buffer_support_ = std::make_unique<gpu::GpuMemoryBufferSupport>(); - return true; + // base::Unretained() is fine here because we control |decoder_task_runner_| + // lifetime. + decoder_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &VaapiMjpegDecodeAccelerator::InitializeOnDecoderTaskRunner, + base::Unretained(this), std::move(init_cb))); +} + +void VaapiMjpegDecodeAccelerator::InitializeAsync( + chromeos_camera::MjpegDecodeAccelerator::Client* client, + chromeos_camera::MjpegDecodeAccelerator::InitCB init_cb) { + VLOGF(2); + DCHECK(task_runner_->BelongsToCurrentThread()); + + // To guarantee that the caller receives an asynchronous call after the + // return path, we are making use of InitializeOnTaskRunner. + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&VaapiMjpegDecodeAccelerator::InitializeOnTaskRunner, + weak_this_factory_.GetWeakPtr(), client, + BindToCurrentLoop(std::move(init_cb)))); } bool VaapiMjpegDecodeAccelerator::OutputPictureLibYuvOnTaskRunner( @@ -182,7 +227,7 @@ DCHECK_EQ(video_frame->visible_rect().size(), video_frame->coded_size()); DCHECK_EQ(0, video_frame->visible_rect().x()); DCHECK_EQ(0, video_frame->visible_rect().y()); - DCHECK(decoder_.GetScopedVASurface()); + DCHECK(decoder_->GetScopedVASurface()); const gfx::Size visible_size(base::strict_cast<int>(image->width), base::strict_cast<int>(image->height)); if (visible_size != video_frame->visible_rect().size()) { @@ -448,12 +493,12 @@ // TODO(andrescj): validate that the video frame's visible size is the same as // the parsed JPEG's visible size when it is returned from Decode(), and // remove the size checks in OutputPicture*(). - VaapiImageDecodeStatus status = decoder_.Decode(src_image); + VaapiImageDecodeStatus status = decoder_->Decode(src_image); if (status != VaapiImageDecodeStatus::kSuccess) { NotifyError(task_id, VaapiJpegDecodeStatusToError(status)); return; } - const ScopedVASurface* surface = decoder_.GetScopedVASurface(); + const ScopedVASurface* surface = decoder_->GetScopedVASurface(); DCHECK(surface); DCHECK(surface->IsValid()); @@ -492,7 +537,7 @@ // 2. VPP doesn't support the format conversion. This is intended for AMD // VAAPI driver whose VPP only supports converting decoded 4:2:0 JPEGs. std::unique_ptr<ScopedVAImage> image = - decoder_.GetImage(*video_frame_va_fourcc, &status); + decoder_->GetImage(*video_frame_va_fourcc, &status); if (status != VaapiImageDecodeStatus::kSuccess) { NotifyError(task_id, VaapiJpegDecodeStatusToError(status)); return;
diff --git a/media/gpu/vaapi/vaapi_mjpeg_decode_accelerator.h b/media/gpu/vaapi/vaapi_mjpeg_decode_accelerator.h index 419ddd4..7c41829 100644 --- a/media/gpu/vaapi/vaapi_mjpeg_decode_accelerator.h +++ b/media/gpu/vaapi/vaapi_mjpeg_decode_accelerator.h
@@ -50,8 +50,9 @@ ~VaapiMjpegDecodeAccelerator() override; // chromeos_camera::MjpegDecodeAccelerator implementation. - bool Initialize( - chromeos_camera::MjpegDecodeAccelerator::Client* client) override; + void InitializeAsync( + chromeos_camera::MjpegDecodeAccelerator::Client* client, + chromeos_camera::MjpegDecodeAccelerator::InitCB init_cb) override; void Decode(BitstreamBuffer bitstream_buffer, scoped_refptr<VideoFrame> video_frame) override; void Decode(int32_t task_id, @@ -100,6 +101,14 @@ int32_t input_buffer_id, scoped_refptr<VideoFrame> video_frame); + void InitializeOnDecoderTaskRunner(InitCB init_cb); + + void InitializeOnTaskRunner( + chromeos_camera::MjpegDecodeAccelerator::Client* client, + InitCB init_cb); + + void CleanUpOnDecoderThread(); + // ChildThread's task runner. const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; @@ -109,7 +118,7 @@ // The client of this class. chromeos_camera::MjpegDecodeAccelerator::Client* client_; - VaapiJpegDecoder decoder_; + std::unique_ptr<media::VaapiJpegDecoder> decoder_; // VaapiWrapper for VPP context. This is used to convert decoded data into // client buffer.
diff --git a/media/gpu/vaapi/vaapi_video_decoder.h b/media/gpu/vaapi/vaapi_video_decoder.h index 8aabb95..837ac11 100644 --- a/media/gpu/vaapi/vaapi_video_decoder.h +++ b/media/gpu/vaapi/vaapi_video_decoder.h
@@ -10,7 +10,6 @@ #include <map> #include <memory> -#include <string> #include <utility> #include "base/containers/mru_cache.h"
diff --git a/media/gpu/windows/d3d11_video_decoder.h b/media/gpu/windows/d3d11_video_decoder.h index a539820..60fa5198 100644 --- a/media/gpu/windows/d3d11_video_decoder.h +++ b/media/gpu/windows/d3d11_video_decoder.h
@@ -6,7 +6,6 @@ #define MEDIA_GPU_WINDOWS_D3D11_VIDEO_DECODER_H_ #include <d3d11.h> -#include <string> #include <vector> #include "base/memory/ptr_util.h"
diff --git a/media/gpu/windows/d3d11_video_decoder_impl.h b/media/gpu/windows/d3d11_video_decoder_impl.h index 4a7f1449..004295b5 100644 --- a/media/gpu/windows/d3d11_video_decoder_impl.h +++ b/media/gpu/windows/d3d11_video_decoder_impl.h
@@ -10,7 +10,6 @@ #include <list> #include <memory> -#include <string> #include <tuple> #include "base/callback.h"
diff --git a/media/midi/midi_manager_winrt.h b/media/midi/midi_manager_winrt.h index 0d9ac02..121ff6f 100644 --- a/media/midi/midi_manager_winrt.h +++ b/media/midi/midi_manager_winrt.h
@@ -6,7 +6,6 @@ #define MEDIA_MIDI_MIDI_MANAGER_WINRT_H_ #include <memory> -#include <string> #include "base/thread_annotations.h" #include "media/midi/midi_manager.h"
diff --git a/media/mojo/mojom/media_metrics_provider.mojom b/media/mojo/mojom/media_metrics_provider.mojom index b4cd252f..da74931d 100644 --- a/media/mojo/mojom/media_metrics_provider.mojom +++ b/media/mojo/mojom/media_metrics_provider.mojom
@@ -55,6 +55,17 @@ SetTimeToFirstFrame(mojo_base.mojom.TimeDelta elapsed); SetTimeToPlayReady(mojo_base.mojom.TimeDelta elapsed); + // Sets the RendererType used in the playback. + SetRendererType(RendererType renderer_type); + + // Sets the EME key system used for an EME playback. For clear playback, or if + // the `key_system` is not recognized, value 0 (kUnknownKeySystemForUkm) will + // be reported. + SetKeySystem(string key_system); + + // Called when the EME playback uses a hardware secure pipeline. + SetIsHardwareSecure(); + // For src= playbacks, this is the container (".mp4", ".webm", etc). SetContainerName(MediaContainerName container_name); @@ -78,7 +89,6 @@ pending_receiver<PlaybackEventsRecorder> receiver); // Can be called multiple times to set properties about a playback. - SetRendererType(RendererType renderer_type); SetHasAudio(AudioCodec codec); SetHasVideo(VideoCodec codec); SetVideoPipelineInfo(VideoDecoderInfo info);
diff --git a/media/mojo/services/media_metrics_provider.cc b/media/mojo/services/media_metrics_provider.cc index df63b74..758349a 100644 --- a/media/mojo/services/media_metrics_provider.cc +++ b/media/mojo/services/media_metrics_provider.cc
@@ -12,6 +12,7 @@ #include "base/metrics/histogram_macros.h" #include "build/build_config.h" #include "build/chromecast_buildflags.h" +#include "media/base/key_systems.h" #include "media/learning/mojo/mojo_learning_task_controller_service.h" #include "media/mojo/services/video_decode_stats_recorder.h" #include "media/mojo/services/watch_time_recorder.h" @@ -73,6 +74,8 @@ builder.SetIsEME(uma_info_.is_eme); builder.SetIsMSE(is_mse_); builder.SetRendererType(static_cast<int>(renderer_type_)); + builder.SetKeySystem(GetKeySystemIntForUKM(key_system_)); + builder.SetIsHardwareSecure(is_hardware_secure_); builder.SetFinalPipelineStatus(uma_info_.last_pipeline_status); if (!is_mse_) { builder.SetURLScheme(static_cast<int64_t>(url_scheme_)); @@ -266,6 +269,14 @@ renderer_type_ = renderer_type; } +void MediaMetricsProvider::SetKeySystem(const std::string& key_system) { + key_system_ = key_system; +} + +void MediaMetricsProvider::SetIsHardwareSecure() { + is_hardware_secure_ = true; +} + void MediaMetricsProvider::AcquireWatchTimeRecorder( mojom::PlaybackPropertiesPtr properties, mojo::PendingReceiver<mojom::WatchTimeRecorder> receiver) {
diff --git a/media/mojo/services/media_metrics_provider.h b/media/mojo/services/media_metrics_provider.h index 07736259..dc0bb7aa 100644 --- a/media/mojo/services/media_metrics_provider.h +++ b/media/mojo/services/media_metrics_provider.h
@@ -110,6 +110,8 @@ void SetContainerName( container_names::MediaContainerName container_name) override; void SetRendererType(RendererType renderer_type) override; + void SetKeySystem(const std::string& key_system) override; + void SetIsHardwareSecure() override; void SetHasAudio(AudioCodec audio_codec) override; void SetHasPlayed() override; void SetHasVideo(VideoCodec video_codec) override; @@ -158,6 +160,8 @@ mojom::MediaURLScheme url_scheme_; mojom::MediaStreamType media_stream_type_; RendererType renderer_type_ = RendererType::kDefault; + std::string key_system_; + bool is_hardware_secure_ = false; base::TimeDelta time_to_metadata_ = kNoTimestamp; base::TimeDelta time_to_first_frame_ = kNoTimestamp;
diff --git a/media/mojo/services/media_metrics_provider_unittest.cc b/media/mojo/services/media_metrics_provider_unittest.cc index 972f79d..29aef85 100644 --- a/media/mojo/services/media_metrics_provider_unittest.cc +++ b/media/mojo/services/media_metrics_provider_unittest.cc
@@ -101,6 +101,8 @@ EXPECT_HAS_UKM(UkmEntry::kPlayerIDName); EXPECT_UKM(UkmEntry::kIsTopFrameName, true); EXPECT_UKM(UkmEntry::kIsEMEName, false); + EXPECT_UKM(UkmEntry::kKeySystemName, 0); + EXPECT_UKM(UkmEntry::kIsHardwareSecureName, false); EXPECT_UKM(UkmEntry::kIsMSEName, true); EXPECT_UKM(UkmEntry::kFinalPipelineStatusName, PIPELINE_OK); @@ -118,6 +120,7 @@ // Now try one with different values and optional parameters set. const std::string kTestOrigin2 = "https://test2.google.com/"; + const std::string kClearKeyKeySystem = "org.w3.clearkey"; const base::TimeDelta kMetadataTime = base::TimeDelta::FromSeconds(1); const base::TimeDelta kFirstFrameTime = base::TimeDelta::FromSeconds(2); const base::TimeDelta kPlayReadyTime = base::TimeDelta::FromSeconds(3); @@ -125,6 +128,8 @@ ResetMetricRecorders(); Initialize(false, false, false, kTestOrigin2, mojom::MediaURLScheme::kHttps); provider_->SetIsEME(); + provider_->SetKeySystem(kClearKeyKeySystem); + provider_->SetIsHardwareSecure(); provider_->SetTimeToMetadata(kMetadataTime); provider_->SetTimeToFirstFrame(kFirstFrameTime); provider_->SetTimeToPlayReady(kPlayReadyTime); @@ -142,6 +147,8 @@ EXPECT_HAS_UKM(UkmEntry::kPlayerIDName); EXPECT_UKM(UkmEntry::kIsTopFrameName, false); EXPECT_UKM(UkmEntry::kIsEMEName, true); + EXPECT_UKM(UkmEntry::kKeySystemName, 1); + EXPECT_UKM(UkmEntry::kIsHardwareSecureName, true); EXPECT_UKM(UkmEntry::kIsMSEName, false); EXPECT_UKM(UkmEntry::kURLSchemeName, static_cast<int64_t>(mojom::MediaURLScheme::kHttps)); @@ -228,7 +235,7 @@ histogram_tester.ExpectBucketCount("Media.HasEverPlayed", true, 0); } -TEST_F(MediaMetricsProviderTest, TestPipelineUMANoAudioEMEHW) { +TEST_F(MediaMetricsProviderTest, TestPipelineUMANoAudioWithEme) { base::HistogramTester histogram_tester; Initialize(false, false, false, kTestOrigin, mojom::MediaURLScheme::kHttps); provider_->SetIsEME();
diff --git a/media/mojo/services/mojo_audio_output_stream.h b/media/mojo/services/mojo_audio_output_stream.h index bbb56fce..8a85269 100644 --- a/media/mojo/services/mojo_audio_output_stream.h +++ b/media/mojo/services/mojo_audio_output_stream.h
@@ -6,7 +6,6 @@ #define MEDIA_MOJO_SERVICES_MOJO_AUDIO_OUTPUT_STREAM_H_ #include <memory> -#include <string> #include "base/sequence_checker.h" #include "media/audio/audio_output_delegate.h"
diff --git a/media/mojo/services/mojo_video_decoder_service.cc b/media/mojo/services/mojo_video_decoder_service.cc index 80bc77c..bc67d12 100644 --- a/media/mojo/services/mojo_video_decoder_service.cc +++ b/media/mojo/services/mojo_video_decoder_service.cc
@@ -59,6 +59,13 @@ elapsed); } +base::debug::CrashKeyString* GetNumVideoDecodersCrashKeyString() { + static base::debug::CrashKeyString* codec_count_crash_key = + base::debug::AllocateCrashKeyString("num-video-decoders", + base::debug::CrashKeySize::Size32); + return codec_count_crash_key; +} + } // namespace class VideoFrameHandleReleaserImpl final @@ -126,8 +133,12 @@ if (reset_cb_) OnDecoderReset(); - if (is_active_instance_) + if (is_active_instance_) { g_num_active_mvd_instances--; + base::debug::SetCrashKeyString( + GetNumVideoDecodersCrashKeyString(), + base::NumberToString(g_num_active_mvd_instances)); + } // Destruct the VideoDecoder here so its destruction duration is included by // the histogram timer below. @@ -244,6 +255,17 @@ return; } + auto gfx_cs = config.color_space_info().ToGfxColorSpace(); + codec_string_ = base::StringPrintf( + "name=%s:codec=%s:profile=%d:size=%s:cs=[%d,%d,%d,%d]:hdrm=%d", + GetDecoderName(decoder_->GetDecoderType()).c_str(), + GetCodecName(config.codec()).c_str(), config.profile(), + config.coded_size().ToString().c_str(), + static_cast<int>(gfx_cs.GetPrimaryID()), + static_cast<int>(gfx_cs.GetTransferID()), + static_cast<int>(gfx_cs.GetMatrixID()), + static_cast<int>(gfx_cs.GetRangeID()), config.hdr_metadata().has_value()); + using Self = MojoVideoDecoderService; decoder_->Initialize( config, low_delay, cdm_context, @@ -277,6 +299,14 @@ g_num_active_mvd_instances++; UMA_HISTOGRAM_EXACT_LINEAR("Media.MojoVideoDecoder.ActiveInstances", g_num_active_mvd_instances, 64); + base::debug::SetCrashKeyString( + GetNumVideoDecodersCrashKeyString(), + base::NumberToString(g_num_active_mvd_instances)); + + // This will be overwritten as subsequent decoders are created. + static auto* last_codec_crash_key = base::debug::AllocateCrashKeyString( + "last-video-decoder", base::debug::CrashKeySize::Size256); + base::debug::SetCrashKeyString(last_codec_crash_key, codec_string_); } mojo_decoder_buffer_reader_->ReadDecoderBuffer(
diff --git a/media/mojo/services/mojo_video_decoder_service.h b/media/mojo/services/mojo_video_decoder_service.h index 8fbb7f6..df1c13b 100644 --- a/media/mojo/services/mojo_video_decoder_service.h +++ b/media/mojo/services/mojo_video_decoder_service.h
@@ -93,6 +93,9 @@ // Whether this instance is active (Decode() was called at least once). bool is_active_instance_ = false; + // Codec information stored via crash key. + std::string codec_string_; + // Decoder factory. MojoMediaClient* mojo_media_client_;
diff --git a/media/mojo/services/video_decode_perf_history.h b/media/mojo/services/video_decode_perf_history.h index 4c50c74..30e3823a 100644 --- a/media/mojo/services/video_decode_perf_history.h +++ b/media/mojo/services/video_decode_perf_history.h
@@ -8,7 +8,6 @@ #include <stdint.h> #include <memory> #include <queue> -#include <string> #include "base/callback.h" #include "base/metrics/field_trial_params.h"
diff --git a/media/mojo/services/watch_time_recorder.h b/media/mojo/services/watch_time_recorder.h index 77e768f..669781c 100644 --- a/media/mojo/services/watch_time_recorder.h +++ b/media/mojo/services/watch_time_recorder.h
@@ -6,7 +6,6 @@ #define MEDIA_MOJO_SERVICES_WATCH_TIME_RECORDER_H_ #include <stdint.h> -#include <string> #include "base/compiler_specific.h" #include "base/containers/flat_map.h"
diff --git a/media/remoting/proto_utils.h b/media/remoting/proto_utils.h index f0bba1c..0265bef 100644 --- a/media/remoting/proto_utils.h +++ b/media/remoting/proto_utils.h
@@ -6,7 +6,6 @@ #define MEDIA_REMOTING_PROTO_UTILS_H_ #include <cstdint> -#include <string> #include <vector> #include "base/macros.h"
diff --git a/media/remoting/rpc_broker.h b/media/remoting/rpc_broker.h index 6830228..b0d8227 100644 --- a/media/remoting/rpc_broker.h +++ b/media/remoting/rpc_broker.h
@@ -7,7 +7,6 @@ #include <map> #include <memory> -#include <string> #include <vector> #include "base/callback.h"
diff --git a/media/renderers/win/media_foundation_renderer.cc b/media/renderers/win/media_foundation_renderer.cc index d58dfb7..f37f9d8b 100644 --- a/media/renderers/win/media_foundation_renderer.cc +++ b/media/renderers/win/media_foundation_renderer.cc
@@ -11,6 +11,7 @@ #include "base/callback_helpers.h" #include "base/guid.h" +#include "base/process/process_handle.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/win/scoped_bstr.h" @@ -421,7 +422,19 @@ HANDLE surface_handle = INVALID_HANDLE_VALUE; HRESULT hr = GetDCompSurfaceInternal(&surface_handle); DVLOG_IF(1, FAILED(hr)) << "Failed to get DComp surface: " << PrintHr(hr); - std::move(callback).Run(std::move(surface_handle)); + + // Only need read & execute access right for the handle to be duplicated + // without breaking in sandbox_win.cc!CheckDuplicateHandle(). + const base::ProcessHandle process = ::GetCurrentProcess(); + HANDLE duplicated_handle = INVALID_HANDLE_VALUE; + const BOOL result = ::DuplicateHandle( + process, surface_handle, process, &duplicated_handle, + GENERIC_READ | GENERIC_EXECUTE, false, DUPLICATE_CLOSE_SOURCE); + if (!result) { + DLOG(ERROR) << "Duplicate surface_handle failed: " << ::GetLastError(); + } + + std::move(callback).Run(std::move(duplicated_handle)); } // TODO(crbug.com/1070030): Investigate if we need to add
diff --git a/net/android/network_change_notifier_delegate_android.h b/net/android/network_change_notifier_delegate_android.h index 905d2e6d..a703ee6c 100644 --- a/net/android/network_change_notifier_delegate_android.h +++ b/net/android/network_change_notifier_delegate_android.h
@@ -6,7 +6,6 @@ #define NET_ANDROID_NETWORK_CHANGE_NOTIFIER_DELEGATE_ANDROID_H_ #include <map> -#include <string> #include "base/android/jni_android.h" #include "base/memory/ref_counted.h"
diff --git a/net/base/interval.h b/net/base/interval.h index 24f3853..8ac3b5e 100644 --- a/net/base/interval.h +++ b/net/base/interval.h
@@ -65,7 +65,6 @@ #include <algorithm> #include <functional> #include <ostream> -#include <string> #include <utility> #include <vector>
diff --git a/net/cert/internal/path_builder.h b/net/cert/internal/path_builder.h index e7ef60d..0a358ced 100644 --- a/net/cert/internal/path_builder.h +++ b/net/cert/internal/path_builder.h
@@ -6,7 +6,6 @@ #define NET_CERT_INTERNAL_PATH_BUILDER_H_ #include <memory> -#include <string> #include <vector> #include "base/supports_user_data.h"
diff --git a/net/cookies/cookie_store_test_callbacks.h b/net/cookies/cookie_store_test_callbacks.h index b3195c20..71597d99 100644 --- a/net/cookies/cookie_store_test_callbacks.h +++ b/net/cookies/cookie_store_test_callbacks.h
@@ -5,7 +5,6 @@ #ifndef NET_COOKIES_COOKIE_STORE_TEST_CALLBACKS_H_ #define NET_COOKIES_COOKIE_STORE_TEST_CALLBACKS_H_ -#include <string> #include <vector> #include "base/bind.h"
diff --git a/net/disk_cache/simple/simple_index_file.h b/net/disk_cache/simple/simple_index_file.h index 0e768f98..b397469 100644 --- a/net/disk_cache/simple/simple_index_file.h +++ b/net/disk_cache/simple/simple_index_file.h
@@ -8,7 +8,6 @@ #include <stdint.h> #include <memory> -#include <string> #include <vector> #include "base/files/file_path.h" @@ -205,7 +204,6 @@ DISALLOW_COPY_AND_ASSIGN(SimpleIndexFile); }; - } // namespace disk_cache #endif // NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_FILE_H_
diff --git a/net/http/http_network_layer.h b/net/http/http_network_layer.h index 51223d9..49ec2247 100644 --- a/net/http/http_network_layer.h +++ b/net/http/http_network_layer.h
@@ -6,7 +6,6 @@ #define NET_HTTP_HTTP_NETWORK_LAYER_H_ #include <memory> -#include <string> #include "base/compiler_specific.h" #include "base/macros.h"
diff --git a/net/log/test_net_log.h b/net/log/test_net_log.h index 2aebd279..f59e23a 100644 --- a/net/log/test_net_log.h +++ b/net/log/test_net_log.h
@@ -7,7 +7,6 @@ #include <stddef.h> -#include <string> #include <vector> #include "base/callback.h"
diff --git a/net/network_error_logging/mock_persistent_nel_store.h b/net/network_error_logging/mock_persistent_nel_store.h index a5a646da..15af5fa 100644 --- a/net/network_error_logging/mock_persistent_nel_store.h +++ b/net/network_error_logging/mock_persistent_nel_store.h
@@ -5,7 +5,6 @@ #ifndef NET_NETWORK_ERROR_LOGGING_MOCK_PERSISTENT_NEL_STORE_H_ #define NET_NETWORK_ERROR_LOGGING_MOCK_PERSISTENT_NEL_STORE_H_ -#include <string> #include <vector> #include "base/callback.h"
diff --git a/net/nqe/network_quality_estimator.h b/net/nqe/network_quality_estimator.h index 4c8d636b..dd9111a9 100644 --- a/net/nqe/network_quality_estimator.h +++ b/net/nqe/network_quality_estimator.h
@@ -9,7 +9,6 @@ #include <map> #include <memory> -#include <string> #include <vector> #include "base/compiler_specific.h"
diff --git a/net/ntlm/ntlm_buffer_reader.h b/net/ntlm/ntlm_buffer_reader.h index d014934..d6cb7d7 100644 --- a/net/ntlm/ntlm_buffer_reader.h +++ b/net/ntlm/ntlm_buffer_reader.h
@@ -8,7 +8,6 @@ #include <stddef.h> #include <stdint.h> -#include <string> #include <vector> #include "base/containers/span.h"
diff --git a/net/proxy_resolution/proxy_resolver.h b/net/proxy_resolution/proxy_resolver.h index ed59ffcc..7b54e57 100644 --- a/net/proxy_resolution/proxy_resolver.h +++ b/net/proxy_resolution/proxy_resolver.h
@@ -5,8 +5,6 @@ #ifndef NET_PROXY_RESOLUTION_PROXY_RESOLVER_H_ #define NET_PROXY_RESOLUTION_PROXY_RESOLVER_H_ -#include <string> - #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/ref_counted.h"
diff --git a/net/proxy_resolution/win/proxy_config_service_win.h b/net/proxy_resolution/win/proxy_config_service_win.h index b9ed016..886ebfc 100644 --- a/net/proxy_resolution/win/proxy_config_service_win.h +++ b/net/proxy_resolution/win/proxy_config_service_win.h
@@ -9,7 +9,6 @@ #include <winhttp.h> #include <memory> -#include <string> #include <vector> #include "base/compiler_specific.h"
diff --git a/net/quic/mock_crypto_client_stream.h b/net/quic/mock_crypto_client_stream.h index 9cb0cfd..68e5ad9 100644 --- a/net/quic/mock_crypto_client_stream.h +++ b/net/quic/mock_crypto_client_stream.h
@@ -5,8 +5,6 @@ #ifndef NET_QUIC_MOCK_CRYPTO_CLIENT_STREAM_H_ #define NET_QUIC_MOCK_CRYPTO_CLIENT_STREAM_H_ -#include <string> - #include "base/macros.h" #include "net/quic/crypto/proof_verifier_chromium.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h"
diff --git a/net/quic/mock_crypto_client_stream_factory.h b/net/quic/mock_crypto_client_stream_factory.h index b5e89f0..b0f8193e6 100644 --- a/net/quic/mock_crypto_client_stream_factory.h +++ b/net/quic/mock_crypto_client_stream_factory.h
@@ -6,7 +6,6 @@ #define NET_QUIC_MOCK_CRYPTO_CLIENT_STREAM_FACTORY_H_ #include <memory> -#include <string> #include "base/containers/queue.h" #include "base/macros.h"
diff --git a/net/quic/quic_client_session_cache.h b/net/quic/quic_client_session_cache.h index cf1a90f8..d566fca 100644 --- a/net/quic/quic_client_session_cache.h +++ b/net/quic/quic_client_session_cache.h
@@ -9,7 +9,6 @@ #include <time.h> #include <memory> -#include <string> #include "base/bind.h" #include "base/containers/mru_cache.h"
diff --git a/net/quic/quic_connection_logger.h b/net/quic/quic_connection_logger.h index 8234979..6e41cb2 100644 --- a/net/quic/quic_connection_logger.h +++ b/net/quic/quic_connection_logger.h
@@ -8,7 +8,6 @@ #include <stddef.h> #include <bitset> -#include <string> #include "base/macros.h" #include "net/base/ip_endpoint.h"
diff --git a/net/quic/quic_crypto_client_stream_factory.h b/net/quic/quic_crypto_client_stream_factory.h index a010b7f..33ddde2 100644 --- a/net/quic/quic_crypto_client_stream_factory.h +++ b/net/quic/quic_crypto_client_stream_factory.h
@@ -6,7 +6,6 @@ #define NET_QUIC_QUIC_CRYPTO_CLIENT_STREAM_FACTORY_H_ #include <memory> -#include <string> #include "net/base/net_export.h" #include "net/third_party/quiche/src/quic/core/quic_server_id.h"
diff --git a/net/reporting/mock_persistent_reporting_store.h b/net/reporting/mock_persistent_reporting_store.h index 04f1d89..b53e397 100644 --- a/net/reporting/mock_persistent_reporting_store.h +++ b/net/reporting/mock_persistent_reporting_store.h
@@ -5,7 +5,6 @@ #ifndef NET_REPORTING_MOCK_PERSISTENT_REPORTING_STORE_H_ #define NET_REPORTING_MOCK_PERSISTENT_REPORTING_STORE_H_ -#include <string> #include <vector> #include "base/callback.h"
diff --git a/net/reporting/reporting_endpoint_manager.h b/net/reporting/reporting_endpoint_manager.h index a760849bd..5b14a597 100644 --- a/net/reporting/reporting_endpoint_manager.h +++ b/net/reporting/reporting_endpoint_manager.h
@@ -6,7 +6,6 @@ #define NET_REPORTING_REPORTING_ENDPOINT_MANAGER_H_ #include <memory> -#include <string> #include "base/macros.h" #include "net/base/net_export.h"
diff --git a/net/socket/client_socket_handle.h b/net/socket/client_socket_handle.h index 1a8f4c5..2e41eba 100644 --- a/net/socket/client_socket_handle.h +++ b/net/socket/client_socket_handle.h
@@ -6,7 +6,6 @@ #define NET_SOCKET_CLIENT_SOCKET_HANDLE_H_ #include <memory> -#include <string> #include <utility> #include "base/bind.h"
diff --git a/net/socket/fuzzed_server_socket.h b/net/socket/fuzzed_server_socket.h index 03c64672..7d8dc80 100644 --- a/net/socket/fuzzed_server_socket.h +++ b/net/socket/fuzzed_server_socket.h
@@ -8,7 +8,6 @@ #include <stdint.h> #include <memory> -#include <string> #include "base/macros.h" #include "base/memory/weak_ptr.h"
diff --git a/net/socket/socks_connect_job.h b/net/socket/socks_connect_job.h index 7ce44f52..21db95cf 100644 --- a/net/socket/socks_connect_job.h +++ b/net/socket/socks_connect_job.h
@@ -6,7 +6,6 @@ #define NET_SOCKET_SOCKS_CONNECT_JOB_H_ #include <memory> -#include <string> #include "base/macros.h" #include "base/memory/ref_counted.h"
diff --git a/net/socket/transport_connect_job.h b/net/socket/transport_connect_job.h index 5b394234..6fbf0b9a3 100644 --- a/net/socket/transport_connect_job.h +++ b/net/socket/transport_connect_job.h
@@ -6,7 +6,6 @@ #define NET_SOCKET_TRANSPORT_CONNECT_JOB_H_ #include <memory> -#include <string> #include "base/callback.h" #include "base/macros.h"
diff --git a/net/socket/websocket_transport_connect_job.h b/net/socket/websocket_transport_connect_job.h index aa7939e..b4aae073 100644 --- a/net/socket/websocket_transport_connect_job.h +++ b/net/socket/websocket_transport_connect_job.h
@@ -7,7 +7,6 @@ #include <memory> #include <set> -#include <string> #include "base/macros.h" #include "base/memory/ref_counted.h"
diff --git a/net/ssl/ssl_client_auth_cache.h b/net/ssl/ssl_client_auth_cache.h index a380ea7..facbc5f9 100644 --- a/net/ssl/ssl_client_auth_cache.h +++ b/net/ssl/ssl_client_auth_cache.h
@@ -6,7 +6,6 @@ #define NET_SSL_SSL_CLIENT_AUTH_CACHE_H_ #include <map> -#include <string> #include <utility> #include "base/compiler_specific.h"
diff --git a/net/test/spawned_test_server/local_test_server.h b/net/test/spawned_test_server/local_test_server.h index a9dc1af..74622a8 100644 --- a/net/test/spawned_test_server/local_test_server.h +++ b/net/test/spawned_test_server/local_test_server.h
@@ -5,7 +5,6 @@ #ifndef NET_TEST_SPAWNED_TEST_SERVER_LOCAL_TEST_SERVER_H_ #define NET_TEST_SPAWNED_TEST_SERVER_LOCAL_TEST_SERVER_H_ -#include <string> #include <vector> #include "base/files/file_util.h"
diff --git a/net/tools/cert_verify_tool/verify_using_path_builder.h b/net/tools/cert_verify_tool/verify_using_path_builder.h index 31f0145..1e8e844 100644 --- a/net/tools/cert_verify_tool/verify_using_path_builder.h +++ b/net/tools/cert_verify_tool/verify_using_path_builder.h
@@ -5,7 +5,6 @@ #ifndef NET_TOOLS_CERT_VERIFY_TOOL_VERIFY_USING_PATH_BUILDER_H_ #define NET_TOOLS_CERT_VERIFY_TOOL_VERIFY_USING_PATH_BUILDER_H_ -#include <string> #include <vector> #include "base/memory/ref_counted.h"
diff --git a/net/tools/huffman_trie/trie/trie_writer.h b/net/tools/huffman_trie/trie/trie_writer.h index 3c824e7..9fdc1ee 100644 --- a/net/tools/huffman_trie/trie/trie_writer.h +++ b/net/tools/huffman_trie/trie/trie_writer.h
@@ -5,7 +5,6 @@ #ifndef NET_TOOLS_HUFFMAN_TRIE_TRIE_TRIE_WRITER_H_ #define NET_TOOLS_HUFFMAN_TRIE_TRIE_TRIE_WRITER_H_ -#include <string> #include <vector> #include "net/tools/huffman_trie/bit_writer.h"
diff --git a/net/tools/quic/quic_client_message_loop_network_helper.h b/net/tools/quic/quic_client_message_loop_network_helper.h index 82aeedda..a0ba9ad 100644 --- a/net/tools/quic/quic_client_message_loop_network_helper.h +++ b/net/tools/quic/quic_client_message_loop_network_helper.h
@@ -11,7 +11,6 @@ #include <stddef.h> #include <memory> -#include <string> #include "base/command_line.h" #include "base/macros.h"
diff --git a/net/tools/quic/quic_simple_client.h b/net/tools/quic/quic_simple_client.h index 3ac2841..5e9d4d1f 100644 --- a/net/tools/quic/quic_simple_client.h +++ b/net/tools/quic/quic_simple_client.h
@@ -11,7 +11,6 @@ #include <stddef.h> #include <memory> -#include <string> #include "base/command_line.h" #include "base/macros.h"
diff --git a/net/url_request/report_sender.h b/net/url_request/report_sender.h index 7e2f57c..2400db5 100644 --- a/net/url_request/report_sender.h +++ b/net/url_request/report_sender.h
@@ -7,7 +7,6 @@ #include <map> #include <memory> -#include <string> #include "base/callback.h" #include "base/macros.h"
diff --git a/remoting/protocol/webrtc_video_track_source.cc b/remoting/protocol/webrtc_video_track_source.cc index 071543f..588bb62 100644 --- a/remoting/protocol/webrtc_video_track_source.cc +++ b/remoting/protocol/webrtc_video_track_source.cc
@@ -4,7 +4,11 @@ #include "remoting/protocol/webrtc_video_track_source.h" +#include <utility> + +#include "base/logging.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "remoting/protocol/webrtc_video_frame_adapter.h" namespace remoting { namespace protocol { @@ -40,11 +44,26 @@ void WebrtcVideoTrackSource::AddOrUpdateSink( rtc::VideoSinkInterface<webrtc::VideoFrame>* sink, const rtc::VideoSinkWants& wants) { + DCHECK(sink); + if (sink_ && (sink != sink_)) { + // The same sink can be added more than once, but there should only be 1 + // in total. + LOG(WARNING) << "More than one sink added, only the latest will be used."; + } + sink_ = sink; main_task_runner_->PostTask(FROM_HERE, add_sink_callback_); } void WebrtcVideoTrackSource::RemoveSink( - rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) {} + rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) { + DCHECK(sink); + if (sink != sink_) { + // This might happen if more than one sink was added. + LOG(WARNING) << "RemoveSink() called with unexpected sink."; + return; + } + sink_ = nullptr; +} bool WebrtcVideoTrackSource::SupportsEncodedOutput() const { return false; @@ -58,5 +77,18 @@ void WebrtcVideoTrackSource::RemoveEncodedSink( rtc::VideoSinkInterface<webrtc::RecordableEncodedFrame>* sink) {} +void WebrtcVideoTrackSource::SendCapturedFrame( + std::unique_ptr<webrtc::DesktopFrame> desktop_frame, + std::unique_ptr<WebrtcVideoEncoder::FrameStats> frame_stats) { + if (!sink_) { + LOG(WARNING) << "No sink registered, dropping frame."; + return; + } + + webrtc::VideoFrame video_frame = WebrtcVideoFrameAdapter::CreateVideoFrame( + std::move(desktop_frame), std::move(frame_stats)); + sink_->OnFrame(video_frame); +} + } // namespace protocol } // namespace remoting
diff --git a/remoting/protocol/webrtc_video_track_source.h b/remoting/protocol/webrtc_video_track_source.h index 11b248f5..e54e44b 100644 --- a/remoting/protocol/webrtc_video_track_source.h +++ b/remoting/protocol/webrtc_video_track_source.h
@@ -7,8 +7,12 @@ #include "base/callback.h" #include "base/sequenced_task_runner.h" +#include "remoting/codec/webrtc_video_encoder.h" #include "third_party/webrtc/api/media_stream_interface.h" #include "third_party/webrtc/api/notifier.h" +#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" + +#include <memory> namespace remoting { namespace protocol { @@ -39,7 +43,15 @@ void RemoveEncodedSink( rtc::VideoSinkInterface<webrtc::RecordableEncodedFrame>* sink) override; + // Sends a captured frame to the sink if one was added. The |frame_stats| + // will be associated with the frame and will be attached to the output + // EncodedFrame. + void SendCapturedFrame( + std::unique_ptr<webrtc::DesktopFrame> desktop_frame, + std::unique_ptr<WebrtcVideoEncoder::FrameStats> frame_stats); + private: + rtc::VideoSinkInterface<webrtc::VideoFrame>* sink_ = nullptr; base::RepeatingClosure add_sink_callback_; scoped_refptr<base::SequencedTaskRunner> main_task_runner_; };
diff --git a/remoting/protocol/webrtc_video_track_source_unittest.cc b/remoting/protocol/webrtc_video_track_source_unittest.cc index 122fd329..70dd343 100644 --- a/remoting/protocol/webrtc_video_track_source_unittest.cc +++ b/remoting/protocol/webrtc_video_track_source_unittest.cc
@@ -4,14 +4,37 @@ #include "remoting/protocol/webrtc_video_track_source.h" +#include <memory> +#include <utility> + +#include "base/callback_helpers.h" #include "base/test/bind.h" #include "base/test/task_environment.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" +#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" #include "third_party/webrtc/rtc_base/ref_counted_object.h" +using testing::Property; +using webrtc::BasicDesktopFrame; +using webrtc::DesktopSize; +using webrtc::VideoFrame; + namespace remoting { namespace protocol { +namespace { + +class MockVideoSink : public rtc::VideoSinkInterface<VideoFrame> { + public: + ~MockVideoSink() override = default; + + MOCK_METHOD(void, OnFrame, (const VideoFrame& frame), (override)); +}; + +} // namespace + class WebrtcVideoTrackSourceTest : public testing::Test { public: WebrtcVideoTrackSourceTest() = default; @@ -19,13 +42,27 @@ protected: base::test::SingleThreadTaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + + MockVideoSink video_sink_; }; TEST_F(WebrtcVideoTrackSourceTest, AddSinkTriggersCallback) { rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source = new rtc::RefCountedObject<WebrtcVideoTrackSource>( base::MakeExpectedRunAtLeastOnceClosure(FROM_HERE)); - source->AddOrUpdateSink(nullptr, rtc::VideoSinkWants()); + source->AddOrUpdateSink(&video_sink_, rtc::VideoSinkWants()); + + task_environment_.FastForwardUntilNoTasksRemain(); +} + +TEST_F(WebrtcVideoTrackSourceTest, CapturedFrameSentToAddedSink) { + auto frame = std::make_unique<BasicDesktopFrame>(DesktopSize(123, 234)); + EXPECT_CALL(video_sink_, OnFrame(Property(&VideoFrame::width, 123))); + + rtc::scoped_refptr<WebrtcVideoTrackSource> source = + new rtc::RefCountedObject<WebrtcVideoTrackSource>(base::DoNothing()); + source->AddOrUpdateSink(&video_sink_, rtc::VideoSinkWants()); + source->SendCapturedFrame(std::move(frame), nullptr); task_environment_.FastForwardUntilNoTasksRemain(); }
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index e37de78..aa69a5f 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -4689,7 +4689,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.82" + "revision": "version:91.0.4472.83" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -4768,7 +4768,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.32" + "revision": "version:92.0.4515.36" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -4926,7 +4926,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.82" + "revision": "version:91.0.4472.83" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -5005,7 +5005,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.32" + "revision": "version:92.0.4515.36" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 6394061..1faf0ae 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -53852,7 +53852,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.82" + "revision": "version:91.0.4472.83" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -53932,7 +53932,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.32" + "revision": "version:92.0.4515.36" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -54092,7 +54092,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.82" + "revision": "version:91.0.4472.83" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -54172,7 +54172,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.32" + "revision": "version:92.0.4515.36" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -54397,7 +54397,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.82" + "revision": "version:91.0.4472.83" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -54476,7 +54476,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.32" + "revision": "version:92.0.4515.36" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -54634,7 +54634,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.82" + "revision": "version:91.0.4472.83" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -54713,7 +54713,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.32" + "revision": "version:92.0.4515.36" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -54938,7 +54938,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.82" + "revision": "version:91.0.4472.83" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -55017,7 +55017,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.32" + "revision": "version:92.0.4515.36" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -55175,7 +55175,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.82" + "revision": "version:91.0.4472.83" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -55254,7 +55254,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.32" + "revision": "version:92.0.4515.36" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 51c1735..49709b1 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -19626,6 +19626,1289 @@ } ] }, + "fuchsia-fyi-arm64-femu": { + "additional_compile_targets": [ + "all" + ], + "gtest_tests": [ + { + "args": [ + "--device=aemu" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "absl_hardening_tests", + "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "accessibility_unittests", + "test_id_prefix": "ninja://ui/accessibility:accessibility_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "aura_unittests", + "test_id_prefix": "ninja://ui/aura:aura_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "base_unittests", + "test_id_prefix": "ninja://base:base_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "base_util_unittests", + "test_id_prefix": "ninja://base/util:base_util_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_common_unittests", + "test_id_prefix": "ninja://third_party/blink/common:blink_common_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_heap_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/platform/heap:blink_heap_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_platform_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_platform_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.blink_unittests.filter", + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "boringssl_crypto_tests", + "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "boringssl_ssl_tests", + "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "capture_unittests", + "test_id_prefix": "ninja://media/capture:capture_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cast_runner_browsertests", + "test_id_prefix": "ninja://fuchsia/runners:cast_runner_browsertests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cast_runner_integration_tests", + "test_id_prefix": "ninja://fuchsia/runners:cast_runner_integration_tests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cast_runner_unittests", + "test_id_prefix": "ninja://fuchsia/runners:cast_runner_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test": "cc_unittests", + "test_id_prefix": "ninja://cc:cc_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "compositor_unittests", + "test_id_prefix": "ninja://ui/compositor:compositor_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter", + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "content_unittests", + "test_id_prefix": "ninja://content/test:content_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cr_fuchsia_base_unittests", + "test_id_prefix": "ninja://fuchsia/base:cr_fuchsia_base_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cronet_tests", + "test_id_prefix": "ninja://components/cronet:cronet_tests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cronet_unittests", + "test_id_prefix": "ninja://components/cronet:cronet_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "crypto_unittests", + "test_id_prefix": "ninja://crypto:crypto_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "display_unittests", + "test_id_prefix": "ninja://ui/display:display_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "events_unittests", + "test_id_prefix": "ninja://ui/events:events_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gfx_unittests", + "test_id_prefix": "ninja://ui/gfx:gfx_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gin_unittests", + "test_id_prefix": "ninja://gin:gin_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "google_apis_unittests", + "test_id_prefix": "ninja://google_apis:google_apis_unittests/" + }, + { + "args": [ + "--device=aemu" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gpu_unittests", + "test_id_prefix": "ninja://gpu:gpu_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.headless_browsertests.filter", + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "headless_browsertests", + "test_id_prefix": "ninja://headless:headless_browsertests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "headless_unittests", + "test_id_prefix": "ninja://headless:headless_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "http_service_tests", + "test_id_prefix": "ninja://fuchsia/http:http_service_tests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "ipc_tests", + "test_id_prefix": "ninja://ipc:ipc_tests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "latency_unittests", + "test_id_prefix": "ninja://ui/latency:latency_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "media_blink_unittests", + "test_id_prefix": "ninja://media/blink:media_blink_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "media_unittests", + "test_id_prefix": "ninja://media:media_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "mojo_unittests", + "test_id_prefix": "ninja://mojo:mojo_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "native_theme_unittests", + "test_id_prefix": "ninja://ui/native_theme:native_theme_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.net_unittests.filter", + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 4 + }, + "test": "net_unittests", + "test_id_prefix": "ninja://net:net_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "perfetto_unittests", + "test_id_prefix": "ninja://third_party/perfetto:perfetto_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "service_manager_unittests", + "test_id_prefix": "ninja://services/service_manager/tests:service_manager_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.services_unittests.filter", + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "services_unittests", + "test_id_prefix": "ninja://services:services_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "shell_dialogs_unittests", + "test_id_prefix": "ninja://ui/shell_dialogs:shell_dialogs_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "skia_unittests", + "test_id_prefix": "ninja://skia:skia_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "snapshot_unittests", + "test_id_prefix": "ninja://ui/snapshot:snapshot_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "sql_unittests", + "test_id_prefix": "ninja://sql:sql_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.storage_unittests.filter", + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "storage_unittests", + "test_id_prefix": "ninja://storage:storage_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ui_base_unittests.filter", + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "ui_base_unittests", + "test_id_prefix": "ninja://ui/base:ui_base_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "url_unittests", + "test_id_prefix": "ninja://url:url_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.viz_unittests.filter", + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "viz_unittests", + "test_id_prefix": "ninja://components/viz:viz_unittests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "web_engine_browsertests", + "test_id_prefix": "ninja://fuchsia/engine:web_engine_browsertests/" + }, + { + "args": [ + "--child-arg=--vmodule=test_navigation_listener=1", + "--device=aemu" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "web_engine_integration_tests", + "test_id_prefix": "ninja://fuchsia/engine:web_engine_integration_tests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "web_engine_unittests", + "test_id_prefix": "ninja://fuchsia/engine:web_engine_unittests/" + }, + { + "args": [ + "--device=aemu" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "web_runner_integration_tests", + "test_id_prefix": "ninja://fuchsia/runners:web_runner_integration_tests/" + }, + { + "args": [ + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "wtf_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/platform/wtf:wtf_unittests/" + } + ], + "isolated_scripts": [ + { + "args": [ + "bin/run_angle_unittests", + "--device=aemu", + "--runner-logs-dir=${ISOLATED_OUTDIR}/runner_logs" + ], + "isolate_name": "angle_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "angle_unittests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://third_party/angle/src/tests:angle_unittests/" + } + ] + }, "fuchsia-fyi-arm64-rel": { "additional_compile_targets": [ "all"
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index 613e265..fd2932c 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -391,6 +391,13 @@ ], }, }, + 'fuchsia-femu': { + '$mixin_append': { + 'args': [ + '--device=aemu', + ], + }, + }, 'fuchsia_runner_logs': { '$mixin_append': { 'args': [ @@ -546,6 +553,13 @@ }, }, }, + 'linux-focal': { + 'swarming': { + 'dimensions': { + 'os': 'Ubuntu-20.04', + }, + }, + }, 'linux-trusty': { 'swarming': { 'dimensions': {
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index b584340..aefd12f 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1094,6 +1094,7 @@ 'Fuchsia x64', # https://crbug.com/961457 'fuchsia-code-coverage', # https://crbug.com/961457 'fuchsia-fyi-arm64-dbg', # https://crbug.com/961457 + 'fuchsia-fyi-arm64-femu', # https://crbug.com/961457 'fuchsia-fyi-arm64-rel', # https://crbug.com/961457 'fuchsia-fyi-x64-dbg', # https://crbug.com/961457 'fuchsia-fyi-x64-rel', # https://crbug.com/961457
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index dd4f394..5811895 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -424,7 +424,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M92', - 'revision': 'version:92.0.4515.32', + 'revision': 'version:92.0.4515.36', } ], }, @@ -448,7 +448,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M91', - 'revision': 'version:91.0.4472.82', + 'revision': 'version:91.0.4472.83', } ], }, @@ -496,7 +496,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M92', - 'revision': 'version:92.0.4515.32', + 'revision': 'version:92.0.4515.36', } ], }, @@ -520,7 +520,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M91', - 'revision': 'version:91.0.4472.82', + 'revision': 'version:91.0.4472.83', } ], }, @@ -568,7 +568,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M92', - 'revision': 'version:92.0.4515.32', + 'revision': 'version:92.0.4515.36', } ], }, @@ -592,7 +592,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M91', - 'revision': 'version:91.0.4472.82', + 'revision': 'version:91.0.4472.83', } ], },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 993e4d8..01b2e3d 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -2795,6 +2795,21 @@ 'linux-xenial', ], }, + 'fuchsia-fyi-arm64-femu': { + 'additional_compile_targets': [ + 'all', + ], + 'test_suites': { + 'gtest_tests': 'fuchsia_gtests', + 'isolated_scripts': 'gpu_angle_fuchsia_unittests_isolated_scripts', + }, + 'mixins': [ + 'arm64', + 'docker', + 'fuchsia-femu', + 'linux-focal', + ], + }, 'fuchsia-fyi-arm64-rel': { 'additional_compile_targets': [ 'all',
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index c3eb4d77..a4b956eb 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -26,6 +26,10 @@ const base::Feature kCSSContainerQueries{"CSSContainerQueries", base::FEATURE_DISABLED_BY_DEFAULT}; +// Controls whether the Conversion Measurement API infrastructure is enabled. +const base::Feature kConversionMeasurement{"ConversionMeasurement", + base::FEATURE_ENABLED_BY_DEFAULT}; + const base::Feature kGMSCoreEmoji{"GMSCoreEmoji", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index f4f0925..4f97c5709 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -20,6 +20,7 @@ kBlockingDownloadsInAdFrameWithoutUserActivation; BLINK_COMMON_EXPORT extern const base::Feature kCOLRV1Fonts; BLINK_COMMON_EXPORT extern const base::Feature kCSSContainerQueries; +BLINK_COMMON_EXPORT extern const base::Feature kConversionMeasurement; BLINK_COMMON_EXPORT extern const base::Feature kGMSCoreEmoji; BLINK_COMMON_EXPORT extern const base::Feature kHandwritingRecognitionWebPlatformApi;
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index 0aa93ca..accd722 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -236,8 +236,6 @@ bool); BLINK_PLATFORM_EXPORT static void EnableContentIndex(bool); BLINK_PLATFORM_EXPORT static void EnableRestrictGamepadAccess(bool); - BLINK_PLATFORM_EXPORT static void EnableConversionMeasurementInfraSupport( - bool); BLINK_PLATFORM_EXPORT static void EnableTargetBlankImpliesNoOpener(bool);
diff --git a/third_party/blink/renderer/bindings/BUILD.gn b/third_party/blink/renderer/bindings/BUILD.gn index 538cfc1..f133084 100644 --- a/third_party/blink/renderer/bindings/BUILD.gn +++ b/third_party/blink/renderer/bindings/BUILD.gn
@@ -171,9 +171,6 @@ template("generate_bindings") { action_with_pydeps(target_name) { - # TODO(crbug.com/1194277): Investigate non-determinism in Py3 builds. - run_under_python2 = true - script = "${bindings_scripts_dir}/generate_bindings.py" if (defined(invoker.visibility)) {
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py index ddf6e21..621e3080 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
@@ -2232,9 +2232,9 @@ arg_list.append( ArgumentInfo(v8_type, v8_arg_name, blink_arg_name, symbol_node)) - arg_decls = (["v8::Local<v8::Object> v8_arg0_receiver"] + - map(lambda arg: "{} {}".format(arg.v8_type, arg.v8_arg_name), - arg_list) + + arg_decls = (["v8::Local<v8::Object> v8_arg0_receiver"] + list( + map(lambda arg: "{} {}".format(arg.v8_type, arg.v8_arg_name), + arg_list)) + ["v8::FastApiCallbackOptions& v8_arg_callback_options"]) return_type = ("void" if cg_context.operation.return_type.is_void else blink_type_info(cg_context.operation.return_type).value_t)
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc index 335d2875..d1328c8 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -548,10 +548,13 @@ NGLogicalLineItems* line_box) { DCHECK(item_result->layout_result); - // The input |position| is the line-left edge of the margin box. - // Adjust it to the border box by adding the line-left margin. - // const ComputedStyle& style = *item.Style(); - // position += item_result->margins.LineLeft(style.Direction()); + // Reset the ellipsizing state. Atomic inline is monolithic. + LayoutObject* layout_object = item.GetLayoutObject(); + DCHECK(layout_object); + DCHECK(layout_object->IsAtomicInlineLevel()); + DCHECK_EQ(To<LayoutBox>(layout_object)->GetNGPaginationBreakability(), + LayoutBox::kForbidBreaks); + layout_object->SetIsTruncated(false); item_result->has_edge = true; NGInlineBoxState* box =
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc index 6cfdc37d..a7260a4 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc
@@ -410,7 +410,12 @@ if (fragment.HasOutOfFlowPositionedDescendants()) return; - child->layout_result = fragment.CloneAsHiddenForPaint(); + // Truncate this object. Atomic inline is monolithic. + DCHECK(fragment.IsMonolithic()); + LayoutObject* layout_object = fragment.GetMutableLayoutObject(); + DCHECK(layout_object); + DCHECK(layout_object->IsAtomicInlineLevel()); + layout_object->SetIsTruncated(true); return; }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc index ac8bf4ea..60b95d2 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
@@ -512,19 +512,6 @@ : nullptr), table_cell_column_index(other.table_cell_column_index) {} -scoped_refptr<const NGLayoutResult> -NGPhysicalBoxFragment::CloneAsHiddenForPaint() const { - const ComputedStyle& style = Style(); - NGBoxFragmentBuilder builder(GetMutableLayoutObject(), &style, - style.GetWritingDirection()); - builder.SetBoxType(BoxType()); - NGFragmentGeometry initial_fragment_geometry{ - Size().ConvertToLogical(style.GetWritingMode())}; - builder.SetInitialFragmentGeometry(initial_fragment_geometry); - builder.SetIsHiddenForPaint(true); - return builder.ToBoxFragment(); -} - const LayoutBox* NGPhysicalBoxFragment::OwnerLayoutBox() const { const LayoutBox* owner_box = DynamicTo<LayoutBox>(GetSelfOrContainerLayoutObject());
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h index a9bb22f..c5e4b18 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
@@ -58,8 +58,6 @@ const PhysicalRect& layout_overflow, bool recalculate_layout_overflow); - scoped_refptr<const NGLayoutResult> CloneAsHiddenForPaint() const; - ~NGPhysicalBoxFragment() { ink_overflow_.Reset(InkOverflowType()); if (const_has_fragment_items_)
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h index 37c61b9c..fbb88ad 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
@@ -343,7 +343,9 @@ // This fragment is hidden for paint purpose, but exists for querying layout // information. Used for `text-overflow: ellipsis`. - bool IsHiddenForPaint() const { return is_hidden_for_paint_; } + bool IsHiddenForPaint() const { + return is_hidden_for_paint_ || layout_object_->IsTruncated(); + } // Return true if this fragment is monolithic, as far as block fragmentation // is concerned.
diff --git a/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc b/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc index 44185845..d1f3ee0 100644 --- a/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc +++ b/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc
@@ -460,6 +460,10 @@ !base::FeatureList::IsEnabled(features::kSpeculationRulesPrefetchProxy)) { return false; } + if (trial_name == "ConversionMeasurement" && + !base::FeatureList::IsEnabled(features::kConversionMeasurement)) { + return false; + } return true; }
diff --git a/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc b/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc index c196239..04e80a8 100644 --- a/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc +++ b/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc
@@ -185,6 +185,8 @@ media::mojom::blink::MediaContainerName container_name) override {} void SetRendererType( media::mojom::blink::RendererType renderer_type) override {} + void SetKeySystem(const String& key_system) override {} + void SetIsHardwareSecure() override {} void SetHasPlayed() override {} void SetHaveEnough() override {} void SetHasAudio(media::mojom::AudioCodec audio_codec) override {}
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index 7a4bfa26..1870532e 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -662,10 +662,6 @@ RuntimeEnabledFeatures::SetRestrictGamepadAccessEnabled(enable); } -void WebRuntimeFeatures::EnableConversionMeasurementInfraSupport(bool enable) { - RuntimeEnabledFeatures::SetConversionMeasurementInfraSupportEnabled(enable); -} - void WebRuntimeFeatures::EnableParseUrlProtocolHandler(bool enable) { RuntimeEnabledFeatures::SetParseUrlProtocolHandlerEnabled(enable); }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 17fbb1a..ea4e277a 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -424,12 +424,6 @@ origin_trial_feature_name: "ConversionMeasurement", origin_trial_allows_third_party: true, status: "experimental", - depends_on: ["ConversionMeasurementInfraSupport"], - }, - { - // Feature to explicitly disable/enable the Conversion - // Measurement API when there is not browser process side infra. - name: "ConversionMeasurementInfraSupport", }, { name: "CookiesWithoutSameSiteMustBeSecure",
diff --git a/third_party/blink/renderer/platform/wtf/text/atomic_string.h b/third_party/blink/renderer/platform/wtf/text/atomic_string.h index a533ffaa..b36b2e90 100644 --- a/third_party/blink/renderer/platform/wtf/text/atomic_string.h +++ b/third_party/blink/renderer/platform/wtf/text/atomic_string.h
@@ -274,7 +274,6 @@ } // Define external global variables for the commonly used atomic strings. -// These are only usable from the main thread. WTF_EXPORT extern const AtomicString& g_null_atom; WTF_EXPORT extern const AtomicString& g_empty_atom; WTF_EXPORT extern const AtomicString& g_star_atom;
diff --git a/third_party/blink/renderer/platform/wtf/text/string_statics.cc b/third_party/blink/renderer/platform/wtf/text/string_statics.cc index aeb0d1d2..3c90f13d 100644 --- a/third_party/blink/renderer/platform/wtf/text/string_statics.cc +++ b/third_party/blink/renderer/platform/wtf/text/string_statics.cc
@@ -83,7 +83,8 @@ String(StringImpl::empty16_bit_); // FIXME: These should be allocated at compile time. - new (NotNullTag::kNotNull, (void*)&g_star_atom) AtomicString("*"); + new (NotNullTag::kNotNull, (void*)&g_star_atom) + AtomicString(AddStaticASCIILiteral("*")); new (NotNullTag::kNotNull, (void*)&g_xml_atom) AtomicString(AddStaticASCIILiteral("xml")); new (NotNullTag::kNotNull, (void*)&g_xmlns_atom)
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-after-full-event.html b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-after-full-event.html index 84d257e..43dc3d8 100644 --- a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-after-full-event.html +++ b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-after-full-event.html
@@ -2,84 +2,26 @@ <html> <head> <meta charset="utf-8"> -<link rel="help" href="https://w3c.github.io/resource-timing/#dom-performance-setresourcetimingbuffersize"> +<link rel="author" title="Google" href="http://www.google.com/" /> +<link rel="help" href="https://www.w3.org/TR/resource-timing-2/#dom-performance-setresourcetimingbuffersize"> <title>This test validates that setResourceTimingBufferFull behaves appropriately when set to the current buffer level.</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/resource-loaders.js"></script> <script src="resources/buffer-full-utilities.js"></script> </head> <body> <script> -let eventFired = false; -let loadRandomResource = () => { - return fetch(window.location.href + "?" + Math.random()).then(r => r.text()); -} - -setup(() => { - // Get the browser into a consistent state. - clearBufferAndSetSize(100); -}); - -let loadResourcesToFillFutureBuffer = () => { +promise_test(async t => { + await forceBufferFullEvent(); + performance.clearResourceTimings(); return new Promise(resolve => { - // Gather up 3 Resource Entries to kick off the rest of test behavior. - let resources = 0; - let observer = new PerformanceObserver(function(list) { - resources += list.getEntriesByType("resource").length; - if (resources !== 3) - return; - observer.disconnect(); - resolve(); - }); - observer.observe({entryTypes: ["resource"]}); - for (let i = 0; i < 3; ++i) - loadRandomResource(); + new PerformanceObserver(t.step_func(() => { + assert_equals(performance.getEntriesByType('resource').length, 1, + 'The entry should be available in the performance timeline!'); + resolve(); + })).observe({type: 'resource'}); + load.script(scriptResources[2]); }); -}; - -let setBufferFullEventAndBufferSize = () => { - performance.setResourceTimingBufferSize(3); - performance.onresourcetimingbufferfull = function() { - eventFired = true; - performance.clearResourceTimings(); - }; -}; - -let clearAndAddAnotherEntryToBuffer = () => { - return new Promise(resolve => { - performance.clearResourceTimings(); - loadRandomResource().then(resolve); - }); -}; - -let testThatEntryWasAdded = () => { - let tries = 1; - let maxTries = 5; - return waitUntilConditionIsMet( function() { - if (performance.getEntriesByType("resource").length) { - return true; - } else { - if (tries < maxTries) { - tries++; - return false; - } else { - return true; - } - } - }).then( () => { - assert_true((performance.getEntriesByType("resource").length) === 1); - }); -}; - -promise_test(async () => { - await loadResourcesToFillFutureBuffer(); - setBufferFullEventAndBufferSize(); - // Overflow the buffer. - await loadRandomResource(); - await waitForEventToFire(); - await clearAndAddAnotherEntryToBuffer(); - // Since we have no strict guarantees when an entry will be added to the - // buffer, waiting till next task to try to avoid flakiness. - await testThatEntryWasAdded(); }, "Test that entry was added to the buffer after a buffer full event"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-entries-during-callback-that-drop.html b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-entries-during-callback-that-drop.html index d61d2af0..b00185c5 100644 --- a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-entries-during-callback-that-drop.html +++ b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-entries-during-callback-that-drop.html
@@ -3,48 +3,26 @@ <head onload> <meta charset="utf-8" /> <title>This test validates that synchronously adding entries in onresourcetimingbufferfull callback results in these entries being properly handled.</title> -<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> +<link rel="author" title="Google" href="http://www.google.com/" /> +<link rel="help" href="https://www.w3.org/TR/resource-timing-2/#dom-performance-onresourcetimingbufferfull"/> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/resource-loaders.js"></script> <script src="resources/buffer-full-utilities.js"></script> </head> <body> <script> -const resource_timing_buffer_size = 1; - -setup(() => { - // Get the browser into a consistent state. - clearBufferAndSetSize(resource_timing_buffer_size); -}); - -let overflowTheBufferAndWaitForEvent = () => { - return new Promise(resolve => { - var add_entry = () => { - performance.setResourceTimingBufferSize(resource_timing_buffer_size + 1); - // The sync entry is added to the secondary buffer, so will be the last one there and eventually dropped. - xhrScript("resources/empty.js?xhr"); - resolve(); - } - performance.addEventListener('resourcetimingbufferfull', add_entry); - // This resource overflows the entry buffer, and goes into the secondary buffer. - appendScript('resources/empty_script.js'); - }); -}; - -let testThatBufferContainsTheRightResources = () => { - let entries = performance.getEntriesByType('resource'); - assert_equals(entries.length, 2, - 'Both entries should be stored in resource timing buffer since its increases size once it overflows.'); - assert_true(entries[0].name.includes('empty.js'), "empty.js is in the entries buffer"); - assert_true(entries[1].name.includes('empty_script.js'), "empty_script.js is in the entries buffer"); -}; - promise_test(async () => { - await fillUpTheBufferWithSingleResource("resources/empty.js"); - await overflowTheBufferAndWaitForEvent(); - // TODO(yoav): Figure out why this task is needed - await waitForNextTask(); - testThatBufferContainsTheRightResources(); + await fillUpTheBufferWithSingleResource(); + performance.addEventListener('resourcetimingbufferfull', () => { + performance.setResourceTimingBufferSize(2); + // The sync entry is added to the secondary buffer, so will be the last one there and eventually dropped. + load.xhr_sync(scriptResources[2]); + }); + // This resource overflows the entry buffer, and goes into the secondary buffer. + load.script(scriptResources[1]); + await bufferFullFirePromise; + checkEntries(2); }, "Test that entries synchronously added to the buffer during the callback are dropped"); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-entries-during-callback.html b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-entries-during-callback.html index b37c47b..d5883d3 100644 --- a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-entries-during-callback.html +++ b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-entries-during-callback.html
@@ -3,47 +3,25 @@ <head onload> <meta charset="utf-8" /> <title>This test validates that synchronously adding entries in onresourcetimingbufferfull callback results in these entries being properly handled.</title> -<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> +<link rel="author" title="Google" href="http://www.google.com/" /> +<link rel="help" href="https://www.w3.org/TR/resource-timing-2/#dom-performance-onresourcetimingbufferfull"/> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/resource-loaders.js"></script> <script src="resources/buffer-full-utilities.js"></script> </head> <body> <script> -const resource_timing_buffer_size = 1; - -setup(() => { - // Get the browser into a consistent state. - clearBufferAndSetSize(resource_timing_buffer_size); -}); - -let overflowTheBufferAndWaitForEvent = () => { - return new Promise(resolve => { - var add_entry = () => { - performance.setResourceTimingBufferSize(resource_timing_buffer_size + 2); - xhrScript("resources/empty.js?xhr"); - resolve(); - } - performance.addEventListener('resourcetimingbufferfull', add_entry); - // This resource overflows the entry buffer, and goes into the secondary buffer. - appendScript('resources/empty_script.js'); - }); -}; - -let testThatBufferContainsTheRightResources = () => { - let entries = performance.getEntriesByType('resource'); - assert_equals(entries.length, 3, - 'All entries should be stored in resource timing buffer since its increases size once it overflows.'); - assert_true(entries[0].name.includes('empty.js'), "empty.js is in the entries buffer"); - assert_true(entries[1].name.includes('empty_script.js'), "empty_script.js is in the entries buffer"); - assert_true(entries[2].name.includes('empty.js?xhr'), "empty.js?xhr is in the entries buffer"); -}; - promise_test(async () => { - await fillUpTheBufferWithSingleResource("resources/empty.js"); - await overflowTheBufferAndWaitForEvent(); - await waitForNextTask(); - testThatBufferContainsTheRightResources(); + await fillUpTheBufferWithSingleResource(); + performance.addEventListener('resourcetimingbufferfull', () => { + performance.setResourceTimingBufferSize(3); + load.xhr_sync(scriptResources[2]); + }); + // This resource overflows the entry buffer, and goes into the secondary buffer. + load.script(scriptResources[1]); + await bufferFullFirePromise; + checkEntries(3); }, "Test that entries synchronously added to the buffer during the callback don't get dropped if the buffer is increased"); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-then-clear.html b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-then-clear.html index 710852c..5617c30 100644 --- a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-then-clear.html +++ b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-then-clear.html
@@ -3,46 +3,28 @@ <head onload> <meta charset="utf-8" /> <title>This test validates that synchronously adding entries in onresourcetimingbufferfull callback results in these entries being properly handled.</title> -<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> +<link rel="author" title="Google" href="http://www.google.com/" /> +<link rel="help" href="https://www.w3.org/TR/resource-timing-2/#dom-performance-onresourcetimingbufferfull"/> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/resource-loaders.js"></script> <script src="resources/buffer-full-utilities.js"></script> </head> <body> <script> -const resource_timing_buffer_size = 1; - -setup(() => { - // Get the browser into a consistent state. - clearBufferAndSetSize(resource_timing_buffer_size); - performance.addEventListener('resourcetimingbufferfull', () => { assert_unreached("resourcetimingbufferfull should not fire")}); -}); - -let overflowTheBuffer = () => { +promise_test(async t => { + addAssertUnreachedBufferFull(t); + await fillUpTheBufferWithSingleResource('resources/empty.js?willbelost'); // These resources overflow the entry buffer, and go into the secondary buffer. - xhrScript('resources/empty.js?xhr2'); - xhrScript('resources/empty.js?xhr3'); + load.xhr_sync(scriptResources[0]); + load.xhr_sync(scriptResources[1]); performance.clearResourceTimings(); performance.setResourceTimingBufferSize(3); - xhrScript('resources/empty.js?xhr4'); - window.entriesAfterAddition = performance.getEntriesByType('resource'); -}; - -let testThatBufferContainsTheRightResources = () => { - let entries = performance.getEntriesByType('resource'); - assert_equals(entries.length, 3, - 'the last 3 resources should be in the buffer, since the first one was cleared'); - assert_true(entries[0].name.includes('empty.js?xhr2'), "empty.js?xhr2 is in the entries buffer"); - assert_true(entries[1].name.includes('empty.js?xhr3'), "empty.js?xhr3 is in the entries buffer"); - assert_true(entries[2].name.includes('empty.js?xhr4'), "empty.js?xhr4 is in the entries buffer"); - assert_equals(entriesAfterAddition.length, 0, "No entries should have been added to the primary buffer before the task to 'fire a buffer full event'."); -}; - -promise_test(async () => { - await fillUpTheBufferWithSingleResource("resources/empty.js"); - overflowTheBuffer(); + load.xhr_sync(scriptResources[2]); + const entriesAfterAddition = performance.getEntriesByType('resource'); await waitForNextTask(); - testThatBufferContainsTheRightResources(); + checkEntries(3); + assert_equals(entriesAfterAddition.length, 0, "No entries should have been added to the primary buffer before the task to 'fire a buffer full event'."); }, "Test that if the buffer is cleared after entries were added to the secondary buffer, those entries make it into the primary one"); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-decrease-buffer-during-callback.html b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-decrease-buffer-during-callback.html index e6de33d..3091fcf 100644 --- a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-decrease-buffer-during-callback.html +++ b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-decrease-buffer-during-callback.html
@@ -3,46 +3,23 @@ <head onload> <meta charset="utf-8" /> <title>This test validates that decreasing the buffer size in onresourcetimingbufferfull callback does not result in extra entries being dropped.</title> -<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> +<link rel="author" title="Google" href="http://www.google.com/" /> +<link rel="help" href="https://www.w3.org/TR/resource-timing-2/#dom-performance-onresourcetimingbufferfull"/> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/resource-loaders.js"></script> <script src="resources/buffer-full-utilities.js"></script> </head> <body> <script> -const resource_timing_buffer_size = 2; -let eventFired = false; -setup(() => { - // Get the browser into a consistent state. - clearBufferAndSetSize(resource_timing_buffer_size); - let resize = () => { - performance.setResourceTimingBufferSize(resource_timing_buffer_size - 1); - eventFired = true; - } - performance.addEventListener('resourcetimingbufferfull', resize); -}); - -let overflowTheBuffer = () => { - return new Promise(resolve => { - // This resource overflows the entry buffer, and goes into the secondary buffer. - // Since the buffer size doesn't increase, it will eventually be dropped. - appendScript('resources/empty_script.js', resolve); - }); -}; - -let testThatBufferContainsTheRightResources = () => { - let entries = performance.getEntriesByType('resource'); - assert_equals(entries.length, 2, - 'Both entries should be stored in resource timing buffer since it decreased its limit only after it overflowed.'); - assert_true(entries[0].name.includes('empty.js'), "empty.js is in the entries buffer"); - assert_true(entries[1].name.includes('empty.js?second'), "empty.js?second is in the entries buffer"); -}; - promise_test(async () => { - await fillUpTheBufferWithTwoResources('resources/empty.js'); - await overflowTheBuffer(); - await waitForEventToFire(); - testThatBufferContainsTheRightResources(); + performance.addEventListener('resourcetimingbufferfull', () => { + performance.setResourceTimingBufferSize(1); + }); + await fillUpTheBufferWithTwoResources(); + load.script(scriptResources[2]); + await bufferFullFirePromise; + checkEntries(2); }, "Test that decreasing the buffer limit during the callback does not drop entries"); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-increase-buffer-during-callback.html b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-increase-buffer-during-callback.html index b46d2d65..dd12dd7 100644 --- a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-increase-buffer-during-callback.html +++ b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-increase-buffer-during-callback.html
@@ -3,46 +3,23 @@ <head onload> <meta charset="utf-8" /> <title>This test validates increasing the buffer size in onresourcetimingbufferfull callback of resource timing.</title> -<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> +<link rel="author" title="Google" href="http://www.google.com/" /> +<link rel="help" href="https://www.w3.org/TR/resource-timing-2/#dom-performance-onresourcetimingbufferfull"/> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/resource-loaders.js"></script> <script src="resources/buffer-full-utilities.js"></script> </head> <body> <script> -const resource_timing_buffer_size = 1; -let eventFired = false; - -setup(() => { - // Get the browser into a consistent state. - clearBufferAndSetSize(resource_timing_buffer_size); - var increase = function() { - performance.setResourceTimingBufferSize(resource_timing_buffer_size * 2); - eventFired = true; - } - performance.addEventListener('resourcetimingbufferfull', increase); -}); - -let overflowTheBuffer = () => { - return new Promise(resolve => { - // This resource overflows the entry buffer, and goes into the secondary buffer. - appendScript('resources/empty_script.js', resolve); - }); -}; - -let testThatBufferContainsTheRightResources = () => { - let entries = performance.getEntriesByType('resource'); - assert_equals(entries.length, 2, - 'Both entries should be stored in resource timing buffer since its increases size once it overflows.'); - assert_true(entries[0].name.includes('empty.js'), "empty.js is in the entries buffer"); - assert_true(entries[1].name.includes('empty_script.js'), "empty_script.js is in the entries buffer"); -}; - promise_test(async () => { - await fillUpTheBufferWithSingleResource("resources/empty.js"); - await overflowTheBuffer(); - await waitForEventToFire(); - testThatBufferContainsTheRightResources(); + await fillUpTheBufferWithSingleResource(); + performance.addEventListener('resourcetimingbufferfull', () => { + performance.setResourceTimingBufferSize(2); + }); + await load.script(scriptResources[1]); + await bufferFullFirePromise; + checkEntries(2); }, "Test that increasing the buffer during the callback is enough for entries not to be dropped"); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-inspect-buffer-during-callback.html b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-inspect-buffer-during-callback.html index d46d469..d5cc8e6 100644 --- a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-inspect-buffer-during-callback.html +++ b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-inspect-buffer-during-callback.html
@@ -3,53 +3,27 @@ <head onload> <meta charset="utf-8" /> <title>This test validates the buffer doesn't contain more entries than it should inside onresourcetimingbufferfull callback.</title> -<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> +<link rel="author" title="Google" href="http://www.google.com/" /> +<link rel="help" href="https://www.w3.org/TR/resource-timing-2/#dom-performance-setresourcetimingbuffersize"/> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/resource-loaders.js"></script> <script src="resources/buffer-full-utilities.js"></script> </head> <body> <script> -let resource_timing_buffer_size = 2; -let eventFired = false; - -setup(() => { - clearBufferAndSetSize(resource_timing_buffer_size); - var resize = function() { - assert_equals(performance.getEntriesByType("resource").length, resource_timing_buffer_size, "resource timing buffer in resourcetimingbufferfull is the size of the limit"); - ++resource_timing_buffer_size; - performance.setResourceTimingBufferSize(resource_timing_buffer_size); - xhrScript("resources/empty.js?xhr"); - assert_equals(performance.getEntriesByType("resource").length, resource_timing_buffer_size - 1, "A sync request was not added to the primary buffer just yet, because it is full"); - ++resource_timing_buffer_size; - performance.setResourceTimingBufferSize(resource_timing_buffer_size); - eventFired = true; - } - performance.addEventListener('resourcetimingbufferfull', resize); -}); - -let overflowTheBuffer = () => { - return new Promise(resolve => { - // This resource overflows the entry buffer, and goes into the secondary buffer. - appendScript('resources/empty_script.js', resolve); - }); -}; - -let testThatBufferContainsTheRightResources = () => { - let entries = performance.getEntriesByType('resource'); - assert_equals(entries.length, resource_timing_buffer_size, - 'All 4 entries should be stored in resource timing buffer.'); - assert_true(entries[0].name.includes('empty.js'), "empty.js is in the entries buffer"); - assert_true(entries[1].name.includes('empty.js?second'), "empty.js?second is in the entries buffer"); - assert_true(entries[2].name.includes('empty_script.js'), "empty_script.js is in the entries buffer"); - assert_true(entries[3].name.includes('empty.js?xhr'), "empty.js?xhr is in the entries buffer"); -}; - -promise_test(async () => { - await fillUpTheBufferWithTwoResources('resources/empty.js'); - await overflowTheBuffer(); - await waitForEventToFire(); - testThatBufferContainsTheRightResources(); +promise_test(async t => { + performance.addEventListener('resourcetimingbufferfull', t.step_func(() => { + assert_equals(performance.getEntriesByType("resource").length, 1, + "resource timing buffer in resourcetimingbufferfull is the size of the limit"); + load.xhr_sync(scriptResources[2]); + performance.setResourceTimingBufferSize(3); + assert_equals(performance.getEntriesByType("resource").length, 1, + "A sync request must not be added to the primary buffer just yet, because it is full"); + })); + await forceBufferFullEvent(); + await waitForNextTask(); + checkEntries(3); }, "Test that entries in the secondary buffer are not exposed during the callback and before they are copied to the primary buffer"); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-set-to-current-buffer.html b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-set-to-current-buffer.html index 1e5486ec..dc527b9a 100644 --- a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-set-to-current-buffer.html +++ b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-set-to-current-buffer.html
@@ -2,81 +2,33 @@ <html> <head> <meta charset="utf-8"> -<link rel="help" href="https://w3c.github.io/resource-timing/#dom-performance-setresourcetimingbuffersize"> <title>This test validates that setResourceTimingBufferFull behaves appropriately when set to the current buffer level.</title> +<link rel="author" title="Google" href="http://www.google.com/" /> +<link rel="help" href="https://www.w3.org/TR/resource-timing-2/#dom-performance-onresourcetimingbufferfull"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/resource-loaders.js"></script> <script src="resources/buffer-full-utilities.js"></script> </head> <body> <script> -let eventFired = false; - -let loadRandomResource = () => { - return fetch(window.location.href + "?" + Math.random()); -}; - -setup(() => { - // Get the browser into a consistent state. - clearBufferAndSetSize(100); - window.result = ""; -}); - -let fillUpTheBuffer = () => { - return new Promise(resolve => { - // Gather up 3 Resource Entries to kick off the rest of test behavior. - let resources = 0; - let observer = new PerformanceObserver(list => { - resources += list.getEntriesByType("resource").length; - if (resources !== 3) - return; - observer.disconnect(); - resolve(); - }); - observer.observe({entryTypes: ["resource"]}); - for (let i = 0; i < 3; ++i) - loadRandomResource(); - }); -}; - -let setBufferSize = () => { - performance.onresourcetimingbufferfull = () => { - eventFired = true; - window.result += "Event Fired with " + performance.getEntriesByType("resource").length + " entries. "; - performance.clearResourceTimings(); - }; - window.result += "before setLimit(3). "; - performance.setResourceTimingBufferSize(3); - window.result += "after setLimit(3). "; -}; - -let overflowTheBuffer = () => { - return new Promise(resolve => { - loadRandomResource().then(() => { - window.result += "after loading 4th resource. "; - resolve(); - }); - }); -}; - -let checkResult = () => { - return new Promise((resolve, reject) => { - if (window.result != "before setLimit(3). after setLimit(3). after loading 4th resource. Event Fired with 3 entries. ") { - reject("Non matching value: " + window.result); - } - let entries = performance.getEntriesByType("resource"); - if (entries.length != 1) { - reject("Number of entries in resource timing buffer is unexpected: " + entries.length); - } - resolve(); - }); -}; - promise_test(async () => { - await fillUpTheBuffer(); - setBufferSize(); - await overflowTheBuffer(); - await waitForEventToFire(); - await checkResult(); -}, "Test that entries added and event firing happened in the right sequence"); + let result = ''; + performance.addEventListener('resourcetimingbufferfull', () => { + result += 'Event Fired with ' + + performance.getEntriesByType('resource').length + ' entries.'; + performance.clearResourceTimings(); + }); + result += 'Before adding entries. '; + await fillUpTheBufferWithTwoResources(); + result += 'After adding entries. '; + load.script(scriptResources[2]); + await bufferFullFirePromise; + assert_equals(result, 'Before adding entries. After adding entries. Event Fired with 2 entries.'); + const entries = performance.getEntriesByType('resource'); + assert_equals(entries.length, 1, + 'Number of entries in resource timing buffer is unexpected'); + assert_true(entries[0].name.includes(scriptResources[2]), + 'The entry must correspond to the last resource loaded.') +}, "Test that adding entries and firing the buffer full event happen in the right order."); </script>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-store-and-clear-during-callback.html b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-store-and-clear-during-callback.html index f0791cba..3ea05772 100644 --- a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-store-and-clear-during-callback.html +++ b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-store-and-clear-during-callback.html
@@ -4,52 +4,33 @@ <meta charset="utf-8" /> <title>This test validates the behavior of read and clear operation in onresourcetimingbufferfull callback of resource timing.</title> <link rel="author" title="Intel" href="http://www.intel.com/" /> -<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> +<link rel="help" href="https://www.w3.org/TR/resource-timing-2/#dom-performance-onresourcetimingbufferfull"/> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/resource-loaders.js"></script> <script src="resources/buffer-full-utilities.js"></script> </head> <body> <script> -const resource_timing_buffer_size = 1; -let global_buffer = []; -let eventFired = false; - -setup(() => { - clearBufferAndSetSize(resource_timing_buffer_size); - let store_and_clear = function() { - const entryList = performance.getEntriesByType('resource'); - entryList.forEach(function (entry) { - global_buffer.push(entry); - }); - performance.clearResourceTimings(); - eventFired = true; - } - performance.addEventListener('resourcetimingbufferfull', store_and_clear); -}); - -let overflowTheBuffer = () => { - return new Promise(resolve => { - // This resource overflows the entry buffer, and goes into the secondary buffer. - appendScript('resources/empty_script.js', resolve); - }); -}; - -let testThatBufferContainsTheRightResources = () => { - let entries = performance.getEntriesByType('resource'); - assert_equals(entries.length, 1, - "Only the last entry should be stored in resource timing buffer since it's cleared once it overflows."); - assert_equals(global_buffer.length, 1, '1 resource timing entry should be moved to global buffer.'); - assert_true(global_buffer[0].name.includes('empty.js'), "empty.js is in the global buffer"); - assert_true(entries[0].name.includes('empty_script.js'), "empty_script.js is in the entries buffer"); -}; - promise_test(async () => { - await fillUpTheBufferWithSingleResource("resources/empty.js"); - await overflowTheBuffer(); - await waitForEventToFire(); - testThatBufferContainsTheRightResources(); -}, "Test that entries overflowing the buffer trigger the buffer full event, can be stored, and find themselves in the primary buffer after it's cleared."); + await fillUpTheBufferWithSingleResource(); + const entryBuffer = []; + performance.addEventListener('resourcetimingbufferfull', () => { + entryBuffer.push(...performance.getEntriesByType('resource')); + performance.clearResourceTimings(); + }); + load.script(scriptResources[1]); + await bufferFullFirePromise; + const entries = performance.getEntriesByType('resource'); + assert_equals(entries.length, 1, + "Only the last entry should be stored in resource timing buffer since it's cleared once it overflows."); + assert_true(entries[0].name.includes(scriptResources[1]), + scriptResources[1] + " is in the entries buffer"); + assert_equals(entryBuffer.length, 1, + '1 resource timing entry should be moved to entryBuffer.'); + assert_true(entryBuffer[0].name.includes(scriptResources[0]), + scriptResources[0] + ' is in the entryBuffer'); +}, "Test that entries overflowing the buffer trigger the buffer full event, can be stored, and make their way to the primary buffer after it's cleared in the buffer full event."); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-then-increased.html b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-then-increased.html index 2265077..de517bf4 100644 --- a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-then-increased.html +++ b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-then-increased.html
@@ -3,41 +3,25 @@ <head onload> <meta charset="utf-8" /> <title>This test validates that synchronously adding entries in onresourcetimingbufferfull callback results in these entries being properly handled.</title> -<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> +<link rel="author" title="Google" href="http://www.google.com/" /> +<link rel="help" href="https://www.w3.org/TR/resource-timing-2/#dom-performance-onresourcetimingbufferfull"/> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/resource-loaders.js"></script> <script src="resources/buffer-full-utilities.js"></script> </head> <body> <script> -const resource_timing_buffer_size = 1; - -setup(() => { - clearBufferAndSetSize(resource_timing_buffer_size); - performance.addEventListener('resourcetimingbufferfull', () => { assert_unreached("resourcetimingbufferfull should not fire"); }); -}); - -let overflowTheBuffer = () => { +promise_test(async t => { + addAssertUnreachedBufferFull(t); + await fillUpTheBufferWithSingleResource(); // These resources overflow the entry buffer, and go into the secondary buffer. - xhrScript('resources/empty.js?xhr2'); - xhrScript('resources/empty.js?xhr3'); + load.xhr_sync(scriptResources[1]); + load.xhr_sync(scriptResources[2]); + // Immediately increase the size: the bufferfull event should not be fired. performance.setResourceTimingBufferSize(3); -}; - -let testThatBufferContainsTheRightResources = () => { - let entries = performance.getEntriesByType('resource'); - assert_equals(entries.length, 3, - 'All resources should be in the buffer, since its size was increased'); - assert_true(entries[0].name.includes('empty.js'), "empty.js?xhr2 is in the entries buffer"); - assert_true(entries[1].name.includes('empty.js?xhr2'), "empty.js?xhr3 is in the entries buffer"); - assert_true(entries[2].name.includes('empty.js?xhr3'), "empty.js?xhr3 is in the entries buffer"); -}; - -promise_test(async () => { - await fillUpTheBufferWithSingleResource("resources/empty.js"); - overflowTheBuffer(); await waitForNextTask(); - testThatBufferContainsTheRightResources(); + checkEntries(3); }, "Test that overflowing the buffer and immediately increasing its limit does not trigger the resourcetimingbufferfull event"); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-when-populate-entries.html b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-when-populate-entries.html index 00d2ae0..f4b1a2e 100644 --- a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-when-populate-entries.html +++ b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-when-populate-entries.html
@@ -2,44 +2,28 @@ <html> <head> <meta charset="utf-8" /> -<link rel="author" title="Intel" href="http://www.intel.com/" /> -<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> <title>This test validates the functionality of onresourcetimingbufferfull in resource timing.</title> +<link rel="author" title="Intel" href="http://www.intel.com/" /> +<link rel="help" href="https://www.w3.org/TR/resource-timing-2/#dom-performance-onresourcetimingbufferfull"/> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/resource-loaders.js"></script> <script src="resources/buffer-full-utilities.js"></script> </head> <body> <script> -const resource_timing_buffer_size = 2; -let bufferFullCount = 0; -let eventFired = false; -setup(() => { - clearBufferAndSetSize(resource_timing_buffer_size); +promise_test(async () => { + let bufferFullCount = 0; performance.addEventListener('resourcetimingbufferfull', e => { assert_equals(e.bubbles, false, "Event bubbles attribute is false"); bufferFullCount++; - eventFired = true; }); -}); - -let overflowTheBuffer = () => { - return new Promise(resolve => { - // This resource overflows the entry buffer, and goes into the secondary buffer. - appendScript('resources/empty_script.js', resolve); - }); -}; - -let testThatBufferContainsTheRightResources = () => { - assert_equals(performance.getEntriesByType('resource').length, resource_timing_buffer_size, 'There should only be |bufferSize| resource entries.'); + await fillUpTheBufferWithTwoResources(); + // Overflow the buffer + await load.script(scriptResources[2]); + await waitForNextTask(); + checkEntries(2); assert_equals(bufferFullCount, 1, 'onresourcetimingbufferfull should have been invoked once.'); -}; - -promise_test(async () => { - await fillUpTheBufferWithTwoResources('resources/empty.js'); - await overflowTheBuffer(); - await waitForEventToFire(); - testThatBufferContainsTheRightResources(); }, "Test that a buffer full event does not bubble and that resourcetimingbufferfull is called only once per overflow"); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/resources/buffer-full-utilities.js b/third_party/blink/web_tests/external/wpt/resource-timing/resources/buffer-full-utilities.js index e0a4f0b1..6cb1753 100644 --- a/third_party/blink/web_tests/external/wpt/resource-timing/resources/buffer-full-utilities.js +++ b/third_party/blink/web_tests/external/wpt/resource-timing/resources/buffer-full-utilities.js
@@ -1,71 +1,75 @@ -let appendScript = (src, resolve) => { - const script = document.createElement('script'); - script.type = 'text/javascript'; - script.src = src; - script.onload = resolve; - document.body.appendChild(script); -} +// This script relies on resources/resource-loaders.js. Include it before in order for the below +// methods to work properly. -let xhrScript = src => { - var xhr = new XMLHttpRequest(); - xhr.open("GET", src, false); - xhr.send(null); -} +// The resources used to trigger new entries. +const scriptResources = [ + 'resources/empty.js', + 'resources/empty_script.js', + 'resources/empty.js?id' +]; -let waitForNextTask = () => { +const waitForNextTask = () => { return new Promise(resolve => { step_timeout(resolve, 0); }); }; -let waitUntilConditionIsMet = cond => { - return new Promise(resolve => { - let checkCondition = function() { - if (cond.apply(null)) { - resolve(); - } else { - step_timeout(checkCondition.bind(null,cond), 0); - } - } - step_timeout(checkCondition.bind(null, cond), 0); - }); +const clearBufferAndSetSize = size => { + performance.clearResourceTimings(); + performance.setResourceTimingBufferSize(size); } -let waitForEventToFire = () => { - return new Promise(resolve => { - let waitForIt = function() { - if (eventFired) { - eventFired = false; - resolve(); - } else { - step_timeout(waitForIt, 0); - } - } - step_timeout(waitForIt, 0); - }); +const forceBufferFullEvent = async () => { + clearBufferAndSetSize(1); + return new Promise(async resolve => { + performance.addEventListener('resourcetimingbufferfull', resolve); + // Load 2 resources to ensure onresourcetimingbufferfull is fired. + // Load them in order in order to get the entries in that order! + await load.script(scriptResources[0]); + await load.script(scriptResources[1]); + }); }; -let clearBufferAndSetSize = size => { - performance.clearResourceTimings(); - performance.setResourceTimingBufferSize(size); +const fillUpTheBufferWithSingleResource = async (src = scriptResources[0]) => { + clearBufferAndSetSize(1); + await load.script(src); +}; + +const fillUpTheBufferWithTwoResources = async () => { + clearBufferAndSetSize(2); + // Load them in order in order to get the entries in that order! + await load.script(scriptResources[0]); + await load.script(scriptResources[1]); +}; + +const addAssertUnreachedBufferFull = t => { + performance.addEventListener('resourcetimingbufferfull', t.step_func(() => { + assert_unreached("resourcetimingbufferfull should not fire") + })); +}; + +const checkEntries = numEntries => { + const entries = performance.getEntriesByType('resource'); + assert_equals(entries.length, numEntries, + 'Number of entries does not match the expected value.'); + assert_true(entries[0].name.includes(scriptResources[0]), + scriptResources[0] + " is in the entries buffer"); + if (entries.length > 1) { + assert_true(entries[1].name.includes(scriptResources[1]), + scriptResources[1] + " is in the entries buffer"); + } + if (entries.length > 2) { + assert_true(entries[2].name.includes(scriptResources[2]), + scriptResources[2] + " is in the entries buffer"); + } } -let fillUpTheBufferWithSingleResource = src => { - return new Promise(resolve => { - // This resource gets buffered in the resource timing entry buffer. - appendScript(src, resolve); - }); -}; - -let loadResource = src => { - return new Promise(resolve => { - appendScript(src, resolve); - }); -}; - -let fillUpTheBufferWithTwoResources = async src => { - // These resources get buffered in the resource timing entry buffer. - await loadResource(src); - await loadResource(src + '?second'); -}; - +const bufferFullFirePromise = new Promise(resolve => { + performance.addEventListener('resourcetimingbufferfull', async () => { + // Wait for the next task just to ensure that all bufferfull events have fired, and to ensure + // that the secondary buffer is copied (as this is an event, there may be microtask checkpoints + // right after running an event handler). + await waitForNextTask(); + resolve(); + }); +});
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold.html index 2b57b4d..0a8e7a7 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold.html +++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold.html
@@ -59,7 +59,7 @@ function(task, should) { cancelTest(should, linearRampTest('linearRampToValueAtTime'), { valueThreshold: 8.3998e-5, - curveThreshold: 0 + curveThreshold: 5.9605e-5 }).then(task.done.bind(task)); }); @@ -247,7 +247,7 @@ summary: 'Initial setTargetAtTime', }; }, { - valueThreshold: 1.2320e-6, + valueThreshold: 3.1210e-6, curveThreshold: 0 }).then(task.done.bind(task)); }); @@ -269,7 +269,7 @@ cancelTest( should, linearRampTest('Post cancellation linearRampToValueAtTime'), - {valueThreshold: 8.3998e-5, curveThreshold: 0}, + {valueThreshold: 8.3998e-5, curveThreshold: 5.9605e-8}, function(g, cancelTime, expectedConstant) { // Schedule the linear ramp on g[0], and do the same for g[2], // using the starting point given by expectedConstant. @@ -298,7 +298,7 @@ cancelTest( should, linearRampTest('Post cancel exponentialRampToValueAtTime'), - {valueThreshold: 8.3998e-5, curveThreshold: 0}, + {valueThreshold: 8.3998e-5, curveThreshold: 5.9605e-8}, function(g, cancelTime, expectedConstant) { // Schedule the exponential ramp on g[0], and do the same for // g[2], using the starting point given by expectedConstant. @@ -320,7 +320,7 @@ // Then schedule a setValueCurve after the cancellation. cancelTest( should, linearRampTest('Post cancel setValueCurveAtTime'), - {valueThreshold: 8.3998e-5, curveThreshold: 0}, + {valueThreshold: 8.3998e-5, curveThreshold: 5.9605e-8}, function(g, cancelTime, expectedConstant) { // Schedule the exponential ramp on g[0], and do the same for // g[2], using the starting point given by expectedConstant. @@ -345,7 +345,7 @@ // Then schedule a setTarget after the cancellation. cancelTest( should, linearRampTest('Post cancel setTargetAtTime'), - {valueThreshold: 8.3998e-5, curveThreshold: 0}, + {valueThreshold: 8.3998e-5, curveThreshold: 5.9605e-8}, function(g, cancelTime, expectedConstant) { // Schedule the exponential ramp on g[0], and do the same for // g[2], using the starting point given by expectedConstant. @@ -370,7 +370,7 @@ // Then schedule a setTarget after the cancellation. cancelTest( should, linearRampTest('Post cancel setValueAtTime'), - {valueThreshold: 8.3998e-5, curveThreshold: 0}, + {valueThreshold: 8.3998e-5, curveThreshold: 5.9605e-8}, function(g, cancelTime, expectedConstant) { // Schedule the exponential ramp on g[0], and do the same for // g[2], using the starting point given by expectedConstant. @@ -494,7 +494,7 @@ cancelTest2( should, linearRampTest('1st linearRamp'), - {valueThreshold: 0, curveThreshold: 0}, + {valueThreshold: 0, curveThreshold: 5.9605e-8}, (g, cancelTime, expectedConstant, cancelTime2) => { // Ramp from first cancel time to the end will be cancelled at // second cancel time.
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html index 2eef895..b846f98 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html +++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html
@@ -206,7 +206,7 @@ `At time ${eventTime} (frame ${ eventFrame }) and later`) - .beCloseToArray(expected, {relativeThreshold: 1.7807e-7}); + .beCloseToArray(expected, {relativeThreshold: 2.6694e-7}); }) .then(() => task.done()); });
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/page/reload-with-oopifs-crash-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/page/reload-with-oopifs-crash-expected.txt new file mode 100644 index 0000000..596ea66 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/page/reload-with-oopifs-crash-expected.txt
@@ -0,0 +1,3 @@ +Tests that reload of an OOPIF page doesn't cause a crash +PASSED: alive and kicking! +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/page/reload-with-oopifs-crash.js b/third_party/blink/web_tests/http/tests/inspector-protocol/page/reload-with-oopifs-crash.js new file mode 100644 index 0000000..e9709d2 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/page/reload-with-oopifs-crash.js
@@ -0,0 +1,30 @@ +(async function(testRunner) { + const {session, dp} = await testRunner.startBlank( + `Tests that reload of an OOPIF page doesn't cause a crash`); + + dp.Target.setAutoAttach({autoAttach: true, flatten: true, waitForDebuggerOnStart: false}); + dp.Network.enable(); + + dp.Page.navigate({url: 'http://localhost:8000/inspector-protocol/resources/iframe-navigation.html'}); + + const oopifRequests = new Set(); + dp.Network.onRequestWillBeSent(event => { + const params = event.params; + if (/oopif/.test(params.request.url)) + oopifRequests.add(params.requestId); + }); + dp.Network.onLoadingFinished(event => { + if (!oopifRequests.has(event.params.requestId)) + return; + // Site isolation disabled, nothing to test here, bail out. + testRunner.log('PASSED: alive and kicking!'); + testRunner.completeTest(); + }); + const attachedEvent = await dp.Target.onceAttachedToTarget(); + session.evaluate(`location.reload()`); + await dp.Target.onceDetachedFromTarget(); + await dp.Target.onceAttachedToTarget(); + + testRunner.log('PASSED: alive and kicking!'); + testRunner.completeTest(); +}) \ No newline at end of file
diff --git a/third_party/blink/web_tests/webaudio/AudioParam/audioparam-setTargetAtTime-limit.html b/third_party/blink/web_tests/webaudio/AudioParam/audioparam-setTargetAtTime-limit.html index bf36d71..23d2938ea 100644 --- a/third_party/blink/web_tests/webaudio/AudioParam/audioparam-setTargetAtTime-limit.html +++ b/third_party/blink/web_tests/webaudio/AudioParam/audioparam-setTargetAtTime-limit.html
@@ -71,7 +71,7 @@ timeConstant: timeConstant, eps: limitThreshold, // Experimentally determined - threshold: 4.7470e-8, + threshold: 1.2591e-7, tailThreshold: {absoluteThreshold: 2.3310e-5} }).then(() => task.done()); }); @@ -104,7 +104,7 @@ duration, 0, targetValue, context.sampleRate, timeConstant); should(actual, 'Output') - .beCloseToArray(expected, {absoluteThreshold: 9.8172e-7}); + .beCloseToArray(expected, {absoluteThreshold: 5.0098e-6}); }) .then(() => task.done()); });
diff --git a/tools/json_comment_eater/json_comment_eater.py b/tools/json_comment_eater/json_comment_eater.py index 17a1525..8506772 100755 --- a/tools/json_comment_eater/json_comment_eater.py +++ b/tools/json_comment_eater/json_comment_eater.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/json_comment_eater/json_comment_eater_test.py b/tools/json_comment_eater/json_comment_eater_test.py index ae03474..d053faf 100755 --- a/tools/json_comment_eater/json_comment_eater_test.py +++ b/tools/json_comment_eater/json_comment_eater_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2013 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/json_schema_compiler/PRESUBMIT.py b/tools/json_schema_compiler/PRESUBMIT.py index 5c8a221a..ef37b32 100644 --- a/tools/json_schema_compiler/PRESUBMIT.py +++ b/tools/json_schema_compiler/PRESUBMIT.py
@@ -9,6 +9,7 @@ """ FILE_PATTERN = [ r'.+_test.py$' ] +USE_PYTHON3 = True def CheckChangeOnUpload(input_api, output_api): return input_api.canned_checks.RunUnitTestsInDirectory(
diff --git a/tools/json_schema_compiler/code_test.py b/tools/json_schema_compiler/code_test.py index 6d54ecc..151a6ea1 100755 --- a/tools/json_schema_compiler/code_test.py +++ b/tools/json_schema_compiler/code_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -10,7 +10,7 @@ def testAppend(self): c = Code() c.Append('line') - self.assertEquals('line', c.Render()) + self.assertEqual('line', c.Render()) def testBlock(self): c = Code() @@ -24,7 +24,7 @@ .Append('inner') .Eblock('out') ) - self.assertEquals( + self.assertEqual( 'line\n' 'sblock\n' ' inner\n' @@ -59,9 +59,9 @@ d = Code() a = Code() a.Concat(d) - self.assertEquals('', a.Render()) + self.assertEqual('', a.Render()) a.Concat(c) - self.assertEquals( + self.assertEqual( '1\n' ' 2\n' ' 2\n' @@ -85,11 +85,11 @@ c = Code() c.Append('%(var1)s %(var2)s %(var1)s') c.Substitute({'var1': 'one', 'var2': 'two'}) - self.assertEquals('one two one', c.Render()) + self.assertEqual('one two one', c.Render()) c.Append('%(var1)s %(var2)s %(var3)s') c.Append('%(var2)s %(var1)s %(var3)s') c.Substitute({'var1': 'one', 'var2': 'two', 'var3': 'three'}) - self.assertEquals( + self.assertEqual( 'one two one\n' 'one two three\n' 'two one three', @@ -121,7 +121,7 @@ 'that is, using a different word, length.') c = Code() c.Comment(long_comment) - self.assertEquals( + self.assertEqual( '// This comment is ninety one characters ' 'in longness, that is, using a different\n' '// word, length.', @@ -131,7 +131,7 @@ c.Comment(long_comment) c.Eblock('eblock') c.Comment(long_comment) - self.assertEquals( + self.assertEqual( 'sblock\n' ' // This comment is ninety one characters ' 'in longness, that is, using a\n' @@ -147,7 +147,7 @@ c.Comment('xxx') c.Comment(long_word) c.Comment('xxx') - self.assertEquals( + self.assertEqual( '// xxx\n' '// ' + 'x' * 100 + '\n' '// xxx', @@ -155,7 +155,7 @@ c = Code(indent_size=2, comment_length=40) c.Comment('Pretend this is a Closure Compiler style comment, which should ' 'both wrap and indent', comment_prefix=' * ', wrap_indent=4) - self.assertEquals( + self.assertEqual( ' * Pretend this is a Closure Compiler\n' ' * style comment, which should both\n' ' * wrap and indent', @@ -165,11 +165,11 @@ c = Code() c.Comment('20% of 80%s') c.Substitute({}) - self.assertEquals('// 20% of 80%s', c.Render()) + self.assertEqual('// 20% of 80%s', c.Render()) d = Code() d.Append('90') d.Concat(c) - self.assertEquals('90\n' + self.assertEqual('90\n' '// 20% of 80%s', d.Render()) @@ -202,14 +202,14 @@ d = Code() d.Append('And this.') c.Concat(d, new_line=False) - self.assertEquals('This is a line.This too.And this.', c.Render()) + self.assertEqual('This is a line.This too.And this.', c.Render()) c = Code() c.Append('This is a') c.Comment(' spectacular 80-character line thingy ' + 'that fits wonderfully everywhere.', comment_prefix='', new_line=False) - self.assertEquals('This is a spectacular 80-character line thingy that ' + + self.assertEqual('This is a spectacular 80-character line thingy that ' + 'fits wonderfully everywhere.', c.Render())
diff --git a/tools/json_schema_compiler/compiler.py b/tools/json_schema_compiler/compiler.py index 216146b..6e69905 100755 --- a/tools/json_schema_compiler/compiler.py +++ b/tools/json_schema_compiler/compiler.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/json_schema_compiler/cpp_bundle_generator_test.py b/tools/json_schema_compiler/cpp_bundle_generator_test.py index 172fecae6..69fa42cf 100755 --- a/tools/json_schema_compiler/cpp_bundle_generator_test.py +++ b/tools/json_schema_compiler/cpp_bundle_generator_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2016 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -21,20 +21,20 @@ def _getPlatformIfdefs(cpp_bundle_generator, model): return cpp_bundle_generator._GetPlatformIfdefs( - model.namespaces.values()[0].functions.values()[0]) + list(list(model.namespaces.values())[0].functions.values())[0]) class CppBundleGeneratorTest(unittest.TestCase): def testIfDefsForWinLinux(self): cpp_bundle_generator, model = _createCppBundleGenerator( 'test/function_platform_win_linux.json') - self.assertEquals( + self.assertEqual( 'defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))', _getPlatformIfdefs(cpp_bundle_generator, model)) def testIfDefsForAll(self): cpp_bundle_generator, model = _createCppBundleGenerator( 'test/function_platform_all.json') - self.assertEquals( + self.assertEqual( 'defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) || ' '(defined(OS_CHROMEOS) && !BUILDFLAG(IS_CHROMEOS_LACROS))', _getPlatformIfdefs(cpp_bundle_generator, model)) @@ -42,7 +42,7 @@ def testIfDefsForChromeOS(self): cpp_bundle_generator, model = _createCppBundleGenerator( 'test/function_platform_chromeos.json') - self.assertEquals('(defined(OS_CHROMEOS) && ' + self.assertEqual('(defined(OS_CHROMEOS) && ' '!BUILDFLAG(IS_CHROMEOS_LACROS))', _getPlatformIfdefs(cpp_bundle_generator, model))
diff --git a/tools/json_schema_compiler/cpp_type_generator.py b/tools/json_schema_compiler/cpp_type_generator.py index 4e394f1d..4cae3c11 100644 --- a/tools/json_schema_compiler/cpp_type_generator.py +++ b/tools/json_schema_compiler/cpp_type_generator.py
@@ -32,7 +32,7 @@ """ self._default_namespace = default_namespace if self._default_namespace is None: - self._default_namespace = model.namespaces.values()[0] + self._default_namespace = list(model.namespaces.values())[0] self._namespace_resolver = namespace_resolver def GetEnumNoneValue(self, type_):
diff --git a/tools/json_schema_compiler/cpp_type_generator_test.py b/tools/json_schema_compiler/cpp_type_generator_test.py index 3aaa575a..8ac7f7dc2 100755 --- a/tools/json_schema_compiler/cpp_type_generator_test.py +++ b/tools/json_schema_compiler/cpp_type_generator_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -86,10 +86,10 @@ environment=CppNamespaceEnvironment('%(namespace)s')) manager = CppTypeGenerator(m, _FakeSchemaLoader(m)) - self.assertEquals('', manager.GenerateIncludes().Render()) - self.assertEquals('#include "path/to/tabs.h"', + self.assertEqual('', manager.GenerateIncludes().Render()) + self.assertEqual('#include "path/to/tabs.h"', manager.GenerateIncludes(include_soft=True).Render()) - self.assertEquals( + self.assertEqual( 'namespace tabs {\n' 'struct Tab;\n' '} // namespace tabs', @@ -105,7 +105,7 @@ environment=CppNamespaceEnvironment( 'foo::bar::%(namespace)s')) manager = CppTypeGenerator(m, _FakeSchemaLoader(m)) - self.assertEquals( + self.assertEqual( 'namespace foo {\n' 'namespace bar {\n' 'namespace tabs {\n' @@ -116,12 +116,12 @@ manager.GenerateForwardDeclarations().Render()) manager = CppTypeGenerator(self.models.get('permissions'), _FakeSchemaLoader(m)) - self.assertEquals('', manager.GenerateIncludes().Render()) - self.assertEquals('', manager.GenerateIncludes().Render()) - self.assertEquals('', manager.GenerateForwardDeclarations().Render()) + self.assertEqual('', manager.GenerateIncludes().Render()) + self.assertEqual('', manager.GenerateIncludes().Render()) + self.assertEqual('', manager.GenerateForwardDeclarations().Render()) manager = CppTypeGenerator(self.models.get('content_settings'), _FakeSchemaLoader(m)) - self.assertEquals('', manager.GenerateIncludes().Render()) + self.assertEqual('', manager.GenerateIncludes().Render()) def testGenerateIncludesAndForwardDeclarationsDependencies(self): m = model.Model() @@ -134,54 +134,54 @@ manager = CppTypeGenerator(m, _FakeSchemaLoader(m), default_namespace=dependency_tester) - self.assertEquals('#include "path/to/browser_action.h"\n' + self.assertEqual('#include "path/to/browser_action.h"\n' '#include "path/to/font_settings.h"', manager.GenerateIncludes().Render()) - self.assertEquals('', manager.GenerateForwardDeclarations().Render()) + self.assertEqual('', manager.GenerateForwardDeclarations().Render()) def testGetCppTypeSimple(self): manager = CppTypeGenerator(self.models.get('tabs'), _FakeSchemaLoader(None)) - self.assertEquals( + self.assertEqual( 'int', manager.GetCppType(self.tabs.types['Tab'].properties['id'].type_)) - self.assertEquals( + self.assertEqual( 'std::string', manager.GetCppType(self.tabs.types['Tab'].properties['status'].type_)) - self.assertEquals( + self.assertEqual( 'bool', manager.GetCppType(self.tabs.types['Tab'].properties['selected'].type_)) def testStringAsType(self): manager = CppTypeGenerator(self.models.get('font_settings'), _FakeSchemaLoader(None)) - self.assertEquals( + self.assertEqual( 'std::string', manager.GetCppType(self.font_settings.types['FakeStringType'])) def testArrayAsType(self): manager = CppTypeGenerator(self.models.get('browser_action'), _FakeSchemaLoader(None)) - self.assertEquals( + self.assertEqual( 'std::vector<int>', manager.GetCppType(self.browser_action.types['ColorArray'])) def testGetCppTypeArray(self): manager = CppTypeGenerator(self.models.get('windows'), _FakeSchemaLoader(None)) - self.assertEquals( + self.assertEqual( 'std::vector<Window>', manager.GetCppType( self.windows.functions['getAll'].returns_async.params[0].type_)) manager = CppTypeGenerator(self.models.get('permissions'), _FakeSchemaLoader(None)) - self.assertEquals( + self.assertEqual( 'std::vector<std::string>', manager.GetCppType( self.permissions.types['Permissions'].properties['origins'].type_)) manager = CppTypeGenerator(self.models.get('objects_movable'), _FakeSchemaLoader(None)) - self.assertEquals( + self.assertEqual( 'std::vector<MovablePod>', manager.GetCppType( self.objects_movable.types['MovableParent']. @@ -189,7 +189,7 @@ def testGetCppTypeLocalRef(self): manager = CppTypeGenerator(self.models.get('tabs'), _FakeSchemaLoader(None)) - self.assertEquals( + self.assertEqual( 'Tab', manager.GetCppType( self.tabs.functions['get'].returns_async.params[0].type_)) @@ -203,7 +203,7 @@ 'path/to/tabs.json', environment=CppNamespaceEnvironment('%(namespace)s')) manager = CppTypeGenerator(m, _FakeSchemaLoader(m)) - self.assertEquals( + self.assertEqual( 'std::vector<tabs::Tab>', manager.GetCppType( self.windows.types['Window'].properties['tabs'].type_)) @@ -211,15 +211,15 @@ def testGetCppTypeWithPadForGeneric(self): manager = CppTypeGenerator(self.models.get('permissions'), _FakeSchemaLoader(None)) - self.assertEquals('std::vector<std::string>', + self.assertEqual('std::vector<std::string>', manager.GetCppType( self.permissions.types['Permissions'].properties['origins'].type_, is_in_container=False)) - self.assertEquals('std::vector<std::string>', + self.assertEqual('std::vector<std::string>', manager.GetCppType( self.permissions.types['Permissions'].properties['origins'].type_, is_in_container=True)) - self.assertEquals( + self.assertEqual( 'bool', manager.GetCppType(self.permissions.functions['contains'].returns_async. params[0].type_, is_in_container=True)) @@ -239,7 +239,7 @@ manager = CppTypeGenerator(self.models.get('crossref_enums'), _FakeSchemaLoader(m)) - self.assertEquals('#include "path/to/simple_api.h"', + self.assertEqual('#include "path/to/simple_api.h"', manager.GenerateIncludes().Render()) def testHardIncludesForEnumArrays(self): @@ -257,7 +257,7 @@ manager = CppTypeGenerator(self.models.get('crossref_enums_array'), _FakeSchemaLoader(m)) - self.assertEquals('#include "path/to/simple_api.h"', + self.assertEqual('#include "path/to/simple_api.h"', manager.GenerateIncludes().Render()) if __name__ == '__main__':
diff --git a/tools/json_schema_compiler/cpp_util_test.py b/tools/json_schema_compiler/cpp_util_test.py index eef4c554b..e913ecf5 100755 --- a/tools/json_schema_compiler/cpp_util_test.py +++ b/tools/json_schema_compiler/cpp_util_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -10,44 +10,44 @@ class CppUtilTest(unittest.TestCase): def testClassname(self): - self.assertEquals('Permissions', Classname('permissions')) - self.assertEquals('UpdateAllTheThings', + self.assertEqual('Permissions', Classname('permissions')) + self.assertEqual('UpdateAllTheThings', Classname('updateAllTheThings')) - self.assertEquals('Aa_Bb_Cc', Classname('aa.bb.cc')) + self.assertEqual('Aa_Bb_Cc', Classname('aa.bb.cc')) def testNamespaceDeclaration(self): - self.assertEquals('namespace foo {', + self.assertEqual('namespace foo {', OpenNamespace('foo').Render()) - self.assertEquals('} // namespace foo', + self.assertEqual('} // namespace foo', CloseNamespace('foo').Render()) - self.assertEquals( + self.assertEqual( 'namespace extensions {\n' 'namespace foo {', OpenNamespace('extensions::foo').Render()) - self.assertEquals( + self.assertEqual( '} // namespace foo\n' '} // namespace extensions', CloseNamespace('extensions::foo').Render()) - self.assertEquals( + self.assertEqual( 'namespace extensions {\n' 'namespace gen {\n' 'namespace api {', OpenNamespace('extensions::gen::api').Render()) - self.assertEquals( + self.assertEqual( '} // namespace api\n' '} // namespace gen\n' '} // namespace extensions', CloseNamespace('extensions::gen::api').Render()) - self.assertEquals( + self.assertEqual( 'namespace extensions {\n' 'namespace gen {\n' 'namespace api {\n' 'namespace foo {', OpenNamespace('extensions::gen::api::foo').Render()) - self.assertEquals( + self.assertEqual( '} // namespace foo\n' '} // namespace api\n' '} // namespace gen\n' @@ -55,8 +55,8 @@ CloseNamespace('extensions::gen::api::foo').Render()) def testGenerateIfndefName(self): - self.assertEquals('FOO_BAR_BAZ_H__', GenerateIfndefName('foo\\bar\\baz.h')) - self.assertEquals('FOO_BAR_BAZ_H__', GenerateIfndefName('foo/bar/baz.h')) + self.assertEqual('FOO_BAR_BAZ_H__', GenerateIfndefName('foo\\bar\\baz.h')) + self.assertEqual('FOO_BAR_BAZ_H__', GenerateIfndefName('foo/bar/baz.h')) if __name__ == '__main__':
diff --git a/tools/json_schema_compiler/feature_compiler_test.py b/tools/json_schema_compiler/feature_compiler_test.py index ff7231d0..40a7f851 100755 --- a/tools/json_schema_compiler/feature_compiler_test.py +++ b/tools/json_schema_compiler/feature_compiler_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2015 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/json_schema_compiler/features_compiler.py b/tools/json_schema_compiler/features_compiler.py index 1b744e2..ef85940 100755 --- a/tools/json_schema_compiler/features_compiler.py +++ b/tools/json_schema_compiler/features_compiler.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2013 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/json_schema_compiler/idl_schema.py b/tools/json_schema_compiler/idl_schema.py index 1ab54c8..029e83c 100755 --- a/tools/json_schema_compiler/idl_schema.py +++ b/tools/json_schema_compiler/idl_schema.py
@@ -1,4 +1,4 @@ -#! /usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/json_schema_compiler/idl_schema_test.py b/tools/json_schema_compiler/idl_schema_test.py index e98a20a..915d4629a 100755 --- a/tools/json_schema_compiler/idl_schema_test.py +++ b/tools/json_schema_compiler/idl_schema_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -34,30 +34,30 @@ class IdlSchemaTest(unittest.TestCase): def setUp(self): loaded = idl_schema.Load('test/idl_basics.idl') - self.assertEquals(1, len(loaded)) - self.assertEquals('idl_basics', loaded[0]['namespace']) + self.assertEqual(1, len(loaded)) + self.assertEqual('idl_basics', loaded[0]['namespace']) self.idl_basics = loaded[0] self.maxDiff = None def testSimpleCallbacks(self): schema = self.idl_basics expected = [{'type': 'function', 'name': 'cb', 'parameters':[]}] - self.assertEquals(expected, getParams(schema, 'function4')) + self.assertEqual(expected, getParams(schema, 'function4')) expected = [{'type': 'function', 'name': 'cb', 'parameters':[{'name': 'x', 'type': 'integer'}]}] - self.assertEquals(expected, getParams(schema, 'function5')) + self.assertEqual(expected, getParams(schema, 'function5')) expected = [{'type': 'function', 'name': 'cb', 'parameters':[{'name': 'arg', '$ref': 'MyType1'}]}] - self.assertEquals(expected, getParams(schema, 'function6')) + self.assertEqual(expected, getParams(schema, 'function6')) def testCallbackWithArrayArgument(self): schema = self.idl_basics expected = [{'type': 'function', 'name': 'cb', 'parameters':[{'name': 'arg', 'type': 'array', 'items':{'$ref': 'MyType2'}}]}] - self.assertEquals(expected, getParams(schema, 'function12')) + self.assertEqual(expected, getParams(schema, 'function12')) def testArrayOfCallbacks(self): @@ -65,10 +65,10 @@ expected = [{'type': 'array', 'name': 'callbacks', 'items':{'type': 'function', 'name': 'MyCallback', 'parameters':[{'type': 'integer', 'name': 'x'}]}}] - self.assertEquals(expected, getParams(schema, 'whatever')) + self.assertEqual(expected, getParams(schema, 'whatever')) def testLegalValues(self): - self.assertEquals({ + self.assertEqual({ 'x': {'name': 'x', 'type': 'integer', 'enum': [1,2], 'description': 'This comment tests "double-quotes".', 'jsexterns': None}, @@ -80,9 +80,9 @@ getType(self.idl_basics, 'MyType1')['properties']) def testMemberOrdering(self): - self.assertEquals( + self.assertEqual( ['x', 'y', 'z', 'a', 'b', 'c'], - getType(self.idl_basics, 'MyType1')['properties'].keys()) + list(getType(self.idl_basics, 'MyType1')['properties'].keys())) def testEnum(self): schema = self.idl_basics @@ -90,36 +90,36 @@ {'name': 'name2'}], 'description': 'Enum description', 'type': 'string', 'id': 'EnumType'} - self.assertEquals(expected, getType(schema, expected['id'])) + self.assertEqual(expected, getType(schema, expected['id'])) expected = [{'name': 'type', '$ref': 'EnumType'}, {'type': 'function', 'name': 'cb', 'parameters':[{'name': 'type', '$ref': 'EnumType'}]}] - self.assertEquals(expected, getParams(schema, 'function13')) + self.assertEqual(expected, getParams(schema, 'function13')) expected = [{'items': {'$ref': 'EnumType'}, 'name': 'types', 'type': 'array'}] - self.assertEquals(expected, getParams(schema, 'function14')) + self.assertEqual(expected, getParams(schema, 'function14')) def testScopedArguments(self): schema = self.idl_basics expected = [{'name': 'value', '$ref': 'idl_other_namespace.SomeType'}] - self.assertEquals(expected, getParams(schema, 'function20')) + self.assertEqual(expected, getParams(schema, 'function20')) expected = [{'items': {'$ref': 'idl_other_namespace.SomeType'}, 'name': 'values', 'type': 'array'}] - self.assertEquals(expected, getParams(schema, 'function21')) + self.assertEqual(expected, getParams(schema, 'function21')) expected = [{'name': 'value', '$ref': 'idl_other_namespace.sub_namespace.AnotherType'}] - self.assertEquals(expected, getParams(schema, 'function22')) + self.assertEqual(expected, getParams(schema, 'function22')) expected = [{'items': {'$ref': 'idl_other_namespace.sub_namespace.' 'AnotherType'}, 'name': 'values', 'type': 'array'}] - self.assertEquals(expected, getParams(schema, 'function23')) + self.assertEqual(expected, getParams(schema, 'function23')) def testNoCompile(self): schema = self.idl_basics @@ -150,114 +150,114 @@ 'id': 'EnumTypeWithNoDocValue', 'description': '' } - self.assertEquals(expected, getType(schema, expected['id'])) + self.assertEqual(expected, getType(schema, expected['id'])) def testInternalNamespace(self): idl_basics = self.idl_basics - self.assertEquals('idl_basics', idl_basics['namespace']) + self.assertEqual('idl_basics', idl_basics['namespace']) self.assertTrue(idl_basics['internal']) self.assertFalse(idl_basics['nodoc']) def testReturnTypes(self): schema = self.idl_basics - self.assertEquals({'name': 'function24', 'type': 'integer'}, + self.assertEqual({'name': 'function24', 'type': 'integer'}, getReturns(schema, 'function24')) - self.assertEquals({'name': 'function25', '$ref': 'MyType1', + self.assertEqual({'name': 'function25', '$ref': 'MyType1', 'optional': True}, getReturns(schema, 'function25')) - self.assertEquals({'name': 'function26', 'type': 'array', + self.assertEqual({'name': 'function26', 'type': 'array', 'items': {'$ref': 'MyType1'}}, getReturns(schema, 'function26')) - self.assertEquals({'name': 'function27', '$ref': 'EnumType', + self.assertEqual({'name': 'function27', '$ref': 'EnumType', 'optional': True}, getReturns(schema, 'function27')) - self.assertEquals({'name': 'function28', 'type': 'array', + self.assertEqual({'name': 'function28', 'type': 'array', 'items': {'$ref': 'EnumType'}}, getReturns(schema, 'function28')) - self.assertEquals({'name': 'function29', '$ref': + self.assertEqual({'name': 'function29', '$ref': 'idl_other_namespace.SomeType', 'optional': True}, getReturns(schema, 'function29')) - self.assertEquals({'name': 'function30', 'type': 'array', + self.assertEqual({'name': 'function30', 'type': 'array', 'items': {'$ref': 'idl_other_namespace.SomeType'}}, getReturns(schema, 'function30')) def testChromeOSPlatformsNamespace(self): schema = idl_schema.Load('test/idl_namespace_chromeos.idl')[0] - self.assertEquals('idl_namespace_chromeos', schema['namespace']) + self.assertEqual('idl_namespace_chromeos', schema['namespace']) expected = ['chromeos'] - self.assertEquals(expected, schema['platforms']) + self.assertEqual(expected, schema['platforms']) def testAllPlatformsNamespace(self): schema = idl_schema.Load('test/idl_namespace_all_platforms.idl')[0] - self.assertEquals('idl_namespace_all_platforms', schema['namespace']) + self.assertEqual('idl_namespace_all_platforms', schema['namespace']) expected = ['chromeos', 'linux', 'mac', 'win'] - self.assertEquals(expected, schema['platforms']) + self.assertEqual(expected, schema['platforms']) def testNonSpecificPlatformsNamespace(self): schema = idl_schema.Load('test/idl_namespace_non_specific_platforms.idl')[0] - self.assertEquals('idl_namespace_non_specific_platforms', + self.assertEqual('idl_namespace_non_specific_platforms', schema['namespace']) expected = None - self.assertEquals(expected, schema['platforms']) + self.assertEqual(expected, schema['platforms']) def testGenerateErrorMessages(self): schema = idl_schema.Load('test/idl_generate_error_messages.idl')[0] - self.assertEquals('idl_generate_error_messages', schema['namespace']) + self.assertEqual('idl_generate_error_messages', schema['namespace']) self.assertTrue(schema['compiler_options'].get('generate_error_messages', False)) schema = idl_schema.Load('test/idl_basics.idl')[0] - self.assertEquals('idl_basics', schema['namespace']) + self.assertEqual('idl_basics', schema['namespace']) self.assertFalse(schema['compiler_options'].get('generate_error_messages', False)) def testSpecificImplementNamespace(self): schema = idl_schema.Load('test/idl_namespace_specific_implement.idl')[0] - self.assertEquals('idl_namespace_specific_implement', + self.assertEqual('idl_namespace_specific_implement', schema['namespace']) expected = 'idl_namespace_specific_implement.idl' - self.assertEquals(expected, schema['compiler_options']['implemented_in']) + self.assertEqual(expected, schema['compiler_options']['implemented_in']) def testSpecificImplementOnChromeOSNamespace(self): schema = idl_schema.Load( 'test/idl_namespace_specific_implement_chromeos.idl')[0] - self.assertEquals('idl_namespace_specific_implement_chromeos', + self.assertEqual('idl_namespace_specific_implement_chromeos', schema['namespace']) expected_implemented_path = 'idl_namespace_specific_implement_chromeos.idl' expected_platform = ['chromeos'] - self.assertEquals(expected_implemented_path, + self.assertEqual(expected_implemented_path, schema['compiler_options']['implemented_in']) - self.assertEquals(expected_platform, schema['platforms']) + self.assertEqual(expected_platform, schema['platforms']) def testCallbackComment(self): schema = self.idl_basics - self.assertEquals('A comment on a callback.', + self.assertEqual('A comment on a callback.', getParams(schema, 'function16')[0]['description']) - self.assertEquals( + self.assertEqual( 'A parameter.', getParams(schema, 'function16')[0]['parameters'][0]['description']) - self.assertEquals( + self.assertEqual( 'Just a parameter comment, with no comment on the callback.', getParams(schema, 'function17')[0]['parameters'][0]['description']) - self.assertEquals( + self.assertEqual( 'Override callback comment.', getParams(schema, 'function18')[0]['description']) def testFunctionComment(self): schema = self.idl_basics func = getFunction(schema, 'function3') - self.assertEquals(('This comment should appear in the documentation, ' + self.assertEqual(('This comment should appear in the documentation, ' 'despite occupying multiple lines.'), func['description']) - self.assertEquals( + self.assertEqual( [{'description': ('So should this comment about the argument. ' '<em>HTML</em> is fine too.'), 'name': 'arg', '$ref': 'MyType1'}], func['parameters']) func = getFunction(schema, 'function4') - self.assertEquals( + self.assertEqual( '<p>This tests if "double-quotes" are escaped correctly.</p>' '<p>It also tests a comment with two newlines.</p>', func['description']) @@ -266,62 +266,62 @@ schema = idl_schema.Load('test/idl_reserved_words.idl')[0] foo_type = getType(schema, 'Foo') - self.assertEquals([{'name': 'float'}, {'name': 'DOMString'}], + self.assertEqual([{'name': 'float'}, {'name': 'DOMString'}], foo_type['enum']) enum_type = getType(schema, 'enum') - self.assertEquals([{'name': 'callback'}, {'name': 'namespace'}], + self.assertEqual([{'name': 'callback'}, {'name': 'namespace'}], enum_type['enum']) dictionary = getType(schema, 'dictionary') - self.assertEquals('integer', dictionary['properties']['long']['type']) + self.assertEqual('integer', dictionary['properties']['long']['type']) mytype = getType(schema, 'MyType') - self.assertEquals('string', mytype['properties']['interface']['type']) + self.assertEqual('string', mytype['properties']['interface']['type']) params = getParams(schema, 'static') - self.assertEquals('Foo', params[0]['$ref']) - self.assertEquals('enum', params[1]['$ref']) + self.assertEqual('Foo', params[0]['$ref']) + self.assertEqual('enum', params[1]['$ref']) def testObjectTypes(self): schema = idl_schema.Load('test/idl_object_types.idl')[0] foo_type = getType(schema, 'FooType') - self.assertEquals('object', foo_type['type']) - self.assertEquals('integer', foo_type['properties']['x']['type']) - self.assertEquals('object', foo_type['properties']['y']['type']) - self.assertEquals( + self.assertEqual('object', foo_type['type']) + self.assertEqual('integer', foo_type['properties']['x']['type']) + self.assertEqual('object', foo_type['properties']['y']['type']) + self.assertEqual( 'any', foo_type['properties']['y']['additionalProperties']['type']) - self.assertEquals('object', foo_type['properties']['z']['type']) - self.assertEquals( + self.assertEqual('object', foo_type['properties']['z']['type']) + self.assertEqual( 'any', foo_type['properties']['z']['additionalProperties']['type']) - self.assertEquals('Window', foo_type['properties']['z']['isInstanceOf']) + self.assertEqual('Window', foo_type['properties']['z']['isInstanceOf']) bar_type = getType(schema, 'BarType') - self.assertEquals('object', bar_type['type']) - self.assertEquals('any', bar_type['properties']['x']['type']) + self.assertEqual('object', bar_type['type']) + self.assertEqual('any', bar_type['properties']['x']['type']) def testObjectTypesInFunctions(self): schema = idl_schema.Load('test/idl_object_types.idl')[0] params = getParams(schema, 'objectFunction1') - self.assertEquals('object', params[0]['type']) - self.assertEquals('any', params[0]['additionalProperties']['type']) - self.assertEquals('ImageData', params[0]['isInstanceOf']) + self.assertEqual('object', params[0]['type']) + self.assertEqual('any', params[0]['additionalProperties']['type']) + self.assertEqual('ImageData', params[0]['isInstanceOf']) params = getParams(schema, 'objectFunction2') - self.assertEquals('any', params[0]['type']) + self.assertEqual('any', params[0]['type']) def testObjectTypesWithOptionalFields(self): schema = idl_schema.Load('test/idl_object_types.idl')[0] baz_type = getType(schema, 'BazType') - self.assertEquals(True, baz_type['properties']['x']['optional']) - self.assertEquals('integer', baz_type['properties']['x']['type']) - self.assertEquals(True, baz_type['properties']['foo']['optional']) - self.assertEquals('FooType', baz_type['properties']['foo']['$ref']) + self.assertEqual(True, baz_type['properties']['x']['optional']) + self.assertEqual('integer', baz_type['properties']['x']['type']) + self.assertEqual(True, baz_type['properties']['foo']['optional']) + self.assertEqual('FooType', baz_type['properties']['foo']['$ref']) def testObjectTypesWithUnions(self): schema = idl_schema.Load('test/idl_object_types.idl')[0] @@ -358,7 +358,7 @@ }, } - self.assertEquals(expected, union_type) + self.assertEqual(expected, union_type) def testUnionsWithModifiers(self): schema = idl_schema.Load('test/idl_object_types.idl')[0] @@ -379,7 +379,7 @@ } } - self.assertEquals(expected, union_type) + self.assertEqual(expected, union_type) def testSerializableFunctionType(self): schema = idl_schema.Load('test/idl_object_types.idl')[0] @@ -396,7 +396,7 @@ } } } - self.assertEquals(expected, object_type) + self.assertEqual(expected, object_type) def testUnionsWithFunctions(self): schema = idl_schema.Load('test/idl_function_types.idl')[0] @@ -410,7 +410,7 @@ ] }] - self.assertEquals(expected, union_params) + self.assertEqual(expected, union_params) def testUnionsWithCallbacks(self): schema = idl_schema.Load('test/idl_function_types.idl')[0] @@ -425,7 +425,7 @@ ]} ] }] - self.assertEquals(expected, blah_params) + self.assertEqual(expected, blah_params) badabish_params = getParams(schema, 'badabish') expected = [{ @@ -437,7 +437,7 @@ }] }] - self.assertEquals(expected, badabish_params) + self.assertEqual(expected, badabish_params) def testFunctionWithPromise(self): schema = idl_schema.Load('test/idl_function_types.idl')[0] @@ -452,7 +452,7 @@ ('name', 'promise_supporting'), ('type', 'function') ]) - self.assertEquals(expected, promise_function) + self.assertEqual(expected, promise_function) def testFunctionWithPromiseAndParams(self): schema = idl_schema.Load('test/idl_function_types.idl')[0] @@ -475,11 +475,11 @@ ('name', 'promise_supporting_with_params'), ('type', 'function') ]) - self.assertEquals(expected, promise_function) + self.assertEqual(expected, promise_function) def testProperties(self): schema = idl_schema.Load('test/idl_properties.idl')[0] - self.assertEquals(OrderedDict([ + self.assertEqual(OrderedDict([ ('first', OrderedDict([ ('description', 'Integer property.'), ('jsexterns', None), @@ -507,7 +507,7 @@ def testManifestKeys(self): schema = self.idl_basics - self.assertEquals( + self.assertEqual( OrderedDict([('key_str', OrderedDict([('description', 'String manifest key.'), ('jsexterns', None), ('name', 'key_str'),
diff --git a/tools/json_schema_compiler/js_externs_generator_test.py b/tools/json_schema_compiler/js_externs_generator_test.py index f7f46974..07d8600 100755 --- a/tools/json_schema_compiler/js_externs_generator_test.py +++ b/tools/json_schema_compiler/js_externs_generator_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2015 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/json_schema_compiler/js_interface_generator_test.py b/tools/json_schema_compiler/js_interface_generator_test.py index a108bf5..6d3bddf 100755 --- a/tools/json_schema_compiler/js_interface_generator_test.py +++ b/tools/json_schema_compiler/js_interface_generator_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2015 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/json_schema_compiler/json_schema_test.py b/tools/json_schema_compiler/json_schema_test.py index edbb06e5..5b24967 100755 --- a/tools/json_schema_compiler/json_schema_test.py +++ b/tools/json_schema_compiler/json_schema_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -76,7 +76,7 @@ ] schema = json_schema.CachedLoad('test/json_schema_test.json') - self.assertEquals(compiled, json_schema.DeleteNodes(schema, 'nocompile')) + self.assertEqual(compiled, json_schema.DeleteNodes(schema, 'nocompile')) def should_delete(value): return isinstance(value, dict) and not value.get('valid', True) @@ -91,7 +91,7 @@ {}, {'valid': False} ] - self.assertEquals( + self.assertEqual( expected, json_schema.DeleteNodes(given, matcher=should_delete))
diff --git a/tools/json_schema_compiler/model_test.py b/tools/json_schema_compiler/model_test.py index a560279e..3b5757e 100755 --- a/tools/json_schema_compiler/model_test.py +++ b/tools/json_schema_compiler/model_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -70,47 +70,47 @@ 'function_platform_win_linux') def testNamespaces(self): - self.assertEquals(12, len(self.model.namespaces)) + self.assertEqual(12, len(self.model.namespaces)) self.assertTrue(self.permissions) def testHasFunctions(self): - self.assertEquals(["contains", "getAll", "remove", "request"], + self.assertEqual(["contains", "getAll", "remove", "request"], sorted(self.permissions.functions.keys())) def testHasTypes(self): - self.assertEquals(['Tab'], self.tabs.types.keys()) - self.assertEquals(['Permissions'], self.permissions.types.keys()) - self.assertEquals(['Window'], self.windows.types.keys()) + self.assertEqual(['Tab'], list(self.tabs.types.keys())) + self.assertEqual(['Permissions'], list(self.permissions.types.keys())) + self.assertEqual(['Window'], list(self.windows.types.keys())) def testHasProperties(self): - self.assertEquals(["active", "favIconUrl", "highlighted", "id", + self.assertEqual(["active", "favIconUrl", "highlighted", "id", "incognito", "index", "pinned", "selected", "status", "title", "url", "windowId"], sorted(self.tabs.types['Tab'].properties.keys())) def testProperties(self): string_prop = self.tabs.types['Tab'].properties['status'] - self.assertEquals(model.PropertyType.STRING, + self.assertEqual(model.PropertyType.STRING, string_prop.type_.property_type) integer_prop = self.tabs.types['Tab'].properties['id'] - self.assertEquals(model.PropertyType.INTEGER, + self.assertEqual(model.PropertyType.INTEGER, integer_prop.type_.property_type) array_prop = self.windows.types['Window'].properties['tabs'] - self.assertEquals(model.PropertyType.ARRAY, + self.assertEqual(model.PropertyType.ARRAY, array_prop.type_.property_type) - self.assertEquals(model.PropertyType.REF, + self.assertEqual(model.PropertyType.REF, array_prop.type_.item_type.property_type) - self.assertEquals('tabs.Tab', array_prop.type_.item_type.ref_type) + self.assertEqual('tabs.Tab', array_prop.type_.item_type.ref_type) object_prop = self.tabs.functions['query'].params[0] - self.assertEquals(model.PropertyType.OBJECT, + self.assertEqual(model.PropertyType.OBJECT, object_prop.type_.property_type) - self.assertEquals( + self.assertEqual( ["active", "highlighted", "pinned", "status", "title", "url", "windowId", "windowType"], sorted(object_prop.type_.properties.keys())) def testChoices(self): - self.assertEquals(model.PropertyType.CHOICES, + self.assertEqual(model.PropertyType.CHOICES, self.tabs.functions['move'].params[0].type_.property_type) def testPropertyNotImplemented(self): @@ -135,7 +135,7 @@ def testDescription(self): self.assertFalse( self.permissions.functions['contains'].params[0].description) - self.assertEquals( + self.assertEqual( 'True if the extension has the specified permissions.', self. permissions.functions['contains'].returns_async.params[0].description) @@ -153,7 +153,7 @@ def testPropertyUnixName(self): param = self.tabs.functions['move'].params[0] - self.assertEquals('tab_ids', param.unix_name) + self.assertEqual('tab_ids', param.unix_name) def testUnixName(self): expectations = { @@ -170,7 +170,7 @@ 'foo_Bar_Baz_box': 'foo_bar_baz_box', } for name in expectations: - self.assertEquals(expectations[name], model.UnixName(name)) + self.assertEqual(expectations[name], model.UnixName(name)) def testCamelName(self): expectations = { @@ -185,7 +185,7 @@ 'bar_baz_': 'barBaz', } for testcase, expected in expectations.items(): - self.assertEquals(expected, model.CamelName(testcase)) + self.assertEqual(expected, model.CamelName(testcase)) def testPlatforms(self): self.assertEqual([Platforms.CHROMEOS],
diff --git a/tools/json_schema_compiler/preview.py b/tools/json_schema_compiler/preview.py index 208e7fa..1d6f43e 100755 --- a/tools/json_schema_compiler/preview.py +++ b/tools/json_schema_compiler/preview.py
@@ -1,5 +1,4 @@ -#!/usr/bin/env python - +#!/usr/bin/env python3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/json_schema_compiler/schema_util_test.py b/tools/json_schema_compiler/schema_util_test.py index 154da0137..0cc024d 100755 --- a/tools/json_schema_compiler/schema_util_test.py +++ b/tools/json_schema_compiler/schema_util_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -9,16 +9,16 @@ class SchemaUtilTest(unittest.TestCase): def testStripNamespace(self): - self.assertEquals('Bar', StripNamespace('foo.Bar')) - self.assertEquals('Baz', StripNamespace('Baz')) + self.assertEqual('Bar', StripNamespace('foo.Bar')) + self.assertEqual('Baz', StripNamespace('Baz')) def testJsFunctionNameToClassName(self): - self.assertEquals('FooBar', JsFunctionNameToClassName('foo', 'bar')) - self.assertEquals('FooBar', + self.assertEqual('FooBar', JsFunctionNameToClassName('foo', 'bar')) + self.assertEqual('FooBar', JsFunctionNameToClassName('experimental.foo', 'bar')) - self.assertEquals('FooBarBaz', + self.assertEqual('FooBarBaz', JsFunctionNameToClassName('foo.bar', 'baz')) - self.assertEquals('FooBarBaz', + self.assertEqual('FooBarBaz', JsFunctionNameToClassName('experimental.foo.bar', 'baz')) if __name__ == '__main__':
diff --git a/tools/json_to_struct/PRESUBMIT.py b/tools/json_to_struct/PRESUBMIT.py index bb36f47..d77764f 100644 --- a/tools/json_to_struct/PRESUBMIT.py +++ b/tools/json_to_struct/PRESUBMIT.py
@@ -8,6 +8,7 @@ for more details about the presubmit API built into depot_tools. """ +USE_PYTHON3 = True WHITELIST = [ r'.+_test.py$' ] def CheckChangeOnUpload(input_api, output_api):
diff --git a/tools/json_to_struct/element_generator_test.py b/tools/json_to_struct/element_generator_test.py index ac856c8..9a3b9e1b 100755 --- a/tools/json_to_struct/element_generator_test.py +++ b/tools/json_to_struct/element_generator_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/json_to_struct/json_to_struct.py b/tools/json_to_struct/json_to_struct.py index c98d3cd..86d1772b 100755 --- a/tools/json_to_struct/json_to_struct.py +++ b/tools/json_to_struct/json_to_struct.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/json_to_struct/struct_generator_test.py b/tools/json_to_struct/struct_generator_test.py index a6c1c46f..51bc609 100755 --- a/tools/json_to_struct/struct_generator_test.py +++ b/tools/json_to_struct/struct_generator_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/licenses.py b/tools/licenses.py index 7c2e504..d6787f6 100755 --- a/tools/licenses.py +++ b/tools/licenses.py
@@ -550,7 +550,7 @@ third_party_dirs.add(dir) ProcessAdditionalReadmePathsJson(root, dir, third_party_dirs) - return third_party_dirs + return sorted(third_party_dirs) def FindThirdPartyDirsWithFiles(root): @@ -601,7 +601,7 @@ # Skip over files that are known not to be used on iOS. continue third_party_deps.add(third_party_path[:-1]) - return third_party_deps + return sorted(third_party_deps) def FindThirdPartyDeps(gn_out_dir, gn_target, target_os):
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index a4c0da8..cd4bf1c 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -315,6 +315,7 @@ 'chromeos-amd64-generic-rel-dchecks': 'chromeos_amd64-generic_use_fake_dbus_clients_dchecks', 'fuchsia-code-coverage': 'fuchsia_clang_code_coverage', 'fuchsia-fyi-arm64-dbg': 'debug_bot_fuchsia_arm64', + 'fuchsia-fyi-arm64-femu': 'release_bot_fuchsia_arm64', 'fuchsia-fyi-arm64-rel': 'release_bot_fuchsia_arm64', 'fuchsia-fyi-x64-dbg': 'debug_bot_fuchsia', 'fuchsia-fyi-x64-rel': 'release_bot_fuchsia', @@ -824,7 +825,7 @@ 'android_cronet': 'android_cronet_release_trybot_arm_no_neon', 'android_mojo': 'android_release_trybot_arm64', 'android_n5x_swarming_dbg': 'android_debug_trybot_arm64', - 'android_optional_gpu_tests_rel': 'gpu_tests_android_release_trybot_arm64', + 'android_optional_gpu_tests_rel': 'gpu_tests_android_release_trybot', 'android_unswarmed_pixel_aosp': 'android_debug_trybot_arm64', 'android-deterministic-dbg': 'android_debug_bot', 'android-deterministic-rel': 'android_without_codecs_release_trybot', @@ -965,6 +966,7 @@ 'fuchsia-compile-x64-dbg': 'debug_bot_fuchsia_compile_only', 'fuchsia-deterministic-dbg': 'debug_bot_fuchsia', 'fuchsia-fyi-arm64-dbg': 'debug_bot_fuchsia_arm64', + 'fuchsia-fyi-arm64-femu': 'release_trybot_fuchsia_arm64', 'fuchsia-fyi-arm64-rel': 'release_trybot_fuchsia_arm64', 'fuchsia-fyi-x64-dbg': 'debug_bot_fuchsia', 'fuchsia-fyi-x64-rel': 'release_trybot_fuchsia',
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json index 76dcab0..5d68f2d 100644 --- a/tools/mb/mb_config_expectations/chromium.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -492,6 +492,15 @@ "use_goma": true } }, + "fuchsia-fyi-arm64-femu": { + "gn_args": { + "is_component_build": false, + "is_debug": false, + "target_cpu": "arm64", + "target_os": "fuchsia", + "use_goma": true + } + }, "fuchsia-fyi-arm64-rel": { "gn_args": { "is_component_build": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.android.json b/tools/mb/mb_config_expectations/tryserver.chromium.android.json index 75255b1..06442af 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.android.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
@@ -820,7 +820,6 @@ "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, - "target_cpu": "arm64", "target_os": "android", "use_goma": true, "use_static_angle": true
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json index 622fd83..984a0bb 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
@@ -78,6 +78,17 @@ "use_goma": true } }, + "fuchsia-fyi-arm64-femu": { + "gn_args": { + "dcheck_always_on": true, + "is_component_build": false, + "is_debug": false, + "symbol_level": 1, + "target_cpu": "arm64", + "target_os": "fuchsia", + "use_goma": true + } + }, "fuchsia-fyi-arm64-rel": { "gn_args": { "dcheck_always_on": true,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 8506411..d9cfc7b6 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -44816,6 +44816,7 @@ <int value="-2105498697" label="EnableImeSandbox:disabled"/> <int value="-2105133782" label="GesturePropertiesDBusService:enabled"/> <int value="-2104950596" label="HandwritingGesture:enabled"/> + <int value="-2103692632" label="EnhancedNetworkVoices:disabled"/> <int value="-2102286055" label="WebViewVulkanIntermediateBuffer:disabled"/> <int value="-2101682955" label="EnableNotificationIndicator:enabled"/> <int value="-2101338272" label="EnablePciguardUi:disabled"/> @@ -46091,6 +46092,7 @@ <int value="-1073479583" label="ShowArcFilesApp:disabled"/> <int value="-1069628248" label="OmniboxZeroSuggestionsOnSERP:enabled"/> <int value="-1069453905" label="CCTModuleUseIntentExtras:disabled"/> + <int value="-1068197506" label="EnhancedNetworkVoices:enabled"/> <int value="-1067635248" label="SpeculativeResourcePrefetching:disabled"/> <int value="-1065227777" label="CrOSAutoSelect:disabled"/> <int value="-1064733740" label="ui-show-composited-layer-borders"/> @@ -47790,6 +47792,7 @@ <int value="425072496" label="GridLayoutForNtpShortcuts:enabled"/> <int value="426199960" label="Commander:enabled"/> <int value="427184788" label="WebFeed:enabled"/> + <int value="427945554" label="StrictExtensionIsolation:enabled"/> <int value="430776375" label="TextureLayerSkipWaitForActivation:disabled"/> <int value="430959979" label="SyncStandaloneTransport:disabled"/> <int value="431691805" label="MediaDocumentDownloadButton:enabled"/> @@ -48314,6 +48317,7 @@ <int value="877238334" label="WebUITabStripTabDragIntegration:enabled"/> <int value="877257918" label="InterestFeedV2ClickAndViewActionsConditionalUpload:enabled"/> + <int value="877907263" label="StrictExtensionIsolation:disabled"/> <int value="878773995" label="ChromeHomeBottomNavLabels:disabled"/> <int value="879699575" label="disable-gesture-tap-highlight"/> <int value="879992337" label="disable-pull-to-refresh-effect"/> @@ -86592,6 +86596,11 @@ <int value="53" label="Show tips for Chrome"/> </enum> +<enum name="WrongConfigurationMetric"> + <int value="0" label="Thunderbolt peripheral - wrong cable"/> + <int value="1" label="USB4 peripheral - wrong cable"/> +</enum> + <enum name="XFrameOptions"> <int value="0" label="NONE"> A frame is loaded without any X-Frame-Options header.
diff --git a/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml b/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml index d7d643f..33e801f 100644 --- a/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml
@@ -1181,6 +1181,16 @@ </summary> </histogram> +<histogram name="Accessibility.WebSpeech.Duration" units="ms" + expires_after="2021-11-30"> + <owner>evliu@google.com</owner> + <owner>chrome-media-ux@google.com</owner> + <summary> + Measures the duration of a call to the WebSpeech API. Recorded once per call + to the Open Speech API that powers the WebSpeech API. + </summary> +</histogram> + <histogram name="Accessibility.Win.AnimationsEnabled" enum="BooleanEnabled" expires_after="M85"> <owner>dmazzoni@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/chromeos/histograms.xml b/tools/metrics/histograms/histograms_xml/chromeos/histograms.xml index c8cdb0db..0afa0c7 100644 --- a/tools/metrics/histograms/histograms_xml/chromeos/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/chromeos/histograms.xml
@@ -38,6 +38,11 @@ <owner>cros-oac@google.com</owner> <owner>chromeos-fingerprint@google.com</owner> </variant> + <variant name="NearbyShare" summary="Nearby Share"> + <owner>nohle@chromium.org</owner> + <owner>vecore@chromium.org</owner> + <owner>nearby-share-chromeos-eng@google.com</owner> + </variant> </variants> <histogram name="ChromeOS.Apps.ExternalProtocolDialog" @@ -1633,6 +1638,17 @@ </summary> </histogram> +<histogram name="ChromeOS.TypeC.WrongConfiguration" + enum="WrongConfigurationMetric" expires_after="2021-10-31"> + <owner>pmalani@chromium.org</owner> + <owner>chromeos-power@google.com</owner> + <summary> + This value represents events where a USB Type-C peripheral couldn't be + configured correctly, or experienced some other unexpected behaviour. It is + recorded every time a new peripheral is connected. + </summary> +</histogram> + <histogram name="ChromeOS.UrlXattrsCount" units="units" expires_after="2021-12-01"> <owner>jorgelo@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/history/histograms.xml b/tools/metrics/histograms/histograms_xml/history/histograms.xml index dc6dfb1..4ce6bcb 100644 --- a/tools/metrics/histograms/histograms_xml/history/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/history/histograms.xml
@@ -444,6 +444,16 @@ latest unreported day, while the profile remains open. If no domains are visited in a given day, a count of 0 will be reported for that day. + Warning about delayed data: Chrome may upload logs on a given day without + uploading this histogram. This can happen because Chrome uploads logs + initially upon startup. This histogram is emitted shortly _after_ startup. + In the case of short sessions, it's possible the log with this histogram did + not have time to be uploaded. Generally the log will be cached and uploaded + the next time the user starts Chrome. We should still get one count per + calendar day; it simply may not be on the day the metric was computed. + (Exception: on Android before M-91, sometimes these emitted histograms were + lost due to lack of robust "background logging".) + Note: for users syncing between multiple devices, this count may include some URLs/domains that weren't visited on this device. In other words, some domains may be counted for multiple client_ids even though they were only @@ -470,6 +480,16 @@ period, while the profile remains open. If no domains are visited during a 28-day period, a count of 0 will be reported for that period. + Warning about delayed data: Chrome may upload logs on a given day without + uploading this histogram. This can happen because Chrome uploads logs + initially upon startup. This histogram is emitted shortly _after_ startup. + In the case of short sessions, it's possible the log with this histogram did + not have time to be uploaded. Generally the log will be cached and uploaded + the next time the user starts Chrome. We should still get one count per + calendar day; it simply may not be on the day the metric was computed. + (Exception: on Android before M-91, sometimes these emitted histograms were + lost due to lack of robust "background logging".) + Note: for users syncing between multiple devices, this count may include some URLs/domains that weren't visited on this device. In other words, some domains may be counted for multiple client_ids even though they were only @@ -496,6 +516,16 @@ period, while the profile remains open. If no domains are visited during a 7-day period, a count 0 will be reported for that period. + Warning about delayed data: Chrome may upload logs on a given day without + uploading this histogram. This can happen because Chrome uploads logs + initially upon startup. This histogram is emitted shortly _after_ startup. + In the case of short sessions, it's possible the log with this histogram did + not have time to be uploaded. Generally the log will be cached and uploaded + the next time the user starts Chrome. We should still get one count per + calendar day; it simply may not be on the day the metric was computed. + (Exception: on Android before M-91, sometimes these emitted histograms were + lost due to lack of robust "background logging".) + Note: for users syncing between multiple devices, this count may include some URLs/domains that weren't visited on this device. In other words, some domains may be counted for multiple client_ids even though they were only
diff --git a/tools/metrics/histograms/histograms_xml/sb_client/histograms.xml b/tools/metrics/histograms/histograms_xml/sb_client/histograms.xml index febbeb1..c087c40 100644 --- a/tools/metrics/histograms/histograms_xml/sb_client/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/sb_client/histograms.xml
@@ -548,6 +548,16 @@ </summary> </histogram> +<histogram name="SBClientPhishing.FlatBufferScorer.CreationStatus" + enum="SBClientPhishingScorerCreationStatus" expires_after="M94"> + <owner>bhatiarohit@google.com</owner> + <owner>chrome-safebrowsing-alerts@google.com</owner> + <summary> + Records the status when we create a FlatBuffer scorer object for the + client-side phishing detection classifier. + </summary> +</histogram> + <histogram name="SBClientPhishing.IllegalFeatureValue" units="units" expires_after="M90"> <obsolete> @@ -641,6 +651,16 @@ </summary> </histogram> +<histogram name="SBClientPhishing.ProtobufScorer.CreationStatus" + enum="SBClientPhishingScorerCreationStatus" expires_after="M94"> + <owner>bhatiarohit@google.com</owner> + <owner>chrome-safebrowsing-alerts@google.com</owner> + <summary> + Records the status when we create a Protobuf scorer object for the + client-side phishing detection classifier. + </summary> +</histogram> + <histogram name="SBClientPhishing.ReportLimitSkipped" enum="BooleanHit" expires_after="2021-01-27"> <obsolete> @@ -689,6 +709,10 @@ <histogram name="SBClientPhishing.ScorerCreationStatus" enum="SBClientPhishingScorerCreationStatus" expires_after="M94"> + <obsolete> + Removed 05-27-2021. Using SBClientPhishing.ProtobufScorer.CreationStatus and + SBClientPhishing.FlatBufferScorer.CreationStatus + </obsolete> <owner>drubery@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 1db0937d..d7e8fe2 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -8828,7 +8828,7 @@ we don't know the video codec. </summary> </metric> - <metric name="Video.EME.KeySystem"> + <metric name="Video.EME.KeySystem" enum="MediaKeySystem"> <summary> Name of the KeySystem used during for an encrypted (EME) playback. Will be unset when EME is not used. @@ -8971,6 +8971,12 @@ once attached can't be removed. </summary> </metric> + <metric name="IsHardwareSecure" enum="Boolean"> + <summary> + Boolean value indicating whether the EME playback is using hardware secure + pipeline. For clear playback, this will always be false. + </summary> + </metric> <metric name="IsMSE"> <summary> Boolean value indicating if this event is for an MSE playback. If false it @@ -8985,6 +8991,12 @@ playbacks. </summary> </metric> + <metric name="KeySystem" enum="MediaKeySystem"> + <summary> + For EME playback, this is the key system used. For clear playback, this + will always be the default value 0 (kUnknownKeySystemForUkm). + </summary> + </metric> <metric name="PlayerID"> <summary> ID which corresponds to a given WebMediaPlayerImpl instance. May be linked
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index e473c64d..d4a66ca4 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -2,7 +2,7 @@ "trace_processor_shell": { "win": { "hash": "6e445a89816f61bdf2942742657ab5542492b01e", - "remote_path": "perfetto_binaries/trace_processor_shell/win/e46c9b802f8761df0341aad1d7845b7732a48596/trace_processor_shell.exe" + "remote_path": "perfetto_binaries/trace_processor_shell/win/49518bb65f7110253ac1b0e576c2592eb394031e/trace_processor_shell.exe" }, "mac": { "hash": "76cfeee650db8a487cfd6c86b74d2a02f732d67a", @@ -10,7 +10,7 @@ }, "linux": { "hash": "46ee9624f529202741eaa0126a9fb42641b0ea1f", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/e46c9b802f8761df0341aad1d7845b7732a48596/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/linux/49518bb65f7110253ac1b0e576c2592eb394031e/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/accessibility/accessibility_features.cc b/ui/accessibility/accessibility_features.cc index 57551faa..51163db3 100644 --- a/ui/accessibility/accessibility_features.cc +++ b/ui/accessibility/accessibility_features.cc
@@ -127,6 +127,13 @@ return base::FeatureList::IsEnabled( ::features::kExperimentalAccessibilityDictationListening); } + +const base::Feature kEnhancedNetworkVoices{"EnhancedNetworkVoices", + base::FEATURE_DISABLED_BY_DEFAULT}; + +bool IsEnhancedNetworkVoicesEnabled() { + return base::FeatureList::IsEnabled(::features::kEnhancedNetworkVoices); +} #endif // BUILDFLAG(IS_CHROMEOS_ASH) const base::Feature kAugmentExistingImageLabels{
diff --git a/ui/accessibility/accessibility_features.h b/ui/accessibility/accessibility_features.h index 09e87f2..c0793b8ed 100644 --- a/ui/accessibility/accessibility_features.h +++ b/ui/accessibility/accessibility_features.h
@@ -110,6 +110,13 @@ // Returns true if the feature to allow experimental listening features for // Dictation is enabled. AX_BASE_EXPORT bool IsExperimentalAccessibilityDictationListeningEnabled(); + +// Enables high-quality, network-based voices in Select-to-speak. +AX_BASE_EXPORT extern const base::Feature kEnhancedNetworkVoices; + +// Returns true if network-based voices are enabled in Select-to-speak. +AX_BASE_EXPORT bool IsEnhancedNetworkVoicesEnabled(); + #endif // BUILDFLAG(IS_CHROMEOS_ASH) // Enables Get Image Descriptions to augment existing images labels,
diff --git a/ui/aura/native_window_occlusion_tracker_win.cc b/ui/aura/native_window_occlusion_tracker_win.cc index 7146e55..974ffd8 100644 --- a/ui/aura/native_window_occlusion_tracker_win.cc +++ b/ui/aura/native_window_occlusion_tracker_win.cc
@@ -180,9 +180,12 @@ // Filter out "tool windows", which are floating windows that do not appear on // the taskbar or ALT-TAB. Floating windows can have larger window rectangles // than what is visible to the user, so by filtering them out we will avoid - // incorrectly marking native windows as occluded. - if (ex_styles & WS_EX_TOOLWINDOW) - return false; + // incorrectly marking native windows as occluded. We do not filter out the + // Windows Taskbar. + if (ex_styles & WS_EX_TOOLWINDOW) { + if (gfx::GetClassName(hwnd) != L"Shell_TrayWnd") + return false; + } // Filter out layered windows that are not opaque or that set a transparency // colorkey. @@ -230,15 +233,36 @@ return false; // Ignore popup windows since they're transient unless it is a Chrome Widget - // Window. + // Window or the Windows Taskbar if (::GetWindowLong(hwnd, GWL_STYLE) & WS_POPUP) { - if (!base::StartsWith(gfx::GetClassName(hwnd), L"Chrome_WidgetWin_")) { + std::wstring hwnd_class_name = gfx::GetClassName(hwnd); + if (!base::StartsWith(hwnd_class_name, L"Chrome_WidgetWin_") && + hwnd_class_name != L"Shell_TrayWnd") { return false; } } *window_rect = gfx::Rect(win_rect); + WINDOWPLACEMENT window_placement = {0}; + window_placement.length = sizeof(WINDOWPLACEMENT); + ::GetWindowPlacement(hwnd, &window_placement); + if (window_placement.showCmd == SW_MAXIMIZE) { + // If the window is maximized the window border extends beyond the visible + // region of the screen. Adjust the maximized window rect to fit the + // screen dimensions to ensure that fullscreen windows, which do not extend + // beyond the screen boundaries since they typically have no borders, will + // occlude maximized windows underneath them. + HMONITOR hmon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + if (hmon) { + MONITORINFO mi; + mi.cbSize = sizeof(mi); + if (GetMonitorInfo(hmon, &mi)) { + (*window_rect).AdjustToFit(gfx::Rect(mi.rcWork)); + } + } + } + return true; } @@ -695,12 +719,14 @@ return; // We generally ignore events for popup windows, except for when the taskbar - // is hidden or when the popup is a Chrome Widget, in which case we - // recalculate occlusion. + // is hidden or when the popup is a Chrome Widget or Windows Taskbar, in + // which case we recalculate occlusion. bool calculate_occlusion = true; if (::GetWindowLong(hwnd, GWL_STYLE) & WS_POPUP) { + std::wstring hwnd_class_name = gfx::GetClassName(hwnd); calculate_occlusion = - base::StartsWith(gfx::GetClassName(hwnd), L"Chrome_WidgetWin_"); + base::StartsWith(hwnd_class_name, L"Chrome_WidgetWin_") || + hwnd_class_name == L"Shell_TrayWnd"; } // Detect if either the alt tab view or the task list thumbnail is being
diff --git a/ui/base/l10n/l10n_util.cc b/ui/base/l10n/l10n_util.cc index 19a139ad..07d38591e 100644 --- a/ui/base/l10n/l10n_util.cc +++ b/ui/base/l10n/l10n_util.cc
@@ -237,7 +237,11 @@ // for on the current platform. Guaranteed to be in sorted order and guaranteed // to have no duplicates. // -// Note that this could have false positives at runtime on iOS: +// Note that this could have false positives at runtime on Android and iOS: +// - On Android, some locales aren't shipped (|android_apk_omitted_locales| in +// GN), and some locales files are dynamically shipped in app bundles +// (|android_bundle_only_locales|). Both of these lists are included in +// this variable. // - On iOS, some locales aren't shipped (|ios_unsupported_locales|) as they are // not supported by the operating system. These locales are included in this // variable.
diff --git a/ui/gfx/color_utils.cc b/ui/gfx/color_utils.cc index 9849410..01f4902 100644 --- a/ui/gfx/color_utils.cc +++ b/ui/gfx/color_utils.cc
@@ -64,8 +64,135 @@ : pow((component + 0.055f) / 1.055f, 2.4f); } +constexpr size_t kNumGoogleColors = 10; +constexpr SkColor kGrey[kNumGoogleColors] = { + gfx::kGoogleGrey050, gfx::kGoogleGrey100, gfx::kGoogleGrey200, + gfx::kGoogleGrey300, gfx::kGoogleGrey400, gfx::kGoogleGrey500, + gfx::kGoogleGrey600, gfx::kGoogleGrey700, gfx::kGoogleGrey800, + gfx::kGoogleGrey900, +}; + +constexpr SkColor kRed[kNumGoogleColors] = { + gfx::kGoogleRed050, gfx::kGoogleRed100, gfx::kGoogleRed200, + gfx::kGoogleRed300, gfx::kGoogleRed400, gfx::kGoogleRed500, + gfx::kGoogleRed600, gfx::kGoogleRed700, gfx::kGoogleRed800, + gfx::kGoogleRed900, +}; + +constexpr SkColor kOrange[kNumGoogleColors] = { + gfx::kGoogleOrange050, gfx::kGoogleOrange100, gfx::kGoogleOrange200, + gfx::kGoogleOrange300, gfx::kGoogleOrange400, gfx::kGoogleOrange500, + gfx::kGoogleOrange600, gfx::kGoogleOrange700, gfx::kGoogleOrange800, + gfx::kGoogleOrange900, +}; + +constexpr SkColor kYellow[kNumGoogleColors] = { + gfx::kGoogleYellow050, gfx::kGoogleYellow100, gfx::kGoogleYellow200, + gfx::kGoogleYellow300, gfx::kGoogleYellow400, gfx::kGoogleYellow500, + gfx::kGoogleYellow600, gfx::kGoogleYellow700, gfx::kGoogleYellow800, + gfx::kGoogleYellow900, +}; + +constexpr SkColor kGreen[kNumGoogleColors] = { + gfx::kGoogleGreen050, gfx::kGoogleGreen100, gfx::kGoogleGreen200, + gfx::kGoogleGreen300, gfx::kGoogleGreen400, gfx::kGoogleGreen500, + gfx::kGoogleGreen600, gfx::kGoogleGreen700, gfx::kGoogleGreen800, + gfx::kGoogleGreen900, +}; + +constexpr SkColor kBlue[kNumGoogleColors] = { + gfx::kGoogleBlue050, gfx::kGoogleBlue100, gfx::kGoogleBlue200, + gfx::kGoogleBlue300, gfx::kGoogleBlue400, gfx::kGoogleBlue500, + gfx::kGoogleBlue600, gfx::kGoogleBlue700, gfx::kGoogleBlue800, + gfx::kGoogleBlue900, +}; + +constexpr SkColor kPurple[kNumGoogleColors] = { + gfx::kGooglePurple050, gfx::kGooglePurple100, gfx::kGooglePurple200, + gfx::kGooglePurple300, gfx::kGooglePurple400, gfx::kGooglePurple500, + gfx::kGooglePurple600, gfx::kGooglePurple700, gfx::kGooglePurple800, + gfx::kGooglePurple900, +}; + +constexpr SkColor kPink[kNumGoogleColors] = { + gfx::kGooglePink050, gfx::kGooglePink100, gfx::kGooglePink200, + gfx::kGooglePink300, gfx::kGooglePink400, gfx::kGooglePink500, + gfx::kGooglePink600, gfx::kGooglePink700, gfx::kGooglePink800, + gfx::kGooglePink900, +}; + +SkColor PickGoogleColor(const SkColor (&colors)[kNumGoogleColors], + SkColor background_color, + float min_contrast) { + // For dark backgrounds we start at 500 and go down (toward brighter colors). + constexpr size_t kDarkBackgroundStartIndex = 5; + static_assert(kBlue[kDarkBackgroundStartIndex] == gfx::kGoogleBlue500, + "The start index needs to match kGoogleBlue500"); + if (IsDark(background_color)) { + for (size_t i = kDarkBackgroundStartIndex; i > 0; --i) { + if (GetContrastRatio(colors[i], background_color) > min_contrast) + return colors[i]; + } + return colors[0]; + } + + // For light backgrounds we start at 400 and go up (toward darker colors). + constexpr size_t kLightBackgroundStartIndex = 4; + static_assert(kBlue[kLightBackgroundStartIndex] == gfx::kGoogleBlue400, + "The start index needs to match kGoogleBlue400"); + for (size_t i = kLightBackgroundStartIndex; i < kNumGoogleColors - 1; ++i) { + if (GetContrastRatio(colors[i], background_color) > min_contrast) + return colors[i]; + } + return colors[kNumGoogleColors - 1]; +} + } // namespace +SkColor PickGoogleColor(SkColor color, + SkColor background_color, + float min_contrast) { + HSL hsl; + SkColorToHSL(color, &hsl); + if (hsl.s < 0.1) { + // Low saturation, let this be a grey. + return PickGoogleColor(kGrey, background_color, min_contrast); + } + + // Map hue to angles for readability. + const float color_angle = hsl.h * 360; + + // Hues in comments below are accent colors from MacOS 11.3.1 light mode as + // point of reference. + // TODO(pbos): Complement this with more Google colors and verify the hue + // ranges, this currently knows about enough colors to pick a corresponding + // color correctly from MacOS accent colors. + // RED: 357.654 + if (color_angle < 20) + return PickGoogleColor(kRed, background_color, min_contrast); + // ORANGE: 28.0687 + if (color_angle < 40) + return PickGoogleColor(kOrange, background_color, min_contrast); + // YELLOW: 44.4156 + if (color_angle < 70) + return PickGoogleColor(kYellow, background_color, min_contrast); + // GREEN: 105.484 + if (color_angle < 160) + return PickGoogleColor(kGreen, background_color, min_contrast); + // BLUE: 214.672 + if (color_angle < 250) + return PickGoogleColor(kBlue, background_color, min_contrast); + // PURPLE: 299.362 + if (color_angle < 310) + return PickGoogleColor(kPurple, background_color, min_contrast); + // PINK: 331.685 + if (color_angle < 345) + return PickGoogleColor(kPink, background_color, min_contrast); + + // End of hue wheel is red. + return PickGoogleColor(kRed, background_color, min_contrast); +} + float GetContrastRatio(SkColor color_a, SkColor color_b) { return GetContrastRatio(GetRelativeLuminance(color_a), GetRelativeLuminance(color_b));
diff --git a/ui/gfx/color_utils.h b/ui/gfx/color_utils.h index 64031d8..5d5c430 100644 --- a/ui/gfx/color_utils.h +++ b/ui/gfx/color_utils.h
@@ -158,6 +158,13 @@ // surface. GFX_EXPORT SkColor DeriveDefaultIconColor(SkColor text_color); +// Gets a Google color that matches the hue of `color` and contrasts well +// enough against `background_color` to meet `min_contrast`. If `color` isn't +// very saturated, grey will be used instead. +GFX_EXPORT SkColor PickGoogleColor(SkColor color, + SkColor background_color, + float min_contrast); + // Creates an rgba string for an SkColor. For example: 'rgba(255,0,255,0.5)'. GFX_EXPORT std::string SkColorToRgbaString(SkColor color);
diff --git a/ui/gtk/gdk.sigs b/ui/gtk/gdk.sigs index c8223a5..7a393ed 100644 --- a/ui/gtk/gdk.sigs +++ b/ui/gtk/gdk.sigs
@@ -33,3 +33,4 @@ void gdk_set_allowed_backends(const gchar* backends); void gdk_display_notify_startup_complete(GdkDisplay* display, const char* startup_id); guint32 gdk_keyval_to_unicode(guint keyval); +gdouble gdk_screen_get_resolution(GdkScreen *screen);
diff --git a/ui/gtk/gtk_ui.cc b/ui/gtk/gtk_ui.cc index 3706fca8..a3302b6 100644 --- a/ui/gtk/gtk_ui.cc +++ b/ui/gtk/gtk_ui.cc
@@ -379,9 +379,15 @@ G_CALLBACK(OnCursorThemeNameChangedThunk), this); g_signal_connect_after(settings, "notify::gtk-cursor-theme-size", G_CALLBACK(OnCursorThemeSizeChangedThunk), this); - g_signal_connect_after(settings, "notify::gtk-xft-dpi", - G_CALLBACK(OnDeviceScaleFactorMaybeChangedThunk), - this); + + // Listen for DPI changes. + auto* dpi_callback = G_CALLBACK(OnDeviceScaleFactorMaybeChangedThunk); + if (GtkCheckVersion(4)) { + g_signal_connect_after(settings, "notify::gtk-xft-dpi", dpi_callback, this); + } else { + GdkScreen* screen = gdk_screen_get_default(); + g_signal_connect_after(screen, "notify::resolution", dpi_callback, this); + } // Listen for scale factor changes. We would prefer to listen on // a GdkScreen, but there is no scale-factor property, so use an @@ -1065,11 +1071,18 @@ float scale = gtk_widget_get_scale_factor(GetDummyWindow()); DCHECK_GT(scale, 0.0); - auto* settings = gtk_settings_get_default(); - int resolution = kDefaultDPI; - g_object_get(settings, "gtk-xft-dpi", &resolution, nullptr); + double resolution = 0; + if (GtkCheckVersion(4)) { + auto* settings = gtk_settings_get_default(); + int dpi = 0; + g_object_get(settings, "gtk-xft-dpi", &dpi, nullptr); + resolution = dpi / 1024.0; + } else { + GdkScreen* screen = gdk_screen_get_default(); + resolution = gdk_screen_get_resolution(screen); + } if (resolution > 0) - scale *= resolution / kDefaultDPI / 1024; + scale *= resolution / kDefaultDPI; // Round to the nearest 64th so that UI can losslessly multiply and divide // the scale factor.
diff --git a/ui/views/cocoa/native_widget_mac_ns_window_host.h b/ui/views/cocoa/native_widget_mac_ns_window_host.h index b6d8600..c164c3a8 100644 --- a/ui/views/cocoa/native_widget_mac_ns_window_host.h +++ b/ui/views/cocoa/native_widget_mac_ns_window_host.h
@@ -146,7 +146,9 @@ void SetBoundsInScreen(const gfx::Rect& bounds); // Tell the window to transition to being fullscreen or not-fullscreen. - void SetFullscreen(bool fullscreen); + // If `delay` is true, this will set the target fullscreen state and then post + // a delayed task to request the window transition. See crbug.com/1210548 + void SetFullscreen(bool fullscreen, bool delay = false); // The ultimate fullscreen state that is being targeted (irrespective of any // active transitions).
diff --git a/ui/views/cocoa/native_widget_mac_ns_window_host.mm b/ui/views/cocoa/native_widget_mac_ns_window_host.mm index 1de90c3b..d20f9af 100644 --- a/ui/views/cocoa/native_widget_mac_ns_window_host.mm +++ b/ui/views/cocoa/native_widget_mac_ns_window_host.mm
@@ -464,13 +464,33 @@ } } -void NativeWidgetMacNSWindowHost::SetFullscreen(bool fullscreen) { +void NativeWidgetMacNSWindowHost::SetFullscreen(bool fullscreen, bool delay) { // Note that when the NSWindow begins a fullscreen transition, the value of // |target_fullscreen_state_| updates via OnWindowFullscreenTransitionStart. // The update here is necessary for the case where we are currently in // transition (and therefore OnWindowFullscreenTransitionStart will not be // called until the current transition completes). target_fullscreen_state_ = fullscreen; + + if (delay) { + // Synchronously requesting fullscreen after moving the window to another + // display causes the window to resign key. Workaround this OS-specific + // quirk by delaying the fullscreen request, after setting the target state, + // to encapsulate some of these details from the calling client window code, + // i.e. so BrowserView::ProcessFullscreen will still hide its frame, etc. + // TODO(crbug.com/1034783): Refine cross-display fullscreen implementations. + // Maybe add fullscreen-on-target-display helpers on views::Widget, etc. to + // better encapsulate per-platform complexity, or at least wait for the + // window move before entering fullscreen, instead of posting a task with a + // locally-tested delay. + auto callback = base::BindOnce( + &remote_cocoa::mojom::NativeWidgetNSWindow::SetFullscreen, + base::Unretained(GetNSWindowMojo()), target_fullscreen_state_); + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, std::move(callback), base::TimeDelta::FromMilliseconds(1)); + return; + } + GetNSWindowMojo()->SetFullscreen(target_fullscreen_state_); }
diff --git a/ui/views/controls/focus_ring.cc b/ui/views/controls/focus_ring.cc index c72e28e..677bd52 100644 --- a/ui/views/controls/focus_ring.cc +++ b/ui/views/controls/focus_ring.cc
@@ -50,8 +50,10 @@ } SkColor GetColor(View* focus_ring, bool valid) { + const ui::NativeTheme* const native_theme = focus_ring->GetNativeTheme(); const SkColor default_color = - focus_ring->GetNativeTheme()->GetSystemColor(ColorIdForValidity(valid)); + native_theme->GetSystemColor(ColorIdForValidity(valid)); + if (!valid) return default_color; @@ -64,31 +66,20 @@ : focus_ring->GetNativeTheme()->GetSystemColor( ui::NativeTheme::kColorId_WindowBackground); - // This blends towards the fully-opaque version of the focus-ring color until - // the minimum contrast is reached (if possible). If `default_color` is - // already contrasty enough it will be used directly. - const color_utils::BlendResult contrasty_color = - color_utils::BlendForMinContrast( - default_color, background_color, SkColorSetA(default_color, 0xFF), - color_utils::kMinimumVisibleContrastRatio); + const SkColor focus_ring_color = + color_utils::PickGoogleColor(default_color, background_color, + color_utils::kMinimumVisibleContrastRatio); - const float boosted_contrast = color_utils::GetContrastRatio( - color_utils::GetResultingPaintColor(contrasty_color.color, - background_color), - background_color); + // If the Google color is contrasty enough, use it. + if (color_utils::GetContrastRatio(focus_ring_color, background_color) > + color_utils::kMinimumVisibleContrastRatio) { + return focus_ring_color; + } - // If the contrast of the boosted color is enough, use it. If not, increasing - // opacity was insufficient to meet contrast minimums. This happens when - // painting a blue focus ring on a blue theme for instance. - if (boosted_contrast > color_utils::kMinimumVisibleContrastRatio) - return contrasty_color.color; - - // If a fallback color exists, use it. Otherwise use the boosted color as it's - // the best we have here for now. return fallback_color_view ? focus_ring->GetThemeProvider()->GetColor( fallback_color_view->GetProperty(kFocusRingFallbackColorId)) - : contrasty_color.color; + : focus_ring_color; } double GetCornerRadius() {
diff --git a/ui/views/layout/grid_layout.h b/ui/views/layout/grid_layout.h index 073b313a..c0cd1058 100644 --- a/ui/views/layout/grid_layout.h +++ b/ui/views/layout/grid_layout.h
@@ -27,8 +27,7 @@ // // resized. // 1.0, // This column has a resize weight of 1. // ColumnSize::kUsePreferred, // Use the preferred size of -// the -// // view. +// // the view. // 0, // Ignored for kUsePref. // 0); // A minimum width of 0. // columns->AddPaddingColumn(kFixedSize, // The padding column is not resizable.
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc index 45fbf5d4..1c46b1cd 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -906,7 +906,7 @@ desktop_window_tree_host_->Restore(); } -void DesktopNativeWidgetAura::SetFullscreen(bool fullscreen) { +void DesktopNativeWidgetAura::SetFullscreen(bool fullscreen, bool delay) { if (content_window_) desktop_window_tree_host_->SetFullscreen(fullscreen); }
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h index 8dd86cd..4be3ddfb 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -167,7 +167,7 @@ bool IsMaximized() const override; bool IsMinimized() const override; void Restore() override; - void SetFullscreen(bool fullscreen) override; + void SetFullscreen(bool fullscreen, bool delay) override; bool IsFullscreen() const override; void SetCanAppearInExistingFullscreenSpaces( bool can_appear_in_existing_fullscreen_spaces) override;
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc index 3b63e2b9..15c54966 100644 --- a/ui/views/widget/native_widget_aura.cc +++ b/ui/views/widget/native_widget_aura.cc
@@ -700,7 +700,7 @@ window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); } -void NativeWidgetAura::SetFullscreen(bool fullscreen) { +void NativeWidgetAura::SetFullscreen(bool fullscreen, bool delay) { if (!window_ || IsFullscreen() == fullscreen) return; // Nothing to do.
diff --git a/ui/views/widget/native_widget_aura.h b/ui/views/widget/native_widget_aura.h index db6effaa..701f5b4a 100644 --- a/ui/views/widget/native_widget_aura.h +++ b/ui/views/widget/native_widget_aura.h
@@ -126,7 +126,7 @@ bool IsMaximized() const override; bool IsMinimized() const override; void Restore() override; - void SetFullscreen(bool fullscreen) override; + void SetFullscreen(bool fullscreen, bool delay) override; bool IsFullscreen() const override; void SetCanAppearInExistingFullscreenSpaces( bool can_appear_in_existing_fullscreen_spaces) override;
diff --git a/ui/views/widget/native_widget_mac.h b/ui/views/widget/native_widget_mac.h index 088c98a..174f797 100644 --- a/ui/views/widget/native_widget_mac.h +++ b/ui/views/widget/native_widget_mac.h
@@ -157,7 +157,7 @@ bool IsMaximized() const override; bool IsMinimized() const override; void Restore() override; - void SetFullscreen(bool fullscreen) override; + void SetFullscreen(bool fullscreen, bool delay) override; bool IsFullscreen() const override; void SetCanAppearInExistingFullscreenSpaces( bool can_appear_in_existing_fullscreen_spaces) override;
diff --git a/ui/views/widget/native_widget_mac.mm b/ui/views/widget/native_widget_mac.mm index 51358d1..e24526ef 100644 --- a/ui/views/widget/native_widget_mac.mm +++ b/ui/views/widget/native_widget_mac.mm
@@ -644,10 +644,10 @@ GetNSWindowMojo()->SetMiniaturized(false); } -void NativeWidgetMac::SetFullscreen(bool fullscreen) { +void NativeWidgetMac::SetFullscreen(bool fullscreen, bool delay) { if (!ns_window_host_) return; - ns_window_host_->SetFullscreen(fullscreen); + ns_window_host_->SetFullscreen(fullscreen, delay); } bool NativeWidgetMac::IsFullscreen() const {
diff --git a/ui/views/widget/native_widget_private.h b/ui/views/widget/native_widget_private.h index 5738ffb..8897a1327 100644 --- a/ui/views/widget/native_widget_private.h +++ b/ui/views/widget/native_widget_private.h
@@ -195,7 +195,7 @@ virtual bool IsMaximized() const = 0; virtual bool IsMinimized() const = 0; virtual void Restore() = 0; - virtual void SetFullscreen(bool fullscreen) = 0; + virtual void SetFullscreen(bool fullscreen, bool delay) = 0; virtual bool IsFullscreen() const = 0; virtual void SetCanAppearInExistingFullscreenSpaces( bool can_appear_in_existing_fullscreen_spaces) = 0;
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc index 0dcab77..e634630 100644 --- a/ui/views/widget/widget.cc +++ b/ui/views/widget/widget.cc
@@ -769,12 +769,12 @@ return native_widget_->IsMinimized(); } -void Widget::SetFullscreen(bool fullscreen) { +void Widget::SetFullscreen(bool fullscreen, bool delay) { if (IsFullscreen() == fullscreen) return; auto weak_ptr = GetWeakPtr(); - native_widget_->SetFullscreen(fullscreen); + native_widget_->SetFullscreen(fullscreen, delay); if (!weak_ptr) return;
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h index ef3892d6..62df568e 100644 --- a/ui/views/widget/widget.h +++ b/ui/views/widget/widget.h
@@ -686,7 +686,11 @@ bool IsMinimized() const; // Accessors for fullscreen state. - void SetFullscreen(bool fullscreen); + // If `delay` is true, some underlying implementations will set their target + // fullscreen state and then post a delayed task to request the actual window + // transition, in order to handle some platform-specific quirks in specific + // fullscreen scenarios. See crbug.com/1210548 and crbug.com/1034783. + void SetFullscreen(bool fullscreen, bool delay = false); bool IsFullscreen() const; // macOS: Sets whether the window can share fullscreen windows' spaces.