diff --git a/.gitignore b/.gitignore index 0700f2c6..08a05ccf 100644 --- a/.gitignore +++ b/.gitignore
@@ -131,7 +131,6 @@ /chrome/test/chromeos/autotest/files/client/deps/perf_data_dep/test_src/ /chrome/test/chromeos/autotest/files/client/deps/pyauto_dep/test_src/ /chrome/test/chromeos/autotest/files/client/deps/telemetry_dep/test_src/ -/chrome/test/data/android/render_tests/*.png /chrome/test/data/extensions/api_test/permissions/nacl_enabled/bin /chrome/test/data/firefox2_profile/searchplugins /chrome/test/data/firefox2_searchplugins @@ -173,9 +172,6 @@ /components/resources/default_200_percent/google_chrome /components/search_engines/prepopulated_engines.xml /components/test/data/language/ -/components/test/data/js_dialogs/render_tests/*.png -/components/test/data/payments/render_tests/*.png -/components/test/data/permission_dialogs/render_tests/*.png /components/suggestions.xml /components/variations.xml /components/zucchini/testdata/*.exe @@ -291,3 +287,6 @@ /webpagereplay_logs/ /x86-generic_out/ /xcodebuild + +# Ignore any Android RenderTest goldens +**/render_tests/*.png
diff --git a/DEPS b/DEPS index bff83c86..7f7e48d8 100644 --- a/DEPS +++ b/DEPS
@@ -126,11 +126,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': 'a41c6858da8a27d0c8e7a295c5d9f2bf206997db', + 'skia_revision': 'e59d40e0bcab551b47d5c009f8b4d9a94b53e0fb', # 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': 'b8e007d8fe213fe1eea595eea03bc63d938d4284', + 'v8_revision': '37a08a2a6e599bb0a432f117b0bd3cba2e4dccfe', # 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. @@ -138,7 +138,7 @@ # 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': 'e03498f2d25ae2c196cff80cef0ee0aa9796a4d1', + 'angle_revision': 'f256339a19591e6a9286ba306d667cbb6c3c9a4d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -186,7 +186,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': '22b1689dde6c7c028db5e6a5dedc1249f0a30eaf', + 'catapult_revision': 'd77957d206cc21a12ebc213cd1239fcb0e5cc5be', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -234,7 +234,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spv_tools_revision': '10a7def6c03e29c4246a01577199aaf35e29f9f9', + 'spv_tools_revision': '12b3d7e9d661b2f50815e09c34eabe310088dfe4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -1293,7 +1293,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@b1dbb0c6184fcc16397609ddfbe3c3571ee182b7', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@de578cdd6b58dab6721679f2a5f56f87c7e0e3ce', 'condition': 'checkout_src_internal', },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 2feccac..e8aa2db 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -1654,7 +1654,7 @@ r"^courgette[\\/]courgette_minimal_tool\.cc$", r"^courgette[\\/]courgette_tool\.cc$", r"^extensions[\\/]renderer[\\/]logging_native_handler\.cc$", - r"^fuchsia[\\/]browser[\\/]frame_impl.cc$", + r"^fuchsia[\\/]engine[\\/]browser[\\/]frame_impl.cc$", r"^headless[\\/]app[\\/]headless_shell\.cc$", r"^ipc[\\/]ipc_logging\.cc$", r"^native_client_sdk[\\/]",
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java index 3b06e7df..5775a8f0 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
@@ -510,6 +510,34 @@ Assert.assertTrue(testContainer.isBackedByHardwareView()); } + @Test + @Feature({"AndroidWebView"}) + @SmallTest + public void testBasicCookieFunctionality() throws Throwable { + AwTestContainerView testView = + mActivityTestRule.createAwTestContainerViewOnMainSync(mContentsClient); + AwContents awContents = testView.getAwContents(); + + TestWebServer webServer = TestWebServer.start(); + try { + List<Pair<String, String>> responseHeaders = CommonResources.getTextHtmlHeaders(true); + final String cookie = "key=value"; + responseHeaders.add(Pair.create("Set-Cookie", cookie)); + final String url = webServer.setResponse("/" + CommonResources.ABOUT_FILENAME, + CommonResources.ABOUT_HTML, responseHeaders); + AwActivityTestRule.enableJavaScriptOnUiThread(awContents); + mActivityTestRule.loadUrlSync( + awContents, mContentsClient.getOnPageFinishedHelper(), url); + + final String script = "document.cookie"; + Assert.assertEquals("\"key=value\"", + mActivityTestRule.executeJavaScriptAndWaitForResult( + awContents, mContentsClient, script)); + } finally { + webServer.shutdown(); + } + } + /** * Verifies that Web Notifications and the Push API are not exposed in WebView. */
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index f8fe6c4d..5de367c 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1147,6 +1147,8 @@ "wm/tablet_mode/tablet_mode_window_drag_controller.h", "wm/tablet_mode/tablet_mode_window_drag_delegate.cc", "wm/tablet_mode/tablet_mode_window_drag_delegate.h", + "wm/tablet_mode/tablet_mode_window_drag_metrics.cc", + "wm/tablet_mode/tablet_mode_window_drag_metrics.h", "wm/tablet_mode/tablet_mode_window_manager.cc", "wm/tablet_mode/tablet_mode_window_manager.h", "wm/tablet_mode/tablet_mode_window_state.cc",
diff --git a/ash/app_list/views/assistant/dialog_plate.cc b/ash/app_list/views/assistant/dialog_plate.cc index a9f9f6a..1bd41c7 100644 --- a/ash/app_list/views/assistant/dialog_plate.cc +++ b/ash/app_list/views/assistant/dialog_plate.cc
@@ -336,7 +336,7 @@ l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_DIALOG_PLATE_HINT); textfield_->set_placeholder_text(textfield_hint); textfield_->SetAccessibleName(textfield_hint); - textfield_->set_placeholder_text_color(ash::kTextColorHint); + textfield_->set_placeholder_text_color(ash::kTextColorSecondary); textfield_->SetTextColor(ash::kTextColorPrimary); keyboard_layout_container_->AddChildView(textfield_);
diff --git a/ash/assistant/assistant_view_delegate_impl.cc b/ash/assistant/assistant_view_delegate_impl.cc index 640e797..f2dd9617 100644 --- a/ash/assistant/assistant_view_delegate_impl.cc +++ b/ash/assistant/assistant_view_delegate_impl.cc
@@ -8,6 +8,7 @@ #include "ash/assistant/assistant_controller.h" #include "ash/assistant/assistant_controller_observer.h" #include "ash/assistant/assistant_interaction_controller.h" +#include "ash/assistant/assistant_notification_controller.h" #include "ash/shell.h" #include "ash/voice_interaction/voice_interaction_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" @@ -29,6 +30,11 @@ return assistant_controller_->interaction_controller()->model(); } +const AssistantNotificationModel* +AssistantViewDelegateImpl::GetNotificationModel() const { + return assistant_controller_->notification_controller()->model(); +} + const AssistantUiModel* AssistantViewDelegateImpl::GetUiModel() const { return assistant_controller_->ui_controller()->model(); } @@ -37,6 +43,7 @@ AssistantCacheModelObserver* observer) { assistant_controller_->cache_controller()->AddModelObserver(observer); } + void AssistantViewDelegateImpl::RemoveCacheModelObserver( AssistantCacheModelObserver* observer) { assistant_controller_->cache_controller()->RemoveModelObserver(observer); @@ -46,16 +53,29 @@ AssistantInteractionModelObserver* observer) { assistant_controller_->interaction_controller()->AddModelObserver(observer); } + void AssistantViewDelegateImpl::RemoveInteractionModelObserver( AssistantInteractionModelObserver* observer) { assistant_controller_->interaction_controller()->RemoveModelObserver( observer); } +void AssistantViewDelegateImpl::AddNotificationModelObserver( + AssistantNotificationModelObserver* observer) { + assistant_controller_->notification_controller()->AddModelObserver(observer); +} + +void AssistantViewDelegateImpl::RemoveNotificationModelObserver( + AssistantNotificationModelObserver* observer) { + assistant_controller_->notification_controller()->RemoveModelObserver( + observer); +} + void AssistantViewDelegateImpl::AddUiModelObserver( AssistantUiModelObserver* observer) { assistant_controller_->ui_controller()->AddModelObserver(observer); } + void AssistantViewDelegateImpl::RemoveUiModelObserver( AssistantUiModelObserver* observer) { assistant_controller_->ui_controller()->RemoveModelObserver(observer); @@ -65,6 +85,7 @@ AssistantViewDelegateObserver* observer) { view_delegate_observers_.AddObserver(observer); } + void AssistantViewDelegateImpl::RemoveViewDelegateObserver( AssistantViewDelegateObserver* observer) { view_delegate_observers_.RemoveObserver(observer); @@ -74,6 +95,7 @@ DefaultVoiceInteractionObserver* observer) { Shell::Get()->voice_interaction_controller()->AddLocalObserver(observer); } + void AssistantViewDelegateImpl::RemoveVoiceInteractionControllerObserver( DefaultVoiceInteractionObserver* observer) { Shell::Get()->voice_interaction_controller()->RemoveLocalObserver(observer);
diff --git a/ash/assistant/assistant_view_delegate_impl.h b/ash/assistant/assistant_view_delegate_impl.h index cab462e..c20eaf8f 100644 --- a/ash/assistant/assistant_view_delegate_impl.h +++ b/ash/assistant/assistant_view_delegate_impl.h
@@ -23,6 +23,7 @@ // AssistantViewDelegate: const AssistantCacheModel* GetCacheModel() const override; const AssistantInteractionModel* GetInteractionModel() const override; + const AssistantNotificationModel* GetNotificationModel() const override; const AssistantUiModel* GetUiModel() const override; void AddCacheModelObserver(AssistantCacheModelObserver* observer) override; void RemoveCacheModelObserver(AssistantCacheModelObserver* observer) override; @@ -30,6 +31,10 @@ AssistantInteractionModelObserver* observer) override; void RemoveInteractionModelObserver( AssistantInteractionModelObserver* observer) override; + void AddNotificationModelObserver( + AssistantNotificationModelObserver* observer) override; + void RemoveNotificationModelObserver( + AssistantNotificationModelObserver* observer) override; void AddUiModelObserver(AssistantUiModelObserver* observer) override; void RemoveUiModelObserver(AssistantUiModelObserver* observer) override; void AddViewDelegateObserver( @@ -57,7 +62,7 @@ bool VoiceInteractionControllerSetupCompleted() const override; private: - AssistantController* assistant_controller_; + AssistantController* const assistant_controller_; base::ObserverList<AssistantViewDelegateObserver> view_delegate_observers_; DISALLOW_COPY_AND_ASSIGN(AssistantViewDelegateImpl);
diff --git a/ash/assistant/ui/BUILD.gn b/ash/assistant/ui/BUILD.gn index 1a707a0a..bb46a713 100644 --- a/ash/assistant/ui/BUILD.gn +++ b/ash/assistant/ui/BUILD.gn
@@ -40,6 +40,8 @@ "assistant_mini_view.h", "assistant_notification_overlay.cc", "assistant_notification_overlay.h", + "assistant_notification_view.cc", + "assistant_notification_view.h", "assistant_overlay.h", "assistant_view_delegate.h", "assistant_web_view.cc",
diff --git a/ash/assistant/ui/assistant_container_view.cc b/ash/assistant/ui/assistant_container_view.cc index 9ec04c9..c3ce3ba 100644 --- a/ash/assistant/ui/assistant_container_view.cc +++ b/ash/assistant/ui/assistant_container_view.cc
@@ -64,26 +64,8 @@ void Layout() override { views::ClientView::Layout(); - for (AssistantOverlay* overlay : overlays_) { - AssistantOverlay::LayoutParams layout_params = overlay->GetLayoutParams(); - gfx::Size preferred_size = overlay->GetPreferredSize(); - - int left = layout_params.margins.left(); - int top = layout_params.margins.top(); - int width = preferred_size.width(); - int height = preferred_size.height(); - - // Gravity::kBottom. - using Gravity = AssistantOverlay::LayoutParams::Gravity; - if ((layout_params.gravity & Gravity::kBottom) != 0) - top = this->height() - height - layout_params.margins.bottom(); - - // Gravity::kCenterHorizontal. - if ((layout_params.gravity & Gravity::kCenterHorizontal) != 0) - left = (this->width() - width) / 2 - layout_params.margins.left(); - - overlay->SetBounds(left, top, width, height); - } + for (AssistantOverlay* overlay : overlays_) + Layout(overlay); } // views::ViewObserver: @@ -96,6 +78,11 @@ overlays_.erase(it); } + void OnViewPreferredSizeChanged(views::View* view) override { + Layout(static_cast<AssistantOverlay*>(view)); + SchedulePaint(); + } + void AddOverlays(std::vector<AssistantOverlay*> overlays) { for (AssistantOverlay* overlay : overlays) { overlays_.insert(overlay); @@ -105,6 +92,29 @@ } private: + void Layout(AssistantOverlay* overlay) { + AssistantOverlay::LayoutParams layout_params = overlay->GetLayoutParams(); + gfx::Size preferred_size = overlay->GetPreferredSize(); + + int left = layout_params.margins.left(); + int top = layout_params.margins.top(); + int width = std::min(preferred_size.width(), this->width()); + int height = preferred_size.height(); + + // Gravity::kBottom. + using Gravity = AssistantOverlay::LayoutParams::Gravity; + if ((layout_params.gravity & Gravity::kBottom) != 0) + top = this->height() - height - layout_params.margins.bottom(); + + // Gravity::kCenterHorizontal. + if ((layout_params.gravity & Gravity::kCenterHorizontal) != 0) { + width = std::min(width, this->width() - layout_params.margins.width()); + left = (this->width() - width) / 2; + } + + overlay->SetBounds(left, top, width, height); + } + std::set<AssistantOverlay*> overlays_; DISALLOW_COPY_AND_ASSIGN(AssistantContainerClientView);
diff --git a/ash/assistant/ui/assistant_main_view.cc b/ash/assistant/ui/assistant_main_view.cc index 4b0baa7d..af3d61b 100644 --- a/ash/assistant/ui/assistant_main_view.cc +++ b/ash/assistant/ui/assistant_main_view.cc
@@ -168,7 +168,7 @@ // Notification overlay. if (chromeos::assistant::features::IsInAssistantNotificationsEnabled()) { auto notification_overlay = - std::make_unique<AssistantNotificationOverlay>(); + std::make_unique<AssistantNotificationOverlay>(delegate_); notification_overlay->set_owned_by_client(); overlays_.push_back(std::move(notification_overlay)); }
diff --git a/ash/assistant/ui/assistant_notification_overlay.cc b/ash/assistant/ui/assistant_notification_overlay.cc index 6f8133f..d054d83b 100644 --- a/ash/assistant/ui/assistant_notification_overlay.cc +++ b/ash/assistant/ui/assistant_notification_overlay.cc
@@ -4,7 +4,12 @@ #include "ash/assistant/ui/assistant_notification_overlay.h" -#include "ui/gfx/canvas.h" +#include <memory> + +#include "ash/assistant/ui/assistant_notification_view.h" +#include "ash/assistant/ui/assistant_view_delegate.h" +#include "chromeos/services/assistant/public/mojom/assistant.mojom.h" +#include "ui/views/layout/fill_layout.h" namespace ash { @@ -12,44 +17,52 @@ // Appearance. constexpr int kMarginBottomDip = 64; -constexpr int kPreferredHeightDip = 60; -constexpr int kPreferredWidthDip = 576; +constexpr int kMarginHorizontalDip = 32; } // namespace -AssistantNotificationOverlay::AssistantNotificationOverlay() { +AssistantNotificationOverlay::AssistantNotificationOverlay( + AssistantViewDelegate* delegate) + : delegate_(delegate) { InitLayout(); + + // The AssistantViewDelegate outlives the Assistant view hierarchy. + delegate_->AddNotificationModelObserver(this); } -AssistantNotificationOverlay::~AssistantNotificationOverlay() = default; +AssistantNotificationOverlay::~AssistantNotificationOverlay() { + delegate_->RemoveNotificationModelObserver(this); +} const char* AssistantNotificationOverlay::GetClassName() const { return "AssistantNotificationOverlay"; } -gfx::Size AssistantNotificationOverlay::CalculatePreferredSize() const { - return gfx::Size(kPreferredWidthDip, GetHeightForWidth(kPreferredWidthDip)); -} - -int AssistantNotificationOverlay::GetHeightForWidth(int width) const { - return kPreferredHeightDip; -} - AssistantOverlay::LayoutParams AssistantNotificationOverlay::GetLayoutParams() const { using Gravity = AssistantOverlay::LayoutParams::Gravity; AssistantOverlay::LayoutParams layout_params; layout_params.gravity = Gravity::kBottom | Gravity::kCenterHorizontal; - layout_params.margins = gfx::Insets(0, 0, kMarginBottomDip, 0); + layout_params.margins = gfx::Insets(0, kMarginHorizontalDip, kMarginBottomDip, + kMarginHorizontalDip); return layout_params; } -// TODO(dmblack): Remove when notification views have been implemented. -void AssistantNotificationOverlay::OnPaintBackground(gfx::Canvas* canvas) { - canvas->DrawColor(0x20000000); +void AssistantNotificationOverlay::ViewHierarchyChanged( + const ViewHierarchyChangedDetails& details) { + if (details.parent == this) + PreferredSizeChanged(); +} + +void AssistantNotificationOverlay::OnNotificationAdded( + const AssistantNotification* notification) { + // TODO(dmblack): Only add views for notifications of the appropriate type. + AddChildView(new AssistantNotificationView(delegate_, notification)); } void AssistantNotificationOverlay::InitLayout() { + SetLayoutManager(std::make_unique<views::FillLayout>()); + SetPaintToLayer(); layer()->SetFillsBoundsOpaquely(false); }
diff --git a/ash/assistant/ui/assistant_notification_overlay.h b/ash/assistant/ui/assistant_notification_overlay.h index 1f6a1037..acb3b539 100644 --- a/ash/assistant/ui/assistant_notification_overlay.h +++ b/ash/assistant/ui/assistant_notification_overlay.h
@@ -5,30 +5,38 @@ #ifndef ASH_ASSISTANT_UI_ASSISTANT_NOTIFICATION_OVERLAY_H_ #define ASH_ASSISTANT_UI_ASSISTANT_NOTIFICATION_OVERLAY_H_ +#include "ash/assistant/model/assistant_notification_model_observer.h" #include "ash/assistant/ui/assistant_overlay.h" #include "base/component_export.h" #include "base/macros.h" namespace ash { +class AssistantViewDelegate; + // AssistantNotificationOverlay is a pseudo-child of AssistantMainView which is // responsible for parenting in-Assistant notifications. class COMPONENT_EXPORT(ASSISTANT_UI) AssistantNotificationOverlay - : public AssistantOverlay { + : public AssistantOverlay, + public AssistantNotificationModelObserver { public: - AssistantNotificationOverlay(); + AssistantNotificationOverlay(AssistantViewDelegate* delegate); ~AssistantNotificationOverlay() override; // AssistantOverlay: const char* GetClassName() const override; - gfx::Size CalculatePreferredSize() const override; - int GetHeightForWidth(int width) const override; LayoutParams GetLayoutParams() const override; - void OnPaintBackground(gfx::Canvas* canvas) override; + void ViewHierarchyChanged( + const ViewHierarchyChangedDetails& details) override; + + // AssistantNotificationModelObserver: + void OnNotificationAdded(const AssistantNotification* notification) override; private: void InitLayout(); + AssistantViewDelegate* const delegate_; // Owned by AssistantController. + DISALLOW_COPY_AND_ASSIGN(AssistantNotificationOverlay); };
diff --git a/ash/assistant/ui/assistant_notification_view.cc b/ash/assistant/ui/assistant_notification_view.cc new file mode 100644 index 0000000..0b44c18 --- /dev/null +++ b/ash/assistant/ui/assistant_notification_view.cc
@@ -0,0 +1,172 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/assistant/ui/assistant_notification_view.h" + +#include "ash/assistant/ui/assistant_ui_constants.h" +#include "ash/assistant/ui/assistant_view_delegate.h" +#include "ash/assistant/ui/main_stage/suggestion_chip_view.h" +#include "base/strings/utf_string_conversions.h" +#include "chromeos/services/assistant/public/mojom/assistant.mojom.h" +#include "ui/views/animation/ink_drop_painted_layer_delegates.h" +#include "ui/views/controls/button/button.h" +#include "ui/views/controls/label.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/layout/fill_layout.h" + +namespace ash { + +namespace { + +// Appearance. +constexpr int kLineHeightDip = 20; +constexpr int kPaddingLeftDip = 16; +constexpr int kPaddingRightDip = 8; +constexpr int kPreferredHeightDip = 48; +constexpr int kShadowElevationDip = 6; + +// Helpers --------------------------------------------------------------------- + +// TODO(dmblack): Handle button clicks. +views::View* CreateButton( + const chromeos::assistant::mojom::AssistantNotificationButtonPtr& button) { + SuggestionChipView::Params params; + params.text = base::UTF8ToUTF16(button->label); + return new SuggestionChipView(params, /*listener=*/nullptr); +} + +} // namespace + +AssistantNotificationView::AssistantNotificationView( + AssistantViewDelegate* delegate, + const AssistantNotification* notification) + : delegate_(delegate), notification_id_(notification->client_id) { + InitLayout(notification); + + // The AssistantViewDelegate outlives the Assistant view hierarchy. + delegate_->AddNotificationModelObserver(this); +} + +AssistantNotificationView::~AssistantNotificationView() { + delegate_->RemoveNotificationModelObserver(this); +} + +const char* AssistantNotificationView::GetClassName() const { + return "AssistantNotificationView"; +} + +gfx::Size AssistantNotificationView::CalculatePreferredSize() const { + return gfx::Size(INT_MAX, GetHeightForWidth(INT_MAX)); +} + +int AssistantNotificationView::GetHeightForWidth(int width) const { + return kPreferredHeightDip; +} + +void AssistantNotificationView::OnBoundsChanged( + const gfx::Rect& previous_bounds) { + UpdateBackground(); +} + +void AssistantNotificationView::OnNotificationUpdated( + const AssistantNotification* notification) { + if (notification->client_id != notification_id_) + return; + + // Title/Message. + title_->SetText(base::UTF8ToUTF16(notification->title)); + message_->SetText(base::UTF8ToUTF16(notification->message)); + + // Old buttons. + // Note that we don't remove the first two children of |container_| as those + // children are |title_| and |message_| respectively. + for (int i = container_->child_count() - 1; i > 1; --i) + delete container_->child_at(i); + + // New buttons. + for (const auto& button : notification->buttons) + container_->AddChildView(CreateButton(button)); + + // Because |container_| has a fixed size, we need to explicitly trigger a + // layout/paint pass ourselves when manipulating child views. + container_->Layout(); + container_->SchedulePaint(); +} + +void AssistantNotificationView::OnNotificationRemoved( + const AssistantNotification* notification, + bool from_server) { + if (notification->client_id == notification_id_) + delete this; +} + +void AssistantNotificationView::InitLayout( + const AssistantNotification* notification) { + SetLayoutManager(std::make_unique<views::FillLayout>()); + + SetPaintToLayer(); + layer()->SetFillsBoundsOpaquely(false); + + // Background/shadow. + background_layer_.SetFillsBoundsOpaquely(false); + layer()->Add(&background_layer_); + + // Container. + container_ = new views::View(); + container_->SetPreferredSize(gfx::Size(INT_MAX, INT_MAX)); + container_->SetPaintToLayer(); + container_->layer()->SetFillsBoundsOpaquely(false); + AddChildView(container_); + + auto* layout_manager = + container_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal, + gfx::Insets(0, kPaddingLeftDip, 0, kPaddingRightDip), kSpacingDip)); + + layout_manager->set_cross_axis_alignment( + views::BoxLayout::CrossAxisAlignment::CROSS_AXIS_ALIGNMENT_CENTER); + + gfx::FontList font_list = + assistant::ui::GetDefaultFontList().DeriveWithSizeDelta(1); + + // Title. + title_ = new views::Label(base::UTF8ToUTF16(notification->title)); + title_->SetAutoColorReadabilityEnabled(false); + title_->SetEnabledColor(kTextColorPrimary); + title_->SetFontList(font_list.DeriveWithWeight(gfx::Font::Weight::MEDIUM)); + title_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); + title_->SetLineHeight(kLineHeightDip); + container_->AddChildView(title_); + + // Message. + message_ = new views::Label(base::UTF8ToUTF16(notification->message)); + message_->SetAutoColorReadabilityEnabled(false); + message_->SetEnabledColor(kTextColorSecondary); + message_->SetFontList(font_list); + message_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); + message_->SetLineHeight(kLineHeightDip); + container_->AddChildView(message_); + + layout_manager->SetFlexForView(message_, 1); + + // Buttons. + for (const auto& button : notification->buttons) + container_->AddChildView(CreateButton(button)); +} + +void AssistantNotificationView::UpdateBackground() { + gfx::ShadowValues shadow_values = + gfx::ShadowValue::MakeMdShadowValues(kShadowElevationDip); + + shadow_delegate_ = std::make_unique<views::BorderShadowLayerDelegate>( + shadow_values, GetLocalBounds(), + /*fill_color=*/SK_ColorWHITE, + /*corner_radius=*/height() / 2); + + background_layer_.set_delegate(shadow_delegate_.get()); + background_layer_.SetBounds( + gfx::ToEnclosingRect(shadow_delegate_->GetPaintedBounds())); +} + +} // namespace ash
diff --git a/ash/assistant/ui/assistant_notification_view.h b/ash/assistant/ui/assistant_notification_view.h new file mode 100644 index 0000000..d530078 --- /dev/null +++ b/ash/assistant/ui/assistant_notification_view.h
@@ -0,0 +1,68 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_ASSISTANT_UI_ASSISTANT_NOTIFICATION_VIEW_H_ +#define ASH_ASSISTANT_UI_ASSISTANT_NOTIFICATION_VIEW_H_ + +#include <memory> +#include <string> + +#include "ash/assistant/model/assistant_notification_model_observer.h" +#include "base/component_export.h" +#include "base/macros.h" +#include "ui/compositor/layer.h" +#include "ui/views/view.h" + +namespace views { +class BorderShadowLayerDelegate; +class Label; +} // namespace views + +namespace ash { + +class AssistantViewDelegate; + +// AssistantNotificationView is the view for a mojom::AssistantNotification +// which appears in Assistant UI. Its parent is AssistantNotificationOverlay. +class COMPONENT_EXPORT(ASSISTANT_UI) AssistantNotificationView + : public views::View, + public AssistantNotificationModelObserver { + public: + AssistantNotificationView(AssistantViewDelegate* delegate, + const AssistantNotification* notification); + ~AssistantNotificationView() override; + + // views::View: + const char* GetClassName() const override; + gfx::Size CalculatePreferredSize() const override; + int GetHeightForWidth(int width) const override; + void OnBoundsChanged(const gfx::Rect& previous_bounds) override; + + // AssistantNotificationModelObserver: + void OnNotificationUpdated( + const AssistantNotification* notification) override; + void OnNotificationRemoved(const AssistantNotification* notification, + bool from_server) override; + + private: + void InitLayout(const AssistantNotification* notification); + void UpdateBackground(); + + AssistantViewDelegate* const delegate_; // Owned by AssistantController. + const std::string notification_id_; + + views::View* container_; // Owned by view hierarchy. + views::Label* title_; // Owned by view hierarchy. + views::Label* message_; // Owned by view hierarchy. + + // Background/shadow. + ui::Layer background_layer_; + std::unique_ptr<views::BorderShadowLayerDelegate> shadow_delegate_; + + DISALLOW_COPY_AND_ASSIGN(AssistantNotificationView); +}; + +} // namespace ash + +#endif // ASH_ASSISTANT_UI_ASSISTANT_NOTIFICATION_VIEW_H_
diff --git a/ash/assistant/ui/assistant_ui_constants.h b/ash/assistant/ui/assistant_ui_constants.h index eb74d035f..79b589a6 100644 --- a/ash/assistant/ui/assistant_ui_constants.h +++ b/ash/assistant/ui/assistant_ui_constants.h
@@ -25,8 +25,8 @@ constexpr int kUiElementHorizontalMarginDip = 32; // Typography. -constexpr SkColor kTextColorHint = gfx::kGoogleGrey700; constexpr SkColor kTextColorPrimary = gfx::kGoogleGrey900; +constexpr SkColor kTextColorSecondary = gfx::kGoogleGrey700; // TODO(dmblack): Move the other constants into ash::assistant::ui. namespace assistant {
diff --git a/ash/assistant/ui/assistant_view_delegate.h b/ash/assistant/ui/assistant_view_delegate.h index 73b7eeab0..acfcdf82 100644 --- a/ash/assistant/ui/assistant_view_delegate.h +++ b/ash/assistant/ui/assistant_view_delegate.h
@@ -13,6 +13,8 @@ #include "ash/assistant/model/assistant_cache_model_observer.h" #include "ash/assistant/model/assistant_interaction_model.h" #include "ash/assistant/model/assistant_interaction_model_observer.h" +#include "ash/assistant/model/assistant_notification_model.h" +#include "ash/assistant/model/assistant_notification_model_observer.h" #include "ash/assistant/model/assistant_ui_model.h" #include "ash/assistant/model/assistant_ui_model_observer.h" #include "ash/assistant/ui/assistant_mini_view.h" @@ -60,6 +62,9 @@ // Gets the interaction model associated with the view delegate. virtual const AssistantInteractionModel* GetInteractionModel() const = 0; + // Gets the notification model associated with the view delegate. + virtual const AssistantNotificationModel* GetNotificationModel() const = 0; + // Gets the ui model associated with the view delegate. virtual const AssistantUiModel* GetUiModel() const = 0; @@ -75,6 +80,13 @@ virtual void RemoveInteractionModelObserver( AssistantInteractionModelObserver* observer) = 0; + // Adds/removes the notification model observer associated with the view + // delegate. + virtual void AddNotificationModelObserver( + AssistantNotificationModelObserver* observer) = 0; + virtual void RemoveNotificationModelObserver( + AssistantNotificationModelObserver* observer) = 0; + // Adds/removes the ui model observer associated with the view delegate. virtual void AddUiModelObserver(AssistantUiModelObserver* observer) = 0; virtual void RemoveUiModelObserver(AssistantUiModelObserver* observer) = 0;
diff --git a/ash/assistant/ui/dialog_plate/dialog_plate.cc b/ash/assistant/ui/dialog_plate/dialog_plate.cc index 3735d3f..c454cb9 100644 --- a/ash/assistant/ui/dialog_plate/dialog_plate.cc +++ b/ash/assistant/ui/dialog_plate/dialog_plate.cc
@@ -327,7 +327,7 @@ l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_DIALOG_PLATE_HINT); textfield_->set_placeholder_text(textfield_hint); textfield_->SetAccessibleName(textfield_hint); - textfield_->set_placeholder_text_color(kTextColorHint); + textfield_->set_placeholder_text_color(kTextColorSecondary); textfield_->SetTextColor(kTextColorPrimary); keyboard_layout_container_->AddChildView(textfield_);
diff --git a/ash/assistant/ui/main_stage/assistant_query_view.cc b/ash/assistant/ui/main_stage/assistant_query_view.cc index b910aed..4792450 100644 --- a/ash/assistant/ui/main_stage/assistant_query_view.cc +++ b/ash/assistant/ui/main_stage/assistant_query_view.cc
@@ -128,7 +128,7 @@ label_->AddStyleRange(gfx::Range(high_confidence_text_16.length(), high_confidence_text_16.length() + low_confidence_text_16.length()), - CreateStyleInfo(kTextColorHint)); + CreateStyleInfo(kTextColorSecondary)); } } label_->SizeToFit(width());
diff --git a/ash/assistant/ui/main_stage/suggestion_chip_view.h b/ash/assistant/ui/main_stage/suggestion_chip_view.h index b0573fa..b8eeb535 100644 --- a/ash/assistant/ui/main_stage/suggestion_chip_view.h +++ b/ash/assistant/ui/main_stage/suggestion_chip_view.h
@@ -18,6 +18,7 @@ namespace ash { +// TODO(dmblack): Move to /ash/assistant/ui/base/. // View representing a suggestion chip. class COMPONENT_EXPORT(ASSISTANT_UI) SuggestionChipView : public views::Button { public:
diff --git a/ash/magnifier/docked_magnifier_controller.cc b/ash/magnifier/docked_magnifier_controller.cc index 18df196..0b6d162 100644 --- a/ash/magnifier/docked_magnifier_controller.cc +++ b/ash/magnifier/docked_magnifier_controller.cc
@@ -573,10 +573,9 @@ auto* split_view_controller = shell->split_view_controller(); if (split_view_controller->IsSplitViewModeActive()) { // In this case, we're in a single-split-view mode, i.e. a window is - // snapped to one side of the split view, while the other side has the - // window selector active. - // We need to exit split view as well as exiting overview mode, otherwise - // we'll be in an invalid state. + // snapped to one side of the split view, while the other side has + // overview active. We need to exit split view as well as exiting overview + // mode, otherwise we'll be in an invalid state. split_view_controller->EndSplitView( SplitViewController::EndReason::kNormal); }
diff --git a/ash/media/media_notification_controller_unittest.cc b/ash/media/media_notification_controller_unittest.cc index 4d2d475..1493ff3 100644 --- a/ash/media/media_notification_controller_unittest.cc +++ b/ash/media/media_notification_controller_unittest.cc
@@ -191,4 +191,24 @@ notification->custom_view_type()); } +// Test that if we recieve a null media session info that we hide the +// notification. +TEST_F(MediaNotificationControllerTest, HandleNullMediaSessionInfo) { + ExpectNotificationCount(0); + + base::UnguessableToken id = base::UnguessableToken::Create(); + + Shell::Get()->media_notification_controller()->OnFocusGained( + GetRequestStateWithId(id)); + + ExpectNotificationCount(1); + + Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->MediaSessionInfoChanged(nullptr); + + ExpectNotificationCount(0); +} + } // namespace ash
diff --git a/ash/media/media_notification_item.cc b/ash/media/media_notification_item.cc index f044267b..22e6803e 100644 --- a/ash/media/media_notification_item.cc +++ b/ash/media/media_notification_item.cc
@@ -85,7 +85,6 @@ view_ = view; if (view) { - DCHECK(!session_info_.is_null()); view_->UpdateWithMediaSessionInfo(session_info_); view_->UpdateWithMediaMetadata(session_metadata_); view_->UpdateWithMediaActions(session_actions_); @@ -99,7 +98,7 @@ void MediaNotificationItem::MaybeHideOrShowNotification() { // If the |is_controllable| bit is set in MediaSessionInfo then we should show // a media notification. - if (!session_info_->is_controllable) { + if (!session_info_ || !session_info_->is_controllable) { HideNotification(); return; }
diff --git a/ash/media/media_notification_view.cc b/ash/media/media_notification_view.cc index 0c434927..93a1a3b7 100644 --- a/ash/media/media_notification_view.cc +++ b/ash/media/media_notification_view.cc
@@ -205,8 +205,9 @@ void MediaNotificationView::UpdateWithMediaSessionInfo( const media_session::mojom::MediaSessionInfoPtr& session_info) { - bool playing = session_info->playback_state == - media_session::mojom::MediaPlaybackState::kPlaying; + bool playing = + session_info && session_info->playback_state == + media_session::mojom::MediaPlaybackState::kPlaying; play_pause_button_->SetToggled(playing); MediaSessionAction action =
diff --git a/ash/system/network/active_network_icon.cc b/ash/system/network/active_network_icon.cc index 9473d0e..784371b6 100644 --- a/ash/system/network/active_network_icon.cc +++ b/ash/system/network/active_network_icon.cc
@@ -11,11 +11,13 @@ #include "chromeos/network/network_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" +#include "chromeos/network/network_type_pattern.h" #include "third_party/cros_system_api/dbus/service_constants.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/paint_vector_icon.h" using chromeos::NetworkState; +using chromeos::NetworkStateHandler; using chromeos::NetworkTypePattern; namespace ash { @@ -190,10 +192,40 @@ ActiveNetworksChanged(active_networks); } +void ActiveNetworkIcon::SetCellularUninitializedMsg() { + if (network_state_handler_->GetTechnologyState( + NetworkTypePattern::Cellular()) == + NetworkStateHandler::TECHNOLOGY_UNINITIALIZED) { + cellular_uninitialized_msg_ = IDS_ASH_STATUS_TRAY_INITIALIZING_CELLULAR; + uninitialized_state_time_ = base::Time::Now(); + return; + } + + if (network_state_handler_->GetScanningByType( + NetworkTypePattern::Cellular())) { + cellular_uninitialized_msg_ = IDS_ASH_STATUS_TRAY_MOBILE_SCANNING; + uninitialized_state_time_ = base::Time::Now(); + return; + } + + // There can be a delay between leaving the Initializing state and when + // a Cellular device shows up, so keep showing the initializing + // animation for a bit to avoid flashing the disconnect icon. + const int kInitializingDelaySeconds = 1; + base::TimeDelta dtime = base::Time::Now() - uninitialized_state_time_; + if (dtime.InSeconds() >= kInitializingDelaySeconds) + cellular_uninitialized_msg_ = 0; +} + void ActiveNetworkIcon::DeviceListChanged() { UpdateActiveNetworks(); } +void ActiveNetworkIcon::DevicePropertiesUpdated( + const chromeos::DeviceState* device) { + SetCellularUninitializedMsg(); +} + void ActiveNetworkIcon::ActiveNetworksChanged( const std::vector<const NetworkState*>& active_networks) { active_cellular_ = nullptr; @@ -238,7 +270,7 @@ active_non_cellular_ = GetConnectingOrConnected(connecting_non_cellular, connected_non_cellular); - cellular_uninitialized_msg_ = network_icon::GetCellularUninitializedMsg(); + SetCellularUninitializedMsg(); } void ActiveNetworkIcon::OnShuttingDown() {
diff --git a/ash/system/network/active_network_icon.h b/ash/system/network/active_network_icon.h index 7dfe0f67..d0cf999 100644 --- a/ash/system/network/active_network_icon.h +++ b/ash/system/network/active_network_icon.h
@@ -12,6 +12,7 @@ #include "ash/system/network/network_icon.h" #include "base/macros.h" #include "base/strings/string16.h" +#include "base/time/time.h" #include "chromeos/network/network_state_handler_observer.h" namespace chromeos { @@ -59,6 +60,10 @@ gfx::ImageSkia GetDualImageCellular(network_icon::IconType icon_type, bool* animating); + int cellular_uninitialized_msg_for_test() const { + return cellular_uninitialized_msg_; + } + private: gfx::ImageSkia GetDefaultImageImpl( const chromeos::NetworkState* default_network, @@ -71,9 +76,11 @@ bool* animating); void UpdateActiveNetworks(); + void SetCellularUninitializedMsg(); // chromeos::NetworkStateHandlerObserver void DeviceListChanged() override; + void DevicePropertiesUpdated(const chromeos::DeviceState* device) override; void ActiveNetworksChanged(const std::vector<const chromeos::NetworkState*>& active_networks) override; void OnShuttingDown() override; @@ -84,6 +91,7 @@ const chromeos::NetworkState* active_cellular_ = nullptr; const chromeos::NetworkState* active_vpn_ = nullptr; int cellular_uninitialized_msg_ = 0; + base::Time uninitialized_state_time_; DISALLOW_COPY_AND_ASSIGN(ActiveNetworkIcon); };
diff --git a/ash/system/network/network_icon.cc b/ash/system/network/network_icon.cc index d5cb0986..a30b5b3 100644 --- a/ash/system/network/network_icon.cc +++ b/ash/system/network/network_icon.cc
@@ -15,7 +15,7 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "chromeos/network/network_state.h" -#include "chromeos/network/network_state_handler.h" +#include "chromeos/network/network_type_pattern.h" #include "chromeos/network/tether_constants.h" #include "components/vector_icons/vector_icons.h" #include "third_party/cros_system_api/dbus/service_constants.h" @@ -26,10 +26,7 @@ #include "ui/gfx/skia_util.h" #include "ui/gfx/vector_icon_types.h" -using chromeos::NetworkConnectionHandler; -using chromeos::NetworkHandler; using chromeos::NetworkState; -using chromeos::NetworkStateHandler; using chromeos::NetworkTypePattern; namespace ash { @@ -631,44 +628,7 @@ } } -int GetCellularUninitializedMsg() { - static base::Time s_uninitialized_state_time; - static int s_uninitialized_msg(0); - - NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); - - if (handler->GetTechnologyState(NetworkTypePattern::Cellular()) == - NetworkStateHandler::TECHNOLOGY_UNINITIALIZED) { - s_uninitialized_msg = IDS_ASH_STATUS_TRAY_INITIALIZING_CELLULAR; - s_uninitialized_state_time = base::Time::Now(); - return s_uninitialized_msg; - } - - if (handler->GetScanningByType(NetworkTypePattern::Cellular())) { - s_uninitialized_msg = IDS_ASH_STATUS_TRAY_MOBILE_SCANNING; - s_uninitialized_state_time = base::Time::Now(); - return s_uninitialized_msg; - } - - // There can be a delay between leaving the Initializing state and when - // a Cellular device shows up, so keep showing the initializing - // animation for a bit to avoid flashing the disconnect icon. - const int kInitializingDelaySeconds = 1; - base::TimeDelta dtime = base::Time::Now() - s_uninitialized_state_time; - if (dtime.InSeconds() < kInitializingDelaySeconds) - return s_uninitialized_msg; - return 0; -} - -void PurgeNetworkIconCache() { - NetworkStateHandler::NetworkStateList networks; - NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkList( - &networks); - std::set<std::string> network_paths; - for (NetworkStateHandler::NetworkStateList::iterator iter = networks.begin(); - iter != networks.end(); ++iter) { - network_paths.insert((*iter)->path()); - } +void PurgeNetworkIconCache(const std::set<std::string>& network_paths) { PurgeIconMap(ICON_TYPE_TRAY_OOBE, network_paths); PurgeIconMap(ICON_TYPE_TRAY_REGULAR, network_paths); PurgeIconMap(ICON_TYPE_DEFAULT_VIEW, network_paths);
diff --git a/ash/system/network/network_icon.h b/ash/system/network/network_icon.h index f0eba5c..8a3e589 100644 --- a/ash/system/network/network_icon.h +++ b/ash/system/network/network_icon.h
@@ -5,6 +5,7 @@ #ifndef ASH_SYSTEM_NETWORK_NETWORK_ICON_H_ #define ASH_SYSTEM_NETWORK_NETWORK_ICON_H_ +#include <set> #include <string> #include "ash/ash_export.h" @@ -87,14 +88,10 @@ const chromeos::NetworkState* network, IconType icon_type); -// Updates and returns the appropriate message id if the cellular network -// is uninitialized. -ASH_EXPORT int GetCellularUninitializedMsg(); - -// Called when the list of networks changes. Retrieves the list of networks -// from the global NetworkStateHandler instance and removes cached entries -// that are no longer in the list. -ASH_EXPORT void PurgeNetworkIconCache(); +// Called periodically with the current list of network paths. Removes cached +// entries that are no longer in the list. +ASH_EXPORT void PurgeNetworkIconCache( + const std::set<std::string>& network_paths); // Called by ChromeVox to give a verbal indication of the network icon. Returns // the signal strength of |network|, if it is a network type with a signal
diff --git a/ash/system/network/network_icon_purger.cc b/ash/system/network/network_icon_purger.cc index f202013..c6e45b5 100644 --- a/ash/system/network/network_icon_purger.cc +++ b/ash/system/network/network_icon_purger.cc
@@ -9,26 +9,41 @@ #include "chromeos/network/network_state_handler.h" using chromeos::NetworkHandler; - -namespace { -const int kPurgeDelayMs = 300; -} // namespace +using chromeos::NetworkStateHandler; namespace ash { +namespace { + +const int kPurgeDelayMs = 300; + +void PurgeNetworkIconCache() { + NetworkStateHandler::NetworkStateList networks; + NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkList( + &networks); + std::set<std::string> network_paths; + for (NetworkStateHandler::NetworkStateList::iterator iter = networks.begin(); + iter != networks.end(); ++iter) { + network_paths.insert((*iter)->path()); + } + network_icon::PurgeNetworkIconCache(network_paths); +} + +} // namespace + NetworkIconPurger::NetworkIconPurger() { // NetworkHandler may not be initialized in tests. if (NetworkHandler::IsInitialized()) { - auto* network_handler = NetworkHandler::Get(); - network_handler->network_state_handler()->AddObserver(this, FROM_HERE); + NetworkHandler::Get()->network_state_handler()->AddObserver(this, + FROM_HERE); } } NetworkIconPurger::~NetworkIconPurger() { // NetworkHandler may not be initialized in tests. if (NetworkHandler::IsInitialized()) { - auto* network_handler = NetworkHandler::Get(); - network_handler->network_state_handler()->RemoveObserver(this, FROM_HERE); + NetworkHandler::Get()->network_state_handler()->RemoveObserver(this, + FROM_HERE); } } @@ -36,7 +51,7 @@ if (timer_.IsRunning()) return; timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kPurgeDelayMs), - base::BindOnce(&network_icon::PurgeNetworkIconCache)); + base::BindOnce(&PurgeNetworkIconCache)); } } // namespace ash
diff --git a/ash/system/network/network_icon_unittest.cc b/ash/system/network/network_icon_unittest.cc index fc8f8a6..86aa0eb2 100644 --- a/ash/system/network/network_icon_unittest.cc +++ b/ash/system/network/network_icon_unittest.cc
@@ -5,6 +5,7 @@ #include "ash/system/network/network_icon.h" #include <memory> +#include <set> #include "ash/strings/grit/ash_strings.h" #include "ash/system/network/active_network_icon.h" @@ -47,7 +48,7 @@ void TearDown() override { active_network_icon_.reset(); - PurgeNetworkIconCache(); + PurgeNetworkIconCache(std::set<std::string>()); } std::string ConfigureService(const std::string& shill_json_string) { @@ -119,6 +120,10 @@ *label = active_network_icon_->GetDefaultLabel(icon_type); } + int GetCellularUninitializedMsg() { + return active_network_icon_->cellular_uninitialized_msg_for_test(); + } + // The icon for a Tether network should be the same as one for a cellular // network. The icon for a Tether network should be different from one for a // Wi-Fi network. The icon for a cellular network should be different from one
diff --git a/ash/wm/overview/caption_container_view.cc b/ash/wm/overview/caption_container_view.cc index da852ad..ee005f6a 100644 --- a/ash/wm/overview/caption_container_view.cc +++ b/ash/wm/overview/caption_container_view.cc
@@ -10,13 +10,13 @@ #include "ash/wm/overview/overview_item.h" #include "ash/wm/overview/overview_utils.h" #include "ash/wm/overview/rounded_rect_view.h" +#include "ash/wm/overview/scoped_overview_animation_settings.h" #include "ash/wm/splitview/split_view_constants.h" #include "ash/wm/splitview/split_view_utils.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/base/l10n/l10n_util.h" #include "ui/compositor/layer.h" -#include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/strings/grit/ui_strings.h" @@ -60,11 +60,6 @@ // The font delta of the overview window title. constexpr int kLabelFontDelta = 2; -// Duration of the header and close button fade in/out when a drag is -// started/finished on a window selector item; -constexpr base::TimeDelta kDragAnimationDuration = - base::TimeDelta::FromMilliseconds(167); - void AddChildWithLayer(views::View* parent, views::View* child) { child->SetPaintToLayer(); child->layer()->SetFillsBoundsOpaquely(false); @@ -316,8 +311,8 @@ DoSplitviewOpacityAnimation(GetCannotSnapContainer()->layer(), visible - ? SPLITVIEW_ANIMATION_SELECTOR_ITEM_FADE_IN - : SPLITVIEW_ANIMATION_SELECTOR_ITEM_FADE_OUT); + ? SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_IN + : SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_OUT); } void CaptionContainerView::ResetListener() { @@ -382,20 +377,11 @@ return; layer->SetOpacity(1.f - target_opacity); - { - ui::LayerAnimator* animator = layer->GetAnimator(); - ui::ScopedLayerAnimationSettings settings(animator); - settings.SetPreemptionStrategy( - ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); - if (visible) { - animator->SchedulePauseForProperties(kDragAnimationDuration, - ui::LayerAnimationElement::OPACITY); - } - settings.SetTransitionDuration(kDragAnimationDuration); - settings.SetTweenType(visible ? gfx::Tween::LINEAR_OUT_SLOW_IN - : gfx::Tween::FAST_OUT_LINEAR_IN); - layer->SetOpacity(target_opacity); - } + ScopedOverviewAnimationSettings settings( + visible ? OVERVIEW_ANIMATION_OVERVIEW_TITLE_FADE_IN + : OVERVIEW_ANIMATION_OVERVIEW_TITLE_FADE_OUT, + layer->GetAnimator()); + layer->SetOpacity(target_opacity); } } // namespace ash
diff --git a/ash/wm/overview/overview_animation_type.h b/ash/wm/overview/overview_animation_type.h index 8f6ee1b..232fb9c 100644 --- a/ash/wm/overview/overview_animation_type.h +++ b/ash/wm/overview/overview_animation_type.h
@@ -18,9 +18,9 @@ OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_FADE_OUT, // Used to position windows when entering/exiting overview mode and when a // window is closed while overview mode is active. - OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_ON_ENTER, - OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_IN_OVERVIEW, - OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_ON_EXIT, + OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_ENTER, + OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW, + OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_EXIT, // Used to restore windows to their original position when exiting overview // mode. OVERVIEW_ANIMATION_RESTORE_WINDOW, @@ -28,14 +28,26 @@ OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO, // Used to animate scaling down of a window that is about to get closed while // overview mode is active. - OVERVIEW_ANIMATION_CLOSING_SELECTOR_ITEM, + OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM, // Used to animate hiding of a window that is closed while overview mode is // active. - OVERVIEW_ANIMATION_CLOSE_SELECTOR_ITEM, + OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM, // Used to animate windows upon entering or exiting overview mode to or from // the home launcher. OVERVIEW_ANIMATION_ENTER_FROM_HOME_LAUNCHER, OVERVIEW_ANIMATION_EXIT_TO_HOME_LAUNCHER, + // Used to fade in the drop target when dragging an application to enter + // overview mode. + OVERVIEW_ANIMATION_DROP_TARGET_FADE_IN, + // Used to fade in the shield which covers the work area in and out. + OVERVIEW_ANIMATION_SHIELD_FADE, + // Used to animate the selection window which is activated by using tab or the + // arrow keys. + OVERVIEW_ANIMATION_SELECTION_WINDOW_SHADOW, + OVERVIEW_ANIMATION_SELECTION_WINDOW, + // Used to animate the overview items header visibility. + OVERVIEW_ANIMATION_OVERVIEW_TITLE_FADE_IN, + OVERVIEW_ANIMATION_OVERVIEW_TITLE_FADE_OUT, }; } // namespace ash
diff --git a/ash/wm/overview/overview_controller.cc b/ash/wm/overview/overview_controller.cc index 4e361502..e2301811 100644 --- a/ash/wm/overview/overview_controller.cc +++ b/ash/wm/overview/overview_controller.cc
@@ -504,7 +504,7 @@ item_to_snap = current_grid->GetOverviewItemContaining(active_window); } else { // Currently in overview mode, with no snapped windows. Retrieve the first - // window selector item and attempt to snap that window. + // overview item and attempt to snap that window. DCHECK(overview_session_); OverviewGrid* current_grid = overview_session_->GetGridWithRootWindow( wm::GetRootWindowAt(event_location));
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index 8357e06c..f810f45 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -6,10 +6,7 @@ #include <algorithm> #include <functional> -#include <memory> -#include <set> #include <utility> -#include <vector> #include "ash/public/cpp/shelf_types.h" #include "ash/public/cpp/shell_window_ids.h" @@ -50,7 +47,6 @@ #include "ui/compositor/layer_animation_observer.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/compositor_extra/shadow.h" -#include "ui/gfx/animation/tween.h" #include "ui/gfx/color_analysis.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/geometry/safe_integer_conversions.h" @@ -66,11 +62,6 @@ namespace ash { namespace { -// Time it takes for the selector widget to move to the next target. The same -// time is used for fading out shield widget when the overview mode is opened -// or closed. -constexpr int kOverviewSelectorTransitionMilliseconds = 250; - // The color and opacity of the screen shield in overview. constexpr SkColor kShieldColor = SkColorSetARGB(255, 0, 0, 0); @@ -104,9 +95,6 @@ constexpr SkColor kNoItemsIndicatorTextColor = SK_ColorWHITE; constexpr float kNoItemsIndicatorBackgroundOpacity = 0.8f; -// Time duration of the show animation of the drop target. -constexpr int kDropTargetTransitionMilliseconds = 250; - // Returns the vector for the fade in animation. gfx::Vector2d GetSlideVectorForFadeIn(OverviewSession::Direction direction, const gfx::Rect& bounds) { @@ -149,15 +137,12 @@ if (animate) { widget->SetOpacity(0.f); - ui::ScopedLayerAnimationSettings animation_settings( - widget->GetNativeWindow()->layer()->GetAnimator()); - animation_settings.SetTransitionDuration( - base::TimeDelta::FromMilliseconds(kDropTargetTransitionMilliseconds)); - animation_settings.SetTweenType(gfx::Tween::EASE_IN); - animation_settings.SetPreemptionStrategy( - ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); + ScopedOverviewAnimationSettings settings( + OVERVIEW_ANIMATION_DROP_TARGET_FADE_IN, widget->GetNativeWindow()); + widget->SetOpacity(1.f); + } else { + widget->SetOpacity(1.f); } - widget->SetOpacity(1.f); return widget; } @@ -455,8 +440,8 @@ // |window_list_|. OverviewAnimationType animation_type = transition == OverviewSession::OverviewTransition::kEnter - ? OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_ON_ENTER - : OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_IN_OVERVIEW; + ? OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_ENTER + : OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW; for (size_t i = 0; i < window_list_.size(); ++i) { OverviewItem* window_item = window_list_[i].get(); if (window_item->animating_to_close() || @@ -579,12 +564,12 @@ PositionWindows(animate); } -void OverviewGrid::RemoveItem(OverviewItem* selector_item, bool reposition) { - auto iter = GetOverviewItemIterContainingWindow(selector_item->GetWindow()); +void OverviewGrid::RemoveItem(OverviewItem* overview_item, bool reposition) { + auto iter = GetOverviewItemIterContainingWindow(overview_item->GetWindow()); if (iter != window_list_.end()) { - window_observer_.Remove(selector_item->GetWindow()); + window_observer_.Remove(overview_item->GetWindow()); window_state_observer_.Remove( - wm::GetWindowState(selector_item->GetWindow())); + wm::GetWindowState(overview_item->GetWindow())); // Erase from the list first because deleting OverviewItem can lead to // iterating through the |window_list_|. std::unique_ptr<OverviewItem> tmp = std::move(*iter); @@ -703,8 +688,8 @@ } // Also clear ash::kIsDeferredTabDraggingTargetWindowKey key on the target - // window selector item so that it can't merge into this window selector - // item if the dragged window is currently in preview window area. + // overview item so that it can't merge into this overview item if the + // dragged window is currently in preview window area. if (target_window && !IsDropTargetWindow(target_window)) target_window->ClearProperty(ash::kIsDeferredTabDraggingTargetWindowKey); @@ -712,7 +697,7 @@ } // Show the selection widget if |location_in_screen| is contained by the - // browser windows' selector items in overview. + // browser windows' overview item in overview. if (target_window && target_window->GetProperty(ash::kIsDeferredTabDraggingTargetWindowKey)) { size_t previous_selected_index = selected_index_; @@ -826,7 +811,7 @@ if (empty()) { selection_widget_.reset(); - // If the grid is now empty, notify the window selector so that it erases us + // If the grid is now empty, notify |overview_session_| so that it erases us // from its grid list. if (overview_session_) overview_session_->OnGridEmpty(this); @@ -909,8 +894,8 @@ bool OverviewGrid::ShouldAnimateWallpaper() const { // If one of the windows covers the workspace, we do not need to animate. - for (const auto& selector_item : window_list_) { - if (CanCoverAvailableWorkspace(selector_item->GetWindow())) + for (const auto& overview_item : window_list_) { + if (CanCoverAvailableWorkspace(overview_item->GetWindow())) return false; } @@ -1181,7 +1166,7 @@ aura::Window* OverviewGrid::GetTargetWindowOnLocation( const gfx::Point& location_in_screen) { - // Find the window selector item that contains |location_in_screen|. + // Find the overview item that contains |location_in_screen|. auto iter = std::find_if(window_list_.begin(), window_list_.end(), [&location_in_screen](std::unique_ptr<OverviewItem>& item) { @@ -1219,13 +1204,8 @@ if (animate) { shield_widget_->SetOpacity(initial_opacity); - ui::ScopedLayerAnimationSettings animation_settings( - widget_window->layer()->GetAnimator()); - animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( - kOverviewSelectorTransitionMilliseconds)); - animation_settings.SetTweenType(gfx::Tween::EASE_OUT); - animation_settings.SetPreemptionStrategy( - ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); + ScopedOverviewAnimationSettings settings(OVERVIEW_ANIMATION_SHIELD_FADE, + shield_widget_->GetNativeWindow()); shield_widget_->SetOpacity(1.f); } else { shield_widget_->SetOpacity(1.f); @@ -1266,21 +1246,15 @@ gfx::Vector2d fade_out_direction = GetSlideVectorForFadeIn(direction, old_selection_window->bounds()); - ui::ScopedLayerAnimationSettings animation_settings( - old_selection_window->layer()->GetAnimator()); - animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( - kOverviewSelectorTransitionMilliseconds)); - animation_settings.SetPreemptionStrategy( - ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); - animation_settings.SetTweenType(gfx::Tween::FAST_OUT_LINEAR_IN); + ScopedOverviewAnimationSettings settings( + OVERVIEW_ANIMATION_SELECTION_WINDOW, old_selection_window); // CleanupAnimationObserver will delete itself (and the widget) when the - // motion animation is complete. - // Ownership over the observer is passed to the - // overview_session_->delegate() which has longer lifetime so that - // animations can continue even after the overview mode is shut down. + // motion animation is complete. Ownership over the observer is passed to + // the overview_session_->delegate() which has longer lifetime so that + // animations can continue even after the overview session is shut down. std::unique_ptr<CleanupAnimationObserver> observer( new CleanupAnimationObserver(std::move(selection_widget_))); - animation_settings.AddObserver(observer.get()); + settings.AddObserver(observer.get()); overview_session_->delegate()->AddDelayedAnimationObserver( std::move(observer)); old_selection->SetOpacity(0.f); @@ -1305,27 +1279,16 @@ gfx::Rect bounds = SelectedWindow()->target_bounds(); ::wm::ConvertRectFromScreen(root_window_, &bounds); if (animate) { - aura::Window* selection_widget_window = - selection_widget_->GetNativeWindow(); - ui::ScopedLayerAnimationSettings animation_settings( - selection_widget_window->layer()->GetAnimator()); - animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( - kOverviewSelectorTransitionMilliseconds)); - animation_settings.SetTweenType(gfx::Tween::EASE_IN_OUT); - animation_settings.SetPreemptionStrategy( - ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); + ScopedOverviewAnimationSettings settings( + OVERVIEW_ANIMATION_SELECTION_WINDOW, + selection_widget_->GetNativeWindow()); selection_widget_->SetBounds(bounds); selection_widget_->SetOpacity(1.f); if (selector_shadow_) { - ui::ScopedLayerAnimationSettings animation_settings_shadow( + ScopedOverviewAnimationSettings settings( + OVERVIEW_ANIMATION_SELECTION_WINDOW_SHADOW, selector_shadow_->shadow_layer()->GetAnimator()); - animation_settings_shadow.SetTransitionDuration( - base::TimeDelta::FromMilliseconds( - kOverviewSelectorTransitionMilliseconds)); - animation_settings_shadow.SetTweenType(gfx::Tween::EASE_IN_OUT); - animation_settings_shadow.SetPreemptionStrategy( - ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); bounds.Inset(1, 1); selector_shadow_->SetContentBounds( gfx::Rect(gfx::Point(1, 1), bounds.size())); @@ -1549,23 +1512,23 @@ } void OverviewGrid::CalculateOverviewItemAnimationState( - OverviewItem* selector_item, + OverviewItem* overview_item, bool* has_covered_available_workspace, bool selected, OverviewSession::OverviewTransition transition) { - if (!selector_item) + if (!overview_item) return; - aura::Window* window = selector_item->GetWindow(); - // |selector_item| should be contained in the |window_list_|. + aura::Window* window = overview_item->GetWindow(); + // |overview_item| should be contained in the |window_list_|. DCHECK(GetOverviewItemContaining(window)); bool can_cover_available_workspace = CanCoverAvailableWorkspace(window); const bool should_animate = selected || !(*has_covered_available_workspace); if (transition == OverviewSession::OverviewTransition::kEnter) - selector_item->set_should_animate_when_entering(should_animate); + overview_item->set_should_animate_when_entering(should_animate); if (transition == OverviewSession::OverviewTransition::kExit) - selector_item->set_should_animate_when_exiting(should_animate); + overview_item->set_should_animate_when_exiting(should_animate); if (!(*has_covered_available_workspace) && can_cover_available_workspace) *has_covered_available_workspace = true;
diff --git a/ash/wm/overview/overview_grid.h b/ash/wm/overview/overview_grid.h index b2cbe74..f0c6309 100644 --- a/ash/wm/overview/overview_grid.h +++ b/ash/wm/overview/overview_grid.h
@@ -97,17 +97,17 @@ // reposition with animation. void AddItem(aura::Window* window, bool reposition, bool animate); - // Removes |selector_item| from the grid. If |reprosition| is ture, reposition + // Removes |overview_item| from the grid. If |reposition| is true, reposition // all window items in the grid after removing the item. - void RemoveItem(OverviewItem* selector_item, bool reposition); + void RemoveItem(OverviewItem* overview_item, bool reposition); // Sets bounds for the window grid and positions all windows in the grid. void SetBoundsAndUpdatePositions(const gfx::Rect& bounds_in_screen); void SetBoundsAndUpdatePositionsIgnoringWindow(const gfx::Rect& bounds, OverviewItem* ignored_item); - // Shows or hides the selection widget. To be called by a window selector item - // when it is dragged. + // Shows or hides the selection widget. To be called by an overview item when + // it is dragged. void SetSelectionWidgetVisibility(bool visible); void ShowNoRecentsWindowMessage(bool visible); @@ -132,7 +132,7 @@ // Returns true if |window| is the placeholder window from the drop target. bool IsDropTargetWindow(aura::Window* window) const; - // Returns the selector item that accociates with |drop_target_widget_|. + // Returns the overview item that accociates with |drop_target_widget_|. // Returns nullptr if overview does not have the drop target. OverviewItem* GetDropTarget(); @@ -160,9 +160,9 @@ gfx::Rect GetNoItemsIndicatorLabelBoundsForTesting() const; // Calculates |should_animate_when_entering_| and - // |should_animate_when_exiting_| of the window selector items based on where + // |should_animate_when_exiting_| of the overview items based on where // the first MRU window covering the available workspace is found. - // |selector_item| is not nullptr if |selector_item| is the selected item when + // |selected_item| is not nullptr if |selected_item| is the selected item when // exiting overview mode. void CalculateWindowListAnimationStates( OverviewItem* selected_item, @@ -203,14 +203,13 @@ const gfx::Rect& work_area, OverviewSession::UpdateAnimationSettingsCallback callback); - // Returns the window of the window selector item that contains - // |location_in_screen|. + // Returns the window of the overview item that contains |location_in_screen|. aura::Window* GetTargetWindowOnLocation(const gfx::Point& location_in_screen); // Returns true if the grid has no more windows. bool empty() const { return window_list_.empty(); } - // Returns how many window selector items are in the grid. + // Returns how many overview items are in the grid. size_t size() const { return window_list_.size(); } // Returns true if the selection widget is active. @@ -266,7 +265,7 @@ // Moves the selection widget to the targeted window. void MoveSelectionWidgetToTarget(bool animate); - // Gets the layout of the window selector items. Layout is done in 2 stages + // Gets the layout of the overview items. Layout is done in 2 stages // maintaining fixed MRU ordering. // 1. Optimal height is determined. In this stage |height| is bisected to find // maximum height which still allows all the windows to fit. @@ -296,16 +295,16 @@ int* out_min_right, int* out_max_right); - // Calculates |selector_item|'s |should_animate_when_entering_|, - // |should_animate_when_exiting_|. |selected| is true if if |selector_item| is + // Calculates |overview_item|'s |should_animate_when_entering_|, + // |should_animate_when_exiting_|. |selected| is true if |overview_item| is // the selected item when exiting overview mode. void CalculateOverviewItemAnimationState( - OverviewItem* selector_item, + OverviewItem* overview_item, bool* has_fullscreen_coverred, bool selected, OverviewSession::OverviewTransition transition); - // Returns the window selector item iterator that contains |window|. + // Returns the overview item iterator that contains |window|. std::vector<std::unique_ptr<OverviewItem>>::iterator GetOverviewItemIterContainingWindow(aura::Window* window); @@ -316,7 +315,7 @@ // Root window the grid is in. aura::Window* root_window_; - // Pointer to the window selector that spawned this grid. + // Pointer to the OverviewSession that spawned this grid. OverviewSession* overview_session_; // Vector containing all the windows in this grid.
diff --git a/ash/wm/overview/overview_item.cc b/ash/wm/overview/overview_item.cc index 0bc90b9..8f93363 100644 --- a/ash/wm/overview/overview_item.cc +++ b/ash/wm/overview/overview_item.cc
@@ -212,7 +212,7 @@ int new_grid_y, float opacity, OverviewSession::UpdateAnimationSettingsCallback callback) { - // Animate the window selector widget and the window itself. + // Animate |item_widget_| and the window itself. // TODO(sammiequon): Investigate if we can combine with // FadeInWidgetAndMaybeSlideOnEnter. Also when animating we should remove // shadow and rounded corners. @@ -334,7 +334,7 @@ auto animate_window = [this](aura::Window* window, const gfx::Transform& transform, bool observe) { ScopedOverviewAnimationSettings settings( - OVERVIEW_ANIMATION_CLOSE_SELECTOR_ITEM, window); + OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM, window); gfx::Transform original_transform = window->transform(); original_transform.ConcatTransform(transform); window->SetTransform(original_transform); @@ -342,7 +342,7 @@ settings.AddObserver(this); }; - AnimateOpacity(0.0, OVERVIEW_ANIMATION_CLOSE_SELECTOR_ITEM); + AnimateOpacity(0.0, OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM); animate_window(item_widget_->GetNativeWindow(), transform, false); animate_window(GetWindowForStacking(), transform, true); } @@ -352,13 +352,13 @@ inset_bounds.Inset(target_bounds_.width() * kPreCloseScale, target_bounds_.height() * kPreCloseScale); // Scale down both the window and label. - SetBounds(inset_bounds, OVERVIEW_ANIMATION_CLOSING_SELECTOR_ITEM); + SetBounds(inset_bounds, OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM); // First animate opacity to an intermediate value concurrently with the // scaling animation. - AnimateOpacity(kClosingItemOpacity, OVERVIEW_ANIMATION_CLOSING_SELECTOR_ITEM); + AnimateOpacity(kClosingItemOpacity, OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM); // Fade out the window and the label, effectively hiding them. - AnimateOpacity(0.0, OVERVIEW_ANIMATION_CLOSE_SELECTOR_ITEM); + AnimateOpacity(0.0, OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM); transform_window_.Close(); } @@ -568,20 +568,20 @@ } } - // Then find the window which was stacked right above this selector item's - // window before dragging and stack this selector item's window below it. - const std::vector<std::unique_ptr<OverviewItem>>& selector_items = + // Then find the window which was stacked right above this overview item's + // window before dragging and stack this overview item's window below it. + const std::vector<std::unique_ptr<OverviewItem>>& overview_items = overview_grid_->window_list(); aura::Window* stacking_target = nullptr; - for (size_t index = 0; index < selector_items.size(); index++) { + for (size_t index = 0; index < overview_items.size(); index++) { if (index > 0) { - aura::Window* window = selector_items[index - 1].get()->GetWindow(); + aura::Window* window = overview_items[index - 1].get()->GetWindow(); if (window->parent() == parent_window && dragged_window->parent() == parent_window) { stacking_target = window; } } - if (selector_items[index].get() == this && stacking_target) { + if (overview_items[index].get() == this && stacking_target) { parent_window->StackChildBelow(dragged_widget_window, stacking_target); parent_window->StackChildBelow(dragged_window, dragged_widget_window); break; @@ -667,7 +667,7 @@ OverviewAnimationType OverviewItem::GetExitOverviewAnimationType() { return should_animate_when_exiting_ - ? OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_ON_EXIT + ? OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_EXIT : OVERVIEW_ANIMATION_NONE; } @@ -751,18 +751,18 @@ screen_rect.set_size(screen_size); const int top_view_inset = transform_window_.GetTopInset(); - gfx::Rect selector_item_bounds = + gfx::Rect overview_item_bounds = transform_window_.ShrinkRectToFitPreservingAspectRatio( screen_rect, target_bounds, top_view_inset, kHeaderHeightDp); // Do not set transform for drop target, set bounds instead. if (overview_grid_->IsDropTargetWindow(window)) { - window->layer()->SetBounds(selector_item_bounds); + window->layer()->SetBounds(overview_item_bounds); transform_window_.GetOverviewWindow()->SetTransform(gfx::Transform()); return; } gfx::Transform transform = ScopedOverviewTransformWindow::GetTransformForRect( - screen_rect, selector_item_bounds); + screen_rect, overview_item_bounds); ScopedOverviewTransformWindow::ScopedAnimationSettings animation_settings; transform_window_.BeginScopedAnimation(animation_type, &animation_settings); SetTransform(transform_window_.GetOverviewWindow(), transform); @@ -819,7 +819,7 @@ // Create a start animation observer if this is an enter overview layout // animation. - if (animation_type == OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_ON_ENTER) { + if (animation_type == OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_ENTER) { auto start_observer = std::make_unique<StartAnimationObserver>(); animation_settings.AddObserver(start_observer.get()); Shell::Get()->overview_controller()->AddStartAnimationObserver(
diff --git a/ash/wm/overview/overview_item.h b/ash/wm/overview/overview_item.h index 40f2140..f43759d 100644 --- a/ash/wm/overview/overview_item.h +++ b/ash/wm/overview/overview_item.h
@@ -86,7 +86,7 @@ // Returns the transformed bound of |transform_window_|. gfx::Rect GetTransformedBounds() const; - // Sets the bounds of this window selector item to |target_bounds| in the + // Sets the bounds of this overview item to |target_bounds| in the // |root_window_| root window. The bounds change will be animated as specified // by |animation_type|. void SetBounds(const gfx::Rect& target_bounds, @@ -252,9 +252,8 @@ FRIEND_TEST_ALL_PREFIXES(SplitViewOverviewSessionTest, OverviewUnsnappableIndicatorVisibility); - // Sets the bounds of this selector's items to |target_bounds| in - // |root_window_|. The bounds change will be animated as specified - // by |animation_type|. + // Sets the bounds of this overview item to |target_bounds| in |root_window_|. + // The bounds change will be animated as specified by |animation_type|. void SetItemBounds(const gfx::Rect& target_bounds, OverviewAnimationType animation_type); @@ -285,7 +284,7 @@ // The contained Window's wrapper. ScopedOverviewTransformWindow transform_window_; - // The target bounds this selector item is fit within. + // The target bounds this overview item is fit within. gfx::Rect target_bounds_; // True if running SetItemBounds. This prevents recursive calls resulting from
diff --git a/ash/wm/overview/overview_session.h b/ash/wm/overview/overview_session.h index 218f0e7..d7516444 100644 --- a/ash/wm/overview/overview_session.h +++ b/ash/wm/overview/overview_session.h
@@ -105,7 +105,7 @@ // Cancels window selection. void CancelSelection(); - // Called when the last window selector item from a grid is deleted. + // Called when the last overview item from a grid is deleted. void OnGridEmpty(OverviewGrid* grid); // Moves the current selection by |increment| items. Positive values of @@ -147,8 +147,8 @@ // then added to the overview. void AddItem(aura::Window* window, bool reposition, bool animate); - // Removes the window selector item from the overview window grid. And if - // |reposition| is true, re-position all windows in the target window grid. + // Removes the overview item from the overview grid. And if + // |reposition| is true, re-position all windows in the target overview grid. // This may be called in two scenarioes: 1) when a user drags an overview item // to snap to one side of the screen, the item should be removed from the // overview grid; 2) when a window (not from overview) ends its dragging while @@ -201,7 +201,7 @@ const gfx::Rect& work_area, UpdateAnimationSettingsCallback callback); - // Updates all the window selector items' mask and shadow. + // Updates all the overview items' mask and shadow. void UpdateMaskAndShadow(); // Called when the overview mode starting animation completes. @@ -289,8 +289,8 @@ // Tracks observed windows. base::flat_set<aura::Window*> observed_windows_; - // Weak pointer to the selector delegate which will be called when a - // selection is made. + // Weak pointer to the overview delegate which will be called when a selection + // is made. OverviewDelegate* delegate_; // A weak pointer to the window which was focused on beginning window
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc index fe87b0ea..2038b52 100644 --- a/ash/wm/overview/overview_session_unittest.cc +++ b/ash/wm/overview/overview_session_unittest.cc
@@ -2775,9 +2775,9 @@ // Drag |window1| selector item to snap to left. const int grid_index = 0; - OverviewItem* selector_item1 = + OverviewItem* overview_item1 = GetWindowItemForWindow(grid_index, window1.get()); - DragWindowTo(selector_item1, gfx::Point(0, 0)); + DragWindowTo(overview_item1, gfx::Point(0, 0)); EXPECT_TRUE(split_view_controller()->IsSplitViewModeActive()); EXPECT_EQ(split_view_controller()->state(), @@ -2787,9 +2787,9 @@ // Drag |window2| selector item to attempt to snap to left. Since there is // already one left snapped window |window1|, |window1| will be put in // overview mode. - OverviewItem* selector_item2 = + OverviewItem* overview_item2 = GetWindowItemForWindow(grid_index, window2.get()); - DragWindowTo(selector_item2, gfx::Point(0, 0)); + DragWindowTo(overview_item2, gfx::Point(0, 0)); EXPECT_EQ(split_view_controller()->state(), SplitViewController::LEFT_SNAPPED); @@ -2798,10 +2798,10 @@ window1.get())); // Drag |window3| selector item to snap to right. - OverviewItem* selector_item3 = + OverviewItem* overview_item3 = GetWindowItemForWindow(grid_index, window3.get()); const gfx::Point end_location3(GetWorkAreaInScreen(window3.get()).width(), 0); - DragWindowTo(selector_item3, end_location3); + DragWindowTo(overview_item3, end_location3); EXPECT_EQ(split_view_controller()->state(), SplitViewController::BOTH_SNAPPED); @@ -3070,16 +3070,16 @@ const int grid_index = 0; const int window_width = Shell::Get()->GetPrimaryRootWindow()->GetBoundsInScreen().width(); - OverviewItem* selector_item = + OverviewItem* overview_item = GetWindowItemForWindow(grid_index, window1.get()); - gfx::Rect selector_item_bounds = selector_item->target_bounds(); - gfx::Point start_location(selector_item_bounds.CenterPoint()); - overview_session()->InitiateDrag(selector_item, start_location); + gfx::Rect overview_item_bounds = overview_item->target_bounds(); + gfx::Point start_location(overview_item_bounds.CenterPoint()); + overview_session()->InitiateDrag(overview_item, start_location); // Verify that when dragged to the left, the window grid is located where the // right window of split view mode should be. const gfx::Point left(0, 0); - overview_session()->Drag(selector_item, left); + overview_session()->Drag(overview_item, left); EXPECT_FALSE(split_view_controller()->IsSplitViewModeActive()); EXPECT_EQ(SplitViewController::NO_SNAP, split_view_controller()->state()); EXPECT_TRUE(split_view_controller()->left_window() == nullptr); @@ -3088,7 +3088,7 @@ // Verify that when dragged to the right, the window grid is located where the // left window of split view mode should be. const gfx::Point right(window_width, 0); - overview_session()->Drag(selector_item, right); + overview_session()->Drag(overview_item, right); EXPECT_EQ(SplitViewController::NO_SNAP, split_view_controller()->state()); EXPECT_TRUE(split_view_controller()->right_window() == nullptr); EXPECT_EQ(GetSplitViewLeftWindowBounds(window1.get()), GetGridBounds()); @@ -3096,28 +3096,28 @@ // Verify that when dragged to the center, the window grid is has the // dimensions of the work area. const gfx::Point center(window_width / 2, 0); - overview_session()->Drag(selector_item, center); + overview_session()->Drag(overview_item, center); EXPECT_EQ(SplitViewController::NO_SNAP, split_view_controller()->state()); EXPECT_EQ(GetWorkAreaInScreen(window1.get()), GetGridBounds()); // Snap window1 to the left and initialize dragging for window2. - overview_session()->Drag(selector_item, left); - overview_session()->CompleteDrag(selector_item, left); + overview_session()->Drag(overview_item, left); + overview_session()->CompleteDrag(overview_item, left); ASSERT_EQ(SplitViewController::LEFT_SNAPPED, split_view_controller()->state()); ASSERT_EQ(window1.get(), split_view_controller()->left_window()); - selector_item = GetWindowItemForWindow(grid_index, window2.get()); - selector_item_bounds = selector_item->target_bounds(); - start_location = selector_item_bounds.CenterPoint(); - overview_session()->InitiateDrag(selector_item, start_location); + overview_item = GetWindowItemForWindow(grid_index, window2.get()); + overview_item_bounds = overview_item->target_bounds(); + start_location = overview_item_bounds.CenterPoint(); + overview_session()->InitiateDrag(overview_item, start_location); // Verify that when there is a snapped window, the window grid bounds remain // constant despite overview items being dragged left and right. - overview_session()->Drag(selector_item, left); + overview_session()->Drag(overview_item, left); EXPECT_EQ(GetSplitViewRightWindowBounds(window1.get()), GetGridBounds()); - overview_session()->Drag(selector_item, right); + overview_session()->Drag(overview_item, right); EXPECT_EQ(GetSplitViewRightWindowBounds(window1.get()), GetGridBounds()); - overview_session()->Drag(selector_item, center); + overview_session()->Drag(overview_item, center); EXPECT_EQ(GetSplitViewRightWindowBounds(window1.get()), GetGridBounds()); } @@ -3138,16 +3138,16 @@ // Verify that after dragging the unsnappable window to the left and right, // the window grid bounds do not change. - OverviewItem* selector_item = + OverviewItem* overview_item = GetWindowItemForWindow(0, unsnappable_window.get()); overview_session()->InitiateDrag( - selector_item, selector_item->target_bounds().CenterPoint()); - overview_session()->Drag(selector_item, gfx::Point(0, 0)); + overview_item, overview_item->target_bounds().CenterPoint()); + overview_session()->Drag(overview_item, gfx::Point(0, 0)); EXPECT_EQ(expected_grid_bounds, GetGridBounds()); - overview_session()->Drag(selector_item, + overview_session()->Drag(overview_item, gfx::Point(root_window_bounds.right(), 0)); EXPECT_EQ(expected_grid_bounds, GetGridBounds()); - overview_session()->Drag(selector_item, + overview_session()->Drag(overview_item, gfx::Point(root_window_bounds.right() / 2, 0)); EXPECT_EQ(expected_grid_bounds, GetGridBounds()); } @@ -3164,9 +3164,9 @@ // Drag |window1| selector item to snap to left. const int grid_index = 0; - OverviewItem* selector_item1 = + OverviewItem* overview_item1 = GetWindowItemForWindow(grid_index, window1.get()); - DragWindowTo(selector_item1, gfx::Point(0, 0)); + DragWindowTo(overview_item1, gfx::Point(0, 0)); // Test that overview mode is active in this single window case. EXPECT_EQ(split_view_controller()->IsSplitViewModeActive(), true); @@ -3217,8 +3217,8 @@ // Now enter overview and split view again. Test that exiting tablet mode can // end split view and overview correctly. ToggleOverview(); - selector_item1 = GetWindowItemForWindow(grid_index, window1.get()); - DragWindowTo(selector_item1, gfx::Point(0, 0)); + overview_item1 = GetWindowItemForWindow(grid_index, window1.get()); + DragWindowTo(overview_item1, gfx::Point(0, 0)); EXPECT_TRUE(Shell::Get()->IsSplitViewModeActive()); EXPECT_TRUE(overview_controller()->IsSelecting()); Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false); @@ -3258,18 +3258,18 @@ ToggleOverview(); // Test that dragging |window1| to the left of the screen snaps it to left. const int grid_index = 0; - OverviewItem* selector_item1 = + OverviewItem* overview_item1 = GetWindowItemForWindow(grid_index, window1.get()); - DragWindowTo(selector_item1, gfx::Point(0, 0)); + DragWindowTo(overview_item1, gfx::Point(0, 0)); EXPECT_EQ(split_view_controller()->state(), svc::LEFT_SNAPPED); EXPECT_EQ(split_view_controller()->left_window(), window1.get()); // Test that dragging |window2| to the right of the screen snaps it to right. - OverviewItem* selector_item2 = + OverviewItem* overview_item2 = GetWindowItemForWindow(grid_index, window2.get()); gfx::Rect work_area_rect = GetWorkAreaInScreen(window2.get()); gfx::Point end_location2(work_area_rect.width(), work_area_rect.height()); - DragWindowTo(selector_item2, end_location2); + DragWindowTo(overview_item2, end_location2); EXPECT_EQ(split_view_controller()->state(), svc::BOTH_SNAPPED); EXPECT_EQ(split_view_controller()->right_window(), window2.get()); @@ -3288,16 +3288,16 @@ ToggleOverview(); // Test that dragging |window1| to the top of the screen snaps it to left. - selector_item1 = GetWindowItemForWindow(grid_index, window1.get()); - DragWindowTo(selector_item1, gfx::Point(0, 0)); + overview_item1 = GetWindowItemForWindow(grid_index, window1.get()); + DragWindowTo(overview_item1, gfx::Point(0, 0)); EXPECT_EQ(split_view_controller()->state(), svc::LEFT_SNAPPED); EXPECT_EQ(split_view_controller()->left_window(), window1.get()); // Test that dragging |window2| to the bottom of the screen snaps it to right. - selector_item2 = GetWindowItemForWindow(grid_index, window2.get()); + overview_item2 = GetWindowItemForWindow(grid_index, window2.get()); work_area_rect = GetWorkAreaInScreen(window2.get()); end_location2 = gfx::Point(work_area_rect.width(), work_area_rect.height()); - DragWindowTo(selector_item2, end_location2, SelectorItemLocation::ORIGIN); + DragWindowTo(overview_item2, end_location2, SelectorItemLocation::ORIGIN); EXPECT_EQ(split_view_controller()->state(), svc::BOTH_SNAPPED); EXPECT_EQ(split_view_controller()->right_window(), window2.get()); @@ -3316,16 +3316,16 @@ ToggleOverview(); // Test that dragging |window1| to the left of the screen snaps it to right. - selector_item1 = GetWindowItemForWindow(grid_index, window1.get()); - DragWindowTo(selector_item1, gfx::Point(0, 0)); + overview_item1 = GetWindowItemForWindow(grid_index, window1.get()); + DragWindowTo(overview_item1, gfx::Point(0, 0)); EXPECT_EQ(split_view_controller()->state(), svc::RIGHT_SNAPPED); EXPECT_EQ(split_view_controller()->right_window(), window1.get()); // Test that dragging |window2| to the right of the screen snaps it to left. - selector_item2 = GetWindowItemForWindow(grid_index, window2.get()); + overview_item2 = GetWindowItemForWindow(grid_index, window2.get()); work_area_rect = GetWorkAreaInScreen(window2.get()); end_location2 = gfx::Point(work_area_rect.width(), work_area_rect.height()); - DragWindowTo(selector_item2, end_location2, SelectorItemLocation::ORIGIN); + DragWindowTo(overview_item2, end_location2, SelectorItemLocation::ORIGIN); EXPECT_EQ(split_view_controller()->state(), svc::BOTH_SNAPPED); EXPECT_EQ(split_view_controller()->left_window(), window2.get()); @@ -3344,16 +3344,16 @@ ToggleOverview(); // Test that dragging |window1| to the top of the screen snaps it to right. - selector_item1 = GetWindowItemForWindow(grid_index, window1.get()); - DragWindowTo(selector_item1, gfx::Point(0, 0)); + overview_item1 = GetWindowItemForWindow(grid_index, window1.get()); + DragWindowTo(overview_item1, gfx::Point(0, 0)); EXPECT_EQ(split_view_controller()->state(), svc::RIGHT_SNAPPED); EXPECT_EQ(split_view_controller()->right_window(), window1.get()); // Test that dragging |window2| to the bottom of the screen snaps it to left. - selector_item2 = GetWindowItemForWindow(grid_index, window2.get()); + overview_item2 = GetWindowItemForWindow(grid_index, window2.get()); work_area_rect = GetWorkAreaInScreen(window2.get()); end_location2 = gfx::Point(work_area_rect.width(), work_area_rect.height()); - DragWindowTo(selector_item2, end_location2); + DragWindowTo(overview_item2, end_location2); EXPECT_EQ(split_view_controller()->state(), svc::BOTH_SNAPPED); EXPECT_EQ(split_view_controller()->left_window(), window2.get()); @@ -3380,9 +3380,9 @@ // Drag |window1| selector item to snap to left. const int grid_index = 0; - OverviewItem* selector_item1 = + OverviewItem* overview_item1 = GetWindowItemForWindow(grid_index, window1.get()); - DragWindowTo(selector_item1, gfx::Point(0, 0)); + DragWindowTo(overview_item1, gfx::Point(0, 0)); EXPECT_EQ(split_view_controller()->state(), SplitViewController::LEFT_SNAPPED); @@ -3433,11 +3433,11 @@ // Select the unsnappable window. const int grid_index = 0; - OverviewItem* selector_item = + OverviewItem* overview_item = GetWindowItemForWindow(grid_index, unsnappable_window.get()); ui::test::EventGenerator* generator = GetEventGenerator(); generator->set_current_screen_location( - selector_item->target_bounds().CenterPoint()); + overview_item->target_bounds().CenterPoint()); generator->ClickLeftButton(); // Verify that we are out of split view and overview mode, and that the active @@ -3465,9 +3465,9 @@ EXPECT_TRUE(overview_controller()->IsSelecting()); // Now select the unsnappable window. - selector_item = GetWindowItemForWindow(grid_index, unsnappable_window.get()); + overview_item = GetWindowItemForWindow(grid_index, unsnappable_window.get()); generator->set_current_screen_location( - selector_item->target_bounds().CenterPoint()); + overview_item->target_bounds().CenterPoint()); generator->ClickLeftButton(); // Split view mode should be ended. And the unsnappable window should be the @@ -3491,23 +3491,23 @@ ASSERT_TRUE(overview_controller()->IsSelecting()); const int grid_index = 0; - OverviewItem* snappable_selector_item = + OverviewItem* snappable_overview_item = GetWindowItemForWindow(grid_index, window2.get()); - OverviewItem* unsnappable_selector_item = + OverviewItem* unsnappable_overview_item = GetWindowItemForWindow(grid_index, unsnappable_window.get()); // Note: |cannot_snap_label_view_| and its parent will be created on demand. - EXPECT_FALSE(GetCannotSnapLabelView(snappable_selector_item)); - ASSERT_FALSE(GetCannotSnapLabelView(unsnappable_selector_item)); + EXPECT_FALSE(GetCannotSnapLabelView(snappable_overview_item)); + ASSERT_FALSE(GetCannotSnapLabelView(unsnappable_overview_item)); // Snap the extra snappable window to enter split view mode. split_view_controller()->SnapWindow(window1.get(), SplitViewController::LEFT); ASSERT_TRUE(split_view_controller()->IsSplitViewModeActive()); - EXPECT_FALSE(GetCannotSnapLabelView(snappable_selector_item)); - ASSERT_TRUE(GetCannotSnapLabelView(unsnappable_selector_item)); - ASSERT_TRUE(GetCannotSnapLabelView(unsnappable_selector_item)->parent()); + EXPECT_FALSE(GetCannotSnapLabelView(snappable_overview_item)); + ASSERT_TRUE(GetCannotSnapLabelView(unsnappable_overview_item)); + ASSERT_TRUE(GetCannotSnapLabelView(unsnappable_overview_item)->parent()); ui::Layer* unsnappable_layer = - GetCannotSnapLabelView(unsnappable_selector_item)->parent()->layer(); + GetCannotSnapLabelView(unsnappable_overview_item)->parent()->layer(); EXPECT_EQ(1.f, unsnappable_layer->opacity()); // Exiting the splitview will hide the unsnappable label. @@ -3535,9 +3535,9 @@ // Drag |window1| selector item to snap to left. const int grid_index = 0; - OverviewItem* selector_item1 = + OverviewItem* overview_item1 = GetWindowItemForWindow(grid_index, window1.get()); - DragWindowTo(selector_item1, gfx::Point(0, 0)); + DragWindowTo(overview_item1, gfx::Point(0, 0)); // Test that overview mode and split view mode are both active. EXPECT_TRUE(split_view_controller()->IsSplitViewModeActive()); EXPECT_TRUE(Shell::Get()->overview_controller()->IsSelecting()); @@ -3552,9 +3552,9 @@ EXPECT_TRUE(Shell::Get()->overview_controller()->IsSelecting()); // Now drag |window2| selector item to snap to left. - OverviewItem* selector_item2 = + OverviewItem* overview_item2 = GetWindowItemForWindow(grid_index, window2.get()); - DragWindowTo(selector_item2, gfx::Point(0, 0)); + DragWindowTo(overview_item2, gfx::Point(0, 0)); // Test that overview mode and split view mode are both active. EXPECT_TRUE(split_view_controller()->IsSplitViewModeActive()); EXPECT_TRUE(Shell::Get()->overview_controller()->IsSelecting()); @@ -3579,21 +3579,21 @@ ToggleOverview(); ASSERT_TRUE(overview_controller()->IsSelecting()); - OverviewItem* selector_item = GetWindowItemForWindow(0, window1.get()); - gfx::Point start_location(selector_item->target_bounds().CenterPoint()); - const gfx::Rect original_bounds(selector_item->target_bounds()); + OverviewItem* overview_item = GetWindowItemForWindow(0, window1.get()); + gfx::Point start_location(overview_item->target_bounds().CenterPoint()); + const gfx::Rect original_bounds(overview_item->target_bounds()); // Verify that when a overview item receives a resetting gesture, we // stay in overview mode and the bounds of the item are the same as they were // before the press sequence started. - overview_session()->InitiateDrag(selector_item, start_location); + overview_session()->InitiateDrag(overview_item, start_location); overview_session()->ResetDraggedWindowGesture(); EXPECT_TRUE(overview_controller()->IsSelecting()); - EXPECT_EQ(original_bounds, selector_item->target_bounds()); + EXPECT_EQ(original_bounds, overview_item->target_bounds()); // Verify that when a overview item is tapped, we exit overview mode, // and the current active window is the item. - overview_session()->InitiateDrag(selector_item, start_location); + overview_session()->InitiateDrag(overview_item, start_location); overview_session()->ActivateDraggedWindow(); EXPECT_FALSE(overview_controller()->IsSelecting()); EXPECT_EQ(window1.get(), wm::GetActiveWindow()); @@ -3616,9 +3616,9 @@ // Drag |window1| selector item to snap to left. const int grid_index = 0; - OverviewItem* selector_item1 = + OverviewItem* overview_item1 = GetWindowItemForWindow(grid_index, window1.get()); - DragWindowTo(selector_item1, gfx::Point(0, 0)); + DragWindowTo(overview_item1, gfx::Point(0, 0)); EXPECT_EQ(SplitViewController::LEFT_SNAPPED, split_view_controller()->state()); EXPECT_TRUE(Shell::Get()->overview_controller()->IsSelecting()); @@ -3639,12 +3639,12 @@ EXPECT_EQ(window1->bounds().width(), screen_width); // Drag |window2| selector item to snap to right. - OverviewItem* selector_item2 = + OverviewItem* overview_item2 = GetWindowItemForWindow(grid_index, window2.get()); const gfx::Rect work_area_rect = GetWorkAreaInScreen(window2.get()); gfx::Point end_location2 = gfx::Point(work_area_rect.width(), work_area_rect.height()); - DragWindowTo(selector_item2, end_location2); + DragWindowTo(overview_item2, end_location2); EXPECT_EQ(SplitViewController::RIGHT_SNAPPED, split_view_controller()->state()); EXPECT_TRUE(Shell::Get()->overview_controller()->IsSelecting()); @@ -3680,9 +3680,9 @@ // Drag |window1| selector item to snap to left. There should be two items on // the overview grid afterwards, |window2| and |window3|. const int grid_index = 0; - OverviewItem* selector_item1 = + OverviewItem* overview_item1 = GetWindowItemForWindow(grid_index, window1.get()); - DragWindowTo(selector_item1, gfx::Point(0, 0)); + DragWindowTo(overview_item1, gfx::Point(0, 0)); EXPECT_EQ(SplitViewController::LEFT_SNAPPED, split_view_controller()->state()); EXPECT_TRUE(IsSelecting()); @@ -3779,9 +3779,9 @@ ToggleOverview(); const int grid_index = 0; - OverviewItem* selector_item1 = + OverviewItem* overview_item1 = GetWindowItemForWindow(grid_index, window1.get()); - DragWindowTo(selector_item1, gfx::Point(0, 0)); + DragWindowTo(overview_item1, gfx::Point(0, 0)); EXPECT_EQ(split_view_controller()->state(), SplitViewController::LEFT_SNAPPED); EXPECT_EQ(split_view_controller()->left_window(), window1.get()); @@ -3794,8 +3794,8 @@ EXPECT_TRUE(GetWindowItemForWindow(grid_index, window1.get())); // Now snap both |window1| and |window2|. - selector_item1 = GetWindowItemForWindow(grid_index, window1.get()); - DragWindowTo(selector_item1, gfx::Point(0, 0)); + overview_item1 = GetWindowItemForWindow(grid_index, window1.get()); + DragWindowTo(overview_item1, gfx::Point(0, 0)); ::wm::ActivateWindow(window2.get()); EXPECT_FALSE(IsSelecting()); EXPECT_EQ(split_view_controller()->state(), @@ -3839,19 +3839,19 @@ EXPECT_FALSE(window2->layer()->GetTargetTransform().IsIdentity()); EXPECT_FALSE(window3->layer()->GetTargetTransform().IsIdentity()); const int grid_index = 0; - OverviewItem* selector_item1 = + OverviewItem* overview_item1 = GetWindowItemForWindow(grid_index, window1.get()); - DragWindowTo(selector_item1, gfx::Point(0, 0)); + DragWindowTo(overview_item1, gfx::Point(0, 0)); EXPECT_EQ(SplitViewController::LEFT_SNAPPED, split_view_controller()->state()); // Drag |window2| to snap to right. - OverviewItem* selector_item2 = + OverviewItem* overview_item2 = GetWindowItemForWindow(grid_index, window2.get()); const gfx::Rect work_area_rect = screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( window2.get()); const gfx::Point end_location2(work_area_rect.width(), 0); - DragWindowTo(selector_item2, end_location2); + DragWindowTo(overview_item2, end_location2); EXPECT_EQ(SplitViewController::BOTH_SNAPPED, split_view_controller()->state()); EXPECT_FALSE(overview_controller()->IsSelecting()); @@ -3920,9 +3920,9 @@ ToggleOverview(); const int grid_index = 0; - OverviewItem* selector_item1 = + OverviewItem* overview_item1 = GetWindowItemForWindow(grid_index, window1.get()); - DragWindowTo(selector_item1, gfx::Point(0, 0)); + DragWindowTo(overview_item1, gfx::Point(0, 0)); EXPECT_EQ(split_view_controller()->state(), SplitViewController::LEFT_SNAPPED); EXPECT_EQ(split_view_controller()->default_snap_position(),
diff --git a/ash/wm/overview/overview_utils.cc b/ash/wm/overview/overview_utils.cc index 15dc7cb..84cd18b3 100644 --- a/ash/wm/overview/overview_utils.cc +++ b/ash/wm/overview/overview_utils.cc
@@ -35,8 +35,8 @@ namespace { -// The transform applied to a window selector item when animating to or from the -// home launcher. +// The transform applied to an overview item when animating to or from the home +// launcher. const gfx::Transform& GetShiftTransform() { static const base::NoDestructor<gfx::Transform> matrix(1, 0, 0, 1, 0, -100); return *matrix; @@ -150,7 +150,7 @@ void FadeOutWidgetAndMaybeSlideOnExit(std::unique_ptr<views::Widget> widget, OverviewAnimationType animation_type, bool slide) { - // The window selector controller may be nullptr on shutdown. + // The overview controller may be nullptr on shutdown. OverviewController* controller = Shell::Get()->overview_controller(); if (!controller) { widget->SetOpacity(0.f); @@ -164,7 +164,7 @@ widget->GetNativeWindow()); // CleanupAnimationObserver will delete itself (and the widget) when the // opacity animation is complete. Ownership over the observer is passed to the - // window selector controller which has longer lifetime so that animations can + // overview controller which has longer lifetime so that animations can // continue even after the overview mode is shut down. views::Widget* widget_ptr = widget.get(); auto observer = std::make_unique<CleanupAnimationObserver>(std::move(widget)); @@ -231,8 +231,8 @@ int top_inset) { gfx::Rect bounds; for (auto* window : wm::GetTransientTreeIterator(transformed_window)) { - // Ignore other window types when computing bounding box of window - // selector target item. + // Ignore other window types when computing bounding box of overview target + // item. if (window != transformed_window && window->type() != aura::client::WINDOW_TYPE_NORMAL) { continue; @@ -262,8 +262,8 @@ gfx::Rect GetTargetBoundsInScreen(aura::Window* window) { gfx::Rect bounds; for (auto* window_iter : wm::GetTransientTreeIterator(window)) { - // Ignore other window types when computing bounding box of window - // selector target item. + // Ignore other window types when computing bounding box of overview target + // item. if (window_iter != window && window_iter->type() != aura::client::WINDOW_TYPE_NORMAL) { continue;
diff --git a/ash/wm/overview/overview_window_drag_controller.cc b/ash/wm/overview/overview_window_drag_controller.cc index f9d34fbff..6de2e08 100644 --- a/ash/wm/overview/overview_window_drag_controller.cc +++ b/ash/wm/overview/overview_window_drag_controller.cc
@@ -176,7 +176,7 @@ DCHECK(ShouldAllowSplitView()); item_->ScaleUpSelectedItem( - OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_IN_OVERVIEW); + OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW); did_move_ = true; current_drag_behavior_ = DragBehavior::kDragToSnap;
diff --git a/ash/wm/overview/scoped_overview_animation_settings.cc b/ash/wm/overview/scoped_overview_animation_settings.cc index 26e7e99..9bb3ea34 100644 --- a/ash/wm/overview/scoped_overview_animation_settings.cc +++ b/ash/wm/overview/scoped_overview_animation_settings.cc
@@ -18,46 +18,72 @@ namespace { // The time duration for transformation animations. -constexpr int kTransitionMs = 300; +constexpr base::TimeDelta kTransition = base::TimeDelta::FromMilliseconds(300); // The time duration for fading out when closing an item. -constexpr int kCloseFadeOutMs = 100; +constexpr base::TimeDelta kCloseFadeOut = + base::TimeDelta::FromMilliseconds(100); // The time duration for scaling down when an item is closed. -constexpr int kCloseScaleMs = 100; +constexpr base::TimeDelta kCloseScale = base::TimeDelta::FromMilliseconds(100); // The time duration for widgets to fade in. -constexpr int kFadeInDelayMs = 83; -constexpr int kFadeInMs = 167; +constexpr base::TimeDelta kFadeInDelay = base::TimeDelta::FromMilliseconds(83); +constexpr base::TimeDelta kFadeIn = base::TimeDelta::FromMilliseconds(167); // The time duration for widgets to fade out. -constexpr int kFadeOutMs = 100; +constexpr base::TimeDelta kFadeOut = base::TimeDelta::FromMilliseconds(100); -constexpr int kFromHomeLauncherDelayMs = 250; -constexpr int kHomeLauncherTransitionMs = 250; +constexpr base::TimeDelta kFromHomeLauncherDelay = + base::TimeDelta::FromMilliseconds(250); +constexpr base::TimeDelta kHomeLauncherTransition = + base::TimeDelta::FromMilliseconds(250); + +// Time it takes for the selector widget to move to the next target. The same +// time is used for fading out shield widget when the overview mode is opened +// or closed. +constexpr base::TimeDelta kOverviewSelectorTransition = + base::TimeDelta::FromMilliseconds(250); + +// Time duration of the show animation of the drop target. +constexpr base::TimeDelta kDropTargetFadeIn = + base::TimeDelta::FromMilliseconds(250); + +// Duration of the show/hide animation of the overview title bar. +constexpr base::TimeDelta kOverviewTitleFade = + base::TimeDelta::FromMilliseconds(167); base::TimeDelta GetAnimationDuration(OverviewAnimationType animation_type) { switch (animation_type) { case OVERVIEW_ANIMATION_NONE: return base::TimeDelta(); case OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN: - return base::TimeDelta::FromMilliseconds(kFadeInMs); + return kFadeIn; case OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_FADE_OUT: - return base::TimeDelta::FromMilliseconds(kFadeOutMs); - case OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_ON_ENTER: - case OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_IN_OVERVIEW: - case OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_ON_EXIT: + return kFadeOut; + case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_ENTER: + case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW: + case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_EXIT: case OVERVIEW_ANIMATION_RESTORE_WINDOW: case OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO: - return base::TimeDelta::FromMilliseconds(kTransitionMs); - case OVERVIEW_ANIMATION_CLOSING_SELECTOR_ITEM: - return base::TimeDelta::FromMilliseconds(kCloseScaleMs); - case OVERVIEW_ANIMATION_CLOSE_SELECTOR_ITEM: - return base::TimeDelta::FromMilliseconds(kCloseFadeOutMs); + return kTransition; + case OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM: + return kCloseScale; + case OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM: + return kCloseFadeOut; case OVERVIEW_ANIMATION_ENTER_FROM_HOME_LAUNCHER: case OVERVIEW_ANIMATION_EXIT_TO_HOME_LAUNCHER: - return base::TimeDelta::FromMilliseconds(kHomeLauncherTransitionMs); - } + return kHomeLauncherTransition; + case OVERVIEW_ANIMATION_DROP_TARGET_FADE_IN: + return kDropTargetFadeIn; + case OVERVIEW_ANIMATION_SHIELD_FADE: + case OVERVIEW_ANIMATION_SELECTION_WINDOW_SHADOW: + case OVERVIEW_ANIMATION_SELECTION_WINDOW: + return kOverviewSelectorTransition; + case OVERVIEW_ANIMATION_OVERVIEW_TITLE_FADE_IN: + case OVERVIEW_ANIMATION_OVERVIEW_TITLE_FADE_OUT: + return kOverviewTitleFade; + }; NOTREACHED(); return base::TimeDelta(); } @@ -115,20 +141,26 @@ OverviewAnimationType animation_type) { switch (animation_type) { case OVERVIEW_ANIMATION_NONE: - case OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_IN_OVERVIEW: + case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW: + case OVERVIEW_ANIMATION_DROP_TARGET_FADE_IN: + case OVERVIEW_ANIMATION_SHIELD_FADE: + case OVERVIEW_ANIMATION_SELECTION_WINDOW_SHADOW: + case OVERVIEW_ANIMATION_SELECTION_WINDOW: + case OVERVIEW_ANIMATION_OVERVIEW_TITLE_FADE_IN: + case OVERVIEW_ANIMATION_OVERVIEW_TITLE_FADE_OUT: return nullptr; case OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN: - case OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_ON_ENTER: + case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_ENTER: case OVERVIEW_ANIMATION_ENTER_FROM_HOME_LAUNCHER: return g_reporter_enter.Pointer(); case OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_FADE_OUT: case OVERVIEW_ANIMATION_RESTORE_WINDOW: case OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO: - case OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_ON_EXIT: + case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_EXIT: case OVERVIEW_ANIMATION_EXIT_TO_HOME_LAUNCHER: return g_reporter_exit.Pointer(); - case OVERVIEW_ANIMATION_CLOSING_SELECTOR_ITEM: - case OVERVIEW_ANIMATION_CLOSE_SELECTOR_ITEM: + case OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM: + case OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM: return g_reporter_close.Pointer(); } NOTREACHED(); @@ -140,41 +172,46 @@ ScopedOverviewAnimationSettings::ScopedOverviewAnimationSettings( OverviewAnimationType animation_type, aura::Window* window) - : animation_settings_(new ui::ScopedLayerAnimationSettings( - window->layer()->GetAnimator())) { + : ScopedOverviewAnimationSettings(animation_type, + window->layer()->GetAnimator()) {} + +ScopedOverviewAnimationSettings::ScopedOverviewAnimationSettings( + OverviewAnimationType animation_type, + ui::LayerAnimator* animator) + : animation_settings_( + std::make_unique<ui::ScopedLayerAnimationSettings>(animator)) { switch (animation_type) { case OVERVIEW_ANIMATION_NONE: animation_settings_->SetPreemptionStrategy( ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); break; case OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN: - window->layer()->GetAnimator()->SchedulePauseForProperties( - base::TimeDelta::FromMilliseconds(kFadeInDelayMs), - ui::LayerAnimationElement::OPACITY); animation_settings_->SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN); animation_settings_->SetPreemptionStrategy( ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); + animator->SchedulePauseForProperties(kFadeInDelay, + ui::LayerAnimationElement::OPACITY); break; case OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_FADE_OUT: animation_settings_->SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN); animation_settings_->SetPreemptionStrategy( ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); break; - case OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_ON_ENTER: - case OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_IN_OVERVIEW: - case OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_ON_EXIT: + case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_ENTER: + case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW: + case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_EXIT: case OVERVIEW_ANIMATION_RESTORE_WINDOW: animation_settings_->SetTweenType(gfx::Tween::EASE_OUT); animation_settings_->SetPreemptionStrategy( ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); break; case OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO: + animation_settings_->SetTweenType(gfx::Tween::ZERO); animation_settings_->SetPreemptionStrategy( ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); - animation_settings_->SetTweenType(gfx::Tween::ZERO); break; - case OVERVIEW_ANIMATION_CLOSING_SELECTOR_ITEM: - case OVERVIEW_ANIMATION_CLOSE_SELECTOR_ITEM: + case OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM: + case OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM: animation_settings_->SetTweenType(gfx::Tween::EASE_OUT); animation_settings_->SetPreemptionStrategy( ui::LayerAnimator::ENQUEUE_NEW_ANIMATION); @@ -183,16 +220,43 @@ animation_settings_->SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN); animation_settings_->SetPreemptionStrategy( ui::LayerAnimator::ENQUEUE_NEW_ANIMATION); - window->layer()->GetAnimator()->SchedulePauseForProperties( - base::TimeDelta::FromMilliseconds(kFromHomeLauncherDelayMs), - ui::LayerAnimationElement::OPACITY | - ui::LayerAnimationElement::TRANSFORM); + animator->SchedulePauseForProperties( + kFromHomeLauncherDelay, ui::LayerAnimationElement::OPACITY | + ui::LayerAnimationElement::TRANSFORM); break; case OVERVIEW_ANIMATION_EXIT_TO_HOME_LAUNCHER: animation_settings_->SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN); animation_settings_->SetPreemptionStrategy( ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); break; + case OVERVIEW_ANIMATION_DROP_TARGET_FADE_IN: + animation_settings_->SetTweenType(gfx::Tween::EASE_IN); + animation_settings_->SetPreemptionStrategy( + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); + break; + case OVERVIEW_ANIMATION_SHIELD_FADE: + case OVERVIEW_ANIMATION_SELECTION_WINDOW_SHADOW: + animation_settings_->SetTweenType(gfx::Tween::EASE_IN_OUT); + animation_settings_->SetPreemptionStrategy( + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); + break; + case OVERVIEW_ANIMATION_SELECTION_WINDOW: + animation_settings_->SetTweenType(gfx::Tween::EASE_OUT); + animation_settings_->SetPreemptionStrategy( + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); + break; + case OVERVIEW_ANIMATION_OVERVIEW_TITLE_FADE_IN: + animation_settings_->SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); + animation_settings_->SetPreemptionStrategy( + ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); + animator->SchedulePauseForProperties(kOverviewTitleFade, + ui::LayerAnimationElement::OPACITY); + break; + case OVERVIEW_ANIMATION_OVERVIEW_TITLE_FADE_OUT: + animation_settings_->SetTweenType(gfx::Tween::FAST_OUT_LINEAR_IN); + animation_settings_->SetPreemptionStrategy( + ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); + break; } animation_settings_->SetTransitionDuration( GetAnimationDuration(animation_type));
diff --git a/ash/wm/overview/scoped_overview_animation_settings.h b/ash/wm/overview/scoped_overview_animation_settings.h index c8ecbd3..0c765ca 100644 --- a/ash/wm/overview/scoped_overview_animation_settings.h +++ b/ash/wm/overview/scoped_overview_animation_settings.h
@@ -16,17 +16,21 @@ namespace ui { class ImplicitAnimationObserver; +class LayerAnimator; class ScopedLayerAnimationSettings; } // namespace ui namespace ash { // ScopedOverviewAnimationSettings correctly configures the animation -// settings for an aura::Window given an OverviewAnimationType. +// settings for an aura::Window or ui::LayerAnimator given an +// OverviewAnimationType. class ScopedOverviewAnimationSettings { public: ScopedOverviewAnimationSettings(OverviewAnimationType animation_type, aura::Window* window); + ScopedOverviewAnimationSettings(OverviewAnimationType animation_type, + ui::LayerAnimator* animator); ~ScopedOverviewAnimationSettings(); void AddObserver(ui::ImplicitAnimationObserver* observer); void CacheRenderSurface();
diff --git a/ash/wm/overview/scoped_overview_transform_window.cc b/ash/wm/overview/scoped_overview_transform_window.cc index 2e5d76e..d6e69f3 100644 --- a/ash/wm/overview/scoped_overview_transform_window.cc +++ b/ash/wm/overview/scoped_overview_transform_window.cc
@@ -171,9 +171,9 @@ }; ScopedOverviewTransformWindow::ScopedOverviewTransformWindow( - OverviewItem* selector_item, + OverviewItem* overview_item, aura::Window* window) - : selector_item_(selector_item), + : overview_item_(overview_item), window_(window), original_opacity_(window->layer()->GetTargetOpacity()), original_mask_layer_(window_->layer()->layer_mask_layer()), @@ -231,7 +231,7 @@ if (reset_transform) { ScopedAnimationSettings animation_settings_list; - BeginScopedAnimation(selector_item_->GetExitTransformAnimationType(), + BeginScopedAnimation(overview_item_->GetExitTransformAnimationType(), &animation_settings_list); // Use identity transform directly to reset window's transform when exiting // overview. @@ -248,7 +248,7 @@ } ScopedOverviewAnimationSettings animation_settings( - selector_item_->GetExitOverviewAnimationType(), window_); + overview_item_->GetExitOverviewAnimationType(), window_); SetOpacity(original_opacity_); window_->layer()->SetMaskLayer(original_mask_layer_); } @@ -266,7 +266,7 @@ // Create a start animation observer if this is an enter overview layout // animation. - if (animation_type == OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_ON_ENTER) { + if (animation_type == OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_ENTER) { auto start_observer = std::make_unique<StartAnimationObserver>(); settings->AddObserver(start_observer.get()); Shell::Get()->overview_controller()->AddStartAnimationObserver( @@ -276,7 +276,7 @@ animation_settings->push_back(std::move(settings)); } - if (animation_type == OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS_IN_OVERVIEW && + if (animation_type == OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW && animation_settings->size() > 0u) { animation_settings->front()->AddObserver(this); } @@ -465,8 +465,8 @@ return; } - // Add the mask which gives the window selector items rounded corners, and add - // the shadow around the window. + // Add the mask which gives the overview item rounded corners, and add the + // shadow around the window. ui::Layer* layer = minimized_widget_ ? minimized_widget_->GetNativeWindow()->layer() : window_->layer(); @@ -513,12 +513,12 @@ ui::LayerAnimationSequence* sequence) { // Remove the mask before animating because masks affect animation // performance. The mask will be added back once the animation is completed. - selector_item_->UpdateMaskAndShadow(); + overview_item_->UpdateMaskAndShadow(); } void ScopedOverviewTransformWindow::OnImplicitAnimationsCompleted() { - selector_item_->UpdateMaskAndShadow(); - selector_item_->OnDragAnimationCompleted(); + overview_item_->UpdateMaskAndShadow(); + overview_item_->OnDragAnimationCompleted(); } gfx::Rect ScopedOverviewTransformWindow::GetMaskBoundsForTesting() const {
diff --git a/ash/wm/overview/scoped_overview_transform_window.h b/ash/wm/overview/scoped_overview_transform_window.h index f670f9d..00596ca3 100644 --- a/ash/wm/overview/scoped_overview_transform_window.h +++ b/ash/wm/overview/scoped_overview_transform_window.h
@@ -75,7 +75,7 @@ static gfx::Transform GetTransformForRect(const gfx::Rect& src_rect, const gfx::Rect& dst_rect); - ScopedOverviewTransformWindow(OverviewItem* selector_item, + ScopedOverviewTransformWindow(OverviewItem* overview_item, aura::Window* window); ~ScopedOverviewTransformWindow() override; @@ -97,7 +97,7 @@ void BeginScopedAnimation(OverviewAnimationType animation_type, ScopedAnimationSettings* animation_settings); - // Returns true if this window selector window contains the |target|. + // Returns true if this overview window contains the |target|. bool Contains(const aura::Window* target) const; // Returns transformed bounds of the overview window. See @@ -198,8 +198,8 @@ // Makes Close() execute synchronously when used in tests. static void SetImmediateCloseForTests(); - // A weak pointer to the window selector item that owns the transform window. - OverviewItem* selector_item_; + // A weak pointer to the overview item that owns the transform window. + OverviewItem* overview_item_; // A weak pointer to the real window in the overview. aura::Window* window_; @@ -216,8 +216,8 @@ // Specifies how the window is laid out in the grid. GridWindowFillMode type_ = GridWindowFillMode::kNormal; - // Empty if window is of type normal. Contains the bounds the window selector - // item should be if the window is too wide or too tall. + // Empty if window is of type normal. Contains the bounds the overview item + // should be if the window is too wide or too tall. base::Optional<gfx::Rect> overview_bounds_; // A widget that holds the content for the minimized window.
diff --git a/ash/wm/overview/scoped_overview_transform_window_unittest.cc b/ash/wm/overview/scoped_overview_transform_window_unittest.cc index 213d95a..e3a673cb 100644 --- a/ash/wm/overview/scoped_overview_transform_window_unittest.cc +++ b/ash/wm/overview/scoped_overview_transform_window_unittest.cc
@@ -156,11 +156,11 @@ EXPECT_TRUE(overview_bounds.Contains(transformed_rect)); // Verify that for an extreme window, the transform window stores the - // original window selector bounds, minus the header. - gfx::Rect selector_bounds = overview_bounds; - selector_bounds.Inset(0, overview_header, 0, 0); + // original overview item bounds, minus the header. + gfx::Rect new_overview_bounds = overview_bounds; + new_overview_bounds.Inset(0, overview_header, 0, 0); ASSERT_TRUE(transform_window.overview_bounds().has_value()); - EXPECT_EQ(transform_window.overview_bounds().value(), selector_bounds); + EXPECT_EQ(transform_window.overview_bounds().value(), new_overview_bounds); } // Verify that a window which will be displayed like a pillar box on the window @@ -195,11 +195,11 @@ EXPECT_TRUE(overview_bounds.Contains(transformed_rect)); // Verify that for an extreme window, the transform window stores the - // original window selector bounds, minus the header. - gfx::Rect selector_bounds = overview_bounds; - selector_bounds.Inset(0, overview_header, 0, 0); + // original overview item bounds, minus the header. + gfx::Rect new_overview_bounds = overview_bounds; + new_overview_bounds.Inset(0, overview_header, 0, 0); ASSERT_TRUE(transform_window.overview_bounds().has_value()); - EXPECT_EQ(transform_window.overview_bounds().value(), selector_bounds); + EXPECT_EQ(transform_window.overview_bounds().value(), new_overview_bounds); } // Tests the cases when very wide or tall windows enter overview mode.
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc index e96e699..55d556f 100644 --- a/ash/wm/splitview/split_view_controller.cc +++ b/ash/wm/splitview/split_view_controller.cc
@@ -536,6 +536,11 @@ base::Time::Now() - splitview_start_time_); } +bool SplitViewController::IsWindowInSplitView( + const aura::Window* window) const { + return window && (window == left_window_ || window == right_window_); +} + void SplitViewController::OnWindowDragStarted(aura::Window* dragged_window) { DCHECK(dragged_window); if (dragged_window == left_window_ || dragged_window == right_window_)
diff --git a/ash/wm/splitview/split_view_controller.h b/ash/wm/splitview/split_view_controller.h index d8c56b7..7a80ccf 100644 --- a/ash/wm/splitview/split_view_controller.h +++ b/ash/wm/splitview/split_view_controller.h
@@ -135,6 +135,9 @@ // Ends the split view mode. void EndSplitView(EndReason end_reason = EndReason::kNormal); + // Returns true if |window| is a snapped window in splitview. + bool IsWindowInSplitView(const aura::Window* window) const; + // Called when a window (either it's browser window or an app window) start/ // end being dragged. void OnWindowDragStarted(aura::Window* dragged_window);
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc index 1f3d86da..ece9a488 100644 --- a/ash/wm/splitview/split_view_controller_unittest.cc +++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -1962,8 +1962,8 @@ overview_session->GetGridWithRootWindow(window->GetRootWindow()); DCHECK(current_grid); - OverviewItem* selector_item = current_grid->GetDropTarget(); - return selector_item->GetTransformedBounds(); + OverviewItem* overview_item = current_grid->GetDropTarget(); + return overview_item->GetTransformedBounds(); } private: @@ -2628,9 +2628,9 @@ // Test that the dragged window has been added to the overview mode, and it is // added at the front of the grid. EXPECT_EQ(current_grid->window_list().size(), 2u); - OverviewItem* first_selector_item = + OverviewItem* first_overview_item = current_grid->GetOverviewItemContaining(window1.get()); - EXPECT_EQ(first_selector_item, current_grid->window_list().front().get()); + EXPECT_EQ(first_overview_item, current_grid->window_list().front().get()); EXPECT_TRUE(overview_session->IsWindowInOverview(window1.get())); EXPECT_TRUE(overview_session->IsWindowInOverview(window3.get())); // Test that the new window item widget has been destroyed. @@ -2893,9 +2893,9 @@ ASSERT_TRUE(current_grid); EXPECT_EQ(1u, current_grid->window_list().size()); - OverviewItem* selector_item = current_grid->GetDropTarget(); - ASSERT_TRUE(selector_item); - gfx::Rect drop_target_bounds = selector_item->target_bounds(); + OverviewItem* overview_item = current_grid->GetDropTarget(); + ASSERT_TRUE(overview_item); + gfx::Rect drop_target_bounds = overview_item->target_bounds(); DragWindowTo(resizer.get(), drop_target_bounds.CenterPoint()); CompleteDrag(std::move(resizer)); @@ -2904,10 +2904,10 @@ EXPECT_TRUE(overview_session->IsWindowInOverview(window1.get())); // |window1|'s bounds should have been updated to its tablet mode bounds. EXPECT_EQ(tablet_mode_bounds, window1->bounds()); - selector_item = current_grid->window_list().front().get(); - // The new window selector item's bounds should be the same during drag and - // after drag. - EXPECT_EQ(drop_target_bounds, selector_item->target_bounds()); + overview_item = current_grid->window_list().front().get(); + // The new overview item's bounds should be the same during drag and after + // drag. + EXPECT_EQ(drop_target_bounds, overview_item->target_bounds()); ToggleOverview(); EXPECT_FALSE(overview_controller->IsSelecting());
diff --git a/ash/wm/splitview/split_view_utils.cc b/ash/wm/splitview/split_view_utils.cc index b9b9bca..4412b86e 100644 --- a/ash/wm/splitview/split_view_utils.cc +++ b/ash/wm/splitview/split_view_utils.cc
@@ -59,8 +59,8 @@ case SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_OUT: case SPLITVIEW_ANIMATION_PREVIEW_AREA_FADE_IN: case SPLITVIEW_ANIMATION_PREVIEW_AREA_FADE_OUT: - case SPLITVIEW_ANIMATION_SELECTOR_ITEM_FADE_IN: - case SPLITVIEW_ANIMATION_SELECTOR_ITEM_FADE_OUT: + case SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_IN: + case SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_OUT: case SPLITVIEW_ANIMATION_TEXT_FADE_IN_WITH_HIGHLIGHT: case SPLITVIEW_ANIMATION_TEXT_FADE_OUT_WITH_HIGHLIGHT: case SPLITVIEW_ANIMATION_PREVIEW_AREA_SLIDE_IN_OUT: @@ -127,7 +127,7 @@ switch (type) { case SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_OUT: case SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_FADE_OUT: - case SPLITVIEW_ANIMATION_SELECTOR_ITEM_FADE_OUT: + case SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_OUT: case SPLITVIEW_ANIMATION_TEXT_FADE_OUT: case SPLITVIEW_ANIMATION_TEXT_FADE_OUT_WITH_HIGHLIGHT: target_opacity = 0.f; @@ -140,7 +140,7 @@ case SPLITVIEW_ANIMATION_PREVIEW_AREA_FADE_OUT: target_opacity = kHighlightOpacity; break; - case SPLITVIEW_ANIMATION_SELECTOR_ITEM_FADE_IN: + case SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_IN: case SPLITVIEW_ANIMATION_TEXT_FADE_IN: case SPLITVIEW_ANIMATION_TEXT_FADE_IN_WITH_HIGHLIGHT: target_opacity = 1.f;
diff --git a/ash/wm/splitview/split_view_utils.h b/ash/wm/splitview/split_view_utils.h index 984b55c5..92ec92e 100644 --- a/ash/wm/splitview/split_view_utils.h +++ b/ash/wm/splitview/split_view_utils.h
@@ -34,17 +34,16 @@ SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_FADE_IN, SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_FADE_OUT, // Used to fade in and out the preview area highlight which indicate the - // bounds of - // the window that is about to get snapped. + // bounds of the window that is about to get snapped. SPLITVIEW_ANIMATION_PREVIEW_AREA_FADE_IN, SPLITVIEW_ANIMATION_PREVIEW_AREA_FADE_OUT, - // Used to fade in and out the label on the selector item which warns users - // the item cannot be snapped. The label appears on the selector item after + // Used to fade in and out the label on the overview item which warns users + // the item cannot be snapped. The label appears on the overview item after // another window has been snapped. - SPLITVIEW_ANIMATION_SELECTOR_ITEM_FADE_IN, - SPLITVIEW_ANIMATION_SELECTOR_ITEM_FADE_OUT, + SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_IN, + SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_OUT, // Used to fade in and out the labels which appear on either side of overview - // mode when a selector item is selected. They indicate where to drag the + // mode when a overview item is selected. They indicate where to drag the // selector item if it is snappable, or if an item cannot be snapped. SPLITVIEW_ANIMATION_TEXT_FADE_IN, SPLITVIEW_ANIMATION_TEXT_FADE_OUT,
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.cc b/ash/wm/tablet_mode/tablet_mode_controller.cc index 6e37ccc..0c0842d 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller.cc
@@ -164,8 +164,17 @@ } TabletModeController::~TabletModeController() { - Shell::Get()->RemoveShellObserver(this); + UMA_HISTOGRAM_COUNTS_1000("Tablet.AppWindowDrag.CountOfPerUserSession", + app_window_drag_count_); + UMA_HISTOGRAM_COUNTS_1000( + "Tablet.AppWindowDrag.InSplitView.CountOfPerUserSession", + app_window_drag_in_splitview_count_); + UMA_HISTOGRAM_COUNTS_1000("Tablet.TabDrag.CountOfPerUserSession", + tab_drag_count_); + UMA_HISTOGRAM_COUNTS_1000("Tablet.TabDrag.InSplitView.CountOfPerUserSession", + tab_drag_in_splitview_count_); + Shell::Get()->RemoveShellObserver(this); if (IsEnabled()) { Shell::Get()->window_tree_host_manager()->RemoveObserver(this); AccelerometerReader::GetInstance()->RemoveObserver(this);
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.h b/ash/wm/tablet_mode/tablet_mode_controller.h index 24b143f..c189f5ed 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.h +++ b/ash/wm/tablet_mode/tablet_mode_controller.h
@@ -140,6 +140,15 @@ void OnInputDeviceConfigurationChanged(uint8_t input_device_types) override; void OnDeviceListsComplete() override; + void increment_app_window_drag_count() { ++app_window_drag_count_; } + void increment_app_window_drag_in_splitview_count() { + ++app_window_drag_in_splitview_count_; + } + void increment_tab_drag_count() { ++tab_drag_count_; } + void increment_tab_drag_in_splitview_count() { + ++tab_drag_in_splitview_count_; + } + private: friend class TabletModeControllerTestApi; @@ -272,6 +281,19 @@ // not enter tablet mode if this is true. bool has_external_pointing_device_ = false; + // Counts the app window drag from top in tablet mode. + int app_window_drag_count_ = 0; + + // Counts the app window drag from top when splitview is active. + int app_window_drag_in_splitview_count_ = 0; + + // Counts of the tab drag from top in tablet mode, includes both non-source + // window and source window drag. + int tab_drag_count_ = 0; + + // Counts of the tab drag from top when splitview is active. + int tab_drag_in_splitview_count_ = 0; + // Tracks smoothed accelerometer data over time. This is done when the hinge // is approaching vertical to remove abrupt acceleration that can lead to // incorrect calculations of hinge angles.
diff --git a/ash/wm/tablet_mode/tablet_mode_window_drag_controller.cc b/ash/wm/tablet_mode/tablet_mode_window_drag_controller.cc index 6c06533..c8a3349 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_drag_controller.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_drag_controller.cc
@@ -6,6 +6,7 @@ #include "ash/shell.h" #include "ash/wm/tablet_mode/tablet_mode_browser_window_drag_delegate.h" +#include "ash/wm/tablet_mode/tablet_mode_window_drag_metrics.h" #include "ash/wm/window_util.h" #include "ui/wm/core/coordinate_conversion.h" #include "ui/wm/core/cursor_manager.h" @@ -66,16 +67,20 @@ drag_delegate_->EndWindowDrag( wm::WmToplevelWindowEventHandler::DragResult::SUCCESS, previous_location_in_screen_); + RecordWindowDragEndTypeHistogram( + WindowDragEndEventType::kEndsWithNormalComplete); } void TabletModeWindowDragController::RevertDrag() { drag_delegate_->EndWindowDrag( wm::WmToplevelWindowEventHandler::DragResult::REVERT, previous_location_in_screen_); + RecordWindowDragEndTypeHistogram(WindowDragEndEventType::kEndsWithRevert); } void TabletModeWindowDragController::FlingOrSwipe(ui::GestureEvent* event) { drag_delegate_->FlingOrSwipe(event); + RecordWindowDragEndTypeHistogram(WindowDragEndEventType::kEndsWithFling); } } // namespace ash
diff --git a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc index 4a3c8ff4..dd2733b 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc
@@ -9,6 +9,7 @@ #include "ash/shell.h" #include "ash/system/overview/overview_button_tray.h" #include "ash/system/status_area_widget.h" +#include "ash/wm/mru_window_tracker.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_grid.h" #include "ash/wm/overview/overview_item.h" @@ -19,7 +20,13 @@ #include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/splitview/split_view_drag_indicators.h" #include "ash/wm/splitview/split_view_utils.h" +#include "ash/wm/tablet_mode/tablet_mode_controller.h" +#include "ash/wm/tablet_mode/tablet_mode_window_drag_metrics.h" #include "ash/wm/window_transient_descendant_iterator.h" +#include "ash/wm/window_util.h" +#include "base/metrics/histogram_macros.h" +#include "base/metrics/user_metrics.h" +#include "base/metrics/user_metrics_action.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/gfx/transform_util.h" #include "ui/wm/core/coordinate_conversion.h" @@ -106,6 +113,8 @@ OverviewController* controller = Shell::Get()->overview_controller(); bool was_overview_open = controller->IsSelecting(); + const bool was_splitview_active = + split_view_controller_->IsSplitViewModeActive(); // If the dragged window is one of the snapped windows, SplitViewController // might open overview in the dragged window side of the screen. split_view_controller_->OnWindowDragStarted(dragged_window_); @@ -135,6 +144,33 @@ original_shadow_elevation_ = ::wm::GetShadowElevationConvertDefault(dragged_window_); ::wm::SetShadowElevation(dragged_window_, ::wm::kShadowElevationActiveWindow); + + Shell* shell = Shell::Get(); + TabletModeController* tablet_mode_controller = + shell->tablet_mode_controller(); + if (wm::IsDraggingTabs(dragged_window_)) { + tablet_mode_controller->increment_tab_drag_count(); + if (was_splitview_active) + tablet_mode_controller->increment_tab_drag_in_splitview_count(); + + // For tab drag, we only open the overview behind if the dragged window is + // the source window. + if (ShouldOpenOverviewWhenDragStarts()) + RecordTabDragTypeHistogram(TabDragType::kDragSourceWindow); + else + RecordTabDragTypeHistogram(TabDragType::kDragTabOutOfWindow); + } else { + tablet_mode_controller->increment_app_window_drag_count(); + if (was_splitview_active) + tablet_mode_controller->increment_app_window_drag_in_splitview_count(); + } + if (controller->IsSelecting()) { + UMA_HISTOGRAM_COUNTS_100( + "Tablet.WindowDrag.OpenedWindowsNumber", + shell->mru_window_tracker()->BuildMruWindowList().size()); + base::RecordAction( + base::UserMetricsAction("Tablet.WindowDrag.OpenedOverview")); + } } void TabletModeWindowDragDelegate::ContinueWindowDrag( @@ -197,7 +233,8 @@ // The window might merge into an overview window or become a new window item // in overview mode. - if (GetOverviewSession()) { + OverviewSession* overview_session = GetOverviewSession(); + if (overview_session) { GetOverviewSession()->OnWindowDragEnded( dragged_window_, location_in_screen, ShouldDropWindowIntoOverview(snap_position, location_in_screen)); @@ -212,6 +249,21 @@ // For child class to do its special handling if any. EndedWindowDrag(location_in_screen); + + if (!wm::IsDraggingTabs(dragged_window_)) { + if (split_view_controller_->IsWindowInSplitView(dragged_window_)) { + RecordAppDragEndWindowStateHistogram( + AppWindowDragEndWindowState::kDraggedIntoSplitView); + } else if (overview_session && + overview_session->IsWindowInOverview(dragged_window_)) { + RecordAppDragEndWindowStateHistogram( + AppWindowDragEndWindowState::kDraggedIntoOverview); + } else { + RecordAppDragEndWindowStateHistogram( + AppWindowDragEndWindowState::kBackToMaximizedOrFullscreen); + } + } + occlusion_excluder_.reset(); dragged_window_ = nullptr; did_move_ = false;
diff --git a/ash/wm/tablet_mode/tablet_mode_window_drag_metrics.cc b/ash/wm/tablet_mode/tablet_mode_window_drag_metrics.cc new file mode 100644 index 0000000..83eecbd --- /dev/null +++ b/ash/wm/tablet_mode/tablet_mode_window_drag_metrics.cc
@@ -0,0 +1,29 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/wm/tablet_mode/tablet_mode_window_drag_metrics.h" + +#include "base/metrics/histogram_macros.h" + +namespace ash { + +constexpr char kWindowDragEndEventTypeHistogram[] = + "Tablet.WindowDrag.DragEndEventType"; +constexpr char kAppDragEndWindowStateHistogram[] = + "Tablet.AppDrag.EndWindowState"; +constexpr char kTabDragTypeHistogram[] = "Tablet.TabDrag.DragType"; + +void RecordWindowDragEndTypeHistogram(WindowDragEndEventType type) { + UMA_HISTOGRAM_ENUMERATION(kWindowDragEndEventTypeHistogram, type); +} + +void RecordAppDragEndWindowStateHistogram(AppWindowDragEndWindowState state) { + UMA_HISTOGRAM_ENUMERATION(kAppDragEndWindowStateHistogram, state); +} + +void RecordTabDragTypeHistogram(TabDragType type) { + UMA_HISTOGRAM_ENUMERATION(kTabDragTypeHistogram, type); +} + +} // namespace ash
diff --git a/ash/wm/tablet_mode/tablet_mode_window_drag_metrics.h b/ash/wm/tablet_mode/tablet_mode_window_drag_metrics.h new file mode 100644 index 0000000..bf64e91 --- /dev/null +++ b/ash/wm/tablet_mode/tablet_mode_window_drag_metrics.h
@@ -0,0 +1,41 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_WM_TABLET_MODE_TABLET_MODE_WINDOW_DRAG_METRICS_H_ +#define ASH_WM_TABLET_MODE_TABLET_MODE_WINDOW_DRAG_METRICS_H_ + +namespace ash { + +// See WindowDragEndEventType at tools/metrics/histograms/enums.xml +enum class WindowDragEndEventType { + kEndsWithNormalComplete = 0, + kEndsWithRevert = 1, + kEndsWithFling = 2, + kMaxValue = kEndsWithFling, +}; + +void RecordWindowDragEndTypeHistogram(WindowDragEndEventType type); + +// See AppWindowDragEndWindowState at tools/metrics/histograms/enums.xml +enum class AppWindowDragEndWindowState { + kBackToMaximizedOrFullscreen = 0, + kDraggedIntoOverview = 1, + kDraggedIntoSplitView = 2, + kMaxValue = kDraggedIntoSplitView, +}; + +void RecordAppDragEndWindowStateHistogram(AppWindowDragEndWindowState state); + +// See TabDragType at tools/metrics/histograms/enums.xml +enum class TabDragType { + kDragSourceWindow = 0, + kDragTabOutOfWindow = 1, + kMaxValue = kDragTabOutOfWindow, +}; + +void RecordTabDragTypeHistogram(TabDragType type); + +} // namespace ash + +#endif // ASH_WM_TABLET_MODE_TABLET_MODE_WINDOW_DRAG_METRICS_H_
diff --git a/ash/ws/ax_ash_window_utils.h b/ash/ws/ax_ash_window_utils.h index f605d32..301e8f5 100644 --- a/ash/ws/ax_ash_window_utils.h +++ b/ash/ws/ax_ash_window_utils.h
@@ -13,7 +13,7 @@ // Provides functions for walking a tree of aura::Windows for accessibility. For // SingleProcessMash we want the accessibility tree to jump from a proxy aura -// Window on the ash side direclty to its corresponding client window. This is +// Window on the ash side directly to its corresponding client window. This is // just a temporary solution to that issue and should be removed once Mash is // fully launched. https://crbug.com/911945 class ASH_EXPORT AXAshWindowUtils : public views::AXAuraWindowUtils {
diff --git a/base/BUILD.gn b/base/BUILD.gn index 47f434f..39ca8f18 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -3146,7 +3146,6 @@ ] java_files = [ - "test/android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java", "test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java", "test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java", "test/android/javatests/src/org/chromium/base/test/BaseChromiumRunnerCommon.java",
diff --git a/base/android/java/src/org/chromium/base/BaseSwitches.java b/base/android/java/src/org/chromium/base/BaseSwitches.java index b0b1726..fe47cdd 100644 --- a/base/android/java/src/org/chromium/base/BaseSwitches.java +++ b/base/android/java/src/org/chromium/base/BaseSwitches.java
@@ -27,9 +27,6 @@ // Default country code to be used for search engine localization. public static final String DEFAULT_COUNTRY_CODE_AT_INSTALL = "default-country-code"; - // Enables the reached code profiler. - public static final String ENABLE_REACHED_CODE_PROFILER = "enable-reached-code-profiler"; - // Prevent instantiation. private BaseSwitches() {} }
diff --git a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java index b5a8824..0ee9aa9 100644 --- a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java +++ b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
@@ -17,7 +17,6 @@ import android.support.v4.content.ContextCompat; import android.system.Os; -import org.chromium.base.BaseSwitches; import org.chromium.base.BuildConfig; import org.chromium.base.BuildInfo; import org.chromium.base.CommandLine; @@ -25,7 +24,6 @@ import org.chromium.base.FileUtils; import org.chromium.base.Log; import org.chromium.base.StreamUtil; -import org.chromium.base.StrictModeContext; import org.chromium.base.SysUtils; import org.chromium.base.TraceEvent; import org.chromium.base.VisibleForTesting; @@ -87,9 +85,6 @@ // SharedPreferences key for "don't prefetch libraries" flag private static final String DONT_PREFETCH_LIBRARIES_KEY = "dont_prefetch_libraries"; - // Shared preferences key for the reached code profiler. - private static final String REACHED_CODE_PROFILER_ENABLED_KEY = "reached_code_profiler_enabled"; - private static final EnumeratedHistogramSample sRelinkerCountHistogram = new EnumeratedHistogramSample("ChromiumAndroidLinker.RelinkerFallbackCount", 2); @@ -311,33 +306,6 @@ } } - /** - * Enables the reached code profiler. The value comes from "ReachedCodeProfiler" - * finch experiment, and is pushed on every run. I.e. the effect of the finch experiment - * lags by one run, which is the best we can do considering that the profiler has to be enabled - * before finch is initialized. Note that since LibraryLoader is in //base, it can't depend - * on ChromeFeatureList, and has to rely on external code pushing the value. - * - * @param enabled whether to enable the reached code profiler. - */ - public static void setReachedCodeProfilerEnabledOnNextRuns(boolean enabled) { - ContextUtils.getAppSharedPreferences() - .edit() - .putBoolean(REACHED_CODE_PROFILER_ENABLED_KEY, enabled) - .apply(); - } - - /** - * @return whether to enable reached code profiler (see - * setReachedCodeProfilerEnabledOnNextRuns()). - */ - private static boolean isReachedCodeProfilerEnabled() { - try (StrictModeContext unused = StrictModeContext.allowDiskReads()) { - return ContextUtils.getAppSharedPreferences().getBoolean( - REACHED_CODE_PROFILER_ENABLED_KEY, false); - } - } - /** Prefetches the native libraries in a background thread. * * Launches an AsyncTask that, through a short-lived forked process, reads a @@ -617,13 +585,6 @@ } mLibraryProcessType = processType; - // Add a switch for the reached code profiler as late as possible since it requires a read - // from the shared preferences. At this point the shared preferences are usually warmed up. - if (mLibraryProcessType == LibraryProcessType.PROCESS_BROWSER - && isReachedCodeProfilerEnabled()) { - CommandLine.getInstance().appendSwitch(BaseSwitches.ENABLE_REACHED_CODE_PROFILER); - } - ensureCommandLineSwitchedAlreadyLocked(); if (!nativeLibraryLoaded(mLibraryProcessType)) {
diff --git a/base/android/reached_code_profiler.cc b/base/android/reached_code_profiler.cc index 07e6d5e..0513500c 100644 --- a/base/android/reached_code_profiler.cc +++ b/base/android/reached_code_profiler.cc
@@ -13,10 +13,8 @@ #include "base/android/library_loader/anchor_functions.h" #include "base/android/orderfile/orderfile_buildflags.h" -#include "base/base_switches.h" #include "base/bind.h" #include "base/command_line.h" -#include "base/feature_list.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/important_file_writer.h" @@ -42,19 +40,6 @@ namespace { -#if !defined(NDEBUG) || defined(COMPONENT_BUILD) -// Always disabled for debug builds to avoid hitting a limit of signal -// interrupts that can get delivered into a single HANDLE_EINTR. Also -// debugging experience would be bad if there are a lot of signals flying -// around. -// Always disabled for component builds because in this case the code is not -// organized in one contiguous region which is required for the reached code -// profiler. -constexpr const bool kConfigurationSupported = false; -#else -constexpr const bool kConfigurationSupported = true; -#endif - constexpr const char kDumpToFileFlag[] = "reached-code-profiler-dump-to-file"; // Enough for 1 << 29 bytes of code, 512MB. @@ -305,11 +290,20 @@ }; bool ShouldEnableReachedCodeProfiler() { - if (!kConfigurationSupported) - return false; - - const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); - return cmdline->HasSwitch(switches::kEnableReachedCodeProfiler); +#if !defined(NDEBUG) || defined(COMPONENT_BUILD) + // Always disabled for debug builds to avoid hitting a limit of signal + // interrupts that can get delivered into a single HANDLE_EINTR. Also + // debugging experience would be bad if there are a lot of signals flying + // around. + // Always disabled for component builds because in this case the code is not + // organized in one contiguous region which is required for the reached code + // profiler. + return false; +#else + // TODO(crbug.com/916263): this should be set up according to the finch + // experiment. + return false; +#endif } } // namespace @@ -329,9 +323,5 @@ return ReachedCodeProfiler::GetInstance()->IsEnabled(); } -bool IsReachedCodeProfilerSupported() { - return kConfigurationSupported; -} - } // namespace android } // namespace base
diff --git a/base/android/reached_code_profiler.h b/base/android/reached_code_profiler.h index 435600e4..8d18e09f 100644 --- a/base/android/reached_code_profiler.h +++ b/base/android/reached_code_profiler.h
@@ -24,10 +24,6 @@ // Returns whether the reached code profiler is enabled. BASE_EXPORT bool IsReachedCodeProfilerEnabled(); -// Returns whether the reached code profiler can be possibly enabled for the -// current build configuration. -BASE_EXPORT bool IsReachedCodeProfilerSupported(); - } // namespace android } // namespace base
diff --git a/base/android/reached_code_profiler_stub.cc b/base/android/reached_code_profiler_stub.cc index f99df5c..56f0fb00 100644 --- a/base/android/reached_code_profiler_stub.cc +++ b/base/android/reached_code_profiler_stub.cc
@@ -14,9 +14,5 @@ return false; } -bool IsReachedCodeProfilerSupported() { - return false; -} - } // namespace android } // namespace base
diff --git a/base/base_switches.cc b/base/base_switches.cc index 1567a3ea..ff781a3 100644 --- a/base/base_switches.cc +++ b/base/base_switches.cc
@@ -123,10 +123,6 @@ #endif #if defined(OS_ANDROID) -// Enables the reached code profiler that samples all threads in all processes -// to determine which functions are almost never executed. -const char kEnableReachedCodeProfiler[] = "enable-reached-code-profiler"; - // Specifies optimization of memory layout of the native library using the // orderfile symbols given in base/android/library_loader/anchor_functions.h, // via madvise and changing the library prefetch behavior.
diff --git a/base/base_switches.h b/base/base_switches.h index 49650dc..5967c1a 100644 --- a/base/base_switches.h +++ b/base/base_switches.h
@@ -45,7 +45,6 @@ #endif #if defined(OS_ANDROID) -extern const char kEnableReachedCodeProfiler[]; extern const char kOrderfileMemoryOptimization[]; #endif
diff --git a/base/fuchsia/scoped_service_binding.h b/base/fuchsia/scoped_service_binding.h index 302af71..efdc30d8 100644 --- a/base/fuchsia/scoped_service_binding.h +++ b/base/fuchsia/scoped_service_binding.h
@@ -31,6 +31,8 @@ fit::bind_member(this, &ScopedServiceBinding::OnBindingSetEmpty)); } + bool has_clients() const { return bindings_.size() != 0; } + private: void BindClient(fidl::InterfaceRequest<Interface> request) { bindings_.AddBinding(impl_, std::move(request));
diff --git a/base/fuchsia/service_directory.cc b/base/fuchsia/service_directory.cc index 93c416f6..31ace9ff 100644 --- a/base/fuchsia/service_directory.cc +++ b/base/fuchsia/service_directory.cc
@@ -19,12 +19,11 @@ ServiceDirectory::ServiceDirectory( fidl::InterfaceRequest<::fuchsia::io::Directory> request) { - zx_status_t status = - svc_dir_create(async_get_default_dispatcher(), - request.TakeChannel().release(), &svc_dir_); - ZX_CHECK(status == ZX_OK, status); + Initialize(std::move(request)); } +ServiceDirectory::ServiceDirectory() = default; + ServiceDirectory::ServiceDirectory(zx::channel request) : ServiceDirectory(fidl::InterfaceRequest<::fuchsia::io::Directory>( std::move(request))) {} @@ -45,10 +44,22 @@ return directory.get(); } +void ServiceDirectory::Initialize( + fidl::InterfaceRequest<::fuchsia::io::Directory> request) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(!svc_dir_); + + zx_status_t status = + svc_dir_create(async_get_default_dispatcher(), + request.TakeChannel().release(), &svc_dir_); + ZX_CHECK(status == ZX_OK, status); +} + void ServiceDirectory::AddServiceUnsafe( StringPiece name, RepeatingCallback<void(zx::channel)> connect_callback) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(svc_dir_); DCHECK(services_.find(name) == services_.end()); std::string name_str = name.as_string(); @@ -67,6 +78,7 @@ void ServiceDirectory::RemoveService(StringPiece name) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(svc_dir_); std::string name_str = name.as_string();
diff --git a/base/fuchsia/service_directory.h b/base/fuchsia/service_directory.h index 9813b58..6a8596e 100644 --- a/base/fuchsia/service_directory.h +++ b/base/fuchsia/service_directory.h
@@ -40,6 +40,12 @@ explicit ServiceDirectory( fidl::InterfaceRequest<::fuchsia::io::Directory> request); + // Creates an uninitialized ServiceDirectory instance. Initialize must be + // called on the instance before any services can be registered. Unless you + // need separate construction & initialization for a ServiceDirectory member, + // use the all-in-one constructor above. + ServiceDirectory(); + // TODO(https://crbug.com/920920): Clean up callers and remove this synonym. explicit ServiceDirectory(zx::channel request); @@ -49,6 +55,10 @@ // publishes services to the directory provided by the process creator. static ServiceDirectory* GetDefault(); + // Configures an uninitialized ServiceDirectory instance to service the + // supplied |directory_request| channel. + void Initialize(fidl::InterfaceRequest<::fuchsia::io::Directory> request); + template <typename Interface> void AddService(RepeatingCallback<void(fidl::InterfaceRequest<Interface>)> connect_callback) {
diff --git a/base/fuchsia/service_provider_impl.cc b/base/fuchsia/service_provider_impl.cc index 9a874ec1..c21ce6c1 100644 --- a/base/fuchsia/service_provider_impl.cc +++ b/base/fuchsia/service_provider_impl.cc
@@ -26,5 +26,17 @@ std::move(client_handle)); } +void ServiceProviderImpl::SetOnLastClientDisconnectedClosure( + base::OnceClosure on_last_client_disconnected) { + on_last_client_disconnected_ = std::move(on_last_client_disconnected); + bindings_.set_empty_set_handler( + fit::bind_member(this, &ServiceProviderImpl::OnBindingSetEmpty)); +} + +void ServiceProviderImpl::OnBindingSetEmpty() { + bindings_.set_empty_set_handler(nullptr); + std::move(on_last_client_disconnected_).Run(); +} + } // namespace fuchsia } // namespace base
diff --git a/base/fuchsia/service_provider_impl.h b/base/fuchsia/service_provider_impl.h index c7e56728..35087ac 100644 --- a/base/fuchsia/service_provider_impl.h +++ b/base/fuchsia/service_provider_impl.h
@@ -12,6 +12,7 @@ #include <lib/zx/channel.h> #include <string> +#include "base/callback.h" #include "base/fuchsia/service_directory_client.h" namespace base { @@ -30,13 +31,20 @@ void AddBinding( fidl::InterfaceRequest<::fuchsia::sys::ServiceProvider> request); + // Sets a Closure to be invoked when the last client disconnects. + void SetOnLastClientDisconnectedClosure( + base::OnceClosure on_last_client_disconnected); + private: // fuchsia::sys::ServiceProvider implementation. void ConnectToService(std::string service_name, zx::channel client_handle) override; + void OnBindingSetEmpty(); + const ServiceDirectoryClient directory_; fidl::BindingSet<::fuchsia::sys::ServiceProvider> bindings_; + base::OnceClosure on_last_client_disconnected_; DISALLOW_COPY_AND_ASSIGN(ServiceProviderImpl); };
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc index 1ffeb61..cec3a133 100644 --- a/base/message_loop/message_loop.cc +++ b/base/message_loop/message_loop.cc
@@ -172,10 +172,9 @@ } MessageLoop::MessageLoop(Type type, MessagePumpFactoryCallback pump_factory) - : backend_( - sequence_manager::internal::SequenceManagerImpl:: - CreateUnboundWithPump(sequence_manager::SequenceManager::Settings{ - .message_loop_type = type})), + : backend_(sequence_manager::internal::SequenceManagerImpl::CreateUnbound( + sequence_manager::SequenceManager::Settings{.message_loop_type = + type})), default_task_queue_(CreateDefaultTaskQueue()), type_(type), pump_factory_(std::move(pump_factory)) { @@ -211,12 +210,6 @@ << "should only have one message loop per thread"; backend_->BindToCurrentThread(std::move(pump)); - -#if defined(OS_ANDROID) - // On Android, attach to the native loop when there is one. - if (type_ == TYPE_UI || type_ == TYPE_JAVA) - backend_->AttachToMessagePump(); -#endif } std::unique_ptr<MessagePump> MessageLoop::CreateMessagePump() {
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h index 8bc516bc..f49f562 100644 --- a/base/message_loop/message_loop.h +++ b/base/message_loop/message_loop.h
@@ -200,7 +200,7 @@ // Whether task execution is allowed at the moment. virtual bool IsTaskExecutionAllowed() const = 0; -#if defined(OS_IOS) || defined(OS_ANDROID) +#if defined(OS_IOS) virtual void AttachToMessagePump() = 0; #endif
diff --git a/base/message_loop/message_loop_current.cc b/base/message_loop/message_loop_current.cc index dca46545..e669669 100644 --- a/base/message_loop/message_loop_current.cc +++ b/base/message_loop/message_loop_current.cc
@@ -176,7 +176,7 @@ } #endif -#if defined(OS_IOS) || defined(OS_ANDROID) +#if defined(OS_IOS) void MessageLoopCurrentForUI::Attach() { current_->AttachToMessagePump(); }
diff --git a/base/message_loop/message_loop_current.h b/base/message_loop/message_loop_current.h index 56c147d..d469a72 100644 --- a/base/message_loop/message_loop_current.h +++ b/base/message_loop/message_loop_current.h
@@ -243,7 +243,7 @@ MessagePumpForUI::FdWatcher* delegate); #endif -#if defined(OS_IOS) || defined(OS_ANDROID) +#if defined(OS_IOS) // Forwards to MessageLoopForUI::Attach(). // TODO(https://crbug.com/825327): Plumb the actual MessageLoopForUI* to // callers and remove ability to access this method from
diff --git a/base/message_loop/message_pump_win.cc b/base/message_loop/message_pump_win.cc index 97f45e7..9de7721 100644 --- a/base/message_loop/message_pump_win.cc +++ b/base/message_loop/message_pump_win.cc
@@ -40,6 +40,7 @@ // MessagePumpWin public: MessagePumpWin::MessagePumpWin() = default; +MessagePumpWin::~MessagePumpWin() = default; void MessagePumpWin::Run(Delegate* delegate) { RunState s; @@ -94,7 +95,8 @@ MessagePumpForUI::~MessagePumpForUI() = default; void MessagePumpForUI::ScheduleWork() { - if (InterlockedExchange(&work_state_, HAVE_WORK) != READY) + bool not_scheduled = false; + if (!work_scheduled_.compare_exchange_strong(not_scheduled, true)) return; // Someone else continued the pumping. // Make sure the MessagePump does some work for us. @@ -112,7 +114,7 @@ // probably be recoverable. // Clarify that we didn't really insert. - InterlockedExchange(&work_state_, READY); + work_scheduled_ = false; UMA_HISTOGRAM_ENUMERATION("Chrome.MessageLoopProblem", MESSAGE_POST_ERROR, MESSAGE_LOOP_PROBLEM_MAX); } @@ -263,7 +265,7 @@ // sort. if (!state_) { // Since we handled a kMsgHaveWork message, we must still update this flag. - InterlockedExchange(&work_state_, READY); + work_scheduled_ = false; return; } @@ -406,10 +408,10 @@ msg.hwnd != message_window_.hwnd()); // Since we discarded a kMsgHaveWork message, we must update the flag. - int old_work_state_ = InterlockedExchange(&work_state_, READY); - DCHECK_EQ(HAVE_WORK, old_work_state_); + DCHECK(work_scheduled_); + work_scheduled_ = false; - // We don't need a special time slice if we didn't have_message to process. + // We don't need a special time slice if we didn't |have_message| to process. if (!have_message) return false; @@ -458,7 +460,8 @@ MessagePumpForIO::~MessagePumpForIO() = default; void MessagePumpForIO::ScheduleWork() { - if (InterlockedExchange(&work_state_, HAVE_WORK) != READY) + bool not_scheduled = false; + if (!work_scheduled_.compare_exchange_strong(not_scheduled, true)) return; // Someone else continued the pumping. // Make sure the MessagePump does some work for us. @@ -469,7 +472,8 @@ return; // Post worked perfectly. // See comment in MessagePumpForUI::ScheduleWork() for this error recovery. - InterlockedExchange(&work_state_, READY); // Clarify that we didn't succeed. + + work_scheduled_ = false; // Clarify that we didn't succeed. UMA_HISTOGRAM_ENUMERATION("Chrome.MessageLoopProblem", COMPLETION_POST_ERROR, MESSAGE_LOOP_PROBLEM_MAX); } @@ -600,7 +604,7 @@ reinterpret_cast<void*>(this) == reinterpret_cast<void*>(item.handler)) { // This is our internal completion. DCHECK(!item.bytes_transfered); - InterlockedExchange(&work_state_, READY); + work_scheduled_ = false; return true; } return false;
diff --git a/base/message_loop/message_pump_win.h b/base/message_loop/message_pump_win.h index 5111ae6..e9db712 100644 --- a/base/message_loop/message_pump_win.h +++ b/base/message_loop/message_pump_win.h
@@ -7,6 +7,7 @@ #include <windows.h> +#include <atomic> #include <list> #include <memory> @@ -25,6 +26,7 @@ class BASE_EXPORT MessagePumpWin : public MessagePump { public: MessagePumpWin(); + ~MessagePumpWin() override; // MessagePump methods: void Run(Delegate* delegate) override; @@ -41,23 +43,34 @@ int run_depth; }; - // State used with |work_state_| variable. - enum WorkState { - READY = 0, // Ready to accept new work. - HAVE_WORK = 1, // New work has been signalled. - WORKING = 2 // Handling the work. - }; - virtual void DoRunLoop() = 0; int GetCurrentDelay() const; // The time at which delayed work should run. TimeTicks delayed_work_time_; - // A value used to indicate if there is a kMsgDoWork message pending - // in the Windows Message queue. There is at most one such message, and it - // can drive execution of tasks when a native message pump is running. - LONG work_state_ = READY; + // True iff: + // * MessagePumpForUI: there's a kMsgDoWork message pending in the Windows + // Message queue. i.e. when: + // a. The pump is about to wakeup from idle. + // b. The pump is about to enter a nested native loop and a + // ScopedNestableTaskAllower was instantiated to allow application + // tasks to execute in that nested loop (ScopedNestableTaskAllower + // invokes ScheduleWork()). + // c. While in a native (nested) loop : HandleWorkMessage() => + // ProcessPumpReplacementMessage() invokes ScheduleWork() before + // processing a native message to guarantee this pump will get another + // time slice if it goes into native Windows code and enters a native + // nested loop. This is different from (b.) because we're not yet + // processing an application task at the current run level and + // therefore are expected to keep pumping application tasks without + // necessitating a ScopedNestableTaskAllower. + // + // * MessagePumpforIO: there's a dummy IO completion item with |this| as an + // lpCompletionKey in the queue which is about to wakeup + // WaitForIOCompletion(). MessagePumpForIO doesn't support nesting so + // this is simpler than MessagePumpForUI. + std::atomic_bool work_scheduled_{false}; // State for the current invocation of Run. RunState* state_ = nullptr;
diff --git a/base/strings/string_util.h b/base/strings/string_util.h index a0d856f..00a0cff 100644 --- a/base/strings/string_util.h +++ b/base/strings/string_util.h
@@ -242,6 +242,10 @@ return bit_cast<wchar_t*>(data(str)); } +inline const wchar_t* as_wcstr(const char16* str) { + return bit_cast<const wchar_t*>(str); +} + inline const wchar_t* as_wcstr(StringPiece16 str) { return bit_cast<const wchar_t*>(str.data()); } @@ -255,6 +259,10 @@ return bit_cast<char16*>(data(str)); } +inline const char16* as_u16cstr(const wchar_t* str) { + return bit_cast<const char16*>(str); +} + inline const char16* as_u16cstr(WStringPiece str) { return bit_cast<const char16*>(str.data()); }
diff --git a/base/task/sequence_manager/sequence_manager.h b/base/task/sequence_manager/sequence_manager.h index 5a0d4bda..5d6cf5f7 100644 --- a/base/task/sequence_manager/sequence_manager.h +++ b/base/task/sequence_manager/sequence_manager.h
@@ -90,23 +90,6 @@ // circumstances. The ownership of the pump is transferred to SequenceManager. virtual void BindToMessagePump(std::unique_ptr<MessagePump> message_pump) = 0; - // Initializes the SequenceManager on the bound thread. Should only be called - // once and only after the ThreadController's dependencies were initialized. - // Note that CreateSequenceManagerOnCurrentThread() performs this - // initialization automatically. - // - // TODO(eseckler): This currently needs to be separate from - // BindToCurrentThread() as it requires that the MessageLoop is bound - // (otherwise we can't add a NestingObserver), while BindToCurrentThread() - // requires that the MessageLoop has not yet been bound (binding the - // MessageLoop would fail if its TaskRunner, i.e. the default task queue, had - // not yet been bound). Reconsider this API once we get rid of MessageLoop. - virtual void CompleteInitializationOnBoundThread() = 0; - - // TODO(kraynov): Bring back CreateOnCurrentThread static method here - // when the move is done. It's not here yet to reduce PLATFORM_EXPORT - // macros hacking during the move. - // Must be called on the main thread. // Can be called only once, before creating TaskQueues. // Observer must outlive the SequenceManager. @@ -208,17 +191,11 @@ std::unique_ptr<MessagePump> message_pump, SequenceManager::Settings settings = SequenceManager::Settings()); -// Create a SequenceManager for a future thread using the provided MessageLoop. -// The SequenceManager can be initialized on the current thread and then needs -// to be bound and initialized on the target thread by calling -// BindToCurrentThread() and CompleteInitializationOnBoundThread() during the -// thread's startup. -// -// Implementation is located in sequence_manager_impl.cc. TODO(scheduler-dev): -// Remove when we get rid of MessageLoop. -// TODO(scheduler-dev): Change this to CreateUnboundSequenceManagerWithPump. +// Create an unbound SequenceManager (typically for a future thread or because +// additional setup is required before binding). The SequenceManager can be +// initialized on the current thread and then needs to be bound and initialized +// on the target thread by calling one of the Bind*() methods. BASE_EXPORT std::unique_ptr<SequenceManager> CreateUnboundSequenceManager( - MessageLoopBase* message_loop_base, SequenceManager::Settings settings = SequenceManager::Settings()); } // namespace sequence_manager
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc index 528269bb..aceea17 100644 --- a/base/task/sequence_manager/sequence_manager_impl.cc +++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -48,16 +48,14 @@ std::unique_ptr<MessagePump> message_pump, SequenceManager::Settings settings) { std::unique_ptr<SequenceManager> sequence_manager = - internal::SequenceManagerImpl::CreateUnboundWithPump(std::move(settings)); + internal::SequenceManagerImpl::CreateUnbound(std::move(settings)); sequence_manager->BindToMessagePump(std::move(message_pump)); return sequence_manager; } std::unique_ptr<SequenceManager> CreateUnboundSequenceManager( - MessageLoopBase* message_loop_base, SequenceManager::Settings settings) { - return internal::SequenceManagerImpl::CreateUnbound(message_loop_base, - std::move(settings)); + return internal::SequenceManagerImpl::CreateUnbound(std::move(settings)); } namespace internal { @@ -178,25 +176,17 @@ // static std::unique_ptr<SequenceManagerImpl> SequenceManagerImpl::CreateOnCurrentThread( SequenceManager::Settings settings) { - std::unique_ptr<SequenceManagerImpl> manager = - CreateUnbound(MessageLoopCurrent::Get()->ToMessageLoopBaseDeprecated(), - std::move(settings)); + MessageLoopBase* message_loop_base = + MessageLoopCurrent::Get()->ToMessageLoopBaseDeprecated(); + std::unique_ptr<SequenceManagerImpl> manager(new SequenceManagerImpl( + ThreadControllerImpl::Create(message_loop_base, settings.clock), + std::move(settings))); manager->BindToCurrentThread(); - manager->CompleteInitializationOnBoundThread(); return manager; } // static std::unique_ptr<SequenceManagerImpl> SequenceManagerImpl::CreateUnbound( - MessageLoopBase* message_loop_base, - SequenceManager::Settings settings) { - return WrapUnique(new SequenceManagerImpl( - ThreadControllerImpl::Create(message_loop_base, settings.clock), - std::move(settings))); -} - -// static -std::unique_ptr<SequenceManagerImpl> SequenceManagerImpl::CreateUnboundWithPump( SequenceManager::Settings settings) { return WrapUnique(new SequenceManagerImpl( ThreadControllerWithMessagePumpImpl::CreateUnbound(settings.clock), @@ -212,15 +202,22 @@ void SequenceManagerImpl::BindToMessagePump(std::unique_ptr<MessagePump> pump) { controller_->BindToCurrentThread(std::move(pump)); CompleteInitializationOnBoundThread(); + + // On Android attach to the native loop when there is one. +#if defined(OS_ANDROID) + if (type_ == TYPE_UI || type_ == TYPE_JAVA) + controller_->AttachToMessagePump(); +#endif } void SequenceManagerImpl::BindToCurrentThread() { associated_thread_->BindToCurrentThread(); + CompleteInitializationOnBoundThread(); } void SequenceManagerImpl::BindToCurrentThread( std::unique_ptr<MessagePump> pump) { - BindToCurrentThread(); + associated_thread_->BindToCurrentThread(); BindToMessagePump(std::move(pump)); } @@ -893,7 +890,7 @@ return controller_->IsTaskExecutionAllowed(); } -#if defined(OS_IOS) || defined(OS_ANDROID) +#if defined(OS_IOS) void SequenceManagerImpl::AttachToMessagePump() { return controller_->AttachToMessagePump(); }
diff --git a/base/task/sequence_manager/sequence_manager_impl.h b/base/task/sequence_manager/sequence_manager_impl.h index 88960047e..6c5c85f0 100644 --- a/base/task/sequence_manager/sequence_manager_impl.h +++ b/base/task/sequence_manager/sequence_manager_impl.h
@@ -89,26 +89,17 @@ static std::unique_ptr<SequenceManagerImpl> CreateOnCurrentThread( SequenceManager::Settings settings = SequenceManager::Settings()); - // Create a SequenceManager for a future thread that will run the provided - // MessageLoop. The SequenceManager can be initialized on the current thread - // and then needs to be bound and initialized on the target thread by calling - // BindToCurrentThread() and CompleteInitializationOnBoundThread() during the - // thread's startup. If |message_loop| is null then BindToMessageLoop() must - // be called instead of CompleteInitializationOnBoundThread. - // - // This function should be called only once per MessageLoop. + // Create an unbound SequenceManager (typically for a future thread). The + // SequenceManager can be initialized on the current thread and then needs to + // be bound and initialized on the target thread by calling one of the Bind*() + // methods. static std::unique_ptr<SequenceManagerImpl> CreateUnbound( - MessageLoopBase* message_loop_base, - SequenceManager::Settings settings = Settings()); - - static std::unique_ptr<SequenceManagerImpl> CreateUnboundWithPump( SequenceManager::Settings settings); // SequenceManager implementation: void BindToCurrentThread() override; void BindToMessageLoop(MessageLoopBase* message_loop_base) override; void BindToMessagePump(std::unique_ptr<MessagePump> message_pump) override; - void CompleteInitializationOnBoundThread() override; void SetObserver(Observer* observer) override; void AddTaskTimeObserver(TaskTimeObserver* task_time_observer) override; void RemoveTaskTimeObserver(TaskTimeObserver* task_time_observer) override; @@ -157,7 +148,7 @@ void SetAddQueueTimeToTasks(bool enable) override; void SetTaskExecutionAllowed(bool allowed) override; bool IsTaskExecutionAllowed() const override; -#if defined(OS_IOS) || defined(OS_ANDROID) +#if defined(OS_IOS) void AttachToMessagePump() override; #endif bool IsIdleForTesting() override; @@ -302,6 +293,8 @@ destruction_observers; }; + void CompleteInitializationOnBoundThread(); + // TaskQueueSelector::Observer: void OnTaskQueueEnabled(internal::TaskQueueImpl* queue) override;
diff --git a/base/task/sequence_manager/sequence_manager_impl_unittest.cc b/base/task/sequence_manager/sequence_manager_impl_unittest.cc index c0bfb66..4f58d43 100644 --- a/base/task/sequence_manager/sequence_manager_impl_unittest.cc +++ b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
@@ -3851,43 +3851,9 @@ } TEST_P(SequenceManagerTestWithCustomInitialization, - SequenceManagerCreatedBeforeMessageLoop) { - std::unique_ptr<SequenceManager> manager = - CreateUnboundSequenceManager(nullptr); - EXPECT_FALSE(static_cast<SequenceManagerImpl*>(manager.get()) - ->IsBoundToCurrentThread()); - manager->BindToCurrentThread(); - EXPECT_TRUE(static_cast<SequenceManagerImpl*>(manager.get()) - ->IsBoundToCurrentThread()); - scoped_refptr<TaskQueue> default_task_queue = - manager->CreateTaskQueueWithType<TestTaskQueue>( - TaskQueue::Spec("default")); - EXPECT_THAT(default_task_queue.get(), testing::NotNull()); - - std::unique_ptr<MessageLoop> message_loop(new MessageLoop()); - manager->BindToMessageLoop(message_loop->GetMessageLoopBase()); - - // Check that task posting works. - std::vector<EnqueueOrder> run_order; - default_task_queue->task_runner()->PostTask( - FROM_HERE, BindOnce(&TestTask, 1, &run_order)); - default_task_queue->task_runner()->PostTask( - FROM_HERE, BindOnce(&TestTask, 2, &run_order)); - default_task_queue->task_runner()->PostTask( - FROM_HERE, BindOnce(&TestTask, 3, &run_order)); - RunLoop().RunUntilIdle(); - - EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u)); - - // We must release the SequenceManager before the MessageLoop because - // SequenceManager assumes the MessageLoop outlives it. - manager.reset(); -} - -TEST_P(SequenceManagerTestWithCustomInitialization, CreateUnboundSequenceManagerWhichIsNeverBound) { // This should not crash. - CreateUnboundSequenceManager(nullptr); + CreateUnboundSequenceManager(); } TEST_P(SequenceManagerTest, HasPendingHighResolutionTasks) {
diff --git a/base/task/sequence_manager/test/sequence_manager_for_test.cc b/base/task/sequence_manager/test/sequence_manager_for_test.cc index 42e4921..69c141b1 100644 --- a/base/task/sequence_manager/test/sequence_manager_for_test.cc +++ b/base/task/sequence_manager/test/sequence_manager_for_test.cc
@@ -53,7 +53,6 @@ std::move(task_runner), clock), std::move(settings))); manager->BindToCurrentThread(); - manager->CompleteInitializationOnBoundThread(); return manager; } @@ -64,7 +63,6 @@ std::unique_ptr<SequenceManagerForTest> manager(new SequenceManagerForTest( std::move(thread_controller), std::move(settings))); manager->BindToCurrentThread(); - manager->CompleteInitializationOnBoundThread(); return manager; }
diff --git a/base/task/sequence_manager/time_domain_unittest.cc b/base/task/sequence_manager/time_domain_unittest.cc index 3e9dae1..af37be9 100644 --- a/base/task/sequence_manager/time_domain_unittest.cc +++ b/base/task/sequence_manager/time_domain_unittest.cc
@@ -389,7 +389,7 @@ constexpr auto kType = MessageLoop::TYPE_DEFAULT; constexpr auto kDelay = TimeDelta::FromMilliseconds(20); SimpleTestTickClock clock; - auto sequence_manager = internal::SequenceManagerImpl::CreateUnboundWithPump( + auto sequence_manager = sequence_manager::CreateUnboundSequenceManager( SequenceManager::Settings{.message_loop_type = kType, .clock = &clock}); sequence_manager->BindToMessagePump( MessageLoop::CreateMessagePumpForType(kType));
diff --git a/base/task/sequence_manager/work_queue_unittest.cc b/base/task/sequence_manager/work_queue_unittest.cc index 01a81060..f5c1471 100644 --- a/base/task/sequence_manager/work_queue_unittest.cc +++ b/base/task/sequence_manager/work_queue_unittest.cc
@@ -40,7 +40,8 @@ class WorkQueueTest : public testing::Test { public: void SetUp() override { - dummy_sequence_manager_ = SequenceManagerImpl::CreateUnbound(nullptr); + dummy_sequence_manager_ = + SequenceManagerImpl::CreateUnbound(SequenceManager::Settings{}); scoped_refptr<AssociatedThreadId> thread_checker = dummy_sequence_manager_->associated_thread(); thread_checker->BindToCurrentThread();
diff --git a/base/task/task_features.cc b/base/task/task_features.cc index 632d702..cf56afb 100644 --- a/base/task/task_features.cc +++ b/base/task/task_features.cc
@@ -11,8 +11,11 @@ const Feature kAllTasksUserBlocking{"AllTasksUserBlocking", FEATURE_DISABLED_BY_DEFAULT}; +// This experiment no longer has any impact, but remains enabled by default +// because script streamer depends on it. +// TODO(etiennep): Cleanup this experiment. const Feature kMergeBlockingNonBlockingPools = { - "MergeBlockingNonBlockingPools", base::FEATURE_DISABLED_BY_DEFAULT}; + "MergeBlockingNonBlockingPools", base::FEATURE_ENABLED_BY_DEFAULT}; const Feature kNoDetachBelowInitialCapacity = { "NoDetachBelowInitialCapacity", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/base/task/task_scheduler/environment_config.h b/base/task/task_scheduler/environment_config.h index 4ca8416..5280cd7a 100644 --- a/base/task/task_scheduler/environment_config.h +++ b/base/task/task_scheduler/environment_config.h
@@ -14,19 +14,18 @@ namespace base { namespace internal { +// TODO(etiennep): This is now specific to +// SchedulerSingleThreadTaskRunnerManager, move it there. enum EnvironmentType { FOREGROUND = 0, FOREGROUND_BLOCKING, - // Pools will only be created for the environment above on platforms that - // don't support SchedulerWorkers running with a background priority. - ENVIRONMENT_COUNT_WITHOUT_BACKGROUND_PRIORITY, - BACKGROUND = ENVIRONMENT_COUNT_WITHOUT_BACKGROUND_PRIORITY, + BACKGROUND, BACKGROUND_BLOCKING, ENVIRONMENT_COUNT // Always last. }; // Order must match the EnvironmentType enum. -constexpr struct { +struct EnvironmentParams { // The threads and histograms of this environment will be labeled with // the task scheduler name concatenated to this. const char* name_suffix; @@ -34,7 +33,9 @@ // Preferred priority for threads in this environment; the actual thread // priority depends on shutdown state and platform capabilities. ThreadPriority priority_hint; -} kEnvironmentParams[] = { +}; + +constexpr EnvironmentParams kEnvironmentParams[] = { {"Foreground", base::ThreadPriority::NORMAL}, {"ForegroundBlocking", base::ThreadPriority::NORMAL}, {"Background", base::ThreadPriority::BACKGROUND},
diff --git a/base/task/task_scheduler/task_scheduler.cc b/base/task/task_scheduler/task_scheduler.cc index d98a4f26..02c9297 100644 --- a/base/task/task_scheduler/task_scheduler.cc +++ b/base/task/task_scheduler/task_scheduler.cc
@@ -25,16 +25,10 @@ TaskScheduler::InitParams::InitParams( const SchedulerWorkerPoolParams& background_worker_pool_params_in, - const SchedulerWorkerPoolParams& background_blocking_worker_pool_params_in, const SchedulerWorkerPoolParams& foreground_worker_pool_params_in, - const SchedulerWorkerPoolParams& foreground_blocking_worker_pool_params_in, SharedWorkerPoolEnvironment shared_worker_pool_environment_in) : background_worker_pool_params(background_worker_pool_params_in), - background_blocking_worker_pool_params( - background_blocking_worker_pool_params_in), foreground_worker_pool_params(foreground_worker_pool_params_in), - foreground_blocking_worker_pool_params( - foreground_blocking_worker_pool_params_in), shared_worker_pool_environment(shared_worker_pool_environment_in) {} TaskScheduler::InitParams::~InitParams() = default; @@ -64,17 +58,15 @@ // * The main thread is assumed to be busy, cap foreground workers at // |num_cores - 1|. const int num_cores = SysInfo::NumberOfProcessors(); - constexpr int kBackgroundMaxThreads = 1; - constexpr int kBackgroundBlockingMaxThreads = 2; - const int kForegroundMaxThreads = std::max(1, num_cores - 1); - const int kForegroundBlockingMaxThreads = std::max(2, num_cores - 1); + + // TODO(etiennep): Change this to 2. + constexpr int kBackgroundMaxThreads = 3; + const int kForegroundMaxThreads = std::max(3, num_cores - 1); constexpr TimeDelta kSuggestedReclaimTime = TimeDelta::FromSeconds(30); Start({{kBackgroundMaxThreads, kSuggestedReclaimTime}, - {kBackgroundBlockingMaxThreads, kSuggestedReclaimTime}, - {kForegroundMaxThreads, kSuggestedReclaimTime}, - {kForegroundBlockingMaxThreads, kSuggestedReclaimTime}}); + {kForegroundMaxThreads, kSuggestedReclaimTime}}); } #endif // !defined(OS_NACL)
diff --git a/base/task/task_scheduler/task_scheduler.h b/base/task/task_scheduler/task_scheduler.h index 03cc1d9..63b776a 100644 --- a/base/task/task_scheduler/task_scheduler.h +++ b/base/task/task_scheduler/task_scheduler.h
@@ -64,19 +64,13 @@ InitParams( const SchedulerWorkerPoolParams& background_worker_pool_params_in, - const SchedulerWorkerPoolParams& - background_blocking_worker_pool_params_in, const SchedulerWorkerPoolParams& foreground_worker_pool_params_in, - const SchedulerWorkerPoolParams& - foreground_blocking_worker_pool_params_in, SharedWorkerPoolEnvironment shared_worker_pool_environment_in = SharedWorkerPoolEnvironment::DEFAULT); ~InitParams(); SchedulerWorkerPoolParams background_worker_pool_params; - SchedulerWorkerPoolParams background_blocking_worker_pool_params; SchedulerWorkerPoolParams foreground_worker_pool_params; - SchedulerWorkerPoolParams foreground_blocking_worker_pool_params; SharedWorkerPoolEnvironment shared_worker_pool_environment; };
diff --git a/base/task/task_scheduler/task_scheduler_impl.cc b/base/task/task_scheduler/task_scheduler_impl.cc index f1491c3..f483f47 100644 --- a/base/task/task_scheduler/task_scheduler_impl.cc +++ b/base/task/task_scheduler/task_scheduler_impl.cc
@@ -32,19 +32,11 @@ namespace { -// Returns worker pool EnvironmentType for given arguments |is_background| and -// |is_blocking|. -EnvironmentType GetEnvironmentIndex(bool is_background, bool is_blocking) { - if (is_background) { - if (is_blocking) - return BACKGROUND_BLOCKING; - return BACKGROUND; - } +constexpr EnvironmentParams kForegroundPoolEnvironmentParams{ + "Foreground", base::ThreadPriority::NORMAL}; - if (is_blocking) - return FOREGROUND_BLOCKING; - return FOREGROUND; -} +constexpr EnvironmentParams kBackgroundPoolEnvironmentParams{ + "Background", base::ThreadPriority::BACKGROUND}; } // namespace @@ -66,42 +58,22 @@ tracked_ref_factory_(this) { DCHECK(!histogram_label.empty()); - static_assert( - std::extent<decltype(environment_to_worker_pool_)>() == ENVIRONMENT_COUNT, - "The size of |environment_to_worker_pool_| must match " - "ENVIRONMENT_COUNT."); - static_assert( - size(kEnvironmentParams) == ENVIRONMENT_COUNT, - "The size of |kEnvironmentParams| must match ENVIRONMENT_COUNT."); + foreground_pool_.emplace( + JoinString( + {histogram_label, kForegroundPoolEnvironmentParams.name_suffix}, "."), + kForegroundPoolEnvironmentParams.name_suffix, + kForegroundPoolEnvironmentParams.priority_hint, + task_tracker_->GetTrackedRef(), tracked_ref_factory_.GetTrackedRef()); - int num_pools_to_create = CanUseBackgroundPriorityForSchedulerWorker() - ? ENVIRONMENT_COUNT - : ENVIRONMENT_COUNT_WITHOUT_BACKGROUND_PRIORITY; - for (int environment_type = 0; environment_type < num_pools_to_create; - ++environment_type) { - worker_pools_.emplace_back(std::make_unique<SchedulerWorkerPoolImpl>( + if (CanUseBackgroundPriorityForSchedulerWorker()) { + background_pool_.emplace( JoinString( - {histogram_label, kEnvironmentParams[environment_type].name_suffix}, + {histogram_label, kBackgroundPoolEnvironmentParams.name_suffix}, "."), - kEnvironmentParams[environment_type].name_suffix, - kEnvironmentParams[environment_type].priority_hint, - task_tracker_->GetTrackedRef(), tracked_ref_factory_.GetTrackedRef())); + kBackgroundPoolEnvironmentParams.name_suffix, + kBackgroundPoolEnvironmentParams.priority_hint, + task_tracker_->GetTrackedRef(), tracked_ref_factory_.GetTrackedRef()); } - - // Map environment indexes to pools. |kMergeBlockingNonBlockingPools| is - // assumed to be disabled. - environment_to_worker_pool_[FOREGROUND] = - worker_pools_[GetEnvironmentIndex(false, false)].get(); - environment_to_worker_pool_[FOREGROUND_BLOCKING] = - worker_pools_[GetEnvironmentIndex(false, true)].get(); - environment_to_worker_pool_[BACKGROUND] = - worker_pools_[GetEnvironmentIndex( - CanUseBackgroundPriorityForSchedulerWorker(), false)] - .get(); - environment_to_worker_pool_[BACKGROUND_BLOCKING] = - worker_pools_[GetEnvironmentIndex( - CanUseBackgroundPriorityForSchedulerWorker(), true)] - .get(); } TaskSchedulerImpl::~TaskSchedulerImpl() { @@ -109,8 +81,9 @@ DCHECK(join_for_testing_returned_.IsSet()); #endif - // Clear |worker_pools_| to release held TrackedRefs, which block teardown. - worker_pools_.clear(); + // Reset worker pools to release held TrackedRefs, which block teardown. + foreground_pool_.reset(); + background_pool_.reset(); } void TaskSchedulerImpl::Start( @@ -123,27 +96,6 @@ if (FeatureList::IsEnabled(kAllTasksUserBlocking)) all_tasks_user_blocking_.Set(); - const bool use_blocking_pools = - !base::FeatureList::IsEnabled(kMergeBlockingNonBlockingPools); - - // Remap environment indexes to pools with |use_blocking_pools|. - // TODO(etiennep): This is only necessary because of the - // kMergeBlockingNonBlockingPools experiment. Remove this after the - // experiment. - environment_to_worker_pool_[FOREGROUND] = - worker_pools_[GetEnvironmentIndex(false, false)].get(); - environment_to_worker_pool_[FOREGROUND_BLOCKING] = - worker_pools_[GetEnvironmentIndex(false, use_blocking_pools)].get(); - environment_to_worker_pool_[BACKGROUND] = - worker_pools_[GetEnvironmentIndex( - CanUseBackgroundPriorityForSchedulerWorker(), false)] - .get(); - environment_to_worker_pool_[BACKGROUND_BLOCKING] = - worker_pools_[GetEnvironmentIndex( - CanUseBackgroundPriorityForSchedulerWorker(), - use_blocking_pools)] - .get(); - // Start the service thread. On platforms that support it (POSIX except NaCL // SFI), the service thread runs a MessageLoopForIO which is used to support // FileDescriptorWatcher in the scope in which tasks run. @@ -188,32 +140,17 @@ const int max_best_effort_tasks_in_foreground_pool = std::max( 1, std::min(init_params.background_worker_pool_params.max_tasks(), init_params.foreground_worker_pool_params.max_tasks() / 2)); - worker_pools_[FOREGROUND]->Start( - init_params.foreground_worker_pool_params, - max_best_effort_tasks_in_foreground_pool, service_thread_task_runner, - scheduler_worker_observer, worker_environment); - const int max_best_effort_tasks_in_foreground_blocking_pool = std::max( - 1, - std::min( - init_params.background_blocking_worker_pool_params.max_tasks(), - init_params.foreground_blocking_worker_pool_params.max_tasks() / 2)); - worker_pools_[FOREGROUND_BLOCKING]->Start( - init_params.foreground_blocking_worker_pool_params, - max_best_effort_tasks_in_foreground_blocking_pool, - service_thread_task_runner, scheduler_worker_observer, - worker_environment); + foreground_pool_->Start(init_params.foreground_worker_pool_params, + max_best_effort_tasks_in_foreground_pool, + service_thread_task_runner, scheduler_worker_observer, + worker_environment); - if (CanUseBackgroundPriorityForSchedulerWorker()) { - worker_pools_[BACKGROUND]->Start( + if (background_pool_.has_value()) { + background_pool_->Start( init_params.background_worker_pool_params, init_params.background_worker_pool_params.max_tasks(), service_thread_task_runner, scheduler_worker_observer, worker_environment); - worker_pools_[BACKGROUND_BLOCKING]->Start( - init_params.background_blocking_worker_pool_params, - init_params.background_blocking_worker_pool_params.max_tasks(), - service_thread_task_runner, scheduler_worker_observer, - worker_environment); } } @@ -268,8 +205,9 @@ std::vector<const HistogramBase*> TaskSchedulerImpl::GetHistograms() const { std::vector<const HistogramBase*> histograms; - for (const auto& worker_pool : worker_pools_) - worker_pool->GetHistograms(&histograms); + foreground_pool_->GetHistograms(&histograms); + if (background_pool_.has_value()) + background_pool_->GetHistograms(&histograms); return histograms; } @@ -305,8 +243,9 @@ // https://crbug.com/771701. service_thread_->Stop(); single_thread_task_runner_manager_.JoinForTesting(); - for (const auto& worker_pool : worker_pools_) - worker_pool->JoinForTesting(); + foreground_pool_->JoinForTesting(); + if (background_pool_.has_value()) + background_pool_->JoinForTesting(); #if DCHECK_IS_ON() join_for_testing_returned_.Set(); #endif @@ -385,8 +324,12 @@ } SchedulerWorkerPoolImpl* TaskSchedulerImpl::GetWorkerPoolImplForTraits( - const TaskTraits& traits) const { - return environment_to_worker_pool_[GetEnvironmentIndexForTraits(traits)]; + const TaskTraits& traits) { + if (traits.priority() == TaskPriority::BEST_EFFORT && + background_pool_.has_value()) { + return &background_pool_.value(); + } + return &foreground_pool_.value(); } SchedulerWorkerPool* TaskSchedulerImpl::GetWorkerPoolForTraits( @@ -402,9 +345,9 @@ } void TaskSchedulerImpl::ReportHeartbeatMetrics() const { - for (const auto& worker_pool : worker_pools_) - worker_pool->ReportHeartbeatMetrics(); - delayed_task_manager_.ReportHeartbeatMetrics(); + foreground_pool_->ReportHeartbeatMetrics(); + if (background_pool_.has_value()) + background_pool_->ReportHeartbeatMetrics(); } } // namespace internal
diff --git a/base/task/task_scheduler/task_scheduler_impl.h b/base/task/task_scheduler/task_scheduler_impl.h index ab4152f..2528653 100644 --- a/base/task/task_scheduler/task_scheduler_impl.h +++ b/base/task/task_scheduler/task_scheduler_impl.h
@@ -103,8 +103,12 @@ // TODO(fdoray): Move all methods used by TaskSchedulerImpl to the // SchedulerWorkerPool interface and remove the SchedulerWorkerPool*Impl* // accessors. - SchedulerWorkerPoolImpl* GetWorkerPoolImplForTraits( - const TaskTraits& traits) const; + SchedulerWorkerPoolImpl* GetWorkerPoolImplForTraits(const TaskTraits& traits); + const SchedulerWorkerPoolImpl* GetWorkerPoolImplForTraits( + const TaskTraits& traits) const { + return const_cast<TaskSchedulerImpl*>(this)->GetWorkerPoolImplForTraits( + traits); + } // Returns |traits|, with priority set to TaskPriority::USER_BLOCKING if // |all_tasks_user_blocking_| is set. @@ -136,12 +140,8 @@ // TODO(fdoray): Remove after experiment. https://crbug.com/757022 AtomicFlag all_tasks_user_blocking_; - // Owns all the pools managed by this TaskScheduler. - std::vector<std::unique_ptr<SchedulerWorkerPoolImpl>> worker_pools_; - - // Maps an environment from EnvironmentType to a pool in |worker_pools_|. - SchedulerWorkerPoolImpl* environment_to_worker_pool_[static_cast<int>( - EnvironmentType::ENVIRONMENT_COUNT)]; + Optional<SchedulerWorkerPoolImpl> foreground_pool_; + Optional<SchedulerWorkerPoolImpl> background_pool_; #if DCHECK_IS_ON() // Set once JoinForTesting() has returned.
diff --git a/base/task/task_scheduler/task_scheduler_impl_unittest.cc b/base/task/task_scheduler/task_scheduler_impl_unittest.cc index 9d78749a..0e7388bf 100644 --- a/base/task/task_scheduler/task_scheduler_impl_unittest.cc +++ b/base/task/task_scheduler/task_scheduler_impl_unittest.cc
@@ -59,11 +59,6 @@ namespace { -enum class PoolConfiguration { - kDefault, - kMergeBlockingNonBlocking, -}; - enum class SchedulerState { // TaskScheduler::Start() was not called yet, no thread was created. kBeforeSchedulerStart, @@ -73,15 +68,11 @@ struct TaskSchedulerImplTestParams { TaskSchedulerImplTestParams(const TaskTraits& traits, - test::ExecutionMode execution_mode, - PoolConfiguration pool_config) - : traits(traits), - execution_mode(execution_mode), - pool_config(pool_config) {} + test::ExecutionMode execution_mode) + : traits(traits), execution_mode(execution_mode) {} TaskTraits traits; test::ExecutionMode execution_mode; - PoolConfiguration pool_config; }; #if DCHECK_IS_ON() @@ -130,15 +121,10 @@ ? "Background" : "Foreground")); } - // TaskScheduler only handles |kMergeBlockingNonBlockingPools| once started - // (early task runners are not merged for this experiment). - // TODO(etiennep): Simplify this after the experiment. - // Merging pools does not affect SingleThread workers. - if (base::FeatureList::IsEnabled(kMergeBlockingNonBlockingPools) && - state == SchedulerState::kAfterSchedulerStart && - current_thread_name.find("SingleThread") == std::string::npos) { + if (current_thread_name.find("SingleThread") == std::string::npos) { EXPECT_EQ(std::string::npos, current_thread_name.find("Blocking")); } else { + // SingleThread workers discriminate blocking/non-blocking tasks. EXPECT_EQ(traits.may_block(), current_thread_name.find("Blocking") != std::string::npos); } @@ -243,17 +229,9 @@ priority_index <= static_cast<size_t>(TaskPriority::HIGHEST); ++priority_index) { const TaskPriority priority = static_cast<TaskPriority>(priority_index); - params.push_back(TaskSchedulerImplTestParams( - {priority}, execution_mode, PoolConfiguration::kDefault)); - params.push_back(TaskSchedulerImplTestParams( - {MayBlock()}, execution_mode, PoolConfiguration::kDefault)); - - params.push_back(TaskSchedulerImplTestParams( - {priority}, execution_mode, - PoolConfiguration::kMergeBlockingNonBlocking)); - params.push_back(TaskSchedulerImplTestParams( - {MayBlock()}, execution_mode, - PoolConfiguration::kMergeBlockingNonBlocking)); + params.push_back(TaskSchedulerImplTestParams({priority}, execution_mode)); + params.push_back( + TaskSchedulerImplTestParams({priority, MayBlock()}, execution_mode)); } } @@ -263,17 +241,10 @@ class TaskSchedulerImplTest : public testing::TestWithParam<TaskSchedulerImplTestParams> { protected: - TaskSchedulerImplTest() : scheduler_("Test") { - feature_list_.emplace(); - feature_list_->InitWithFeatures(GetFeaturesEnabledByConstructor(), {}); - } + TaskSchedulerImplTest() : scheduler_("Test") {} void EnableAllTasksUserBlocking() { - feature_list_.reset(); - feature_list_.emplace(); - std::vector<Feature> enabled_features = GetFeaturesEnabledByConstructor(); - enabled_features.push_back(kAllTasksUserBlocking); - feature_list_->InitWithFeatures(enabled_features, {}); + feature_list_.InitWithFeatures({kAllTasksUserBlocking}, {}); } void set_scheduler_worker_observer( @@ -283,14 +254,10 @@ void StartTaskScheduler(TimeDelta reclaim_time = TimeDelta::FromSeconds(30)) { constexpr int kMaxNumBackgroundThreads = 1; - constexpr int kMaxNumBackgroundBlockingThreads = 3; constexpr int kMaxNumForegroundThreads = 4; - constexpr int kMaxNumForegroundBlockingThreads = 12; scheduler_.Start({{kMaxNumBackgroundThreads, reclaim_time}, - {kMaxNumBackgroundBlockingThreads, reclaim_time}, - {kMaxNumForegroundThreads, reclaim_time}, - {kMaxNumForegroundBlockingThreads, reclaim_time}}, + {kMaxNumForegroundThreads, reclaim_time}}, scheduler_worker_observer_); } @@ -306,14 +273,7 @@ TaskSchedulerImpl scheduler_; private: - std::vector<Feature> GetFeaturesEnabledByConstructor() { - if (GetParam().pool_config == PoolConfiguration::kMergeBlockingNonBlocking) - return {kMergeBlockingNonBlockingPools}; - else - return {}; - } - - Optional<base::test::ScopedFeatureList> feature_list_; + base::test::ScopedFeatureList feature_list_; SchedulerWorkerObserver* scheduler_worker_observer_ = nullptr; bool did_tear_down_ = false; @@ -513,7 +473,7 @@ // TaskTraits and ExecutionModes. Verifies that each Task runs on a thread with // the expected priority and I/O restrictions and respects the characteristics // of its ExecutionMode. -TEST_P(TaskSchedulerImplTest, MultipleTaskSchedulerImplTestParams) { +TEST_F(TaskSchedulerImplTest, MultipleTaskSchedulerImplTestParams) { StartTaskScheduler(); std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; for (const auto& test_params : GetTaskSchedulerImplTestParams()) { @@ -529,7 +489,7 @@ } } -TEST_P(TaskSchedulerImplTest, +TEST_F(TaskSchedulerImplTest, GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated) { StartTaskScheduler(); @@ -545,32 +505,19 @@ {MayBlock(), TaskPriority::BEST_EFFORT}); }); - if (GetParam().pool_config == PoolConfiguration::kMergeBlockingNonBlocking) { - EXPECT_EQ(4, scheduler_.GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated( - {TaskPriority::USER_VISIBLE})); - EXPECT_EQ(4, scheduler_.GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated( - {MayBlock(), TaskPriority::USER_VISIBLE})); - EXPECT_EQ(4, scheduler_.GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated( - {TaskPriority::USER_BLOCKING})); - EXPECT_EQ(4, scheduler_.GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated( - {MayBlock(), TaskPriority::USER_BLOCKING})); - } else { - EXPECT_EQ(4, scheduler_.GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated( - {TaskPriority::USER_VISIBLE})); - EXPECT_EQ(12, - scheduler_.GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated( - {MayBlock(), TaskPriority::USER_VISIBLE})); - EXPECT_EQ(4, scheduler_.GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated( - {TaskPriority::USER_BLOCKING})); - EXPECT_EQ(12, - scheduler_.GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated( - {MayBlock(), TaskPriority::USER_BLOCKING})); - } + EXPECT_EQ(4, scheduler_.GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated( + {TaskPriority::USER_VISIBLE})); + EXPECT_EQ(4, scheduler_.GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated( + {MayBlock(), TaskPriority::USER_VISIBLE})); + EXPECT_EQ(4, scheduler_.GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated( + {TaskPriority::USER_BLOCKING})); + EXPECT_EQ(4, scheduler_.GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated( + {MayBlock(), TaskPriority::USER_BLOCKING})); } // Verify that the RunsTasksInCurrentSequence() method of a SequencedTaskRunner // returns false when called from a task that isn't part of the sequence. -TEST_P(TaskSchedulerImplTest, SequencedRunsTasksInCurrentSequence) { +TEST_F(TaskSchedulerImplTest, SequencedRunsTasksInCurrentSequence) { StartTaskScheduler(); auto single_thread_task_runner = scheduler_.CreateSingleThreadTaskRunnerWithTraits( @@ -594,7 +541,7 @@ // Verify that the RunsTasksInCurrentSequence() method of a // SingleThreadTaskRunner returns false when called from a task that isn't part // of the sequence. -TEST_P(TaskSchedulerImplTest, SingleThreadRunsTasksInCurrentSequence) { +TEST_F(TaskSchedulerImplTest, SingleThreadRunsTasksInCurrentSequence) { StartTaskScheduler(); auto sequenced_task_runner = scheduler_.CreateSequencedTaskRunnerWithTraits(TaskTraits()); @@ -617,7 +564,7 @@ } #if defined(OS_WIN) -TEST_P(TaskSchedulerImplTest, COMSTATaskRunnersRunWithCOMSTA) { +TEST_F(TaskSchedulerImplTest, COMSTATaskRunnersRunWithCOMSTA) { StartTaskScheduler(); auto com_sta_task_runner = scheduler_.CreateCOMSTATaskRunnerWithTraits( TaskTraits(), SingleThreadTaskRunnerThreadMode::SHARED); @@ -634,7 +581,7 @@ } #endif // defined(OS_WIN) -TEST_P(TaskSchedulerImplTest, DelayedTasksNotRunAfterShutdown) { +TEST_F(TaskSchedulerImplTest, DelayedTasksNotRunAfterShutdown) { StartTaskScheduler(); // As with delayed tasks in general, this is racy. If the task does happen to // run after Shutdown within the timeout, it will fail this test. @@ -657,7 +604,7 @@ #if defined(OS_POSIX) -TEST_P(TaskSchedulerImplTest, FileDescriptorWatcherNoOpsAfterShutdown) { +TEST_F(TaskSchedulerImplTest, FileDescriptorWatcherNoOpsAfterShutdown) { StartTaskScheduler(); int pipes[2]; @@ -704,7 +651,7 @@ // Verify that tasks posted on the same sequence access the same values on // SequenceLocalStorage, and tasks on different sequences see different values. -TEST_P(TaskSchedulerImplTest, SequenceLocalStorage) { +TEST_F(TaskSchedulerImplTest, SequenceLocalStorage) { StartTaskScheduler(); SequenceLocalStorageSlot<int> slot; @@ -735,7 +682,7 @@ scheduler_.FlushForTesting(); } -TEST_P(TaskSchedulerImplTest, FlushAsyncNoTasks) { +TEST_F(TaskSchedulerImplTest, FlushAsyncNoTasks) { StartTaskScheduler(); bool called_back = false; scheduler_.FlushAsyncForTesting( @@ -779,7 +726,7 @@ // Integration test that verifies that workers have a frame on their stacks // which easily identifies the type of worker and shutdown behavior (useful to // diagnose issues from logs without memory dumps). -TEST_P(TaskSchedulerImplTest, MAYBE_IdentifiableStacks) { +TEST_F(TaskSchedulerImplTest, MAYBE_IdentifiableStacks) { StartTaskScheduler(); // Shutdown behaviors and expected stack frames. @@ -859,14 +806,14 @@ scheduler_.FlushForTesting(); } -TEST_P(TaskSchedulerImplTest, SchedulerWorkerObserver) { +TEST_F(TaskSchedulerImplTest, SchedulerWorkerObserver) { testing::StrictMock<test::MockSchedulerWorkerObserver> observer; set_scheduler_worker_observer(&observer); // A worker should be created for each pool. After that, 4 threads should be // created for each SingleThreadTaskRunnerThreadMode (8 on Windows). const int kExpectedNumPoolWorkers = - CanUseBackgroundPriorityForSchedulerWorker() ? 4 : 2; + CanUseBackgroundPriorityForSchedulerWorker() ? 2 : 1; #if defined(OS_WIN) const int kExpectedNumSingleThreadedWorkersPerMode = 8; #else @@ -984,8 +931,6 @@ constexpr TimeDelta kSuggestedReclaimTime = TimeDelta::FromSeconds(30); scheduler_.Start({{threads_per_pool, kSuggestedReclaimTime}, - {threads_per_pool, kSuggestedReclaimTime}, - {threads_per_pool, kSuggestedReclaimTime}, {threads_per_pool, kSuggestedReclaimTime}}, nullptr); } @@ -1043,13 +988,9 @@ pool_blocking_events.push_back(std::make_unique<PoolBlockingEvents>( TaskTraits({TaskPriority::USER_BLOCKING}))); - pool_blocking_events.push_back(std::make_unique<PoolBlockingEvents>( - TaskTraits({TaskPriority::USER_BLOCKING, MayBlock()}))); if (CanUseBackgroundPriorityForSchedulerWorker()) { pool_blocking_events.push_back(std::make_unique<PoolBlockingEvents>( TaskTraits({TaskPriority::BEST_EFFORT}))); - pool_blocking_events.push_back(std::make_unique<PoolBlockingEvents>( - TaskTraits({TaskPriority::BEST_EFFORT, MayBlock()}))); } // When all blocking tasks signal |scheduled|, there is a task blocked in @@ -1096,10 +1037,6 @@ for (auto& task_runner_and_events : task_runners_and_events_) { test::WaitWithoutBlockingObserver(&task_runner_and_events->task_ran); } - - // Make sure to coalesce tasks from |pool_blocking_events| (they are not - // guaranteed to all have picked up the Signal() to unblock at this point). - scheduler_.FlushForTesting(); } // Update the priority of a sequence when it is scheduled, i.e. not currently
diff --git a/base/task/task_scheduler/task_scheduler_perftest.cc b/base/task/task_scheduler/task_scheduler_perftest.cc index b83cffd..5976687f 100644 --- a/base/task/task_scheduler/task_scheduler_perftest.cc +++ b/base/task/task_scheduler/task_scheduler_perftest.cc
@@ -122,14 +122,10 @@ base::RepeatingClosure post_action) { constexpr TimeDelta kSuggestedReclaimTime = TimeDelta::FromSeconds(30); constexpr int kMaxNumBackgroundThreads = 1; - constexpr int kMaxNumBackgroundBlockingThreads = 1; - constexpr int kMaxNumForegroundBlockingThreads = 1; TaskScheduler::GetInstance()->Start( {{kMaxNumBackgroundThreads, kSuggestedReclaimTime}, - {kMaxNumBackgroundBlockingThreads, kSuggestedReclaimTime}, - {num_running_threads, kSuggestedReclaimTime}, - {kMaxNumForegroundBlockingThreads, kSuggestedReclaimTime}}, + {num_running_threads, kSuggestedReclaimTime}}, nullptr); base::RepeatingClosure done = BarrierClosure(
diff --git a/base/test/BUILD.gn b/base/test/BUILD.gn index dea5aa2b..7c3632a 100644 --- a/base/test/BUILD.gn +++ b/base/test/BUILD.gn
@@ -93,7 +93,6 @@ "perf_time_logger.h", "power_monitor_test_base.cc", "power_monitor_test_base.h", - "reached_code_profiler_android.cc", "scoped_command_line.cc", "scoped_command_line.h", "scoped_environment_variable_override.cc", @@ -436,7 +435,6 @@ sources = [ "android/java/src/org/chromium/base/MainReturnCodeResult.java", "android/java/src/org/chromium/base/MultiprocessTestClientLauncher.java", - "android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java", "android/javatests/src/org/chromium/base/test/task/TaskSchedulerTestHelpers.java", "android/javatests/src/org/chromium/base/test/util/UrlUtils.java", ]
diff --git a/base/test/android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java b/base/test/android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java deleted file mode 100644 index 1b1a5c0e..0000000 --- a/base/test/android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2019 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.base.test; - -import org.chromium.base.annotations.JNINamespace; - -/** - * Class containing only static methods for querying the status of the reached code profiler. - */ -@JNINamespace("base::android") -public class ReachedCodeProfiler { - private ReachedCodeProfiler() {} - - /** - * @return Whether the reached code profiler is enabled. - */ - public static boolean isEnabled() { - return nativeIsReachedCodeProfilerEnabled(); - } - - /** - * @return Whether the currently used version of native library supports the reached code - * profiler. - */ - public static boolean isSupported() { - return nativeIsReachedCodeProfilerSupported(); - } - - private static native boolean nativeIsReachedCodeProfilerEnabled(); - private static native boolean nativeIsReachedCodeProfilerSupported(); -}
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index 206064ba..a25bec59 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc
@@ -139,18 +139,14 @@ void CreateAndStartTaskScheduler(int num_parallel_jobs) { // These values are taken from TaskScheduler::StartWithDefaultParams(), which // is not used directly to allow a custom number of threads in the foreground - // blocking pool. - constexpr int kMaxBackgroundThreads = 1; - constexpr int kMaxBackgroundBlockingThreads = 2; - const int max_foreground_threads = - std::max(1, base::SysInfo::NumberOfProcessors()); + // pool. + // TODO(etiennep): Change this to 2 in future CL. + constexpr int kMaxBackgroundThreads = 3; constexpr base::TimeDelta kSuggestedReclaimTime = base::TimeDelta::FromSeconds(30); base::TaskScheduler::Create("TestLauncher"); base::TaskScheduler::GetInstance()->Start( {{kMaxBackgroundThreads, kSuggestedReclaimTime}, - {kMaxBackgroundBlockingThreads, kSuggestedReclaimTime}, - {max_foreground_threads, kSuggestedReclaimTime}, {num_parallel_jobs, kSuggestedReclaimTime}}); }
diff --git a/base/test/reached_code_profiler_android.cc b/base/test/reached_code_profiler_android.cc deleted file mode 100644 index 2def7fc..0000000 --- a/base/test/reached_code_profiler_android.cc +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/android/jni_android.h" -#include "base/android/reached_code_profiler.h" -#include "jni/ReachedCodeProfiler_jni.h" - -// This file provides functions to query the state of the reached code profiler -// from Java. It's used only for tests. -namespace base { -namespace android { - -static jboolean JNI_ReachedCodeProfiler_IsReachedCodeProfilerEnabled( - JNIEnv* env) { - return IsReachedCodeProfilerEnabled(); -} - -static jboolean JNI_ReachedCodeProfiler_IsReachedCodeProfilerSupported( - JNIEnv* env) { - return IsReachedCodeProfilerSupported(); -} - -} // namespace android -} // namespace base
diff --git a/base/test/scoped_task_environment.cc b/base/test/scoped_task_environment.cc index 75331ca..58fc2a1 100644 --- a/base/test/scoped_task_environment.cc +++ b/base/test/scoped_task_environment.cc
@@ -334,15 +334,10 @@ CHECK(base::ThreadTaskRunnerHandle::IsSet()) << "ThreadTaskRunnerHandle should've been set now."; - // Instantiate a TaskScheduler with 2 threads in each of its 4 pools. Threads - // stay alive even when they don't have work. - // Each pool uses two threads to prevent deadlocks in unit tests that have a - // sequence that uses WithBaseSyncPrimitives() to wait on the result of - // another sequence. This isn't perfect (doesn't solve wait chains) but solves - // the basic use case for now. - // TODO(fdoray/jeffreyhe): Make the TaskScheduler dynamically replace blocked - // threads and get rid of this limitation. http://crbug.com/738104 - constexpr int kMaxThreads = 2; + // Instantiate a TaskScheduler with 4 workers per pool. Having multiple threads + // prevents deadlocks should some blocking APIs not use ScopedBlockingCall. It also + // allows enough concurrency to allow TSAN to spot data races. + constexpr int kMaxThreads = 4; const TimeDelta kSuggestedReclaimTime = TimeDelta::Max(); const SchedulerWorkerPoolParams worker_pool_params(kMaxThreads, kSuggestedReclaimTime); @@ -350,8 +345,7 @@ "ScopedTaskEnvironment", WrapUnique(task_tracker_))); task_scheduler_ = TaskScheduler::GetInstance(); TaskScheduler::GetInstance()->Start({ - worker_pool_params, worker_pool_params, worker_pool_params, - worker_pool_params + worker_pool_params, worker_pool_params #if defined(OS_WIN) , // Enable the MTA in unit tests to match the browser process'
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 27460e0..44ad8773 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -235,6 +235,7 @@ ":document_tab_model_info_proto_java", ":partner_location_descriptor_proto_java", ":thumbnail_cache_entry_proto_java", + ":usage_stats_proto_java", "$google_play_services_package:google_play_services_auth_base_java", "$google_play_services_package:google_play_services_base_java", "$google_play_services_package:google_play_services_basement_java", @@ -489,6 +490,13 @@ ] } +proto_java_library("usage_stats_proto_java") { + proto_path = "../browser/android/usage_stats" + sources = [ + "$proto_path/website_event.proto", + ] +} + java_cpp_template("resource_id_javagen") { sources = [ "java/ResourceId.template", @@ -698,6 +706,7 @@ "//third_party/android_deps:android_support_design_java", "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:android_support_v7_recyclerview_java", + "//third_party/android_deps:com_google_ar_core_java", "//third_party/android_deps:com_google_protobuf_protobuf_lite_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java",
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedConfiguration.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedConfiguration.java index d2187b5..d4388ab 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedConfiguration.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedConfiguration.java
@@ -34,6 +34,10 @@ /** Default value for feed server response length prefixed. */ public static final boolean FEED_SERVER_RESPONSE_LENGTH_PREFIXED_DEFAULT = true; + private static final String FEED_UI_ENABLED = "feed_ui_enabled"; + /** Default value for the type of UI to request from the server. */ + public static final boolean FEED_UI_ENABLED_DEFAULT = false; + private static final String INITIAL_NON_CACHED_PAGE_SIZE = "initial_non_cached_page_size"; /** Default value for initial non cached page size. */ public static final int INITIAL_NON_CACHED_PAGE_SIZE_DEFAULT = 10; @@ -59,6 +63,10 @@ /** Default value for triggering immediate pagination. */ public static final boolean TRIGGER_IMMEDIATE_PAGINATION_DEFAULT = false; + private static final String USE_SECONDARY_PAGE_REQUEST = "use_secondary_page_request"; + /** Default value for pagination behavior. */ + public static final boolean USE_SECONDARY_PAGE_REQUEST_DEFAULT = false; + private static final String USE_TIMEOUT_SCHEDULER = "use_timeout_scheduler"; /** Default value for the type of scheduler handling. */ public static final boolean USE_TIMEOUT_SCHEDULER_DEFAULT = true; @@ -91,6 +99,14 @@ FEED_SERVER_RESPONSE_LENGTH_PREFIXED, FEED_SERVER_RESPONSE_LENGTH_PREFIXED_DEFAULT); } + /** @return Whether to ask the server for "Feed" UI or just basic UI. */ + @VisibleForTesting + static boolean getFeedUiEnabled() { + return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( + ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, FEED_UI_ENABLED, + FEED_UI_ENABLED_DEFAULT); + } + /** @return Used to decide where to place the more button initially. */ static int getInitialNonCachedPageSize() { return ChromeFeatureList.getFieldTrialParamByFeatureAsInt( @@ -154,6 +170,17 @@ USE_TIMEOUT_SCHEDULER_DEFAULT); } + /** + * @return If secondary (a more intuitive) pagination approach should be used, or the original + * Zine matching behavior should be used. + */ + @VisibleForTesting + static boolean getUseSecondaryPageRequest() { + return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( + ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, USE_SECONDARY_PAGE_REQUEST, + USE_SECONDARY_PAGE_REQUEST_DEFAULT); + } + /** @return How much of a card must be on screen to generate a UMA log view. */ @VisibleForTesting static double getViewLogThreshold() { @@ -171,6 +198,7 @@ .put(ConfigKey.FEED_SERVER_METHOD, FeedConfiguration.getFeedServerMethod()) .put(ConfigKey.FEED_SERVER_RESPONSE_LENGTH_PREFIXED, FeedConfiguration.getFeedServerResponseLengthPrefixed()) + .put(ConfigKey.FEED_UI_ENABLED, FeedConfiguration.getFeedUiEnabled()) .put(ConfigKey.INITIAL_NON_CACHED_PAGE_SIZE, FeedConfiguration.getInitialNonCachedPageSize()) .put(ConfigKey.LOGGING_IMMEDIATE_CONTENT_THRESHOLD_MS, @@ -182,6 +210,8 @@ .put(ConfigKey.TRIGGER_IMMEDIATE_PAGINATION, FeedConfiguration.getTriggerImmediatePagination()) .put(ConfigKey.USE_TIMEOUT_SCHEDULER, FeedConfiguration.getUseTimeoutScheduler()) + .put(ConfigKey.USE_SECONDARY_PAGE_REQUEST, + FeedConfiguration.getUseSecondaryPageRequest()) .put(ConfigKey.VIEW_LOG_THRESHOLD, FeedConfiguration.getViewLogThreshold()) .build(); }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java index d6a57fc5..664afbce 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java
@@ -364,7 +364,7 @@ mSectionHeaderView, mUiConfig, mDefaultMargin, mWideMargin); View view = mStream.getView(); - view.setBackgroundColor(Color.WHITE); + view.setBackgroundResource(R.color.modern_primary_color); mRootView.addView(view); UiUtils.removeViewFromParent(mNewTabPageLayout);
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index dca67fac..64644e3 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -139,6 +139,8 @@ android:networkSecurityConfig="@xml/network_security_config" {% block extra_application_attributes %}{% endblock %}> + <meta-data android:name="android.allow_multiple_resumed_activities" android:value="true" /> + <!-- Samsung MultiWindow Support --> <meta-data android:name="com.samsung.android.sdk.multiwindow.enable" android:value="true" /> @@ -177,6 +179,13 @@ manifest entries. --> <meta-data android:name="com.google.ar.core.min_apk_version" android:value="181012000"/> + <activity + android:name="com.google.ar.core.InstallActivity" + android:configChanges="keyboardHidden|orientation|screenSize" + android:excludeFromRecents="true" + android:exported="false" + android:launchMode="singleTop" + android:theme="@android:style/Theme.Material.Light.Dialog.Alert" /> {% endif %} <!-- Cast support --> @@ -337,7 +346,7 @@ <!-- Upgrade related --> <activity android:name="org.chromium.chrome.browser.upgrade.UpgradeActivity" android:excludeFromRecents="true" - android:theme="@style/MainTheme" + android:theme="@style/Theme.Chromium.Activity" android:windowSoftInputMode="adjustResize" android:taskAffinity="" android:launchMode="singleInstance" @@ -366,7 +375,7 @@ <!-- Document mode Activities. --> <activity android:name="org.chromium.chrome.browser.document.DocumentActivity" android:exported="false" - android:theme="@style/MainTheme" + android:theme="@style/Theme.Chromium.Activity" android:taskAffinity="" android:persistableMode="persistAcrossReboots" android:autoRemoveFromRecents="false" @@ -379,7 +388,7 @@ <activity android:name="org.chromium.chrome.browser.document.IncognitoDocumentActivity" android:icon="@mipmap/incognito_app_icon" android:exported="false" - android:theme="@style/IncognitoTheme" + android:theme="@style/Theme.Chromium.Incognito" android:taskAffinity="" android:persistableMode="persistNever" android:autoRemoveFromRecents="false" @@ -392,7 +401,7 @@ <!-- Custom Tabs --> <activity android:name="org.chromium.chrome.browser.customtabs.CustomTabActivity" - android:theme="@style/MainTheme" + android:theme="@style/Theme.Chromium.Activity" android:exported="false" {{ self.chrome_activity_common() }} {{ self.supports_video_persistence() }} @@ -401,7 +410,7 @@ {{ self.extra_web_rendering_activity_definitions() }} </activity> <activity android:name="org.chromium.chrome.browser.customtabs.PaymentHandlerActivity" - android:theme="@style/TranslucentMainTheme" + android:theme="@style/Theme.Chromium.Activity.Translucent" android:exported="false" {{ self.chrome_activity_common() }} {{ self.supports_video_persistence() }} @@ -415,7 +424,7 @@ TODO(arthursonzogni, tedchoc): Enabled this only on Android < 21 after M74. --> <activity android:name="org.chromium.chrome.browser.customtabs.SeparateTaskCustomTabActivity" - android:theme="@style/MainTheme" + android:theme="@style/Theme.Chromium.Activity" android:exported="false" android:taskAffinity="" android:persistableMode="persistNever" @@ -429,7 +438,7 @@ {% if min_sdk_version|int < 21 %} {% for i in range(10) %} <activity android:name="org.chromium.chrome.browser.customtabs.SeparateTaskCustomTabActivity{{ i }}" - android:theme="@style/MainTheme" + android:theme="@style/Theme.Chromium.Activity" android:icon="@mipmap/app_single_page_icon" android:exported="false" android:launchMode="singleTask" @@ -445,13 +454,13 @@ {% endif %} <activity android:name="org.chromium.chrome.browser.incognito.IncognitoDisclosureActivity" - android:theme="@style/FullscreenTransparentActivityTheme" + android:theme="@style/Theme.Chromium.Activity.Fullscreen.Transparent" android:exported="false"> </activity> <!-- ChromeTabbedActivity related --> <activity android:name="org.chromium.chrome.browser.ChromeTabbedActivity" - android:theme="@style/TabbedModeTheme" + android:theme="@style/Theme.Chromium.TabbedMode" android:exported="true" android:launchMode="singleTask" {# We can only use blocks once in Jinja, for future substitutions we use @@ -508,7 +517,7 @@ {% endif %} </activity-alias> <activity android:name="org.chromium.chrome.browser.ChromeTabbedActivity2" - android:theme="@style/TabbedModeTheme" + android:theme="@style/Theme.Chromium.TabbedMode" android:exported="false" android:taskAffinity="{{ manifest_package }}.ChromeTabbedActivity2" android:launchMode="singleTask" @@ -519,13 +528,13 @@ {{ self.extra_web_rendering_activity_definitions() }} </activity> <activity android:name="org.chromium.chrome.browser.multiwindow.MultiInstanceChromeTabbedActivity" - android:theme="@style/TabbedModeTheme" + android:theme="@style/Theme.Chromium.TabbedMode" android:exported="false" {{ self.chrome_activity_common() }}> {{ self.extra_web_rendering_activity_definitions() }} </activity> <activity android:name="org.chromium.chrome.browser.touchless.NoTouchActivity" - android:theme="@style/MainTheme" + android:theme="@style/Theme.Chromium.Activity" android:exported="false" android:launchMode="singleTask" {{ self.chrome_activity_common() }} @@ -534,15 +543,15 @@ </activity> <activity android:name="org.chromium.chrome.browser.sync.ui.PassphraseActivity" - android:theme="@style/MainTheme" + android:theme="@style/Theme.Chromium.Activity" android:autoRemoveFromRecents="true"> </activity> <activity android:name="org.chromium.chrome.browser.firstrun.LightweightFirstRunActivity" - android:theme="@style/SimpleDialog" + android:theme="@style/Theme.Chromium.AlertDialog.NoActionBar" {{ self.first_run_activity_common() }}> </activity> <activity android:name="org.chromium.chrome.browser.firstrun.FirstRunActivity" - android:theme="@style/FirstRunTheme" + android:theme="@style/Theme.Chromium.DialogWhenLarge" {% block first_run_activity_common %} android:label="@string/fre_activity_label" android:launchMode="singleInstance" @@ -553,7 +562,7 @@ {% endblock %}> </activity> <activity android:name="org.chromium.chrome.browser.firstrun.TabbedModeFirstRunActivity" - android:theme="@style/TabbedModeFirstRunTheme" + android:theme="@style/Theme.Chromium.TabbedMode" {{ self.first_run_activity_common() }}> </activity> {% if enable_vr == "true" %} @@ -568,34 +577,34 @@ </activity> {% endif %} <activity android:name="org.chromium.chrome.browser.signin.AccountSigninActivity" - android:theme="@style/DialogWhenLarge" + android:theme="@style/Theme.Chromium.DialogWhenLarge" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> </activity> <activity android:name="org.chromium.chrome.browser.signin.SigninActivity" - android:theme="@style/DialogWhenLarge" + android:theme="@style/Theme.Chromium.DialogWhenLarge" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:exported="false"> </activity> <activity android:name="org.chromium.chrome.browser.preferences.Preferences" - android:theme="@style/PreferencesTheme" + android:theme="@style/Theme.Chromium.Preferences" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:label="@string/preferences" android:exported="false"> </activity> <activity android:name="org.chromium.chrome.browser.preferences.website.ManageSpaceActivity" - android:theme="@style/ManageSpaceTheme" + android:theme="@style/Theme.Chromium.Preferences.ManageSpace" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:label="@string/storage_management_activity_label" android:exported="false"> </activity> <activity android:name="org.chromium.chrome.browser.bookmarks.BookmarkActivity" - android:theme="@style/FullscreenWhiteActivityTheme" + android:theme="@style/Theme.Chromium.Activity.Fullscreen" android:exported="false" android:windowSoftInputMode="stateAlwaysHidden|adjustResize" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> </activity> <activity android:name="org.chromium.chrome.browser.bookmarks.BookmarkAddActivity" - android:theme="@style/DialogWhenLarge" + android:theme="@style/Theme.Chromium.DialogWhenLarge" android:windowSoftInputMode="stateHidden" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> <intent-filter> @@ -604,19 +613,19 @@ </intent-filter> </activity> <activity android:name="org.chromium.chrome.browser.bookmarks.BookmarkEditActivity" - android:theme="@style/DialogWhenLarge" + android:theme="@style/Theme.Chromium.DialogWhenLarge" android:windowSoftInputMode="stateHidden" android:exported="false" android:label="@string/edit_bookmark" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> </activity> <activity android:name="org.chromium.chrome.browser.bookmarks.BookmarkAddEditFolderActivity" - android:theme="@style/DialogWhenLarge" + android:theme="@style/Theme.Chromium.DialogWhenLarge" android:exported="false" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> </activity> <activity android:name="org.chromium.chrome.browser.bookmarks.BookmarkFolderSelectActivity" - android:theme="@style/DialogWhenLarge" + android:theme="@style/Theme.Chromium.DialogWhenLarge" android:windowSoftInputMode="stateAlwaysHidden" android:label="@string/bookmark_choose_folder" android:exported="false" @@ -625,7 +634,7 @@ <!-- Activities for downloads. --> <activity android:name="org.chromium.chrome.browser.download.DownloadActivity" - android:theme="@style/FullscreenWhiteActivityTheme" + android:theme="@style/Theme.Chromium.Activity.Fullscreen" android:windowSoftInputMode="stateAlwaysHidden|adjustResize" android:exported="false" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> @@ -633,7 +642,7 @@ <!-- Activities for history. --> <activity android:name="org.chromium.chrome.browser.history.HistoryActivity" - android:theme="@style/FullscreenWhiteActivityTheme" + android:theme="@style/Theme.Chromium.Activity.Fullscreen" android:windowSoftInputMode="stateAlwaysHidden|adjustResize" android:exported="false" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> @@ -662,7 +671,7 @@ android:targetActivity="org.chromium.chrome.browser.webapps.WebappLauncherActivity"> </activity-alias> <activity android:name="org.chromium.chrome.browser.webapps.WebappActivity" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:label="@string/webapp_activity_title" android:launchMode="singleTop" android:documentLaunchMode="intoExisting" @@ -681,7 +690,7 @@ </activity-alias> {% for i in range(10) %} <activity android:name="org.chromium.chrome.browser.webapps.WebappActivity{{ i }}" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:icon="@mipmap/app_shortcut_icon" android:label="@string/webapp_activity_title" android:launchMode="singleTask" @@ -702,7 +711,7 @@ {% endfor %} <!-- Activities for WebAPKs. --> <activity android:name="org.chromium.chrome.browser.webapps.SameTaskWebApkActivity" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:label="@string/webapp_activity_title" android:exported="false" android:persistableMode="persistNever" @@ -713,7 +722,7 @@ {{ self.extra_web_rendering_activity_definitions() }} </activity> <activity android:name="org.chromium.chrome.browser.webapps.WebApkActivity" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:label="@string/webapp_activity_title" android:launchMode="singleTop" android:documentLaunchMode="intoExisting" @@ -727,7 +736,7 @@ </activity> {% for i in range(10) %} <activity android:name="org.chromium.chrome.browser.webapps.WebApkActivity{{ i }}" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:icon="@mipmap/app_shortcut_icon" android:label="@string/webapp_activity_title" android:launchMode="singleTask" @@ -743,7 +752,7 @@ {% endfor %} <activity android:name="org.chromium.chrome.browser.media.router.caf.remoting.CafExpandedControllerActivity" - android:theme="@style/MainTheme" + android:theme="@style/Theme.Chromium.Activity" android:label="Chrome.CafExpandedControllerActivity" android:hardwareAccelerated="true" android:launchMode="singleTask" @@ -820,7 +829,7 @@ <!-- Activities for Browser Actions --> <activity android:name="org.chromium.chrome.browser.browseractions.BrowserActionActivity" - android:theme="@style/FullscreenTransparentActivityTheme" + android:theme="@style/Theme.Chromium.Activity.Fullscreen.Transparent" android:exported="true" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> <intent-filter> @@ -858,12 +867,12 @@ {% endif %} <activity android:name="org.chromium.chrome.browser.browserservices.ClearDataDialogActivity" - android:theme="@style/ClearDataDialogActivityTheme" + android:theme="@style/Theme.Chromium.ClearDataDialogActivity" android:exported="false"/> <activity android:name="org.chromium.chrome.browser.browserservices.ManageTrustedWebActivityDataActivity" - android:theme="@style/FullscreenTransparentActivityTheme" + android:theme="@style/Theme.Chromium.Activity.Fullscreen.Transparent" android:exported="true"> <intent-filter> <action android:name="android.support.customtabs.action.ACTION_MANAGE_TRUSTED_WEB_ACTIVITY_DATA" /> @@ -964,7 +973,7 @@ <!-- Search Activity --> <activity android:name="org.chromium.chrome.browser.searchwidget.SearchActivity" - android:theme="@style/SearchActivityTheme" + android:theme="@style/Theme.Chromium.SearchActivity" android:label="Search" android:exported="false" android:launchMode="singleTask"
diff --git a/chrome/android/java/monochrome_public_apk.AndroidManifest.expected b/chrome/android/java/monochrome_public_apk.AndroidManifest.expected index 6a5481d..87621e0 100644 --- a/chrome/android/java/monochrome_public_apk.AndroidManifest.expected +++ b/chrome/android/java/monochrome_public_apk.AndroidManifest.expected
@@ -95,7 +95,7 @@ android:name="org.chromium.chrome.browser.upgrade.UpgradeActivity" android:persistableMode="persistNever" android:taskAffinity="" - android:theme="@style/MainTheme" + android:theme="@style/Theme.Chromium.Activity" android:windowSoftInputMode="adjustResize"/> <activity android:autoRemoveFromRecents="false" @@ -106,7 +106,7 @@ android:name="org.chromium.chrome.browser.document.IncognitoDocumentActivity" android:persistableMode="persistNever" android:taskAffinity="" - android:theme="@style/IncognitoTheme" + android:theme="@style/Theme.Chromium.Incognito" android:windowSoftInputMode="adjustResize"/> <activity android:autoRemoveFromRecents="false" @@ -118,7 +118,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="" - android:theme="@style/MainTheme" + android:theme="@style/Theme.Chromium.Activity" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -134,7 +134,7 @@ android:name="org.chromium.chrome.browser.document.DocumentActivity" android:persistableMode="persistAcrossReboots" android:taskAffinity="" - android:theme="@style/MainTheme" + android:theme="@style/Theme.Chromium.Activity" android:windowSoftInputMode="adjustResize"/> <activity android:autoRemoveFromRecents="true" @@ -143,7 +143,7 @@ android:label="@string/fre_activity_label" android:launchMode="singleInstance" android:name="org.chromium.chrome.browser.firstrun.FirstRunActivity" - android:theme="@style/FirstRunTheme" + android:theme="@style/Theme.Chromium.DialogWhenLarge" android:windowSoftInputMode="stateHidden|adjustPan"/> <activity android:autoRemoveFromRecents="true" @@ -152,7 +152,7 @@ android:label="@string/fre_activity_label" android:launchMode="singleInstance" android:name="org.chromium.chrome.browser.firstrun.LightweightFirstRunActivity" - android:theme="@style/SimpleDialog" + android:theme="@style/Theme.Chromium.AlertDialog.NoActionBar" android:windowSoftInputMode="stateHidden|adjustPan"/> <activity android:autoRemoveFromRecents="true" @@ -161,12 +161,12 @@ android:label="@string/fre_activity_label" android:launchMode="singleInstance" android:name="org.chromium.chrome.browser.firstrun.TabbedModeFirstRunActivity" - android:theme="@style/TabbedModeFirstRunTheme" + android:theme="@style/Theme.Chromium.TabbedMode" android:windowSoftInputMode="stateHidden|adjustPan"/> <activity android:autoRemoveFromRecents="true" android:name="org.chromium.chrome.browser.sync.ui.PassphraseActivity" - android:theme="@style/MainTheme"/> + android:theme="@style/Theme.Chromium.Activity"/> <activity android:clearTaskOnLaunch="true" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" @@ -177,7 +177,7 @@ android:launchMode="singleTask" android:name="org.chromium.chrome.browser.searchwidget.SearchActivity" android:taskAffinity="" - android:theme="@style/SearchActivityTheme" + android:theme="@style/Theme.Chromium.SearchActivity" android:windowSoftInputMode="adjustResize"/> <activity android:configChanges="keyboardHidden|orientation|screenSize" @@ -226,66 +226,66 @@ android:launchMode="singleTask" android:name="org.chromium.chrome.browser.media.router.caf.remoting.CafExpandedControllerActivity" android:noHistory="true" - android:theme="@style/MainTheme"/> + android:theme="@style/Theme.Chromium.Activity"/> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:exported="false" android:label="@string/bookmark_choose_folder" android:name="org.chromium.chrome.browser.bookmarks.BookmarkFolderSelectActivity" - android:theme="@style/DialogWhenLarge" + android:theme="@style/Theme.Chromium.DialogWhenLarge" android:windowSoftInputMode="stateAlwaysHidden"/> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:exported="false" android:label="@string/edit_bookmark" android:name="org.chromium.chrome.browser.bookmarks.BookmarkEditActivity" - android:theme="@style/DialogWhenLarge" + android:theme="@style/Theme.Chromium.DialogWhenLarge" android:windowSoftInputMode="stateHidden"/> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:exported="false" android:label="@string/preferences" android:name="org.chromium.chrome.browser.preferences.Preferences" - android:theme="@style/PreferencesTheme"/> + android:theme="@style/Theme.Chromium.Preferences"/> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:exported="false" android:label="@string/storage_management_activity_label" android:name="org.chromium.chrome.browser.preferences.website.ManageSpaceActivity" - android:theme="@style/ManageSpaceTheme"/> + android:theme="@style/Theme.Chromium.Preferences.ManageSpace"/> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:exported="false" android:name="org.chromium.chrome.browser.bookmarks.BookmarkActivity" - android:theme="@style/FullscreenWhiteActivityTheme" + android:theme="@style/Theme.Chromium.Activity.Fullscreen" android:windowSoftInputMode="stateAlwaysHidden|adjustResize"/> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:exported="false" android:name="org.chromium.chrome.browser.bookmarks.BookmarkAddEditFolderActivity" - android:theme="@style/DialogWhenLarge"/> + android:theme="@style/Theme.Chromium.DialogWhenLarge"/> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:exported="false" android:name="org.chromium.chrome.browser.download.DownloadActivity" - android:theme="@style/FullscreenWhiteActivityTheme" + android:theme="@style/Theme.Chromium.Activity.Fullscreen" android:windowSoftInputMode="stateAlwaysHidden|adjustResize"/> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:exported="false" android:name="org.chromium.chrome.browser.history.HistoryActivity" - android:theme="@style/FullscreenWhiteActivityTheme" + android:theme="@style/Theme.Chromium.Activity.Fullscreen" android:windowSoftInputMode="stateAlwaysHidden|adjustResize"/> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:exported="false" android:name="org.chromium.chrome.browser.signin.SigninActivity" - android:theme="@style/DialogWhenLarge"/> + android:theme="@style/Theme.Chromium.DialogWhenLarge"/> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:exported="true" android:name="org.chromium.chrome.browser.browseractions.BrowserActionActivity" - android:theme="@style/FullscreenTransparentActivityTheme"> + android:theme="@style/Theme.Chromium.Activity.Fullscreen.Transparent"> <intent-filter> <action android:name="androidx.browser.browseractions.browser_action_open"/> <category android:name="android.intent.category.DEFAULT"/> @@ -296,7 +296,7 @@ <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:name="org.chromium.chrome.browser.bookmarks.BookmarkAddActivity" - android:theme="@style/DialogWhenLarge" + android:theme="@style/Theme.Chromium.DialogWhenLarge" android:windowSoftInputMode="stateHidden"> <intent-filter> <action android:name="org.chromium.chrome.ADDBOOKMARK"/> @@ -306,7 +306,7 @@ <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:name="org.chromium.chrome.browser.signin.AccountSigninActivity" - android:theme="@style/DialogWhenLarge"/> + android:theme="@style/Theme.Chromium.DialogWhenLarge"/> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize|uiMode" android:enableVrMode="@string/gvr_vr_mode_component" @@ -332,7 +332,7 @@ android:persistableMode="persistNever" android:resizeableActivity="true" android:supportsPictureInPicture="true" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -351,7 +351,7 @@ android:persistableMode="persistNever" android:resizeableActivity="true" android:supportsPictureInPicture="true" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -390,7 +390,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebApkActivity0" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -410,7 +410,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebApkActivity1" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -430,7 +430,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebApkActivity2" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -450,7 +450,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebApkActivity3" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -470,7 +470,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebApkActivity4" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -490,7 +490,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebApkActivity5" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -510,7 +510,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebApkActivity6" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -530,7 +530,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebApkActivity7" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -550,7 +550,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebApkActivity8" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -570,7 +570,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebApkActivity9" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -590,7 +590,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebappActivity0" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -610,7 +610,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebappActivity1" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -630,7 +630,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebappActivity2" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -650,7 +650,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebappActivity3" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -670,7 +670,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebappActivity4" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -690,7 +690,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebappActivity5" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -710,7 +710,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebappActivity6" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -730,7 +730,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebappActivity7" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -750,7 +750,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebappActivity8" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -770,7 +770,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.webapps.WebappActivity9" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -787,7 +787,7 @@ android:persistableMode="persistNever" android:resizeableActivity="true" android:supportsPictureInPicture="true" - android:theme="@style/WebappTheme" + android:theme="@style/Theme.Chromium.Webapp" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -804,7 +804,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:taskAffinity="org.chromium.chrome.ChromeTabbedActivity2" - android:theme="@style/TabbedModeTheme" + android:theme="@style/Theme.Chromium.TabbedMode" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -820,7 +820,7 @@ android:name="org.chromium.chrome.browser.touchless.NoTouchActivity" android:resizeableActivity="true" android:supportsPictureInPicture="true" - android:theme="@style/MainTheme" + android:theme="@style/Theme.Chromium.Activity" android:windowSoftInputMode="adjustResize"/> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize|uiMode|density" @@ -829,7 +829,7 @@ android:name="org.chromium.chrome.browser.customtabs.CustomTabActivity" android:resizeableActivity="true" android:supportsPictureInPicture="true" - android:theme="@style/MainTheme" + android:theme="@style/Theme.Chromium.Activity" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -844,7 +844,7 @@ android:name="org.chromium.chrome.browser.customtabs.PaymentHandlerActivity" android:resizeableActivity="true" android:supportsPictureInPicture="true" - android:theme="@style/TranslucentMainTheme" + android:theme="@style/Theme.Chromium.Activity.Translucent" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -857,7 +857,7 @@ android:exported="false" android:hardwareAccelerated="false" android:name="org.chromium.chrome.browser.multiwindow.MultiInstanceChromeTabbedActivity" - android:theme="@style/TabbedModeTheme" + android:theme="@style/Theme.Chromium.TabbedMode" android:windowSoftInputMode="adjustResize"/> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize|uiMode|density" @@ -867,7 +867,7 @@ android:name="org.chromium.chrome.browser.ChromeTabbedActivity" android:resizeableActivity="true" android:supportsPictureInPicture="true" - android:theme="@style/TabbedModeTheme" + android:theme="@style/Theme.Chromium.TabbedMode" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="org.chromium.chrome.browser.dummy.action"/> @@ -929,15 +929,15 @@ <activity android:exported="false" android:name="org.chromium.chrome.browser.browserservices.ClearDataDialogActivity" - android:theme="@style/ClearDataDialogActivityTheme"/> + android:theme="@style/Theme.Chromium.ClearDataDialogActivity"/> <activity android:exported="false" android:name="org.chromium.chrome.browser.incognito.IncognitoDisclosureActivity" - android:theme="@style/FullscreenTransparentActivityTheme"/> + android:theme="@style/Theme.Chromium.Activity.Fullscreen.Transparent"/> <activity android:exported="true" android:name="org.chromium.chrome.browser.browserservices.ManageTrustedWebActivityDataActivity" - android:theme="@style/FullscreenTransparentActivityTheme"> + android:theme="@style/Theme.Chromium.Activity.Fullscreen.Transparent"> <intent-filter> <action android:name="android.support.customtabs.action.ACTION_MANAGE_TRUSTED_WEB_ACTIVITY_DATA"/> @@ -1158,6 +1158,7 @@ <activity-alias android:name="com.google.android.apps.chrome.webapps.WebappManager" android:targetActivity="org.chromium.chrome.browser.webapps.WebappLauncherActivity"/> + <meta-data android:name="android.allow_multiple_resumed_activities" android:value="true"/> <meta-data android:name="android.arch.lifecycle.VERSION" android:value="27.0.0-SNAPSHOT"/> <meta-data android:name="android.content.APP_RESTRICTIONS"
diff --git a/chrome/android/java/res/drawable-sw600dp/bg_white_dialog.xml b/chrome/android/java/res/drawable-sw600dp/bg_white_dialog.xml index 112698f..6640b3a 100644 --- a/chrome/android/java/res/drawable-sw600dp/bg_white_dialog.xml +++ b/chrome/android/java/res/drawable-sw600dp/bg_white_dialog.xml
@@ -4,4 +4,4 @@ found in the LICENSE file. --> <nine-patch xmlns:android="http://schemas.android.com/apk/res/android" - android:src="@drawable/popup_bg" /> + android:src="@drawable/popup_bg_tinted" />
diff --git a/chrome/android/java/res/drawable-v19/action_bar_activity_bg.xml b/chrome/android/java/res/drawable-v19/action_bar_activity_bg.xml index dd316b24..7818562 100644 --- a/chrome/android/java/res/drawable-v19/action_bar_activity_bg.xml +++ b/chrome/android/java/res/drawable-v19/action_bar_activity_bg.xml
@@ -6,5 +6,5 @@ <!-- Once pre-KitKat devices aren't supported, this drawable can be replaced with a plain old color. --> <shape xmlns:android="http://schemas.android.com/apk/res/android" > - <solid android:color="#fff"/> + <solid android:color="@color/modern_primary_color" /> </shape>
diff --git a/chrome/android/java/res/drawable/account_picker_background.xml b/chrome/android/java/res/drawable/account_picker_background.xml index 7ec829a..5d2c5ef 100644 --- a/chrome/android/java/res/drawable/account_picker_background.xml +++ b/chrome/android/java/res/drawable/account_picker_background.xml
@@ -6,6 +6,6 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> - <solid android:color="@color/modern_grey_100"/> + <solid android:color="@color/modern_secondary_color"/> <corners android:radius="8dp"/> </shape>
diff --git a/chrome/android/java/res/drawable/action_bar_activity_bg.xml b/chrome/android/java/res/drawable/action_bar_activity_bg.xml index e974f2e..95894f2 100644 --- a/chrome/android/java/res/drawable/action_bar_activity_bg.xml +++ b/chrome/android/java/res/drawable/action_bar_activity_bg.xml
@@ -13,6 +13,6 @@ these shenanigans aren't needed. http://crbug.com/448012 --> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item - android:drawable="@android:color/white" + android:drawable="@color/modern_primary_color" android:top="50dp" /> </layer-list>
diff --git a/chrome/android/java/res/drawable/autofill_chip_inset.xml b/chrome/android/java/res/drawable/autofill_chip_inset.xml index 24b20d11..da93ff1 100644 --- a/chrome/android/java/res/drawable/autofill_chip_inset.xml +++ b/chrome/android/java/res/drawable/autofill_chip_inset.xml
@@ -5,7 +5,7 @@ <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape> - <solid android:color="@android:color/white" /> + <solid android:color="@color/modern_primary_color" /> <corners android:radius="@dimen/keyboard_accessory_bar_item_height" /> </shape> </item>
diff --git a/chrome/android/java/res/drawable/bg_white_dialog.xml b/chrome/android/java/res/drawable/bg_white_dialog.xml index 63a53c1..60a3c0d8 100644 --- a/chrome/android/java/res/drawable/bg_white_dialog.xml +++ b/chrome/android/java/res/drawable/bg_white_dialog.xml
@@ -5,5 +5,5 @@ <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> - <solid android:color="@android:color/white" /> + <solid android:color="@color/modern_primary_color" /> </shape> \ No newline at end of file
diff --git a/chrome/android/java/res/drawable/contextual_suggestions_placeholder_thumbnail.xml b/chrome/android/java/res/drawable/contextual_suggestions_placeholder_thumbnail.xml index b1c8a444..4ce61341 100644 --- a/chrome/android/java/res/drawable/contextual_suggestions_placeholder_thumbnail.xml +++ b/chrome/android/java/res/drawable/contextual_suggestions_placeholder_thumbnail.xml
@@ -5,7 +5,7 @@ <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid - android:color="@color/thumbnail_placeholder_on_white_bg" /> + android:color="@color/thumbnail_placeholder_on_primary_bg" /> <corners android:radius="@dimen/default_card_corner_radius" /> </shape> \ No newline at end of file
diff --git a/chrome/android/java/res/drawable/download_home_tabs_bg.xml b/chrome/android/java/res/drawable/download_home_tabs_bg.xml index d7eefef..abb31d6 100644 --- a/chrome/android/java/res/drawable/download_home_tabs_bg.xml +++ b/chrome/android/java/res/drawable/download_home_tabs_bg.xml
@@ -12,7 +12,7 @@ </item> <item android:bottom="1dp"> <shape android:shape="rectangle"> - <solid android:color="@android:color/white" /> + <solid android:color="@color/modern_primary_color" /> </shape> </item> </layer-list>
diff --git a/chrome/android/java/res/drawable/grey_with_top_rounded_corners.xml b/chrome/android/java/res/drawable/grey_with_top_rounded_corners.xml index 6ab2c4a..8dae0177 100644 --- a/chrome/android/java/res/drawable/grey_with_top_rounded_corners.xml +++ b/chrome/android/java/res/drawable/grey_with_top_rounded_corners.xml
@@ -5,7 +5,7 @@ <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid - android:color="@color/modern_grey_100"/> + android:color="@color/modern_secondary_color"/> <corners android:topRightRadius="3.5dp" android:topLeftRadius="3.5dp" />
diff --git a/chrome/android/java/res/drawable/hairline_border_card_background.xml b/chrome/android/java/res/drawable/hairline_border_card_background.xml index 03444e4..ab7333f1 100644 --- a/chrome/android/java/res/drawable/hairline_border_card_background.xml +++ b/chrome/android/java/res/drawable/hairline_border_card_background.xml
@@ -6,7 +6,7 @@ <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > - <solid android:color="@android:color/white" /> + <solid android:color="@color/modern_primary_color" /> <stroke android:width="1dp" android:color="@color/hairline_stroke_color"/> <corners android:radius="@dimen/default_card_corner_radius" /> </shape>
diff --git a/chrome/android/java/res/drawable/ic_snippet_thumbnail_placeholder.xml b/chrome/android/java/res/drawable/ic_snippet_thumbnail_placeholder.xml index b9c2c20..d8d651d 100644 --- a/chrome/android/java/res/drawable/ic_snippet_thumbnail_placeholder.xml +++ b/chrome/android/java/res/drawable/ic_snippet_thumbnail_placeholder.xml
@@ -11,7 +11,7 @@ android:viewportWidth="72" android:viewportHeight="72"> - <path android:fillColor="@color/modern_grey_100" + <path android:fillColor="@color/modern_secondary_color" android:pathData="M0,0 L72,0 L72,71.9997 L0,71.9997 Z" /> <path android:fillColor="@color/default_icon_color" android:pathData="M45,42.9997 L45,28.9997 C45,27.8997,44.1,26.9997,43,26.9997 L29,26.9997
diff --git a/chrome/android/java/res/drawable/infobar_wrapper_bg.xml b/chrome/android/java/res/drawable/infobar_wrapper_bg.xml index b4944df9..8d0afaf 100644 --- a/chrome/android/java/res/drawable/infobar_wrapper_bg.xml +++ b/chrome/android/java/res/drawable/infobar_wrapper_bg.xml
@@ -12,5 +12,5 @@ </item> <item android:top="@dimen/infobar_shadow_height" - android:drawable="@android:color/white" /> + android:drawable="@color/modern_primary_color" /> </layer-list>
diff --git a/chrome/android/java/res/drawable/list_item_icon_modern_bg.xml b/chrome/android/java/res/drawable/list_item_icon_modern_bg.xml index 87ab3bd5..8089c36a 100644 --- a/chrome/android/java/res/drawable/list_item_icon_modern_bg.xml +++ b/chrome/android/java/res/drawable/list_item_icon_modern_bg.xml
@@ -6,7 +6,7 @@ <level-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:maxLevel="@integer/list_item_level_default"> <shape android:shape="oval"> - <solid android:color="@color/modern_grey_100" /> + <solid android:color="@color/modern_secondary_color" /> </shape> </item> <item android:maxLevel="@integer/list_item_level_selected">
diff --git a/chrome/android/java/res/drawable/modern_toolbar_background.xml b/chrome/android/java/res/drawable/modern_toolbar_background.xml index c15e1b0c..b457876 100644 --- a/chrome/android/java/res/drawable/modern_toolbar_background.xml +++ b/chrome/android/java/res/drawable/modern_toolbar_background.xml
@@ -6,7 +6,7 @@ <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > - <solid android:color="@color/modern_grey_100" /> + <solid android:color="@color/toolbar_search_background" /> <size android:width="@dimen/modern_toolbar_background_size" android:height="@dimen/modern_toolbar_background_size" />
diff --git a/chrome/android/java/res/drawable/modern_toolbar_background_white.xml b/chrome/android/java/res/drawable/modern_toolbar_background_white.xml index 902a423..56a8f96 100644 --- a/chrome/android/java/res/drawable/modern_toolbar_background_white.xml +++ b/chrome/android/java/res/drawable/modern_toolbar_background_white.xml
@@ -6,7 +6,7 @@ <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > - <solid android:color="@android:color/white" /> + <solid android:color="@color/toolbar_background_primary" /> <size android:width="@dimen/modern_toolbar_background_size" android:height="@dimen/modern_toolbar_background_size" />
diff --git a/chrome/android/java/res/drawable/tile_view_icon_background_modern.xml b/chrome/android/java/res/drawable/tile_view_icon_background_modern.xml index 55b97c944..6182b0f 100644 --- a/chrome/android/java/res/drawable/tile_view_icon_background_modern.xml +++ b/chrome/android/java/res/drawable/tile_view_icon_background_modern.xml
@@ -6,5 +6,5 @@ <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> - <solid android:color="@color/modern_grey_100" /> + <solid android:color="@color/modern_secondary_color" /> </shape>
diff --git a/chrome/android/java/res/layout-sw600dp/find_toolbar.xml b/chrome/android/java/res/layout-sw600dp/find_toolbar.xml index aff07d41..b873d844 100644 --- a/chrome/android/java/res/layout-sw600dp/find_toolbar.xml +++ b/chrome/android/java/res/layout-sw600dp/find_toolbar.xml
@@ -10,7 +10,7 @@ android:id="@+id/find_toolbar" android:layout_width="0dp" android:layout_height="0dp" - android:background="@drawable/popup_bg" + android:background="@drawable/popup_bg_tinted" android:visibility="gone"> <include android:layout_width="match_parent"
diff --git a/chrome/android/java/res/layout/autofill_editor_base_buttons.xml b/chrome/android/java/res/layout/autofill_editor_base_buttons.xml index 91b7114f..926edb9 100644 --- a/chrome/android/java/res/layout/autofill_editor_base_buttons.xml +++ b/chrome/android/java/res/layout/autofill_editor_base_buttons.xml
@@ -18,7 +18,7 @@ android:paddingEnd="@dimen/pref_autofill_field_horizontal_padding" android:paddingTop="@dimen/editor_dialog_section_large_spacing" android:paddingBottom="@dimen/editor_dialog_section_large_spacing" - android:background="@android:color/white" + android:background="@color/modern_primary_color" app:stackedMargin="@dimen/infobar_margin_between_stacked_buttons" app:primaryButtonText="@string/done" app:secondaryButtonText="@string/cancel"
diff --git a/chrome/android/java/res/layout/contextual_suggestions_layout.xml b/chrome/android/java/res/layout/contextual_suggestions_layout.xml index 6c4d9a1..b9bb9df 100644 --- a/chrome/android/java/res/layout/contextual_suggestions_layout.xml +++ b/chrome/android/java/res/layout/contextual_suggestions_layout.xml
@@ -9,4 +9,4 @@ android:layout_height="match_parent" android:scrollbars="vertical" android:layout_marginTop="@dimen/bottom_sheet_peek_height" - android:background="@android:color/white" /> \ No newline at end of file + android:background="@color/modern_primary_color" /> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/contextual_suggestions_toolbar.xml b/chrome/android/java/res/layout/contextual_suggestions_toolbar.xml index aa5b2894..ba4bfd6 100644 --- a/chrome/android/java/res/layout/contextual_suggestions_toolbar.xml +++ b/chrome/android/java/res/layout/contextual_suggestions_toolbar.xml
@@ -16,7 +16,7 @@ android:layout_height="@dimen/bottom_sheet_peek_height" android:orientation="horizontal" android:gravity="center_vertical" - android:background="@android:color/white" > + android:background="@color/modern_primary_color" > <!-- Use 48dp width and 16dp end/start padding to produce a 16dp, centered icon. --> <ImageView
diff --git a/chrome/android/java/res/layout/keyboard_accessory.xml b/chrome/android/java/res/layout/keyboard_accessory.xml index 78fe1cf..1587fd1 100644 --- a/chrome/android/java/res/layout/keyboard_accessory.xml +++ b/chrome/android/java/res/layout/keyboard_accessory.xml
@@ -33,7 +33,7 @@ android:layout_height="@dimen/keyboard_accessory_height" android:layout_gravity="start|bottom" android:orientation="horizontal" - android:background="@color/modern_grey_100"> + android:background="@color/modern_secondary_color"> <include layout="@layout/keyboard_accessory_tabs" android:id="@+id/tabs"/>
diff --git a/chrome/android/java/res/layout/keyboard_accessory_sheet.xml b/chrome/android/java/res/layout/keyboard_accessory_sheet.xml index 74017d31..b180f50f 100644 --- a/chrome/android/java/res/layout/keyboard_accessory_sheet.xml +++ b/chrome/android/java/res/layout/keyboard_accessory_sheet.xml
@@ -14,7 +14,7 @@ <android.support.v4.view.ViewPager android:id="@+id/keyboard_accessory_sheet" - android:background="@android:color/white" + android:background="@color/modern_primary_color" android:fillViewport="true" android:layout_height="match_parent" android:layout_width="match_parent"/>
diff --git a/chrome/android/java/res/layout/page_info.xml b/chrome/android/java/res/layout/page_info.xml index 665cbe2d..dbe14e94 100644 --- a/chrome/android/java/res/layout/page_info.xml +++ b/chrome/android/java/res/layout/page_info.xml
@@ -11,7 +11,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="8dp" - android:orientation="vertical" > + android:orientation="vertical" + android:background="@color/modern_primary_color"> <LinearLayout android:layout_width="match_parent"
diff --git a/chrome/android/java/res/layout/payment_request.xml b/chrome/android/java/res/layout/payment_request.xml index 937ab3f3..f993aaa 100644 --- a/chrome/android/java/res/layout/payment_request.xml +++ b/chrome/android/java/res/layout/payment_request.xml
@@ -14,7 +14,7 @@ android:gravity="center" app:maxWidthLandscape="@dimen/payments_ui_max_dialog_width" app:maxWidthPortrait="@dimen/payments_ui_max_dialog_width" - android:background="@android:color/white" > + android:background="@color/modern_primary_color" > <include layout="@layout/payment_request_header" /> <include layout="@layout/payment_request_spinny" />
diff --git a/chrome/android/java/res/layout/payment_request_bottom_bar.xml b/chrome/android/java/res/layout/payment_request_bottom_bar.xml index a14323948..603ef72 100644 --- a/chrome/android/java/res/layout/payment_request_bottom_bar.xml +++ b/chrome/android/java/res/layout/payment_request_bottom_bar.xml
@@ -11,7 +11,7 @@ android:layout_height="wrap_content" android:layout_width="match_parent" android:padding="@dimen/editor_dialog_section_large_spacing" - android:background="@android:color/white" + android:background="@color/modern_primary_color" android:visibility="gone" > <ImageView
diff --git a/chrome/android/java/res/layout/payment_request_editor.xml b/chrome/android/java/res/layout/payment_request_editor.xml index 1c48ab9..65618b2 100644 --- a/chrome/android/java/res/layout/payment_request_editor.xml +++ b/chrome/android/java/res/layout/payment_request_editor.xml
@@ -6,7 +6,7 @@ <!-- PaymentRequestUI editor dialog. --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:background="@android:color/white"> + android:background="@color/modern_primary_color"> <!-- Toolbar --> <org.chromium.chrome.browser.widget.prefeditor.EditorDialogToolbar
diff --git a/chrome/android/java/res/layout/payment_request_error.xml b/chrome/android/java/res/layout/payment_request_error.xml index 19a7a92..c812f11 100644 --- a/chrome/android/java/res/layout/payment_request_error.xml +++ b/chrome/android/java/res/layout/payment_request_error.xml
@@ -13,7 +13,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:gravity="center" - android:background="@drawable/popup_bg" + android:background="@drawable/popup_bg_tinted" app:maxWidthLandscape="@dimen/payments_ui_max_dialog_width" app:maxWidthPortrait="@dimen/payments_ui_max_dialog_width" >
diff --git a/chrome/android/java/res/layout/payment_request_header.xml b/chrome/android/java/res/layout/payment_request_header.xml index ab3ce57..12e9602c 100644 --- a/chrome/android/java/res/layout/payment_request_header.xml +++ b/chrome/android/java/res/layout/payment_request_header.xml
@@ -15,7 +15,7 @@ android:layout_height="wrap_content" android:layout_width="match_parent" android:minHeight="64dp" - android:background="@android:color/white" > + android:background="@color/modern_primary_color" > <ImageView android:id="@+id/icon_view"
diff --git a/chrome/android/java/res/layout/promo_dialog_layout.xml b/chrome/android/java/res/layout/promo_dialog_layout.xml index dfe814d..4695102 100644 --- a/chrome/android/java/res/layout/promo_dialog_layout.xml +++ b/chrome/android/java/res/layout/promo_dialog_layout.xml
@@ -20,7 +20,7 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:orientation="vertical" - android:background="@drawable/popup_bg" + android:background="@drawable/popup_bg_tinted" app:maxWidthLandscape="@dimen/dialog_max_width" app:maxWidthPortrait="@dimen/dialog_max_width" >
diff --git a/chrome/android/java/res/layout/tab_grid_card_item.xml b/chrome/android/java/res/layout/tab_grid_card_item.xml index b2b8e69..fe1a2e6 100644 --- a/chrome/android/java/res/layout/tab_grid_card_item.xml +++ b/chrome/android/java/res/layout/tab_grid_card_item.xml
@@ -49,7 +49,7 @@ android:gravity="center_horizontal" android:scaleType="centerCrop" android:importantForAccessibility="no" - android:src="@color/thumbnail_placeholder_on_white_bg" + android:src="@color/thumbnail_placeholder_on_primary_bg" app:cornerRadiusBottomStart="@dimen/default_card_corner_radius" app:cornerRadiusBottomEnd="@dimen/default_card_corner_radius"/>
diff --git a/chrome/android/java/res/layout/tabular_context_menu.xml b/chrome/android/java/res/layout/tabular_context_menu.xml index d83d1f3d..af44e43 100644 --- a/chrome/android/java/res/layout/tabular_context_menu.xml +++ b/chrome/android/java/res/layout/tabular_context_menu.xml
@@ -23,7 +23,7 @@ android:id="@+id/tab_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="@color/modern_grey_100" + android:background="@color/modern_secondary_color" app:tabTextColor="@color/default_text_color_secondary" app:tabSelectedTextColor="@color/light_active_color" app:tabIndicatorColor="@color/light_active_color"
diff --git a/chrome/android/java/res/values-sw600dp-v17/styles.xml b/chrome/android/java/res/values-sw600dp-v17/styles.xml index 54d5a74e..3cdc25d 100644 --- a/chrome/android/java/res/values-sw600dp-v17/styles.xml +++ b/chrome/android/java/res/values-sw600dp-v17/styles.xml
@@ -4,7 +4,7 @@ found in the LICENSE file. --> <resources xmlns:tools="http://schemas.android.com/tools"> - <style name="TabbedModeTheme" parent="MainTheme"> + <style name="Theme.Chromium.TabbedMode" parent="Base.Theme.Chromium.TabbedMode"> <item name="android:statusBarColor" tools:targetApi="21">@android:color/black</item> <item name="android:windowBackground">@drawable/window_background</item> </style>
diff --git a/chrome/android/java/res/values-sw600dp-v26/styles.xml b/chrome/android/java/res/values-sw600dp-v26/styles.xml index ba5989b..f9bbff3 100644 --- a/chrome/android/java/res/values-sw600dp-v26/styles.xml +++ b/chrome/android/java/res/values-sw600dp-v26/styles.xml
@@ -4,7 +4,7 @@ found in the LICENSE file. --> <resources xmlns:tools="http://schemas.android.com/tools"> - <style name="TabbedModeTheme" parent="TabbedModeThemeBase"> + <style name="Theme.Chromium.TabbedMode" parent="Base.Theme.Chromium.TabbedMode"> <item name="android:statusBarColor">@android:color/black</item> <item name="android:windowLightStatusBar">false</item> </style>
diff --git a/chrome/android/java/res/values-sw600dp-v27/styles.xml b/chrome/android/java/res/values-sw600dp-v27/styles.xml index 90a2559..5477f37c 100644 --- a/chrome/android/java/res/values-sw600dp-v27/styles.xml +++ b/chrome/android/java/res/values-sw600dp-v27/styles.xml
@@ -3,9 +3,10 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<resources xmlns:tools="http://schemas.android.com/tools"> - <style name="MainTheme" parent="MainThemeBase" /> - <style name="FullscreenWhite" parent="FullscreenWhiteBase" /> - <style name="ThemeWithActionBar" parent="ThemeWithActionBarBase" /> - <style name="DialogWhenLarge" parent="DialogWhenLargeBase" /> +<resources> + <style name="Theme.Chromium.WithWindowAnimation" + parent="Base.Theme.Chromium.WithWindowAnimation" /> + <style name="Theme.Chromium.Fullscreen" parent="Base.Theme.Chromium.Fullscreen" /> + <style name="Theme.Chromium.WithActionBar" parent="Base.Theme.Chromium.WithActionBar" /> + <style name="Theme.Chromium.DialogWhenLarge" parent="Base.Theme.Chromium.DialogWhenLarge" /> </resources>
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml index e874173..9218420b 100644 --- a/chrome/android/java/res/values-v17/styles.xml +++ b/chrome/android/java/res/values-v17/styles.xml
@@ -16,22 +16,51 @@ the generated style resources under res_v14_compatibility/values/ (crbug.com/243952). --> + <!-- TODO(huayinz): Move themes to another xml file. --> + <!-- Application themes --> <style name="LauncherTheme" parent="@android:style/Theme.NoDisplay" /> - <style name="MainThemeBase" parent="Theme.AppCompat.DayNight.NoActionBar"> - <item name="android:windowContentOverlay">@null</item> - <item name="android:textColorHighlight">@color/text_highlight_color</item> - <item name="android:textColorLink">@color/default_text_color_link</item> - <item name="colorPrimaryDark">@android:color/black</item> - <item name="android:colorAccent" tools:targetApi="21">@color/light_active_color</item> - <item name="android:statusBarColor" tools:targetApi="21">@android:color/black</item> + <style name="Base.Theme.Chromium" parent="Theme.AppCompat.DayNight.NoActionBar"> + <!-- Window Properties --> + <item name="android:windowBackground">@color/modern_primary_color</item> - <!-- Overriding AppCompat values --> + <!-- Action bar color --> + <item name="colorPrimary">@color/modern_primary_color</item> + + <!-- Status bar color --> + <item name="android:statusBarColor" tools:targetApi="21">@android:color/black</item> + <item name="colorPrimaryDark">@android:color/black</item> + + <!-- Text colors --> + <item name="android:textColorLink">@color/default_text_color_link</item> + <item name="android:textColorHighlight">@color/text_highlight_color</item> + + <!-- Color of checkboxes, switches, buttons, etc. --> + <item name="colorAccent">@color/light_active_color</item> <item name="colorControlNormal">@color/control_normal_color</item> <item name="colorControlActivated">@color/light_active_color</item> <item name="colorControlHighlight">@color/control_highlight_color</item> + + <!-- Spinner styles --> <item name="spinnerStyle">@style/SpinnerStyle</item> + <!-- Popup styles --> + <item name="android:popupMenuStyle">@style/PopupMenuStyle</item> + <item name="android:contextPopupMenuStyle" tools:targetApi="24">@style/PopupMenuStyle</item> + </style> + + <style name="Base.Theme.Chromium.WithActionBar"> + <!-- With ActionBar --> + <item name="windowActionBar">true</item> + <item name="windowNoTitle">false</item> + + <!-- Window properties --> + <item name="android:windowBackground">@drawable/action_bar_activity_bg</item> + </style> + + <style name="Base.Theme.Chromium.WithWindowAnimation"> + <item name="android:windowContentOverlay">@null</item> + <!-- Navigation Transitions, requires API level 21 --> <item name="android:windowAllowEnterTransitionOverlap" tools:targetApi="21">false</item> <item name="android:windowAllowReturnTransitionOverlap" tools:targetApi="21">true</item> @@ -40,72 +69,97 @@ <item name="android:windowExitTransition" tools:targetApi="21">@null</item> <item name="android:windowSharedElementEnterTransition" tools:targetApi="21">@transition/move_image</item> <item name="android:windowSharedElementExitTransition" tools:targetApi="21">@transition/move_image</item> - <item name="android:popupMenuStyle">@style/PopupMenuStyle</item> - <item name="android:contextPopupMenuStyle" tools:targetApi="24">@style/PopupMenuStyle</item> </style> - <style name="MainTheme" parent="MainThemeBase" /> - <style name="TranslucentMainTheme" parent="MainThemeBase"> + + <style name="Base.Theme.Chromium.Fullscreen"> + <!-- With ActionBar but not window title --> + <!-- TODO(huayinz): Check if windowActionBar is actually needed. --> + <item name="windowActionBar">true</item> + <item name="colorPrimary">@color/light_active_color</item> + <item name="colorAccent">@color/light_active_color</item> + </style> + + <style name="Theme.Chromium" parent="Base.Theme.Chromium" /> + <style name="Theme.Chromium.WithWindowAnimation" + parent="Base.Theme.Chromium.WithWindowAnimation" /> + <style name="Theme.Chromium.WithActionBar" parent="Base.Theme.Chromium.WithActionBar" /> + <style name="Theme.Chromium.Fullscreen" parent="Base.Theme.Chromium.Fullscreen" /> + + <!-- Activity themes --> + <style name="Theme.Chromium.Activity" parent="Theme.Chromium.WithWindowAnimation" /> + <!-- TODO(huayinz): Can this be merged to Theme.Chromium.Activity.Fullscreen.Transparent? --> + <style name="Theme.Chromium.Activity.Translucent"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowIsTranslucent">true</item> </style> - - <!-- Extend MainThemeBase rather than MainTheme to avoid values-v27 navigation bar colors from - being applied --> - <style name="SearchActivityTheme" parent="MainThemeBase"> - <item name="android:windowBackground">@android:color/white</item> + <style name="Theme.Chromium.Activity.Fullscreen" parent="Theme.Chromium.Fullscreen"> + <!-- No ActionBar --> + <item name="windowActionBar">false</item> </style> - - <style name="TabbedModeThemeBase" parent="MainTheme"> - <item name="android:windowBackground">@android:color/white</item> - </style> - - <style name="TabbedModeTheme" parent="TabbedModeThemeBase" /> - - <style name="FirstRunTheme" parent="DialogWhenLarge"> - </style> - - <style name="TabbedModeFirstRunTheme" parent="TabbedModeTheme"> - </style> - - <style name="FullscreenWhiteBase" parent="Theme.AppCompat.Light" > - <item name="android:windowBackground">@android:color/white</item> - <item name="android:textColorLink">@color/light_active_color</item> - <item name="colorPrimaryDark">@android:color/black</item> - <item name="colorPrimary">@color/light_active_color</item> - <item name="colorAccent">@color/light_active_color</item> - <item name="colorControlHighlight">@color/control_highlight_color</item> - <item name="spinnerStyle">@style/SpinnerStyle</item> - <item name="windowNoTitle">true</item> - <item name="android:popupMenuStyle">@style/PopupMenuStyle</item> - <item name="android:contextPopupMenuStyle" tools:targetApi="24">@style/PopupMenuStyle</item> - </style> - <style name="FullscreenWhite" parent="FullscreenWhiteBase" /> - - <style name="FullscreenTransparentActivityTheme" parent="Theme.AppCompat.Light.NoActionBar" > + <style name="Theme.Chromium.Activity.Fullscreen.Transparent"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowIsFloating">true</item> <item name="android:colorBackgroundCacheHint">@null</item> <item name="android:windowIsTranslucent">true</item> - <item name="colorControlHighlight">@color/control_highlight_color</item> - <item name="spinnerStyle">@style/SpinnerStyle</item> - <item name="windowNoTitle">true</item> </style> - <style name="FullscreenWhiteActivityTheme" parent="FullscreenWhite"> - <item name="windowActionBar">false</item> - </style> + <!-- Extend base theme rather than Theme.Chromium.WithWindowAnimation to avoid values-v27 + navigation bar colors from being applied --> + <style name="Theme.Chromium.SearchActivity" parent="Base.Theme.Chromium.WithWindowAnimation" /> + + <style name="Base.Theme.Chromium.TabbedMode" parent="Theme.Chromium.WithWindowAnimation" /> + <style name="Theme.Chromium.TabbedMode" parent="Base.Theme.Chromium.TabbedMode" /> <!-- Web app themes --> - <!-- Extend MainThemeBase rather than MainTheme to avoid values-v27 navigation bar colors from - being applied --> - <style name="WebappTheme" parent="MainThemeBase"> + <!-- Extend base theme rather than Theme.Chromium.WithWindowAnimation to avoid values-v27 + navigation bar colors from being applied --> + <style name="Theme.Chromium.Webapp" parent="Base.Theme.Chromium.WithWindowAnimation"> <item name="android:windowBackground">@null</item> <item name="android:windowDisablePreview">true</item> </style> - <style name="AlertDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert"> - <item name="android:windowBackground">@drawable/popup_bg</item> + <style name="Base.Theme.Chromium.Preferences" parent="Theme.Chromium.WithActionBar"> + <item name="android:alertDialogTheme">@style/Theme.Chromium.AlertDialog</item> + <item name="android:spinnerItemStyle">@style/PreferenceSpinnerItem</item> + <item name="floatLabelTextAppearance">@style/TextAppearance.BlackCaption</item> + <item name="floatLabelPaddingLeft">@dimen/pref_autofill_field_horizontal_padding</item> + <item name="floatLabelPaddingRight">@dimen/pref_autofill_field_horizontal_padding</item> + <item name="floatLabelPaddingTop">@dimen/pref_autofill_field_top_margin</item> + <item name="actionBarStyle">@style/PreferenceActionBarModern</item> + </style> + + <!-- TODO(huayinz): Verify if these text styles are up to date with UX and override styles in + v21 as well. --> + <style name="Theme.Chromium.Preferences" parent="Base.Theme.Chromium.Preferences"> + <!-- Theme attributes pre-v21 --> + <item name="android:textAppearanceMedium">@style/TextAppearance.PreferenceMediumText</item> + <item name="android:textAppearanceSmall">@style/TextAppearance.BlackBody</item> + <item name="android:preferenceCategoryStyle">@style/PreferenceCategory</item> + <item name="android:windowContentOverlay">@null</item> + </style> + + <style name="Theme.Chromium.Preferences.ManageSpace"> + <!-- Action bar color. This is intentionally a dark color. See crbug.com/871193. --> + <item name="colorPrimary">@color/dark_action_bar_color</item> + <!-- Status bar color --> + <item name="colorPrimaryDark">@color/dark_status_bar_color</item> + <item name="actionBarStyle">@style/ManageSpaceActionBarModern</item> + </style> + + <!-- Trusted Web Activities --> + <style name="Theme.Chromium.ClearDataDialogActivity" + parent="Theme.Chromium.Activity.Fullscreen.Transparent"> + <item name="android:windowBackground">@android:color/transparent</item> + <item name="android:windowEnterAnimation">@null</item> + <item name="android:windowExitAnimation">@null</item> + <item name="android:windowAnimationStyle">@null</item> + </style> + + <!-- Dialog themes --> + <style name="Theme.Chromium.AlertDialog" parent="Theme.AppCompat.DayNight.Dialog.Alert"> + <item name="android:textColorPrimary">@color/default_text_color</item> + <item name="android:windowBackground">@drawable/popup_bg_tinted</item> <item name="android:windowTitleStyle">@style/TextAppearance.AlertDialogTitleStyle</item> <item name="android:textColorHighlight">@color/text_highlight_color</item> @@ -115,49 +169,55 @@ <item name="colorControlNormal">@color/control_normal_color</item> <item name="colorControlHighlight">@color/control_highlight_color</item> <item name="colorPrimary">@color/light_active_color</item> + <item name="buttonBarButtonStyle">@style/AlertDialogButtonStyle</item> <item name="spinnerStyle">@style/SpinnerStyle</item> </style> - <!-- Styled to match BlackHeadline but setup to override values in the app compat parent theme. - Note that the fontFamily doesn't get applied on older versions of Android. - See https://crbug.com/918697.--> - <style name="TextAppearance.AlertDialogTitleStyle" - parent="RtlOverlay.DialogWindowTitle.AppCompat"> - <item name="android:textColor">@color/default_text_color_list</item> - <item name="android:textSize">@dimen/headline_size</item> - <item name="android:fontFamily">@font/accent_font</item> - <item name="android:textStyle">normal</item> - </style> - - <!-- The dim amount should match the alpha of modal_dialog_scrim_color. --> - <style name="ModalDialogTheme" parent="AlertDialogTheme"> - <item name="android:windowFrame">@null</item> - <item name="android:backgroundDimAmount">0.5</item> - <item name="buttonBarButtonStyle">@style/TextButton</item> - <item name="android:windowSoftInputMode">adjustResize|stateHidden</item> - </style> - - <style name="SimpleDialog" parent="AlertDialogTheme"> + <style name="Theme.Chromium.AlertDialog.NoActionBar"> <item name="windowNoTitle">true</item> <item name="windowActionBar">false</item> </style> - <!-- Preferences --> - <style name="PreferencesTheme" parent="ThemeWithActionBar"> - <item name="android:textColorLink">@color/pref_accent_color</item> - <item name="android:textAppearanceMedium">@style/TextAppearance.PreferenceMediumText</item> - <item name="android:textAppearanceSmall">@style/TextAppearance.BlackBody</item> - <item name="android:preferenceCategoryStyle">@style/PreferenceCategory</item> - <item name="android:spinnerItemStyle">@style/PreferenceSpinnerItem</item> - <item name="floatLabelTextAppearance">@style/TextAppearance.BlackCaption</item> - <item name="floatLabelPaddingLeft">@dimen/pref_autofill_field_horizontal_padding</item> - <item name="floatLabelPaddingRight">@dimen/pref_autofill_field_horizontal_padding</item> - <item name="floatLabelPaddingTop">@dimen/pref_autofill_field_top_margin</item> - <item name="actionBarStyle">@style/PreferenceActionBarModern</item> - <item name="android:windowContentOverlay">@null</item> - <item name="android:popupMenuStyle">@style/PopupMenuStyle</item> - <item name="android:contextPopupMenuStyle" tools:targetApi="24">@style/PopupMenuStyle</item> + <!-- The dim amount should match the alpha of modal_dialog_scrim_color. --> + <style name="Theme.Chromium.ModalDialog" parent="Theme.Chromium.AlertDialog"> + <item name="android:windowFrame">@null</item> + <item name="android:backgroundDimAmount">0.65</item> + <item name="buttonBarButtonStyle">@style/TextButton</item> + <item name="android:windowSoftInputMode">adjustResize|stateHidden</item> </style> + + <!-- First Run and Bookmark/recent-tabs dialogs. + TODO(https://crbug.com/819142): Remove textAppearance when all TextViews have text style + explicitly specified. --> + <style name="Base.Theme.Chromium.DialogWhenLarge" + parent="Theme.AppCompat.DayNight.DialogWhenLarge"> + <item name="android:windowBackground">@drawable/bg_white_dialog</item> + <item name="android:textAppearance">@style/TextAppearance.BlackBodyDefault</item> + <item name="android:textColorLink">@color/default_text_color_link</item> + <item name="colorPrimaryDark">@android:color/black</item> + <item name="colorAccent">@color/light_active_color</item> + <item name="colorControlHighlight">@color/control_highlight_color</item> + <item name="spinnerStyle">@style/SpinnerStyle</item> + + <!-- Remove ActionBar --> + <item name="windowNoTitle">true</item> + <item name="windowActionBar">false</item> + </style> + <style name="Theme.Chromium.DialogWhenLarge" parent="Base.Theme.Chromium.DialogWhenLarge" /> + <style name="DimmingDialog" parent="Base.Theme.Chromium.DialogWhenLarge"> + <item name="android:windowLightNavigationBar" tools:targetApi="28">false</item> + </style> + + <!-- ThemeOverlay --> + <style name="OverflowMenuThemeOverlay" parent="Theme.AppCompat.DayNight"> + <item name="android:popupBackground">@null</item> + <item name="android:listDivider">@null</item> + <item name="android:listPreferredItemHeightSmall">48dp</item> + <item name="android:textAppearance">@style/TextAppearance.BlackTitle1</item> + <item name="colorControlHighlight">@color/control_highlight_color</item> + </style> + + <!-- Preferences styles --> <style name="PreferenceActionBarModern" parent="@style/Widget.AppCompat.Light.ActionBar.Solid"> <item name="titleTextStyle">@style/TextAppearance.BlackHeadline</item> </style> @@ -218,29 +278,7 @@ <item name="android:textColor">?android:attr/textColorPrimary</item> </style> - <style name="ThemeWithActionBarBase" parent="Theme.AppCompat.Light"> - <item name="android:windowBackground">@drawable/action_bar_activity_bg</item> - <!-- Action bar color --> - <item name="colorPrimary">@color/modern_primary_color</item> - <!-- Status bar color --> - <item name="colorPrimaryDark">@android:color/black</item> - <!-- Color of checkboxes, switches, buttons, etc. --> - <item name="colorAccent">@color/pref_accent_color</item> - <item name="colorControlHighlight">@color/control_highlight_color</item> - <item name="spinnerStyle">@style/SpinnerStyle</item> - <item name="android:popupMenuStyle">@style/PopupMenuStyle</item> - <item name="android:contextPopupMenuStyle" tools:targetApi="24">@style/PopupMenuStyle</item> - </style> - <style name="ThemeWithActionBar" parent="ThemeWithActionBarBase" /> - - <!-- Manage Space Activity --> - <style name="ManageSpaceTheme" parent="PreferencesTheme"> - <!-- Action bar color. This is intentionally a dark color. See crbug.com/871193. --> - <item name="colorPrimary">@color/dark_action_bar_color</item> - <!-- Status bar color --> - <item name="colorPrimaryDark">@color/dark_status_bar_color</item> - <item name="actionBarStyle">@style/ManageSpaceActionBarModern</item> - </style> + <!-- Manage Space Activity styles --> <style name="ManageSpaceActionBarModern" parent="PreferenceActionBarModern"> <item name="titleTextStyle">@style/TextAppearance.WhiteHeadline</item> </style> @@ -266,7 +304,22 @@ <item name="android:maxLines">1</item> </style> - <!-- Alert dialogs --> + <!-- Alert dialog styles --> + <style name="AlertDialogButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog"> + <item name="android:textAppearance">@style/TextAppearance.BlueButtonText2</item> + </style> + + <!-- Styled to match BlackHeadline but setup to override values in the app compat parent theme. + Note that the fontFamily doesn't get applied on older versions of Android. + See https://crbug.com/918697.--> + <style name="TextAppearance.AlertDialogTitleStyle" + parent="RtlOverlay.DialogWindowTitle.AppCompat"> + <item name="android:textColor">@color/default_text_color_list</item> + <item name="android:textSize">@dimen/headline_size</item> + <item name="android:fontFamily">@font/accent_font</item> + <item name="android:textStyle">normal</item> + </style> + <style name="AlertDialogContent"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> @@ -282,13 +335,7 @@ <item name="android:paddingTop">10dp</item> </style> - <style name="OverflowMenuTheme" parent="Theme.AppCompat.Light"> - <item name="android:popupBackground">@null</item> - <item name="android:listDivider">@null</item> - <item name="android:listPreferredItemHeightSmall">48dp</item> - <item name="android:textAppearance">@style/TextAppearance.BlackTitle1</item> - <item name="colorControlHighlight">@color/control_highlight_color</item> - </style> + <!-- Overflow Menu styles--> <style name="OverflowMenuButton"> <item name="android:layout_width">0dp</item> <item name="android:layout_height">match_parent</item> @@ -351,13 +398,13 @@ <!-- Spinner styles --> <style name="SpinnerStyle" parent="Widget.AppCompat.Spinner"> - <item name="android:popupBackground">@drawable/popup_bg</item> + <item name="android:popupBackground">@drawable/popup_bg_tinted</item> <item name="android:popupElevation" tools:targetApi="21">0dp</item> </style> <!-- Popup and long-press context popup menu style --> <style name="PopupMenuStyle" parent="Widget.AppCompat.Light.PopupMenu"> - <item name="android:popupBackground">@drawable/popup_bg</item> + <item name="android:popupBackground">@drawable/popup_bg_tinted</item> <item name="android:overlapAnchor" tools:targetApi="21">true</item> <item name="android:popupElevation" tools:targetApi="21">0dp</item> </style> @@ -467,36 +514,6 @@ <item name="android:alpha">0.6</item> </style> - <!-- First Run and Bookmark/recent-tabs dialogs. - TODO(https://crbug.com/819142): Remove textAppearance when all TextViews have text style - explicitly specified. --> - <style name="DialogWhenLargeBase" parent="Theme.AppCompat.Light.DialogWhenLarge" > - <item name="android:windowBackground">@drawable/bg_white_dialog</item> - <item name="android:textAppearance">@style/TextAppearance.BlackBodyDefault</item> - <item name="android:textColorLink">@color/default_text_color_link</item> - <item name="colorPrimaryDark">@android:color/black</item> - <item name="colorAccent">@color/light_active_color</item> - <item name="colorControlHighlight">@color/control_highlight_color</item> - <item name="spinnerStyle">@style/SpinnerStyle</item> - - <!-- Remove ActionBar --> - <item name="windowNoTitle">true</item> - <item name="windowActionBar">false</item> - </style> - <style name="DialogWhenLarge" parent="DialogWhenLargeBase" /> - <style name="DimmingDialog" parent="DialogWhenLargeBase"> - <item name="android:windowLightNavigationBar" tools:targetApi="28">false</item> - </style> - - <style name="SigninAlertDialogTheme" parent="AlertDialogTheme"> - <item name="buttonBarButtonStyle">@style/SigninDialogButtonStyle</item> - <item name="android:textColorPrimary">@color/default_text_color</item> - </style> - - <style name="SigninDialogButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog"> - <item name="android:textAppearance">@style/TextAppearance.BlueButtonText2</item> - </style> - <!-- Contextual Search styles --> <style name="ContextualSearchTextViewLayout"> <item name="android:layout_width">match_parent</item> @@ -829,12 +846,12 @@ </style> <style name="TextAppearance.OmniboxAnswerTextLarge"> - <item name="android:textSize">@dimen/text_size_large_leading</item> + <item name="android:textSize">24sp</item> <item name="android:textColor">@color/answers_answer_text</item> </style> <style name="TextAppearance.OmniboxAnswerTextMedium"> - <item name="android:textSize">@dimen/text_size_medium_leading</item> + <item name="android:textSize">20sp</item> <item name="android:textColor">@color/answers_answer_text</item> </style> @@ -844,12 +861,12 @@ </style> <style name="TextAppearance.OmniboxAnswerDescriptionNegative"> - <item name="android:textSize">@dimen/text_size_small_leading</item> + <item name="android:textSize">@dimen/text_size_large</item> <item name="android:textColor">@color/answers_description_text_negative</item> </style> <style name="TextAppearance.OmniboxAnswerDescriptionPositive"> - <item name="android:textSize">@dimen/text_size_small_leading</item> + <item name="android:textSize">@dimen/text_size_large</item> <item name="android:textColor">@color/answers_description_text_positive</item> </style> @@ -869,12 +886,4 @@ <item name="android:layout_height">@dimen/omnibox_suggestion_edit_url_min_height</item> <item name="tint">@color/default_icon_color</item> </style> - - <!-- Trusted Web Activities --> - <style name="ClearDataDialogActivityTheme" parent="FullscreenTransparentActivityTheme"> - <item name="android:windowBackground">@android:color/transparent</item> - <item name="android:windowEnterAnimation">@null</item> - <item name="android:windowExitAnimation">@null</item> - <item name="android:windowAnimationStyle">@null</item> - </style> </resources>
diff --git a/chrome/android/java/res/values-v21/styles.xml b/chrome/android/java/res/values-v21/styles.xml index a7f6ce3..94c8097 100644 --- a/chrome/android/java/res/values-v21/styles.xml +++ b/chrome/android/java/res/values-v21/styles.xml
@@ -9,19 +9,8 @@ </style> <!-- Preferences --> - <style name="PreferencesTheme" parent="ThemeWithActionBar"> - <item name="android:textColorLink">@color/pref_accent_color</item> - <item name="android:alertDialogTheme">@style/PreferencesDialogTheme</item> + <style name="Theme.Chromium.Preferences" parent="Base.Theme.Chromium.Preferences"> <item name="android:divider">@null</item> - <item name="android:spinnerItemStyle">@style/PreferenceSpinnerItem</item> - <item name="floatLabelTextAppearance">@style/TextAppearance.BlackCaption</item> - <item name="floatLabelPaddingLeft">@dimen/pref_autofill_field_horizontal_padding</item> - <item name="floatLabelPaddingRight">@dimen/pref_autofill_field_horizontal_padding</item> - <item name="floatLabelPaddingTop">@dimen/pref_autofill_field_top_margin</item> - <item name="actionBarStyle">@style/PreferenceActionBarModern</item> - </style> - <style name="PreferencesDialogTheme" parent="@android:style/Theme.Material.Light.Dialog.Alert"> - <item name="android:colorAccent">@color/pref_accent_color</item> </style> <style name="PreferenceCategoryWithButtonStyle"> <item name="android:paddingStart">?android:attr/listPreferredItemPaddingStart</item> @@ -92,7 +81,7 @@ <item name="android:padding">3dp</item> </style> - <style name="IncognitoTheme" parent="MainTheme"> + <style name="Theme.Chromium.Incognito" parent="Theme.Chromium.WithWindowAnimation"> <item name="android:colorPrimary">@color/incognito_primary_color</item> </style> @@ -101,20 +90,21 @@ Since ChromeActivities are not HW accelerated, they don't get fancy material shadows for popups. This theme sets drawable with pre-baked shadows to those popups to make them look better. - 'popup_bg' is a 9-patch similar to 'abc_popup_background_mtrl_mult' + 'popup_bg_tinted' is a 9-patch similar to 'abc_popup_background_mtrl_mult' drawable from Android support library, where it's used to simulate material design on earlier Android versions. --> <style name="ListPopupWindow.LowEnd" parent="android:Widget.Material.Light.ListPopupWindow"> - <item name="android:popupBackground">@drawable/popup_bg</item> + <item name="android:popupBackground">@drawable/popup_bg_tinted</item> </style> <style name="Spinner.LowEnd" parent="android:Widget.Material.Light.Spinner"> - <item name="android:popupBackground">@drawable/popup_bg</item> + <item name="android:popupBackground">@drawable/popup_bg_tinted</item> </style> <style name="AutoCompleteTextView.LowEnd" parent="android:Widget.Material.Light.AutoCompleteTextView"> - <item name="android:popupBackground">@drawable/popup_bg</item> + <item name="android:popupBackground">@drawable/popup_bg_tinted</item> </style> - <style name="MainTheme.LowEnd" parent="MainTheme"> + <style name="Theme.Chromium.WithWindowAnimation.LowEnd" + parent="Theme.Chromium.WithWindowAnimation"> <item name="android:popupWindowStyle">@style/ListPopupWindow.LowEnd</item> <item name="android:listPopupWindowStyle">@style/ListPopupWindow.LowEnd</item> <item name="android:spinnerStyle">@style/Spinner.LowEnd</item>
diff --git a/chrome/android/java/res/values-v26/styles.xml b/chrome/android/java/res/values-v26/styles.xml index 28365cfb..a183cf0 100644 --- a/chrome/android/java/res/values-v26/styles.xml +++ b/chrome/android/java/res/values-v26/styles.xml
@@ -4,7 +4,7 @@ found in the LICENSE file. --> <resources xmlns:tools="http://schemas.android.com/tools"> - <style name="TabbedModeTheme" parent="TabbedModeThemeBase"> + <style name="Theme.Chromium.TabbedMode" parent="Base.Theme.Chromium.TabbedMode"> <item name="android:statusBarColor">@color/modern_primary_color</item> <item name="android:windowLightStatusBar">true</item> </style>
diff --git a/chrome/android/java/res/values-v27/styles.xml b/chrome/android/java/res/values-v27/styles.xml index 808cc8a..5b25e89 100644 --- a/chrome/android/java/res/values-v27/styles.xml +++ b/chrome/android/java/res/values-v27/styles.xml
@@ -4,28 +4,28 @@ found in the LICENSE file. --> <resources xmlns:tools="http://schemas.android.com/tools"> - <style name="MainTheme" parent="MainThemeBase"> + <style name="Theme.Chromium.WithWindowAnimation" parent="Base.Theme.Chromium.WithWindowAnimation"> <item name="android:navigationBarColor">@color/bottom_system_nav_color</item> <!--suppress NewApi: crbug.com/856861--> <item name="android:navigationBarDividerColor">@color/bottom_system_nav_divider_color</item> <!--suppress NewApi: crbug.com/856861--> <item name="android:windowLightNavigationBar">true</item> </style> - <style name="FullscreenWhite" parent="FullscreenWhiteBase"> + <style name="Theme.Chromium.Fullscreen" parent="Base.Theme.Chromium.Fullscreen"> <item name="android:navigationBarColor">@color/bottom_system_nav_color</item> <!--suppress NewApi: crbug.com/856861--> <item name="android:navigationBarDividerColor">@color/bottom_system_nav_divider_color</item> <!--suppress NewApi: crbug.com/856861--> <item name="android:windowLightNavigationBar">true</item> </style> - <style name="ThemeWithActionBar" parent="ThemeWithActionBarBase"> + <style name="Theme.Chromium.WithActionBar" parent="Base.Theme.Chromium.WithActionBar"> <item name="android:navigationBarColor">@color/bottom_system_nav_color</item> <!--suppress NewApi: crbug.com/856861--> <item name="android:navigationBarDividerColor">@color/bottom_system_nav_divider_color</item> <!--suppress NewApi: crbug.com/856861--> <item name="android:windowLightNavigationBar">true</item> </style> - <style name="DialogWhenLarge" parent="DialogWhenLargeBase"> + <style name="Theme.Chromium.DialogWhenLarge" parent="Base.Theme.Chromium.DialogWhenLarge"> <item name="android:navigationBarColor">@color/bottom_system_nav_color</item> <!--suppress NewApi: crbug.com/856861--> <item name="android:navigationBarDividerColor">@color/bottom_system_nav_divider_color</item>
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml index fbc5191f..b809d02 100644 --- a/chrome/android/java/res/values/colors.xml +++ b/chrome/android/java/res/values/colors.xml
@@ -25,7 +25,7 @@ <!-- Other colors --> <color name="dark_action_bar_color">#263238</color> <color name="dark_status_bar_color">#161E21</color> - <color name="modal_dialog_scrim_color">#7F000000</color> + <color name="modal_dialog_scrim_color">@color/black_alpha_65</color> <!-- Modern color palette --> <color name="black_alpha_11">#1D000000</color> @@ -35,7 +35,6 @@ <color name="black_alpha_30">#4D000000</color> <color name="black_alpha_40">#66000000</color> <color name="black_alpha_65">#A6000000</color> - <color name="white_alpha_50">#80FFFFFF</color> <color name="white_alpha_65">#A6FFFFFF</color> <color name="white_alpha_90">#E6FFFFFF</color> @@ -112,14 +111,14 @@ <!-- Account Signin Colors --> <!-- As in dimens.xml, signin uses values from the First Run Experience --> - <color name="signin_head_background">@android:color/white</color> + <color name="signin_head_background">@color/modern_primary_color</color> <color name="signin_body_background">@color/modern_grey_50</color> <color name="signin_header_animation_background">@color/modern_grey_50</color> <!-- NTP and Home sheet colors. Also used on the bookmarks and recent tabs pages. --> <color name="ntp_bg">@color/default_primary_color</color> <color name="ntp_bg_incognito">@color/incognito_modern_primary_color</color> - <color name="suggestions_modern_bg">@android:color/white</color> + <color name="suggestions_modern_bg">@color/modern_primary_color</color> <color name="suggestions_offline_badge_tint">@color/default_icon_color_blue</color> <!-- Incognito NTP Colors. --> @@ -136,9 +135,14 @@ <color name="progress_bar_background">#3D4386F7</color> <!-- Theme colors. Also used for toolbar background --> + <!-- TODO(huayinz): Split incognito toolbar background color from primary color. --> <color name="incognito_primary_color">#505050</color> <color name="incognito_modern_primary_color">@color/modern_grey_800</color> - <color name="modern_primary_color">@android:color/white</color> + + <!-- Toolbar colors --> + <color name="toolbar_background_primary">@android:color/white</color> + <color name="toolbar_search_background">@color/modern_grey_100</color> + <color name="toolbar_shadow_color">@color/black_alpha_11</color> <!-- LocationBar colors --> <color name="locationbar_dark_hint_text">@color/search_box_hint</color> @@ -182,7 +186,7 @@ <color name="bookmark_widget_pressed_highlight">@color/black_alpha_11</color> <!-- Payments UI colors --> - <color name="payments_section_edit_background">@color/modern_grey_100</color> + <color name="payments_section_edit_background">@color/modern_secondary_color</color> <color name="payments_section_chevron">#B2B2B2</color> <color name="payments_section_separator">@color/modern_grey_300</color> @@ -193,11 +197,10 @@ <color name="media_viewer_bg">#000000</color> <color name="image_viewer_bg">#0E0E0E</color> <color name="modern_blue_600_alpha_38_opaque">#A8CAF6</color> - <color name="toolbar_shadow_color">@color/black_alpha_11</color> <color name="bottom_system_nav_color">@android:color/white</color> <color name="bottom_system_nav_divider_color">@color/black_alpha_12</color> <color name="search_box_hint">@color/default_text_color_secondary</color> - <color name="thumbnail_placeholder_on_white_bg">@color/modern_grey_100</color> + <color name="thumbnail_placeholder_on_primary_bg">@color/modern_secondary_color</color> <color name="clear_browsing_data_selected_tab_color">@color/modern_blue_600</color> </resources>
diff --git a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_payment_request.xml b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_payment_request.xml index 4ab3deb..9e2e113 100644 --- a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_payment_request.xml +++ b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_payment_request.xml
@@ -14,7 +14,7 @@ android:gravity="center" app:maxWidthLandscape="@dimen/payments_ui_max_dialog_width" app:maxWidthPortrait="@dimen/payments_ui_max_dialog_width" - android:background="@android:color/white" > + android:background="@color/modern_primary_color" > <!-- TODO(crbug.com/806868): Spinny is probably also obsolete. --> <include layout="@layout/payment_request_spinny" />
diff --git a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_payment_request_bottom_bar.xml b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_payment_request_bottom_bar.xml index 26c7554..349d3fd 100644 --- a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_payment_request_bottom_bar.xml +++ b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_payment_request_bottom_bar.xml
@@ -10,7 +10,7 @@ android:layout_height="wrap_content" android:layout_width="match_parent" android:paddingTop="@dimen/editor_dialog_section_large_spacing" - android:background="@android:color/white" + android:background="@color/modern_primary_color" android:gravity="end" android:orientation="horizontal" android:visibility="gone" >
diff --git a/chrome/android/java/res_download/layout/download_location_spinner_dropdown_item.xml b/chrome/android/java/res_download/layout/download_location_spinner_dropdown_item.xml index a3e31c95..cf4a821 100644 --- a/chrome/android/java/res_download/layout/download_location_spinner_dropdown_item.xml +++ b/chrome/android/java/res_download/layout/download_location_spinner_dropdown_item.xml
@@ -6,7 +6,7 @@ <!-- Note: Nested layouts are used because the styling was being overwritten, likely because of the behavior of the Android Spinner class. --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:background="@android:color/white" + android:background="@color/modern_primary_color" android:layout_width="match_parent" android:layout_height="wrap_content" >
diff --git a/chrome/android/java/res_download/layout/download_manager_generic_item.xml b/chrome/android/java/res_download/layout/download_manager_generic_item.xml index 8b024d54..3cddf2f 100644 --- a/chrome/android/java/res_download/layout/download_manager_generic_item.xml +++ b/chrome/android/java/res_download/layout/download_manager_generic_item.xml
@@ -12,7 +12,7 @@ android:layout_height="wrap_content" android:minHeight="64dp" android:clickable="true" - android:background="@android:color/white" + android:background="@color/modern_primary_color" app:columnCount="3" app:rowCount="2">
diff --git a/chrome/android/java/res_download/layout/download_manager_image_item.xml b/chrome/android/java/res_download/layout/download_manager_image_item.xml index fad5d3f..685f8fbd 100644 --- a/chrome/android/java/res_download/layout/download_manager_image_item.xml +++ b/chrome/android/java/res_download/layout/download_manager_image_item.xml
@@ -11,7 +11,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="true" - android:background="@color/modern_grey_100" > + android:background="@color/modern_secondary_color" > <org.chromium.chrome.browser.download.home.list.view.AsyncImageView android:id="@+id/thumbnail"
diff --git a/chrome/android/java/res_download/layout/download_manager_in_progress_image_item.xml b/chrome/android/java/res_download/layout/download_manager_in_progress_image_item.xml index 4f806f9..70d8d94 100644 --- a/chrome/android/java/res_download/layout/download_manager_in_progress_image_item.xml +++ b/chrome/android/java/res_download/layout/download_manager_in_progress_image_item.xml
@@ -11,7 +11,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="true" - android:background="@color/modern_grey_100" > + android:background="@color/modern_secondary_color" > <!-- Set the src attribute in Java to wrap the drawable properly. --> <ImageView
diff --git a/chrome/android/java/res_download/layout/download_manager_in_progress_item.xml b/chrome/android/java/res_download/layout/download_manager_in_progress_item.xml index 7e00b7f6..0dba51b1 100644 --- a/chrome/android/java/res_download/layout/download_manager_in_progress_item.xml +++ b/chrome/android/java/res_download/layout/download_manager_in_progress_item.xml
@@ -11,7 +11,7 @@ android:layout_height="wrap_content" android:minHeight="64dp" android:clickable="true" - android:background="@android:color/white" + android:background="@color/modern_primary_color" app:columnCount="3" app:rowCount="2">
diff --git a/chrome/android/java/res_night/values-night/colors.xml b/chrome/android/java/res_night/values-night/colors.xml index 24962ae0..6b014c0 100644 --- a/chrome/android/java/res_night/values-night/colors.xml +++ b/chrome/android/java/res_night/values-night/colors.xml
@@ -4,6 +4,6 @@ found in the LICENSE file. --> <resources> - <!-- TODO(huayinz): Change the colors. --> - <color name="modern_primary_color">#610000FF</color> + <color name="light_active_color">@color/modern_blue_300</color> + <color name="control_normal_color">@color/modern_grey_200</color> </resources> \ No newline at end of file
diff --git a/chrome/android/java/res_vr/values-vrheadset-v26/styles.xml b/chrome/android/java/res_vr/values-vrheadset-v26/styles.xml index bca4843a..3643e8d5a 100644 --- a/chrome/android/java/res_vr/values-vrheadset-v26/styles.xml +++ b/chrome/android/java/res_vr/values-vrheadset-v26/styles.xml
@@ -5,7 +5,7 @@ <resources xmlns:tools="http://schemas.android.com/tools"> - <style name="TabbedModeTheme" parent="TabbedModeThemeBase"> + <style name="Theme.Chromium.TabbedMode" parent="Base.Theme.Chromium.TabbedMode"> <item name="android:windowDisablePreview">true</item> </style>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index 21517fe9..72f8c07 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -2431,7 +2431,8 @@ public static int getThemeId() { boolean useLowEndTheme = SysUtils.isLowEndDevice() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; - return (useLowEndTheme ? R.style.MainTheme_LowEnd : R.style.MainTheme); + return (useLowEndTheme ? R.style.Theme_Chromium_WithWindowAnimation_LowEnd + : R.style.Theme_Chromium_WithWindowAnimation); } /** @@ -2458,7 +2459,8 @@ } private void setLowEndTheme() { - if (getThemeId() == R.style.MainTheme_LowEnd) setTheme(R.style.MainTheme_LowEnd); + if (getThemeId() == R.style.Theme_Chromium_WithWindowAnimation_LowEnd) + setTheme(R.style.Theme_Chromium_WithWindowAnimation_LowEnd); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index 7b8a2d70..e938ff6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -280,7 +280,6 @@ "PredictivePrefetchingAllowedOnAllConnectionTypes"; public static final String PROGRESS_BAR_THROTTLE = "ProgressBarThrottle"; public static final String PWA_PERSISTENT_NOTIFICATION = "PwaPersistentNotification"; - public static final String REACHED_CODE_PROFILER = "ReachedCodeProfiler"; public static final String READER_MODE_IN_CCT = "ReaderModeInCCT"; public static final String REMOVE_NAVIGATION_HISTORY = "RemoveNavigationHistory"; public static final String SEARCH_READY_OMNIBOX = "SearchReadyOmnibox";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 5b6fd4f18..3a54e26 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -271,6 +271,11 @@ private boolean mUIWithNativeInitialized; private Boolean mMergeTabsOnResume; + /** + * Used to observe state changes to a different ChromeTabbedActivity instances to determine + * when to merge tabs if applicable. + */ + private ApplicationStatus.ActivityStateListener mOtherCTAStateObserver; private Boolean mIsAccessibilityTabSwitcherEnabled; @@ -719,6 +724,8 @@ mScreenshotMonitor.stopMonitoring(); + removeOtherCTAStateObserver(); + super.onPauseWithNative(); } @@ -2297,13 +2304,49 @@ // If the activity is currently resumed when multi-window mode is exited, try to merge // tabs from the other activity instance. if (ApplicationStatus.getStateForActivity(this) == ActivityState.RESUMED) { - maybeMergeTabs(); + ChromeTabbedActivity otherResumedCTA = getOtherResumedCTA(); + if (otherResumedCTA == null) { + maybeMergeTabs(); + } else { + // Wait for the other ChromeTabbedActivity to pause before trying to merge + // tabs. + mOtherCTAStateObserver = new ApplicationStatus.ActivityStateListener() { + @Override + public void onActivityStateChange(Activity activity, int newState) { + if (newState == ActivityState.PAUSED) { + removeOtherCTAStateObserver(); + maybeMergeTabs(); + } + } + }; + ApplicationStatus.registerStateListenerForActivity( + mOtherCTAStateObserver, otherResumedCTA); + } } else { mMergeTabsOnResume = true; } } } + private @Nullable ChromeTabbedActivity getOtherResumedCTA() { + Class<?> otherWindowActivityClass = + MultiWindowUtils.getInstance().getOpenInOtherWindowActivity(this); + for (Activity activity : ApplicationStatus.getRunningActivities()) { + if (activity.getClass().equals(otherWindowActivityClass) + && ApplicationStatus.getStateForActivity(activity) == ActivityState.RESUMED) { + return (ChromeTabbedActivity) activity; + } + } + return null; + } + + private void removeOtherCTAStateObserver() { + if (mOtherCTAStateObserver != null) { + ApplicationStatus.unregisterActivityStateListener(mOtherCTAStateObserver); + mOtherCTAStateObserver = null; + } + } + /** * Writes the tab state to disk. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/LoginPrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/LoginPrompt.java index 84589e9..c91b6d68 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/LoginPrompt.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/LoginPrompt.java
@@ -50,18 +50,17 @@ TextView explanationView = (TextView) v.findViewById(R.id.explanation); explanationView.setText(mAuthHandler.getMessageBody()); - mDialog = new AlertDialog.Builder(mContext, R.style.AlertDialogTheme) - .setTitle(R.string.login_dialog_title) - .setView(v) - .setPositiveButton(R.string.login_dialog_ok_button_label, - (DialogInterface.OnClickListener) (dialog, whichButton) -> mAuthHandler - .proceed( - getUsername(), getPassword())) - .setNegativeButton(R.string.cancel, - (DialogInterface.OnClickListener) (dialog, whichButton) -> mAuthHandler - .cancel()) - .setOnCancelListener(dialog -> mAuthHandler.cancel()) - .create(); + mDialog = new AlertDialog.Builder(mContext, R.style.Theme_Chromium_AlertDialog) + .setTitle(R.string.login_dialog_title) + .setView(v) + .setPositiveButton(R.string.login_dialog_ok_button_label, + (DialogInterface.OnClickListener) (dialog, whichButton) + -> mAuthHandler.proceed(getUsername(), getPassword())) + .setNegativeButton(R.string.cancel, + (DialogInterface.OnClickListener) (dialog, + whichButton) -> mAuthHandler.cancel()) + .setOnCancelListener(dialog -> mAuthHandler.cancel()) + .create(); mDialog.getDelegate().setHandleNativeActionModesEnabled(false); // Make the IME appear when the dialog is displayed if applicable.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/NavigationPopup.java b/chrome/android/java/src/org/chromium/chrome/browser/NavigationPopup.java index a3c1b9bd..86f701a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/NavigationPopup.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/NavigationPopup.java
@@ -105,8 +105,8 @@ mPopup = new ListPopupWindow(context, null, 0, R.style.NavigationPopupDialog); mPopup.setOnDismissListener(this::onDismiss); - mPopup.setBackgroundDrawable(ApiCompatibilityUtils.getDrawable( - resources, anchorToBottom ? R.drawable.popup_bg_bottom : R.drawable.popup_bg)); + mPopup.setBackgroundDrawable(ApiCompatibilityUtils.getDrawable(resources, + anchorToBottom ? R.drawable.popup_bg_bottom : R.drawable.popup_bg_tinted)); mPopup.setModal(true); mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); mPopup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/SSLClientCertificateRequest.java b/chrome/android/java/src/org/chromium/chrome/browser/SSLClientCertificateRequest.java index 8290cdf..ae0615c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/SSLClientCertificateRequest.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/SSLClientCertificateRequest.java
@@ -215,7 +215,7 @@ */ public void show() { final AlertDialog.Builder builder = - new AlertDialog.Builder(mActivity, R.style.AlertDialogTheme); + new AlertDialog.Builder(mActivity, R.style.Theme_Chromium_AlertDialog); builder.setTitle(R.string.client_cert_unsupported_title) .setMessage(R.string.client_cert_unsupported_message) .setNegativeButton(R.string.close,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java index 2e891ecd..10a4be3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java
@@ -202,8 +202,8 @@ // Need to explicitly set the background here. Relying on it being set in the style caused // an incorrectly drawn background. - mPopup.setBackgroundDrawable( - ApiCompatibilityUtils.getDrawable(context.getResources(), R.drawable.popup_bg)); + mPopup.setBackgroundDrawable(ApiCompatibilityUtils.getDrawable( + context.getResources(), R.drawable.popup_bg_tinted)); if (!isByPermanentButton) { mPopup.setAnimationStyle( showFromBottom ? R.style.OverflowMenuAnimBottom : R.style.OverflowMenuAnim);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuHandler.java index aeb3b41..012ccae 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuHandler.java
@@ -131,7 +131,8 @@ } mDelegate.prepareMenu(mMenu); - ContextThemeWrapper wrapper = new ContextThemeWrapper(mActivity, R.style.OverflowMenuTheme); + ContextThemeWrapper wrapper = + new ContextThemeWrapper(mActivity, R.style.OverflowMenuThemeOverlay); if (mAppMenu == null) { TypedArray a = wrapper.obtainStyledAttributes(new int[]
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java index bda68e3b..1387d40 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java
@@ -131,7 +131,7 @@ @CalledByNative private void confirmDeletion(String title, String body) { - new AlertDialog.Builder(mContext, R.style.AlertDialogTheme) + new AlertDialog.Builder(mContext, R.style.Theme_Chromium_AlertDialog) .setTitle(title) .setMessage(body) .setNegativeButton(R.string.cancel, null)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java index 3425c94c..0a8ae75a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java
@@ -109,12 +109,12 @@ @CalledByNative private void confirmDeletion(String title, String body) { - mDeletionDialog = new AlertDialog.Builder(mContext, R.style.AlertDialogTheme) - .setTitle(title) - .setMessage(body) - .setNegativeButton(R.string.cancel, null) - .setPositiveButton(R.string.ok, this) - .create(); + mDeletionDialog = new AlertDialog.Builder(mContext, R.style.Theme_Chromium_AlertDialog) + .setTitle(title) + .setMessage(body) + .setNegativeButton(R.string.cancel, null) + .setPositiveButton(R.string.ok, this) + .create(); mDeletionDialog.show(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialog.java index d137076..13187f8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialog.java
@@ -33,7 +33,7 @@ public ContactsPickerDialog(Context context, ContactsPickerListener listener, boolean allowMultiple, boolean includeNames, boolean includeEmails, boolean includeTel, String formattedOrigin) { - super(context, R.style.FullscreenWhite); + super(context, R.style.Theme_Chromium_Fullscreen); // Initialize the main content view. mCategoryView = new PickerCategoryView(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUi.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUi.java index 922bd17..51ae2f2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUi.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUi.java
@@ -90,8 +90,9 @@ mPagerView = initPagerView(activity, params, itemGroups, (TabularContextMenuViewPager) view.findViewById(R.id.custom_pager)); - final ContextMenuDialog dialog = new ContextMenuDialog(activity, R.style.DialogWhenLarge, - touchPointXPx, touchPointYPx, mTopContentOffsetPx, mPagerView); + final ContextMenuDialog dialog = + new ContextMenuDialog(activity, R.style.Theme_Chromium_DialogWhenLarge, + touchPointXPx, touchPointYPx, mTopContentOffsetPx, mPagerView); dialog.setContentView(view); return dialog;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsView.java b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsView.java index e96ff83..67fe816 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsView.java
@@ -80,7 +80,8 @@ } public static void showDialog(Context context) { - AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.AlertDialogTheme); + AlertDialog.Builder builder = + new AlertDialog.Builder(context, R.style.Theme_Chromium_AlertDialog); builder.setView(DistilledPagePrefsView.create(context)); builder.show(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerUIUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerUIUtils.java index 57e37e63..b12130e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerUIUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerUIUtils.java
@@ -40,7 +40,7 @@ if (webContents != null && activity != null) { RecordUserAction.record("DomDistiller_DistilledPagePrefsOpened"); AlertDialog.Builder builder = - new AlertDialog.Builder(activity, R.style.AlertDialogTheme); + new AlertDialog.Builder(activity, R.style.Theme_Chromium_AlertDialog); builder.setView(DistilledPagePrefsView.create(activity)); builder.show(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadController.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadController.java index 93b081b..b551d5c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadController.java
@@ -204,7 +204,7 @@ null)); AlertDialog.Builder builder = - new AlertDialog.Builder(activity, R.style.AlertDialogTheme) + new AlertDialog.Builder(activity, R.style.Theme_Chromium_AlertDialog) .setView(view) .setPositiveButton(R.string.infobar_update_permissions_button_text, (DialogInterface.OnClickListener) (dialog, id)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java index b35fbc1..260787e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java
@@ -489,8 +489,9 @@ DOWNLOAD_STATUS_USER_CANCELLED); } }; - new AlertDialog.Builder( - ApplicationStatus.getLastTrackedFocusedActivity(), R.style.AlertDialogTheme) + new AlertDialog + .Builder(ApplicationStatus.getLastTrackedFocusedActivity(), + R.style.Theme_Chromium_AlertDialog) .setTitle(R.string.proceed_oma_download_message) .setPositiveButton(R.string.ok, clickListener) .setNegativeButton(R.string.cancel, clickListener) @@ -518,8 +519,9 @@ DownloadItem.INVALID_DOWNLOAD_ID, statusMessage); } }; - new AlertDialog.Builder( - ApplicationStatus.getLastTrackedFocusedActivity(), R.style.AlertDialogTheme) + new AlertDialog + .Builder(ApplicationStatus.getLastTrackedFocusedActivity(), + R.style.Theme_Chromium_AlertDialog) .setTitle(titleId) .setPositiveButton(R.string.ok, clickListener) .setCancelable(false)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java index c1bb7784..f07e9fd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java
@@ -437,7 +437,7 @@ if (!(context instanceof Activity)) return; Activity activity = (Activity) context; - new AlertDialog.Builder(activity, R.style.AlertDialogTheme) + new AlertDialog.Builder(activity, R.style.Theme_Chromium_AlertDialog) .setTitle(R.string.external_app_leave_incognito_warning_title) .setMessage(R.string.external_app_leave_incognito_warning) .setPositiveButton(R.string.external_app_leave_incognito_leave,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java index 0ded3e3..6b2eefcd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -429,12 +429,12 @@ /** * On tablets, where FRE activity is a dialog, transitions from fillscreen activities - * (the ones that use TabbedModeTheme, e.g. ChromeTabbedActivity) look ugly, because + * (the ones that use Theme.Chromium.TabbedMode, e.g. ChromeTabbedActivity) look ugly, because * when FRE is started from CTA.onCreate(), currently running animation for CTA window * is aborted. This is perceived as a flash of white and doesn't look good. * * To solve this, we added TabbedMode FRE activity, which has the same window background - * as TabbedModeTheme activities, but shows content in a FRE-like dialog. + * as Theme.Chromium.TabbedMode activities, but shows content in a FRE-like dialog. * * This function returns whether to use the TabbedModeFRE. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/translate/TranslateMenuHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/translate/TranslateMenuHelper.java index ca6d6c0b..ff1573b5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/translate/TranslateMenuHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/translate/TranslateMenuHelper.java
@@ -51,7 +51,7 @@ public TranslateMenuHelper(Context context, View anchorView, TranslateOptions options, TranslateMenuListener itemListener, boolean isIncognito) { - mContextWrapper = new ContextThemeWrapper(context, R.style.OverflowMenuTheme); + mContextWrapper = new ContextThemeWrapper(context, R.style.OverflowMenuThemeOverlay); mAnchorView = anchorView; mOptions = options; mMenuListener = itemListener; @@ -98,7 +98,7 @@ // caused an incorrectly drawn background. // TODO(martiw): We might need a new menu background here. mPopup.setBackgroundDrawable( - ContextCompat.getDrawable(mContextWrapper, R.drawable.popup_bg)); + ContextCompat.getDrawable(mContextWrapper, R.drawable.popup_bg_tinted)); mPopup.setOnItemClickListener(this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java index 213e4e6..cb77242 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
@@ -240,9 +240,6 @@ ChromeStrictMode.configureStrictMode(); ChromeWebApkHost.init(); - // Time this call takes in background from test devices: - // - Pixel 2: ~10 ms - // - Nokia 1 (Android Go): 20-200 ms warmUpSharedPrefs(); DeviceUtils.addDeviceSpecificUserAgentSwitch();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/InvalidStartupDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/init/InvalidStartupDialog.java index 45ca8f4..0c451128 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/InvalidStartupDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/InvalidStartupDialog.java
@@ -67,7 +67,7 @@ String message = arguments.getString(MESSAGE_KEY, "Failed to start"); AlertDialog.Builder builder = - new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme); + new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog); builder.setMessage(message) .setCancelable(true) .setPositiveButton(getResources().getString(android.R.string.ok), null);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/AppModalPresenter.java b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/AppModalPresenter.java index 7590b260..f57faed41 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/AppModalPresenter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/AppModalPresenter.java
@@ -55,7 +55,7 @@ return; } - mDialog = new Dialog(mActivity, R.style.ModalDialogTheme); + mDialog = new Dialog(mActivity, R.style.Theme_Chromium_ModalDialog); mDialog.setOnCancelListener(dialogInterface -> dismissCurrentDialog(DialogDismissalCause.NAVIGATE_BACK_OR_TOUCH_OUTSIDE)); // Cancel on touch outside should be disabled by default. The ModelChangeProcessor wouldn't
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalPresenter.java b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalPresenter.java index a8c3b5ce..65a5ca48 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalPresenter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalPresenter.java
@@ -141,10 +141,10 @@ @Override protected void addDialogView(PropertyModel model) { if (mDialogContainer == null) initDialogContainer(); - mDialogView = - (ModalDialogView) LayoutInflater - .from(new ContextThemeWrapper(mChromeActivity, R.style.ModalDialogTheme)) - .inflate(R.layout.modal_dialog_view, null); + mDialogView = (ModalDialogView) LayoutInflater + .from(new ContextThemeWrapper( + mChromeActivity, R.style.Theme_Chromium_ModalDialog)) + .inflate(R.layout.modal_dialog_view, null); mModelChangeProcessor = PropertyModelChangeProcessor.create(model, mDialogView, new ViewBinder()); @@ -354,7 +354,7 @@ FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER); - dialogView.setBackgroundResource(R.drawable.popup_bg); + dialogView.setBackgroundResource(R.drawable.popup_bg_tinted); mDialogContainer.addView(dialogView, params); mDialogContainer.setAlpha(0f); mDialogContainer.setVisibility(View.VISIBLE);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java index a84e064..bd2c5ede 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
@@ -62,9 +62,6 @@ private final ObserverList<OfflinePageModelObserver> mObservers = new ObserverList<OfflinePageModelObserver>(); - /** Whether an offline sub-feature is enabled or not. */ - private static Boolean sOfflineBookmarksEnabled; - /** * Callback used when saving an offline page. */ @@ -122,17 +119,6 @@ } /** - * @return True if saving bookmarked pages for offline viewing is enabled. - */ - public static boolean isOfflineBookmarksEnabled() { - ThreadUtils.assertOnUiThread(); - if (sOfflineBookmarksEnabled == null) { - sOfflineBookmarksEnabled = nativeIsOfflineBookmarksEnabled(); - } - return sOfflineBookmarksEnabled; - } - - /** * @return True if offline pages sharing is enabled. */ @VisibleForTesting @@ -747,16 +733,6 @@ nativeAcquireFileAccessPermission(mNativeOfflinePageBridge, webContents, callback); } - /** - * Allows setting the offline bookmarks feature as enabled or disabled for testing. This is - * required for tests that don't load the native binary otherwise UnsatisfiedLinkError sadness - * will occur. - */ - @VisibleForTesting - static void setOfflineBookmarksEnabledForTesting(boolean enabled) { - sOfflineBookmarksEnabled = enabled; - } - @CalledByNative protected void offlinePageModelLoaded() { mIsNativeOfflinePageModelLoaded = true; @@ -836,7 +812,6 @@ return loadUrlParams; } - private static native boolean nativeIsOfflineBookmarksEnabled(); private static native boolean nativeIsPageSharingEnabled(); private static native boolean nativeCanSavePage(String url); private static native OfflinePageBridge nativeGetOfflinePageBridgeForProfile(Profile profile);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java index bc32f61b..79d7274 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java
@@ -257,9 +257,6 @@ // If bookmark ID is missing there is nothing to save here. if (bookmarkId == null) return; - // Making sure the feature is enabled. - if (!OfflinePageBridge.isOfflineBookmarksEnabled()) return; - // Making sure tab is worth keeping. if (shouldSkipSavingTabOffline(tab)) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java index f633959..9e47aaf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java
@@ -189,7 +189,7 @@ } mAdapter = generateAccountsArrayAdapter(mContext, mCredentials); final AlertDialog.Builder builder = - new AlertDialog.Builder(mContext, R.style.AlertDialogTheme) + new AlertDialog.Builder(mContext, R.style.Theme_Chromium_AlertDialog) .setCustomTitle(titleView) .setNegativeButton(R.string.cancel, this) .setAdapter(mAdapter, new DialogInterface.OnClickListener() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AutoSigninFirstRunDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AutoSigninFirstRunDialog.java index 61eeb9d..cb749001 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AutoSigninFirstRunDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AutoSigninFirstRunDialog.java
@@ -67,7 +67,7 @@ private void show() { final AlertDialog.Builder builder = - new AlertDialog.Builder(mContext, R.style.AlertDialogTheme) + new AlertDialog.Builder(mContext, R.style.Theme_Chromium_AlertDialog) .setTitle(mTitle) .setPositiveButton(mOkButtonText, this) .setNegativeButton(mTurnOffButtonText, this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java index e86aeb96..bdd587d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java
@@ -294,7 +294,7 @@ return; } - new AlertDialog.Builder(activity, R.style.AlertDialogTheme) + new AlertDialog.Builder(activity, R.style.Theme_Chromium_AlertDialog) .setTitle(R.string.external_app_leave_incognito_warning_title) .setMessage(ChromeFeatureList.isEnabled(ChromeFeatureList.INCOGNITO_STRINGS) ? R.string.external_payment_app_leave_private_warning
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/permissions/AndroidPermissionRequester.java b/chrome/android/java/src/org/chromium/chrome/browser/permissions/AndroidPermissionRequester.java index 7d2968e9..647107fe 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/permissions/AndroidPermissionRequester.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/permissions/AndroidPermissionRequester.java
@@ -154,7 +154,7 @@ dialogText.setText(deniedStringId); AlertDialog.Builder builder = - new AlertDialog.Builder(activity, R.style.AlertDialogTheme); + new AlertDialog.Builder(activity, R.style.Theme_Chromium_AlertDialog); builder.setView(view); builder.setPositiveButton(R.string.infobar_update_permissions_button_text, new DialogInterface.OnClickListener() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogView.java b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogView.java index 7ecfd5e..72bca65 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogView.java
@@ -36,7 +36,8 @@ public PermissionDialogView(PermissionDialogDelegate delegate) { mDialogDelegate = delegate; ChromeActivity activity = mDialogDelegate.getTab().getActivity(); - AlertDialog.Builder builder = new AlertDialog.Builder(activity, R.style.AlertDialogTheme); + AlertDialog.Builder builder = + new AlertDialog.Builder(activity, R.style.Theme_Chromium_AlertDialog); mDialog = builder.create(); mDialog.getDelegate().setHandleNativeActionModesEnabled(false); mDialog.setCanceledOnTouchOutside(false);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialog.java index d86fa2c3..ae7a10ae 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialog.java
@@ -83,7 +83,7 @@ */ public PhotoPickerDialog(Context context, PhotoPickerListener listener, boolean multiSelectionAllowed, List<String> mimeTypes) { - super(context, R.style.FullscreenWhite); + super(context, R.style.Theme_Chromium_Fullscreen); mContext = context; mListenerWrapper = new PhotoPickerListenerWrapper(listener);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java index 0dd713f..39445d9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java
@@ -603,7 +603,7 @@ @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - return new AlertDialog.Builder(getActivity(), R.style.SigninAlertDialogTheme) + return new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog) .setTitle(R.string.cancel_sync_dialog_title) .setMessage(R.string.cancel_sync_dialog_message) .setNegativeButton(R.string.back, (dialog, which) -> dialog.cancel())
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java index a358e6d3..ff240f6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java
@@ -375,7 +375,7 @@ } }; - new AlertDialog.Builder(getContext(), R.style.AlertDialogTheme) + new AlertDialog.Builder(getContext(), R.style.Theme_Chromium_AlertDialog) .setTitle(DataReductionBrandingResourceProvider.getDataSaverBrandedString( R.string.data_reduction_usage_reset_statistics_confirmation_title)) .setMessage(DataReductionBrandingResourceProvider.getDataSaverBrandedString(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ExportErrorDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ExportErrorDialogFragment.java index fa584a1..c5f7300 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ExportErrorDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ExportErrorDialogFragment.java
@@ -68,7 +68,8 @@ } else { detailedDescription.setVisibility(View.GONE); } - return new AlertDialog.Builder(getActivity(), R.style.SimpleDialog) + return new AlertDialog + .Builder(getActivity(), R.style.Theme_Chromium_AlertDialog_NoActionBar) .setView(dialog) .setTitle(R.string.save_password_preferences_export_error_title) .setPositiveButton(mParams.positiveButtonLabelId, mHandler)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ExportWarningDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ExportWarningDialogFragment.java index 33b5830..93ba062 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ExportWarningDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ExportWarningDialogFragment.java
@@ -38,7 +38,8 @@ */ @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - return new AlertDialog.Builder(getActivity(), R.style.SimpleDialog) + return new AlertDialog + .Builder(getActivity(), R.style.Theme_Chromium_AlertDialog_NoActionBar) .setPositiveButton(R.string.save_password_preferences_export_action_title, mHandler) .setNegativeButton(R.string.cancel, mHandler) .setMessage(getActivity().getResources().getString(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ProgressBarDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ProgressBarDialogFragment.java index 77da777..2c46252 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ProgressBarDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ProgressBarDialogFragment.java
@@ -38,7 +38,8 @@ MaterialProgressBar bar = (MaterialProgressBar) dialog.findViewById(R.id.passwords_progress_bar); bar.setIndeterminate(true); - return new AlertDialog.Builder(getActivity(), R.style.SimpleDialog) + return new AlertDialog + .Builder(getActivity(), R.style.Theme_Chromium_AlertDialog_NoActionBar) .setView(dialog) .setNegativeButton(R.string.cancel, mHandler) .setTitle(getActivity().getResources().getString(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ConfirmImportantSitesDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ConfirmImportantSitesDialogFragment.java index ed0c51d..1b145f3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ConfirmImportantSitesDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ConfirmImportantSitesDialogFragment.java
@@ -318,10 +318,10 @@ mSitesListView.setAdapter(mAdapter); mSitesListView.setOnItemClickListener(mAdapter); final AlertDialog.Builder builder = - new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme) + new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog) .setTitle(R.string.storage_clear_site_storage_title) - .setPositiveButton(R.string.clear_browsing_data_important_dialog_button, - listener) + .setPositiveButton( + R.string.clear_browsing_data_important_dialog_button, listener) .setNegativeButton(R.string.cancel, listener) .setView(messageAndListView); mDialog = builder.create();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/OtherFormsOfHistoryDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/OtherFormsOfHistoryDialogFragment.java index a86dd2f..2ea0c118 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/OtherFormsOfHistoryDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/OtherFormsOfHistoryDialogFragment.java
@@ -66,12 +66,12 @@ textView.setMovementMethod(LinkMovementMethod.getInstance()); // Construct the dialog. - AlertDialog dialog = new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme) - .setView(view) - .setTitle(R.string.clear_browsing_data_history_dialog_title) - .setPositiveButton( - R.string.ok_got_it, this) - .create(); + AlertDialog dialog = + new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog) + .setView(view) + .setTitle(R.string.clear_browsing_data_history_dialog_title) + .setPositiveButton(R.string.ok_got_it, this) + .create(); dialog.setCanceledOnTouchOutside(false); return dialog;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/AddExceptionPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/AddExceptionPreference.java index 050fd676..d8c2b27 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/AddExceptionPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/AddExceptionPreference.java
@@ -109,7 +109,8 @@ } }; - AlertDialog.Builder alert = new AlertDialog.Builder(getContext(), R.style.AlertDialogTheme); + AlertDialog.Builder alert = + new AlertDialog.Builder(getContext(), R.style.Theme_Chromium_AlertDialog); AlertDialog alertDialog = alert .setTitle(R.string.website_settings_add_site_dialog_title) .setMessage(mDialogMessage)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java index d564cbb..db3e5ee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java
@@ -775,15 +775,16 @@ } // Handle the Clear & Reset preference click by showing a confirmation. - new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme) + new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog) .setTitle(R.string.website_reset) .setMessage(R.string.website_reset_confirmation) - .setPositiveButton(R.string.website_reset, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - resetSite(); - } - }) + .setPositiveButton(R.string.website_reset, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + resetSite(); + } + }) .setNegativeButton(R.string.cancel, null) .show(); return true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java index b696f50..447687d6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
@@ -434,7 +434,8 @@ final ShareDialogAdapter adapter = new ShareDialogAdapter(activity, manager, resolveInfoList); - AlertDialog.Builder builder = new AlertDialog.Builder(activity, R.style.AlertDialogTheme); + AlertDialog.Builder builder = + new AlertDialog.Builder(activity, R.style.Theme_Chromium_AlertDialog); builder.setTitle(activity.getString(R.string.share_link_chooser_title)); builder.setAdapter(adapter, null);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountAdder.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountAdder.java index 0fe85a8e..f1bccf3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountAdder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountAdder.java
@@ -53,7 +53,7 @@ private void onOpenAddGoogleAccountPageFailed(final Activity activity, final int result) { AlertDialog.Builder builder = - new AlertDialog.Builder(activity, R.style.SigninAlertDialogTheme); + new AlertDialog.Builder(activity, R.style.Theme_Chromium_AlertDialog); builder.setMessage(R.string.signin_open_add_google_account_page_failed); builder.setPositiveButton(R.string.signin_open_settings_accounts, (dialog, which) -> { // Open Accounts page in device's Settings app.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountPickerDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountPickerDialogFragment.java index 10ccee78..b55b28af 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountPickerDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountPickerDialogFragment.java
@@ -230,7 +230,7 @@ @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = - new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme); + new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog); LayoutInflater inflater = LayoutInflater.from(builder.getContext()); RecyclerView recyclerView = (RecyclerView) inflater.inflate(R.layout.account_picker_dialog_body, null);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java index 2727dd3..903b4b6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java
@@ -172,7 +172,7 @@ layout.addView(mConfirmImportOption); } - return new AlertDialog.Builder(getActivity(), R.style.SigninAlertDialogTheme) + return new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog) .setPositiveButton(R.string.continue_button, this) .setNegativeButton(R.string.cancel, this) .setView(v)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmManagedSyncDataDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmManagedSyncDataDialog.java index da567f2..305c3a586 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmManagedSyncDataDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmManagedSyncDataDialog.java
@@ -133,7 +133,7 @@ String positiveButton = getArguments().getString(KEY_POSITIVE_BUTTON); String negativeButton = getArguments().getString(KEY_NEGATIVE_BUTTON); - return new AlertDialog.Builder(getActivity(), R.style.SigninAlertDialogTheme) + return new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog) .setTitle(title) .setMessage(description) .setPositiveButton(positiveButton, this)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachineDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachineDelegate.java index 249d9e4..3f1a97b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachineDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachineDelegate.java
@@ -65,7 +65,7 @@ dismiss(); } - return new AlertDialog.Builder(getActivity(), R.style.SigninAlertDialogTheme) + return new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog) .setView(R.layout.signin_progress_bar_dialog) .setNegativeButton(R.string.cancel, (dialog, i) -> dialog.cancel()) .create(); @@ -107,7 +107,7 @@ dismiss(); } - return new AlertDialog.Builder(getActivity(), R.style.SigninAlertDialogTheme) + return new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog) .setTitle(R.string.sign_in_timeout_title) .setMessage(R.string.sign_in_timeout_message) .setNegativeButton(R.string.cancel, (dialog, which) -> dialog.cancel())
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java index ae7f802..faf320d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java
@@ -70,7 +70,7 @@ String message = domain == null ? getString(R.string.signout_message) : getString(R.string.signout_managed_account_message, domain); - return new AlertDialog.Builder(getActivity(), R.style.SigninAlertDialogTheme) + return new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog) .setTitle(R.string.signout_title) .setPositiveButton(R.string.continue_button, this) .setNegativeButton(R.string.cancel, this) @@ -83,7 +83,7 @@ String message = domain == null ? getString(R.string.signout_message_legacy) : getString(R.string.signout_managed_account_message, domain); - return new AlertDialog.Builder(getActivity(), R.style.SigninAlertDialogTheme) + return new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog) .setTitle(R.string.signout_title_legacy) .setPositiveButton(R.string.signout_dialog_positive_button, this) .setNegativeButton(R.string.cancel, this)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBinder.java index b2a44a3..a7a1c94 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBinder.java
@@ -238,7 +238,7 @@ new ColorDrawable(mSuggestion.getThumbnailDominantColor() != null ? mSuggestion.getThumbnailDominantColor() : ApiCompatibilityUtils.getColor(mThumbnailView.getResources(), - R.color.thumbnail_placeholder_on_white_bg)); + R.color.thumbnail_placeholder_on_primary_bg)); mThumbnailView.setImageDrawable(colorDrawable); } else { mThumbnailView.setImageResource(R.drawable.ic_snippet_thumbnail_placeholder);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseCreationDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseCreationDialogFragment.java index 3fae113c..a41c880 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseCreationDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseCreationDialogFragment.java
@@ -58,12 +58,13 @@ instructionsView.setMovementMethod(LinkMovementMethod.getInstance()); instructionsView.setText(getInstructionsText()); - AlertDialog dialog = new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme) - .setView(view) - .setTitle(R.string.sync_passphrase_type_custom_dialog_title) - .setPositiveButton(R.string.save, null) - .setNegativeButton(R.string.cancel, null) - .create(); + AlertDialog dialog = + new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog) + .setView(view) + .setTitle(R.string.sync_passphrase_type_custom_dialog_title) + .setPositiveButton(R.string.save, null) + .setNegativeButton(R.string.cancel, null) + .create(); dialog.getDelegate().setHandleNativeActionModesEnabled(false); return dialog; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java index d6f5d99..dab49ce 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java
@@ -130,19 +130,21 @@ ApiCompatibilityUtils.getColor(getResources(), R.color.input_underline_error_color), PorterDuff.Mode.SRC_IN); - final AlertDialog d = new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme) - .setView(v) - .setPositiveButton(R.string.submit, new Dialog.OnClickListener() { - @Override - public void onClick(DialogInterface d, int which) { - // We override the onclick. This is a hack to not dismiss the dialog after - // click of OK and instead dismiss it after confirming the passphrase - // is correct. - } - }) - .setNegativeButton(R.string.cancel, this) - .setTitle(R.string.sign_in_google_account) - .create(); + final AlertDialog d = + new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog) + .setView(v) + .setPositiveButton(R.string.submit, + new Dialog.OnClickListener() { + @Override + public void onClick(DialogInterface d, int which) { + // We override the onclick. This is a hack to not dismiss + // the dialog after click of OK and instead dismiss it after + // confirming the passphrase is correct. + } + }) + .setNegativeButton(R.string.cancel, this) + .setTitle(R.string.sign_in_google_account) + .create(); d.getDelegate().setHandleNativeActionModesEnabled(false); d.setOnShowListener(new DialogInterface.OnShowListener() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragment.java index 4f6af6d..1cdf8df0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragment.java
@@ -184,7 +184,7 @@ list.setSelection(adapter.getPositionForType(currentType)); // Create and return the dialog - return new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme) + return new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog) .setNegativeButton(R.string.cancel, this) .setTitle(R.string.sync_passphrase_type_title) .setView(v)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java index 36fbfe0..ca7be01 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -406,7 +406,8 @@ Drawable drawable = ApiCompatibilityUtils.getDrawable( resources, R.drawable.modern_toolbar_background_white); drawable.mutate(); - drawable.setColorFilter(ApiCompatibilityUtils.getColor(resources, R.color.modern_grey_100), + drawable.setColorFilter( + ApiCompatibilityUtils.getColor(resources, R.color.toolbar_search_background), PorterDuff.Mode.SRC_IN); return drawable; } @@ -2422,9 +2423,9 @@ } DrawableCompat.setTint(mLocationBarBackground, - isIncognito() - ? Color.WHITE - : ApiCompatibilityUtils.getColor(getResources(), R.color.modern_grey_100)); + isIncognito() ? Color.WHITE + : ApiCompatibilityUtils.getColor( + getResources(), R.color.toolbar_search_background)); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsBridge.java index 97d03a2d..4c94676e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsBridge.java
@@ -8,7 +8,9 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.usage_stats.WebsiteEventProtos.WebsiteEvent; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -50,7 +52,15 @@ public void addEvents(List<WebsiteEvent> events, Callback<Boolean> callback) { assert mNativeUsageStatsBridge != 0; - nativeAddEvents(mNativeUsageStatsBridge, events, callback); + + byte[][] serializedEvents = new byte[events.size()][]; + + for (int i = 0; i < events.size(); i++) { + WebsiteEvent event = events.get(i); + serializedEvents[i] = event.toByteArray(); + } + + nativeAddEvents(mNativeUsageStatsBridge, serializedEvents, callback); } public void deleteAllEvents(Callback<Boolean> callback) { @@ -114,6 +124,23 @@ callback.onResult(map); } + @CalledByNative + private static void createEventListAndRunCallback( + byte[][] serializedEvents, Callback<List<WebsiteEvent>> callback) { + List<WebsiteEvent> events = new ArrayList<>(serializedEvents.length); + + for (byte[] serialized : serializedEvents) { + try { + WebsiteEvent event = WebsiteEvent.parseFrom(serialized); + events.add(event); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + // Consume exception for now, ignoring unparseable events. + } + } + + callback.onResult(events); + } + private native long nativeInit(Profile profile); private native void nativeDestroy(long nativeUsageStatsBridge); private native void nativeGetAllEvents( @@ -121,7 +148,7 @@ private native void nativeQueryEventsInRange(long nativeUsageStatsBridge, long start, long end, Callback<List<WebsiteEvent>> callback); private native void nativeAddEvents( - long nativeUsageStatsBridge, List<WebsiteEvent> events, Callback<Boolean> callback); + long nativeUsageStatsBridge, byte[][] events, Callback<Boolean> callback); private native void nativeDeleteAllEvents( long nativeUsageStatsBridge, Callback<Boolean> callback); private native void nativeDeleteEventsInRange(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java index 63bb0e4..d79a126 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java
@@ -130,25 +130,26 @@ if (sOldTalkBackVersionAlertShown) return; sOldTalkBackVersionAlertShown = true; - AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.AlertDialogTheme) - .setTitle(R.string.old_talkback_title) - .setPositiveButton(R.string.update_from_market, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - Uri marketUri = Uri.parse(TALKBACK_MARKET_LINK); - Intent marketIntent = new Intent( - Intent.ACTION_VIEW, marketUri); - context.startActivity(marketIntent); - } - }) - .setNegativeButton(R.string.cancel_talkback_alert, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - // Do nothing, this alert is only shown once either way. - } - }); + AlertDialog.Builder builder = + new AlertDialog.Builder(context, R.style.Theme_Chromium_AlertDialog) + .setTitle(R.string.old_talkback_title) + .setPositiveButton(R.string.update_from_market, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + Uri marketUri = Uri.parse(TALKBACK_MARKET_LINK); + Intent marketIntent = + new Intent(Intent.ACTION_VIEW, marketUri); + context.startActivity(marketIntent); + } + }) + .setNegativeButton(R.string.cancel_talkback_alert, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + // Do nothing, this alert is only shown once either way. + } + }); AlertDialog dialog = builder.create(); dialog.show(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java index 11f6916b..583ce3be 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java
@@ -194,13 +194,11 @@ cacheNightModeAvailable(); cacheDownloadAutoResumptionEnabledInNative(); - // Propagate DONT_PREFETCH_LIBRARIES and REACHED_CODE_PROFILER feature values to - // LibraryLoader. This can't be done in LibraryLoader itself because it lives in //base and - // can't depend on ChromeFeatureList. + // Propagate DONT_PREFETCH_LIBRARIES feature value to LibraryLoader. This can't + // be done in LibraryLoader itself because it lives in //base and can't depend + // on ChromeFeatureList. LibraryLoader.setDontPrefetchLibrariesOnNextRuns( ChromeFeatureList.isEnabled(ChromeFeatureList.DONT_PREFETCH_LIBRARIES)); - LibraryLoader.setReachedCodeProfilerEnabledOnNextRuns( - ChromeFeatureList.isEnabled(ChromeFeatureList.REACHED_CODE_PROFILER)); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreJavaUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreJavaUtils.java index 5341400..fcc6cacc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreJavaUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreJavaUtils.java
@@ -23,7 +23,6 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.components.module_installer.ModuleInstaller; - /** * Provides ARCore classes access to java-related app functionality. */ @@ -153,7 +152,7 @@ if (mNativeArCoreJavaUtils != 0) { if (success) { ui.showInstallSuccessUi(); - nativeOnRequestInstallSupportedArCoreResult(mNativeArCoreJavaUtils, success); + nativeOnRequestInstallArModuleResult(mNativeArCoreJavaUtils, success); } else { ui.showInstallFailureUi(); // early exit - user will be offered a choice to retry & install flow will @@ -167,6 +166,7 @@ @CalledByNative private void requestInstallSupportedArCore(final Tab tab) { assert shouldRequestInstallSupportedArCore(); + @ArCoreShim.Availability int arCoreAvailability = getArCoreInstallStatus(); final Activity activity = tab.getActivity();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrModalPresenter.java b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrModalPresenter.java index 14064522..970f9ee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrModalPresenter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrModalPresenter.java
@@ -42,7 +42,7 @@ mVrDialog = new VrDialog(mContext, mVrDialogManager); ModalDialogView dialogView = (ModalDialogView) LayoutInflater - .from(new ContextThemeWrapper(mContext, R.style.ModalDialogTheme)) + .from(new ContextThemeWrapper(mContext, R.style.Theme_Chromium_ModalDialog)) .inflate(R.layout.modal_dialog_view, null); mModelChangeProcessor = PropertyModelChangeProcessor.create(model, dialogView, new ModalDialogViewBinder());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/AddToHomescreenDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/AddToHomescreenDialog.java index cad435d8..fe78b8c2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/AddToHomescreenDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/AddToHomescreenDialog.java
@@ -94,7 +94,7 @@ public void show() { View view = mActivity.getLayoutInflater().inflate(R.layout.add_to_homescreen_dialog, null); AlertDialog.Builder builder = - new AlertDialog.Builder(mActivity, R.style.AlertDialogTheme) + new AlertDialog.Builder(mActivity, R.style.Theme_Chromium_AlertDialog) .setTitle(AppBannerManager.getHomescreenLanguageOption()) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkOfflineDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkOfflineDialog.java index 684517c3..05e436e8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkOfflineDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkOfflineDialog.java
@@ -29,7 +29,8 @@ * @param errorMessage */ public void show(final Activity activity, String errorMessage) { - AlertDialog.Builder builder = new AlertDialog.Builder(activity, R.style.AlertDialogTheme); + AlertDialog.Builder builder = + new AlertDialog.Builder(activity, R.style.Theme_Chromium_AlertDialog); builder.setMessage(errorMessage) .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ListMenuButton.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ListMenuButton.java index 2ccfbe6..1da0f140 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/ListMenuButton.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ListMenuButton.java
@@ -222,8 +222,8 @@ ViewRectProvider rectProvider = new ViewRectProvider(this); rectProvider.setIncludePadding(true); mPopupMenu = new AnchoredPopupWindow(getContext(), this, - ApiCompatibilityUtils.getDrawable(getResources(), R.drawable.popup_bg), contentView, - rectProvider); + ApiCompatibilityUtils.getDrawable(getResources(), R.drawable.popup_bg_tinted), + contentView, rectProvider); mPopupMenu.setVerticalOverlapAnchor(true); mPopupMenu.setHorizontalOverlapAnchor(true); mPopupMenu.setMaxWidth(mMenuWidth);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/PulseDrawable.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/PulseDrawable.java index 5c532d6..769af18 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/PulseDrawable.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/PulseDrawable.java
@@ -154,7 +154,8 @@ @ColorInt int color = ApiCompatibilityUtils.getColor(resources, - useLightPulseColor ? R.color.modern_grey_100 : R.color.default_icon_color_blue); + useLightPulseColor ? R.color.modern_secondary_color + : R.color.default_icon_color_blue); if (mState.color == color) return; int alpha = getAlpha();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorDialog.java index b5dca4d..a8aae94 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorDialog.java
@@ -112,7 +112,7 @@ */ public EditorDialog( Activity activity, EditorObserverForTest observerForTest, Runnable deleteRunnable) { - super(activity, R.style.FullscreenWhite); + super(activity, R.style.Theme_Chromium_Fullscreen); // Sets transparent background for animating content view. getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); mContext = activity;
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index c085517..f842104 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -3,8 +3,6 @@ # found in the LICENSE file. import("//chrome/android/feed/feed_java_sources.gni") -import( - "//chrome/android/java/src/org/chromium/chrome/browser/usage_stats/features.gni") import("//components/feed/features.gni") import("//components/offline_pages/buildflags/features.gni") import("//device/vr/buildflags/buildflags.gni") @@ -1900,7 +1898,6 @@ "javatests/src/org/chromium/chrome/browser/PowerBroadcastReceiverTest.java", "javatests/src/org/chromium/chrome/browser/PrerenderTest.java", "javatests/src/org/chromium/chrome/browser/ProcessIsolationTest.java", - "javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java", "javatests/src/org/chromium/chrome/browser/RestoreHistogramTest.java", "javatests/src/org/chromium/chrome/browser/SafeBrowsingTest.java", "javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java deleted file mode 100644 index fa025940..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java +++ /dev/null
@@ -1,118 +0,0 @@ -// Copyright 2019 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; - -import android.support.test.filters.SmallTest; - -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.BaseSwitches; -import org.chromium.base.StrictModeContext; -import org.chromium.base.test.ReachedCodeProfiler; -import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; -import org.chromium.chrome.test.ChromeActivityTestRule; -import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.chrome.test.util.browser.Features.DisableFeatures; -import org.chromium.chrome.test.util.browser.Features.EnableFeatures; - -/** - * Tests for the reached code profiler feature setup. - */ -@RunWith(ChromeJUnit4ClassRunner.class) -@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -public final class ReachedCodeProfilerTest { - @Rule - public ChromeActivityTestRule<ChromeActivity> mActivityTestRule = - new ChromeActivityTestRule<>(ChromeActivity.class); - - // Shared preferences key for the reached code profiler. - private static final String REACHED_CODE_PROFILER_ENABLED_KEY = "reached_code_profiler_enabled"; - - /** - * Tests that passing a command line switch enables the reached code profiler no matter what. - */ - @Test - @SmallTest - @DisableFeatures(ChromeFeatureList.REACHED_CODE_PROFILER) - @CommandLineFlags.Add(BaseSwitches.ENABLE_REACHED_CODE_PROFILER) - public void testExplicitlyEnableViaCommandLineSwitch() throws Exception { - mActivityTestRule.startMainActivityFromLauncher(); - assertReachedCodeProfilerIsEnabled(); - } - - /** - * Tests that setting a shared preference enables the reached code profiler. This test imitates - * the second launch after enabling the feature - */ - @Test - @SmallTest - @EnableFeatures(ChromeFeatureList.REACHED_CODE_PROFILER) - public void testEnabledViaCachedSharedPreference() throws Exception { - setReachedCodeProfilerSharedPreference(true); - mActivityTestRule.startMainActivityFromLauncher(); - assertReachedCodeProfilerIsEnabled(); - } - - /** - * Tests that the feature state is cached in shared preferences after native initialization. - * This test imitates the first run when the feature is enabled. - */ - @Test - @SmallTest - @EnableFeatures(ChromeFeatureList.REACHED_CODE_PROFILER) - public void testSharedPreferenceIsCached_Enable() throws Exception { - mActivityTestRule.startMainActivityFromLauncher(); - - Assert.assertTrue(getReachedCodeProfilerSharedPreference()); - // Enabling takes effect only on the second startup. - Assert.assertFalse(ReachedCodeProfiler.isEnabled()); - } - - /** - * Tests that the feature state is cached in shared preferences after native initialization. - * This test imitates disabling the reached code profiler after it has been enabled for some - * time. - */ - @Test - @SmallTest - @DisableFeatures(ChromeFeatureList.REACHED_CODE_PROFILER) - public void testSharedPreferenceIsCached_Disable() throws Exception { - setReachedCodeProfilerSharedPreference(true); - mActivityTestRule.startMainActivityFromLauncher(); - - Assert.assertFalse(getReachedCodeProfilerSharedPreference()); - // Disabling takes effect only on the second startup. - assertReachedCodeProfilerIsEnabled(); - } - - /** - * The reached code profiler is always disabled in some configurations. This helper allows to - * check if the profiler is enabled in supported configurations. - */ - private void assertReachedCodeProfilerIsEnabled() { - if (!ReachedCodeProfiler.isSupported()) { - Assert.assertFalse(ReachedCodeProfiler.isEnabled()); - return; - } - - Assert.assertTrue(ReachedCodeProfiler.isEnabled()); - } - - private boolean getReachedCodeProfilerSharedPreference() { - try (StrictModeContext unused = StrictModeContext.allowDiskReads()) { - return ChromePreferenceManager.getInstance().readBoolean( - REACHED_CODE_PROFILER_ENABLED_KEY, false); - } - } - - private void setReachedCodeProfilerSharedPreference(boolean value) { - ChromePreferenceManager.getInstance().writeBoolean( - REACHED_CODE_PROFILER_ENABLED_KEY, value); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/home/DownloadActivityV2Test.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/home/DownloadActivityV2Test.java index 9d05052d..e8878c74 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/home/DownloadActivityV2Test.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/home/DownloadActivityV2Test.java
@@ -21,6 +21,7 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.test.util.Restriction; +import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.download.home.list.UiUtils; @@ -57,7 +58,7 @@ RecordUserAction.setDisabledForTests(true); RecordHistogram.setDisabledForTests(true); UiUtils.setDisableUrlFormattingForTests(true); - DummyUiActivity.setTestTheme(org.chromium.chrome.R.style.FullscreenWhiteActivityTheme); + DummyUiActivity.setTestTheme(R.style.Theme_Chromium_Activity_Fullscreen); } @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedConfigurationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedConfigurationTest.java index 1af3334..02de97c5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedConfigurationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedConfigurationTest.java
@@ -40,6 +40,7 @@ FeedConfiguration.getFeedServerMethod()); Assert.assertEquals(FeedConfiguration.FEED_SERVER_RESPONSE_LENGTH_PREFIXED_DEFAULT, FeedConfiguration.getFeedServerResponseLengthPrefixed()); + Assert.assertFalse(FeedConfiguration.getFeedUiEnabled()); Assert.assertEquals(FeedConfiguration.INITIAL_NON_CACHED_PAGE_SIZE_DEFAULT, FeedConfiguration.getInitialNonCachedPageSize()); Assert.assertEquals(FeedConfiguration.LOGGING_IMMEDIATE_CONTENT_THRESHOLD_MS_DEFAULT, @@ -52,6 +53,7 @@ FeedConfiguration.getSessionLifetimeMs()); Assert.assertFalse(FeedConfiguration.getTriggerImmediatePagination()); Assert.assertTrue(FeedConfiguration.getUseTimeoutScheduler()); + Assert.assertFalse(FeedConfiguration.getUseSecondaryPageRequest()); Assert.assertEquals(FeedConfiguration.VIEW_LOG_THRESHOLD_DEFAULT, FeedConfiguration.getViewLogThreshold(), ASSERT_EQUALS_DOUBLE_DELTA); } @@ -89,6 +91,16 @@ @Feature({"Feed"}) @CommandLineFlags. Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group", + "force-fieldtrial-params=Trial.Group:feed_ui_enabled/true"}) + public void + testFeedUiEnabled() { + Assert.assertTrue(FeedConfiguration.getFeedUiEnabled()); + } + + @Test + @Feature({"Feed"}) + @CommandLineFlags. + Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group", "force-fieldtrial-params=Trial.Group:initial_non_cached_page_size/100"}) public void testInitialNonCachedPageSize() { @@ -157,6 +169,16 @@ @Feature({"Feed"}) @CommandLineFlags. Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group", + "force-fieldtrial-params=Trial.Group:use_secondary_page_request/true"}) + public void + testUseSecondaryPageRequest() { + Assert.assertTrue(FeedConfiguration.getUseSecondaryPageRequest()); + } + + @Test + @Feature({"Feed"}) + @CommandLineFlags. + Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group", "force-fieldtrial-params=Trial.Group:view_log_threshold/0.33"}) public void testViewLogThreshold() { Assert.assertEquals( @@ -174,6 +196,7 @@ configuration.getValueOrDefault(ConfigKey.FEED_SERVER_METHOD, "")); Assert.assertEquals(FeedConfiguration.FEED_SERVER_RESPONSE_LENGTH_PREFIXED_DEFAULT, configuration.getValueOrDefault(ConfigKey.FEED_SERVER_RESPONSE_LENGTH_PREFIXED, 0)); + Assert.assertFalse(configuration.getValueOrDefault(ConfigKey.FEED_UI_ENABLED, true)); Assert.assertEquals(Integer.valueOf(FeedConfiguration.INITIAL_NON_CACHED_PAGE_SIZE_DEFAULT), configuration.getValueOrDefault(ConfigKey.INITIAL_NON_CACHED_PAGE_SIZE, 0)); Assert.assertEquals( @@ -189,6 +212,8 @@ Assert.assertFalse( configuration.getValueOrDefault(ConfigKey.TRIGGER_IMMEDIATE_PAGINATION, true)); Assert.assertTrue(configuration.getValueOrDefault(ConfigKey.USE_TIMEOUT_SCHEDULER, false)); + Assert.assertFalse( + configuration.getValueOrDefault(ConfigKey.USE_SECONDARY_PAGE_REQUEST, true)); Assert.assertEquals(Double.valueOf(FeedConfiguration.VIEW_LOG_THRESHOLD_DEFAULT), configuration.getValueOrDefault(ConfigKey.VIEW_LOG_THRESHOLD, 0d), ASSERT_EQUALS_DOUBLE_DELTA);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarControlLayoutTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarControlLayoutTest.java index 231cdbb..61bc51c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarControlLayoutTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarControlLayoutTest.java
@@ -44,7 +44,7 @@ @Before public void setUp() throws Exception { mContext = InstrumentationRegistry.getTargetContext(); - mContext.setTheme(R.style.MainTheme); + mContext.setTheme(R.style.Theme_Chromium_WithWindowAnimation); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/UkmTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/UkmTest.java index 13d6530..bb4ed6c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/UkmTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/UkmTest.java
@@ -16,7 +16,6 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.browsing_data.BrowsingDataType; import org.chromium.chrome.browser.browsing_data.TimePeriod; @@ -69,7 +68,6 @@ // @UIThreadTest. @Test @SmallTest - @DisabledTest // TODO(https://crbug.com/842999): Reenable after unflaking. public void testRegularPlusIncognitoCheck() throws Exception { // Keep in sync with UkmBrowserTest.RegularPlusIncognitoCheck in // chrome/browser/metrics/ukm_browsertest.cc.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewTest.java index 0b5d47a..1595324 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewTest.java
@@ -79,10 +79,10 @@ mModelBuilder = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS); mContentView = new FrameLayout(activity); - mModalDialogView = - (ModalDialogView) LayoutInflater - .from(new ContextThemeWrapper(activity, R.style.ModalDialogTheme)) - .inflate(R.layout.modal_dialog_view, null); + mModalDialogView = (ModalDialogView) LayoutInflater + .from(new ContextThemeWrapper( + activity, R.style.Theme_Chromium_ModalDialog)) + .inflate(R.layout.modal_dialog_view, null); activity.setContentView(mContentView); mContentView.addView(mModalDialogView, MATCH_PARENT, WRAP_CONTENT);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/DualControlLayoutTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/DualControlLayoutTest.java index 6efeb99..d17293b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/DualControlLayoutTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/DualControlLayoutTest.java
@@ -54,7 +54,7 @@ @Before public void setUp() throws Exception { mContext = InstrumentationRegistry.getTargetContext(); - mContext.setTheme(R.style.MainTheme); + mContext.setTheme(R.style.Theme_Chromium_WithWindowAnimation); mTinyControlWidth = INFOBAR_WIDTH / 4; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ViewHighlighterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ViewHighlighterTest.java index 4f5c0ae..8c9c44c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ViewHighlighterTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ViewHighlighterTest.java
@@ -37,7 +37,7 @@ @Before public void setUp() throws Exception { mContext = InstrumentationRegistry.getTargetContext(); - mContext.setTheme(R.style.MainTheme); + mContext.setTheme(R.style.Theme_Chromium_WithWindowAnimation); } @Test
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsUnitTest.java index 90295d8..5b12624 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsUnitTest.java
@@ -86,10 +86,6 @@ .when(mOfflinePageUtils) .getOfflinePageBridge((Profile) isNull()); OfflinePageUtils.setInstanceForTesting(mOfflinePageUtils); - - // Setting the default value is required because unit tests don't load native code needed - // to normally call the respective getter. - OfflinePageBridge.setOfflineBookmarksEnabledForTesting(true); } @Test @@ -125,14 +121,6 @@ any(OfflinePageBridge.SavePageCallback.class)); BookmarkId bookmarkId = new BookmarkId(42, BookmarkType.NORMAL); - OfflinePageBridge.setOfflineBookmarksEnabledForTesting(false); - OfflinePageUtils.saveBookmarkOffline(bookmarkId, mTab); - // Save page not called because offline bookmarks are disabled. - verify(mOfflinePageBridge, times(0)) - .savePage(eq(mWebContents), any(ClientId.class), - any(OfflinePageBridge.SavePageCallback.class)); - - OfflinePageBridge.setOfflineBookmarksEnabledForTesting(true); doReturn(true).when(mTab).isShowingErrorPage(); OfflinePageUtils.saveBookmarkOffline(bookmarkId, mTab); // Save page not called because tab is showing an error page.
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index aa590e7..a06641d 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -8312,10 +8312,10 @@ <ph name="ACTION_NAME">$1<ex>Compose</ex></ph> with <ph name="APP_NAME">$2<ex>GMail</ex></ph>. </message> <message name="IDS_APP_LIST_REMOVE_SUGGESTION_ACCESSIBILITY_NAME" desc="The spoken feedback for removing suggestion button"> - Remove this suggestion + Remove the suggestion <ph name="SUGGESTION_NAME">$1<ex>Harry Potter</ex></ph> </message> <message name="IDS_APP_LIST_APPEND_SUGGESTION_ACCESSIBILITY_NAME" desc="The spoken feedback for appending suggestion button"> - Append this suggestion to search box + Append the suggestion <ph name="SUGGESTION_NAME">$1<ex>Harry Potter</ex></ph> to search box </message> <if expr="not use_titlecase"> <message name="IDS_APP_LIST_CONTEXT_MENU_NEW_TAB" desc="Title text for the 'open new' context menu item of an app list item configured to open in a tab">
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index dda0ea7..f24f352 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -33,8 +33,6 @@ # produces a conflict for the "grit" template so we have to only include one. if (is_android) { import("//build/config/android/rules.gni") - import( - "//chrome/android/java/src/org/chromium/chrome/browser/usage_stats/features.gni") } else { import("//tools/grit/grit_rule.gni") } @@ -1687,8 +1685,6 @@ "translate/translate_service.h", "undo/bookmark_undo_service_factory.cc", "undo/bookmark_undo_service_factory.h", - "unified_consent/chrome_unified_consent_service_client.cc", - "unified_consent/chrome_unified_consent_service_client.h", "unified_consent/unified_consent_service_factory.cc", "unified_consent/unified_consent_service_factory.h", "update_client/chrome_update_query_params_delegate.cc", @@ -5413,8 +5409,6 @@ "subresource_filter/test_ruleset_publisher.h", "sync/profile_sync_test_util.cc", "sync/profile_sync_test_util.h", - "unified_consent/unified_consent_test_util.cc", - "unified_consent/unified_consent_test_util.h", ] configs += [ "//build/config:precompiled_headers" ]
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 53cb707..ed91404 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2215,9 +2215,6 @@ FEATURE_VALUE_TYPE(chrome::android::kProgressBarThrottleFeature)}, #endif // OS_ANDROID #if defined(OS_ANDROID) - {"offline-bookmarks", flag_descriptions::kOfflineBookmarksName, - flag_descriptions::kOfflineBookmarksDescription, kOsAndroid, - FEATURE_VALUE_TYPE(offline_pages::kOfflineBookmarksFeature)}, {"offline-pages-load-signal-collecting", flag_descriptions::kOfflinePagesLoadSignalCollectingName, flag_descriptions::kOfflinePagesLoadSignalCollectingDescription,
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index 25f1dc8..ed6aaea 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -146,7 +146,6 @@ &kProgressBarThrottleFeature, &kPwaImprovedSplashScreen, &kPwaPersistentNotification, - &kReachedCodeProfiler, &kReaderModeInCCT, &kSearchReadyOmniboxFeature, &kSearchEnginePromoExistingDevice, @@ -411,9 +410,6 @@ const base::Feature kPwaPersistentNotification{ "PwaPersistentNotification", base::FEATURE_ENABLED_BY_DEFAULT}; -const base::Feature kReachedCodeProfiler{"ReachedCodeProfiler", - base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kReaderModeInCCT{"ReaderModeInCCT", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index 7521a2f..e527f3d 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -78,7 +78,6 @@ extern const base::Feature kProgressBarThrottleFeature; extern const base::Feature kPwaImprovedSplashScreen; extern const base::Feature kPwaPersistentNotification; -extern const base::Feature kReachedCodeProfiler; extern const base::Feature kReaderModeInCCT; extern const base::Feature kSearchReadyOmniboxFeature; extern const base::Feature kServiceManagerForDownload;
diff --git a/chrome/browser/android/usage_stats/usage_stats_bridge.cc b/chrome/browser/android/usage_stats/usage_stats_bridge.cc index 34e8de1..18ac507 100644 --- a/chrome/browser/android/usage_stats/usage_stats_bridge.cc +++ b/chrome/browser/android/usage_stats/usage_stats_bridge.cc
@@ -20,6 +20,7 @@ using base::android::JavaParamRef; using base::android::JavaRef; using base::android::ScopedJavaLocalRef; +using base::android::ToJavaArrayOfByteArray; using base::android::ToJavaArrayOfStrings; namespace usage_stats { @@ -59,35 +60,89 @@ void UsageStatsBridge::GetAllEvents(JNIEnv* j_env, const JavaRef<jobject>& j_this, - const JavaRef<jobject>& j_callback) {} + const JavaRef<jobject>& j_callback) { + ScopedJavaGlobalRef<jobject> callback(j_callback); + + usage_stats_database_->GetAllEvents( + base::BindOnce(&UsageStatsBridge::OnGetEventsDone, + weak_ptr_factory_.GetWeakPtr(), callback)); +} void UsageStatsBridge::QueryEventsInRange(JNIEnv* j_env, const JavaRef<jobject>& j_this, const jlong j_start, const jlong j_end, - const JavaRef<jobject>& j_callback) {} + const JavaRef<jobject>& j_callback) { + ScopedJavaGlobalRef<jobject> callback(j_callback); + + usage_stats_database_->QueryEventsInRange( + j_start, j_end, + base::BindOnce(&UsageStatsBridge::OnGetEventsDone, + weak_ptr_factory_.GetWeakPtr(), callback)); +} void UsageStatsBridge::AddEvents(JNIEnv* j_env, const JavaRef<jobject>& j_this, - const JavaRef<jobject>& j_events, - const JavaRef<jobject>& j_callback) {} + const JavaRef<jobjectArray>& j_events, + const JavaRef<jobject>& j_callback) { + // Deserialize events from byte arrays to proto messages. + std::vector<std::string> serialized_events; + JavaArrayOfByteArrayToStringVector(j_env, j_events, &serialized_events); + + std::vector<WebsiteEvent> events; + events.reserve(serialized_events.size()); + + for (const std::string& serialized : serialized_events) { + WebsiteEvent event; + event.ParseFromString(serialized); + events.emplace_back(event); + } + + ScopedJavaGlobalRef<jobject> callback(j_callback); + + usage_stats_database_->AddEvents( + events, base::BindOnce(&UsageStatsBridge::OnUpdateDone, + weak_ptr_factory_.GetWeakPtr(), callback)); +} void UsageStatsBridge::DeleteAllEvents(JNIEnv* j_env, const JavaRef<jobject>& j_this, - const JavaRef<jobject>& j_callback) {} + const JavaRef<jobject>& j_callback) { + ScopedJavaGlobalRef<jobject> callback(j_callback); + + usage_stats_database_->DeleteAllEvents( + base::BindOnce(&UsageStatsBridge::OnUpdateDone, + weak_ptr_factory_.GetWeakPtr(), callback)); +} void UsageStatsBridge::DeleteEventsInRange(JNIEnv* j_env, const JavaRef<jobject>& j_this, const jlong j_start, const jlong j_end, const JavaRef<jobject>& j_callback) { + ScopedJavaGlobalRef<jobject> callback(j_callback); + + usage_stats_database_->DeleteEventsInRange( + j_start, j_end, + base::BindOnce(&UsageStatsBridge::OnUpdateDone, + weak_ptr_factory_.GetWeakPtr(), callback)); } void UsageStatsBridge::DeleteEventsWithMatchingDomains( JNIEnv* j_env, const JavaRef<jobject>& j_this, const JavaRef<jobjectArray>& j_domains, - const JavaRef<jobject>& j_callback) {} + const JavaRef<jobject>& j_callback) { + std::vector<std::string> domains; + AppendJavaStringArrayToStringVector(j_env, j_domains, &domains); + + ScopedJavaGlobalRef<jobject> callback(j_callback); + + usage_stats_database_->DeleteEventsWithMatchingDomains( + base::flat_set<std::string>(domains), + base::BindOnce(&UsageStatsBridge::OnUpdateDone, + weak_ptr_factory_.GetWeakPtr(), callback)); +} void UsageStatsBridge::GetAllSuspensions(JNIEnv* j_env, const JavaRef<jobject>& j_this, @@ -147,6 +202,37 @@ weak_ptr_factory_.GetWeakPtr(), callback)); } +void UsageStatsBridge::OnGetEventsDone(ScopedJavaGlobalRef<jobject> callback, + UsageStatsDatabase::Error error, + std::vector<WebsiteEvent> events) { + JNIEnv* env = AttachCurrentThread(); + + if (!isSuccess(error)) { + RunObjectCallbackAndroid( + callback, ToJavaArrayOfByteArray(env, std::vector<std::string>())); + return; + } + + // Serialize WebsiteEvent proto messages for passing over JNI bridge as byte + // arrays. + std::vector<std::string> serialized_events; + serialized_events.reserve(events.size()); + + for (WebsiteEvent event : events) { + std::string serialized; + event.SerializeToString(&serialized); + serialized_events.emplace_back(serialized); + } + + ScopedJavaLocalRef<jobjectArray> j_serialized_events = + ToJavaArrayOfByteArray(env, serialized_events); + + // Over JNI, deserialize to list of WebsiteEvent messages, and run on given + // callback. + Java_UsageStatsBridge_createEventListAndRunCallback(env, j_serialized_events, + callback); +} + void UsageStatsBridge::OnGetAllSuspensionsDone( ScopedJavaGlobalRef<jobject> callback, UsageStatsDatabase::Error error,
diff --git a/chrome/browser/android/usage_stats/usage_stats_bridge.h b/chrome/browser/android/usage_stats/usage_stats_bridge.h index e5314c29..dcf2873f 100644 --- a/chrome/browser/android/usage_stats/usage_stats_bridge.h +++ b/chrome/browser/android/usage_stats/usage_stats_bridge.h
@@ -47,7 +47,7 @@ void AddEvents(JNIEnv* j_env, const JavaRef<jobject>& j_this, - const JavaRef<jobject>& j_events, + const JavaRef<jobjectArray>& j_events, const JavaRef<jobject>& j_callback); void DeleteAllEvents(JNIEnv* j_env, @@ -87,6 +87,10 @@ static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); private: + void OnGetEventsDone(ScopedJavaGlobalRef<jobject> callback, + UsageStatsDatabase::Error error, + std::vector<WebsiteEvent> events); + void OnGetAllSuspensionsDone(ScopedJavaGlobalRef<jobject> callback, UsageStatsDatabase::Error error, std::vector<std::string> suspensions);
diff --git a/chrome/browser/android/usage_stats/website_event.proto b/chrome/browser/android/usage_stats/website_event.proto index ae425d3..f14ca94 100644 --- a/chrome/browser/android/usage_stats/website_event.proto +++ b/chrome/browser/android/usage_stats/website_event.proto
@@ -8,6 +8,9 @@ package usage_stats; +option java_package = "org.chromium.chrome.browser.usage_stats"; +option java_outer_classname = "WebsiteEventProtos"; + message WebsiteEvent { // Fully-qualified domain name of the website. Example: "docs.google.com". optional string fqdn = 1;
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc index b316acf..e772509 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc
@@ -357,9 +357,7 @@ ax::mojom::Event::kTextSelectionChanged, true); } } - } else if (!is_notification_event && - event_data->event_type == - arc::mojom::AccessibilityEventType::WINDOW_STATE_CHANGED) { + } else if (!is_notification_event) { UpdateWindowProperties(GetActiveWindow()); }
diff --git a/chrome/browser/chromeos/child_accounts/screen_time_controller.cc b/chrome/browser/chromeos/child_accounts/screen_time_controller.cc index 925060f..f5e1f59 100644 --- a/chrome/browser/chromeos/child_accounts/screen_time_controller.cc +++ b/chrome/browser/chromeos/child_accounts/screen_time_controller.cc
@@ -60,6 +60,9 @@ next_state_timer_(std::make_unique<base::OneShotTimer>()), time_limit_notifier_(context) { session_manager::SessionManager::Get()->AddObserver(this); + if (base::FeatureList::IsEnabled(features::kUsageTimeStateNotifier)) + UsageTimeStateNotifier::GetInstance()->AddObserver(this); + system::TimezoneSettings::GetInstance()->AddObserver(this); chromeos::DBusThreadManager::Get()->GetSystemClockClient()->AddObserver(this); pref_change_registrar_.Init(pref_service_); @@ -71,6 +74,9 @@ ScreenTimeController::~ScreenTimeController() { session_manager::SessionManager::Get()->RemoveObserver(this); + if (base::FeatureList::IsEnabled(features::kUsageTimeStateNotifier)) + UsageTimeStateNotifier::GetInstance()->RemoveObserver(this); + system::TimezoneSettings::GetInstance()->RemoveObserver(this); chromeos::DBusThreadManager::Get()->GetSystemClockClient()->RemoveObserver( this); @@ -157,8 +163,7 @@ usage_time_limit::GetExpectedResetTime( time_limit->CreateDeepCopy(), now, &time_zone)); if (!next_get_state_time.is_null()) { - VLOG(1) << "Scheduling state change timer in " - << state.next_state_change_time - now; + VLOG(1) << "Scheduling state change timer in " << next_get_state_time - now; next_state_timer_->Start( FROM_HERE, next_get_state_time - now, base::BindRepeating(&ScreenTimeController::CheckTimeLimit, @@ -334,6 +339,15 @@ void ScreenTimeController::OnSessionStateChanged() { session_manager::SessionState session_state = session_manager::SessionManager::Get()->session_state(); + if (base::FeatureList::IsEnabled(features::kUsageTimeStateNotifier)) { + if (session_state == session_manager::SessionState::LOCKED && + next_unlock_time_) { + UpdateTimeLimitsMessage(true /*visible*/, next_unlock_time_.value()); + next_unlock_time_.reset(); + } + return; + } + if (session_state == session_manager::SessionState::LOCKED) { if (next_unlock_time_) { UpdateTimeLimitsMessage(true /*visible*/, next_unlock_time_.value()); @@ -345,6 +359,15 @@ } } +void ScreenTimeController::OnUsageTimeStateChange( + const UsageTimeStateNotifier::UsageTimeState state) { + if (state == UsageTimeStateNotifier::UsageTimeState::INACTIVE) { + ResetInSessionTimers(); + } else { + CheckTimeLimit("OnUsageTimeStateChange"); + } +} + void ScreenTimeController::TimezoneChanged(const icu::TimeZone& timezone) { CheckTimeLimit("TimezoneChanged"); }
diff --git a/chrome/browser/chromeos/child_accounts/screen_time_controller.h b/chrome/browser/chromeos/child_accounts/screen_time_controller.h index b8a8005..0ec967c 100644 --- a/chrome/browser/chromeos/child_accounts/screen_time_controller.h +++ b/chrome/browser/chromeos/child_accounts/screen_time_controller.h
@@ -6,11 +6,13 @@ #define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_SCREEN_TIME_CONTROLLER_H_ #include <memory> +#include <string> #include "base/memory/scoped_refptr.h" #include "base/time/time.h" #include "chrome/browser/chromeos/child_accounts/time_limit_notifier.h" #include "chrome/browser/chromeos/child_accounts/usage_time_limit_processor.h" +#include "chrome/browser/chromeos/child_accounts/usage_time_state_notifier.h" #include "chromeos/dbus/system_clock_client.h" #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_change_registrar.h" @@ -38,6 +40,7 @@ // Schedule notifications and lock/unlock screen based on the processor output. class ScreenTimeController : public KeyedService, public session_manager::SessionManagerObserver, + public UsageTimeStateNotifier::Observer, public system::TimezoneSettings::Observer, public chromeos::SystemClockClient::Observer { public: @@ -92,6 +95,10 @@ // session_manager::SessionManagerObserver: void OnSessionStateChanged() override; + // UsageTimeStateNotifier::Observer: + void OnUsageTimeStateChange( + const UsageTimeStateNotifier::UsageTimeState state) override; + // system::TimezoneSettings::Observer: void TimezoneChanged(const icu::TimeZone& timezone) override;
diff --git a/chrome/browser/chromeos/child_accounts/screen_time_controller_browsertest.cc b/chrome/browser/chromeos/child_accounts/screen_time_controller_browsertest.cc index 4eae616a..14672a72 100644 --- a/chrome/browser/chromeos/child_accounts/screen_time_controller_browsertest.cc +++ b/chrome/browser/chromeos/child_accounts/screen_time_controller_browsertest.cc
@@ -9,6 +9,7 @@ #include "base/memory/scoped_refptr.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "base/test/test_mock_time_task_runner.h" #include "base/time/time.h" #include "base/values.h" @@ -22,16 +23,21 @@ #include "chrome/browser/chromeos/policy/user_policy_test_helper.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "components/policy/core/browser/browser_policy_connector.h" #include "components/prefs/pref_service.h" #include "components/session_manager/core/session_manager.h" #include "content/public/browser/notification_service.h" +#include "testing/gtest/include/gtest/gtest.h" namespace chromeos { namespace utils = time_limit_test_utils; -class ScreenTimeControllerTest : public policy::LoginPolicyTestBase { +// Allows testing ScreenTimeController with UsageTimeStateNotifier enabled +// (instantiated with |true|) or disabled (instantiated with |false|). +class ScreenTimeControllerTest : public policy::LoginPolicyTestBase, + public testing::WithParamInterface<bool> { public: ScreenTimeControllerTest() = default; @@ -39,6 +45,14 @@ // policy::LoginPolicyTestBase: void SetUp() override { + bool is_feature_enabled = GetParam(); + base::test::ScopedFeatureList feature_list; + if (is_feature_enabled) { + feature_list.InitAndEnableFeature(features::kUsageTimeStateNotifier); + } else { + feature_list.InitAndDisableFeature(features::kUsageTimeStateNotifier); + } + // Recognize example.com (used by LoginPolicyTestBase) as non-enterprise // account. policy::BrowserPolicyConnector::SetNonEnterpriseDomainForTesting( @@ -105,7 +119,7 @@ }; // Tests a simple lock override. -IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, LockOverride) { +IN_PROC_BROWSER_TEST_P(ScreenTimeControllerTest, LockOverride) { SetupTaskRunnerWithTime(utils::TimeFromString("1 Jan 2018 10:00:00 GMT")); SkipToLoginScreen(); LogIn(kAccountId, kAccountPassword, test::kChildAccountServiceFlags); @@ -135,7 +149,7 @@ } // Tests an unlock override on a bedtime. -IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, UnlockBedtime) { +IN_PROC_BROWSER_TEST_P(ScreenTimeControllerTest, UnlockBedtime) { SetupTaskRunnerWithTime(utils::TimeFromString("5 Jan 2018 22:00:00 BRT")); SkipToLoginScreen(); LogIn(kAccountId, kAccountPassword, test::kChildAccountServiceFlags); @@ -185,7 +199,7 @@ } // Tests the default time window limit. -IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, DefaultBedtime) { +IN_PROC_BROWSER_TEST_P(ScreenTimeControllerTest, DefaultBedtime) { SetupTaskRunnerWithTime(utils::TimeFromString("1 Jan 2018 10:00:00 GMT")); SkipToLoginScreen(); LogIn(kAccountId, kAccountPassword, test::kChildAccountServiceFlags); @@ -251,7 +265,7 @@ } // Tests the default time window limit. -IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, DefaultDailyLimit) { +IN_PROC_BROWSER_TEST_P(ScreenTimeControllerTest, DefaultDailyLimit) { SetupTaskRunnerWithTime(utils::TimeFromString("1 Jan 2018 10:00:00 GMT")); SkipToLoginScreen(); LogIn(kAccountId, kAccountPassword, test::kChildAccountServiceFlags); @@ -320,7 +334,7 @@ } // Tests that the bedtime locks an active session when it is reached. -IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, ActiveSessionBedtime) { +IN_PROC_BROWSER_TEST_P(ScreenTimeControllerTest, ActiveSessionBedtime) { SetupTaskRunnerWithTime(utils::TimeFromString("1 Jan 2018 10:00:00 PST")); SkipToLoginScreen(); LogIn(kAccountId, kAccountPassword, test::kChildAccountServiceFlags); @@ -361,7 +375,7 @@ } // Tests that the daily limit locks the device when it is reached. -IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, ActiveSessionDailyLimit) { +IN_PROC_BROWSER_TEST_P(ScreenTimeControllerTest, ActiveSessionDailyLimit) { SetupTaskRunnerWithTime(utils::TimeFromString("1 Jan 2018 10:00:00 PST")); SkipToLoginScreen(); LogIn(kAccountId, kAccountPassword, test::kChildAccountServiceFlags); @@ -400,7 +414,7 @@ } // Tests bedtime during timezone changes. -IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, BedtimeOnTimezoneChange) { +IN_PROC_BROWSER_TEST_P(ScreenTimeControllerTest, BedtimeOnTimezoneChange) { SetupTaskRunnerWithTime( utils::TimeFromString("3 Jan 2018 10:00:00 GMT-0600")); SkipToLoginScreen(); @@ -455,7 +469,7 @@ } // Tests bedtime during timezone changes that make the clock go back in time. -IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, +IN_PROC_BROWSER_TEST_P(ScreenTimeControllerTest, BedtimeOnEastToWestTimezoneChanges) { SetupTaskRunnerWithTime(utils::TimeFromString("3 Jan 2018 8:00:00 GMT+1300")); SkipToLoginScreen(); @@ -502,4 +516,7 @@ EXPECT_FALSE(IsAuthEnabled()); } +// Run all ScreenTimeControllerTest with UsageTimeStateNotifier feature enabled +// and disabled. +INSTANTIATE_TEST_SUITE_P(, ScreenTimeControllerTest, testing::Bool()); } // namespace chromeos
diff --git a/chrome/browser/chromeos/chrome_content_browser_client_chromeos_part.cc b/chrome/browser/chromeos/chrome_content_browser_client_chromeos_part.cc index e158e40..256cc626 100644 --- a/chrome/browser/chromeos/chrome_content_browser_client_chromeos_part.cc +++ b/chrome/browser/chromeos/chrome_content_browser_client_chromeos_part.cc
@@ -19,6 +19,7 @@ #include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/url_constants.h" #include "content/public/common/web_preferences.h" namespace { @@ -40,7 +41,7 @@ if (profile && search::IsNTPURL(url, profile)) return true; - return url.SchemeIs("chrome"); + return url.SchemeIs(content::kChromeUIScheme); } } // namespace
diff --git a/chrome/browser/chromeos/smb_client/smb_service.cc b/chrome/browser/chromeos/smb_client/smb_service.cc index 5aef176..b2fcaf63 100644 --- a/chrome/browser/chromeos/smb_client/smb_service.cc +++ b/chrome/browser/chromeos/smb_client/smb_service.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/chromeos/smb_client/smb_service.h" +#include <utility> + #include "base/bind.h" #include "base/feature_list.h" #include "base/files/file_path.h" @@ -44,6 +46,7 @@ const char kModeKey[] = "mode"; const char kModeDropDownValue[] = "drop_down"; const char kModePreMountValue[] = "pre_mount"; +const char kModeUnknownValue[] = "unknown"; bool ContainsAt(const std::string& username) { return username.find('@') != std::string::npos; @@ -184,6 +187,26 @@ update_credential_replies_.erase(creds_reply_iter); } +void SmbService::UpdateSharePath(int32_t mount_id, + const std::string& share_path, + StartReadDirIfSuccessfulCallback reply) { + GetSmbProviderClient()->UpdateSharePath( + mount_id, share_path, + base::BindOnce(&SmbService::OnUpdateSharePathResponse, AsWeakPtr(), + mount_id, std::move(reply))); +} + +void SmbService::OnUpdateSharePathResponse( + int32_t mount_id, + StartReadDirIfSuccessfulCallback reply, + smbprovider::ErrorType error) { + if (error != smbprovider::ERROR_OK) { + LOG(ERROR) << "Failed to update the share path for mount id " << mount_id; + std::move(reply).Run(false /* should_retry_start_read_dir */); + } + std::move(reply).Run(true /* should_retry_start_read_dir */); +} + void SmbService::CallMount(const file_system_provider::MountOptions& options, const base::FilePath& share_path, const std::string& username_input, @@ -557,8 +580,20 @@ const base::Value* share_url = info.FindKey(kShareUrlKey); const base::Value* mode = info.FindKey(kModeKey); - if (mode->GetString() == policy_mode) { - preconfigured_urls.emplace_back(share_url->GetString()); + if (policy_mode == kModeUnknownValue) { + // kModeUnknownValue is used to filter for any shares that do not match + // a presently known mode for preconfiguration. As new preconfigure + // modes are added, this should be kept in sync. + if (mode->GetString() != kModeDropDownValue && + mode->GetString() != kModePreMountValue) { + preconfigured_urls.emplace_back(share_url->GetString()); + } + + } else { + // Filter normally + if (mode->GetString() == policy_mode) { + preconfigured_urls.emplace_back(share_url->GetString()); + } } } return preconfigured_urls; @@ -577,7 +612,14 @@ } std::vector<SmbUrl> SmbService::GetPreconfiguredSharePathsForDropdown() const { - return GetPreconfiguredSharePaths(kModeDropDownValue); + auto drop_down_paths = GetPreconfiguredSharePaths(kModeDropDownValue); + auto fallback_paths = GetPreconfiguredSharePaths(kModeUnknownValue); + + for (auto&& fallback_path : fallback_paths) { + drop_down_paths.push_back(std::move(fallback_path)); + } + + return drop_down_paths; } std::vector<SmbUrl> SmbService::GetPreconfiguredSharePathsForPremount() const {
diff --git a/chrome/browser/chromeos/smb_client/smb_service.h b/chrome/browser/chromeos/smb_client/smb_service.h index 3c956ef..49857e74 100644 --- a/chrome/browser/chromeos/smb_client/smb_service.h +++ b/chrome/browser/chromeos/smb_client/smb_service.h
@@ -96,6 +96,11 @@ const std::string& username, const std::string& password); + // Updates the share path for |mount_id|. + void UpdateSharePath(int32_t mount_id, + const std::string& share_path, + StartReadDirIfSuccessfulCallback reply); + private: // Calls SmbProviderClient::Mount(). |temp_file_manager_| must be initialized // before this is called. @@ -182,12 +187,16 @@ bool IsNTLMAuthenticationEnabled() const; // Gets the list of all shares preconfigured via policy with mode - // |policy_mode|. + // |policy_mode|. If |policy_mode| is "unknown", returns a list of all shares + // preconfigured with a mode that does not match any currently known mode. + // This can occur if a new policy is added not yet supported by CrOS. std::vector<SmbUrl> GetPreconfiguredSharePaths( const std::string& policy_mode) const; // Gets the shares preconfigured via policy that should be displayed in the - // discovery dropdown. + // discovery dropdown. This includes shares that are explicitly set to be + // shown in the dropdown as well as shares configured with an unrecognized + // mode. std::vector<SmbUrl> GetPreconfiguredSharePathsForDropdown() const; // Gets the shares preconfigured via policy that should be premounted. @@ -218,6 +227,12 @@ int32_t mount_id, StartReadDirIfSuccessfulCallback reply); + // Handles the response for attempting to update the share path of a mount. + // |reply| will run if |error| is ERROR_OK. Logs the error otherwise. + void OnUpdateSharePathResponse(int32_t mount_id, + StartReadDirIfSuccessfulCallback reply, + smbprovider::ErrorType error); + // Records metrics on the number of SMB mounts a user has. void RecordMountCount() const;
diff --git a/chrome/browser/extensions/permissions_updater.cc b/chrome/browser/extensions/permissions_updater.cc index e158f3f6..7043b03 100644 --- a/chrome/browser/extensions/permissions_updater.cc +++ b/chrome/browser/extensions/permissions_updater.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/extensions/scripting_permissions_modifier.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/permissions.h" +#include "chrome/common/webui_url_constants.h" #include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h" #include "components/keyed_service/core/keyed_service_shutdown_notifier.h" #include "content/public/browser/browser_context.h" @@ -26,6 +27,7 @@ #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/render_process_host.h" +#include "content/public/common/url_constants.h" #include "extensions/browser/event_router.h" #include "extensions/browser/event_router_factory.h" #include "extensions/browser/extension_prefs.h" @@ -345,7 +347,9 @@ std::set<URLPattern> removable_explicit_hosts; bool needs_adjustment = false; for (const auto& pattern : active_permissions_to_remove->explicit_hosts()) { - if (pattern.host() == "favicon" && pattern.scheme() == "chrome") + bool is_chrome_favicon = pattern.scheme() == content::kChromeUIScheme && + pattern.host() == chrome::kChromeUIFaviconHost; + if (is_chrome_favicon) needs_adjustment = true; else removable_explicit_hosts.insert(pattern);
diff --git a/chrome/browser/extensions/scripting_permissions_modifier.cc b/chrome/browser/extensions/scripting_permissions_modifier.cc index ba74dc6..b136fa8 100644 --- a/chrome/browser/extensions/scripting_permissions_modifier.cc +++ b/chrome/browser/extensions/scripting_permissions_modifier.cc
@@ -7,6 +7,7 @@ #include "base/bind_helpers.h" #include "base/feature_list.h" #include "chrome/browser/extensions/permissions_updater.h" +#include "chrome/common/webui_url_constants.h" #include "content/public/common/url_constants.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" @@ -70,7 +71,8 @@ // chrome://favicon/), we auto-grant it and treat it like an API // permission. bool is_chrome_favicon = - pattern.host() == "favicon" && pattern.scheme() == "chrome"; + pattern.scheme() == content::kChromeUIScheme && + pattern.host() == chrome::kChromeUIFaviconHost; if (is_chrome_favicon) granted->AddPattern(pattern); }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index b52d3479..3490851 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -489,6 +489,8 @@ { "name": "dcheck-is-fatal", "owners": [ "wez" ], + // Used to debug failed assertions in environments where debug builds cannot + // be used. "expiry_milestone": -1 }, { @@ -636,6 +638,8 @@ { "name": "disable-threaded-scrolling", "owners": [ "bokan", "input-dev" ], + // This flag is a useful debugging control when investigating scrolling + // issues. "expiry_milestone": -1 }, { @@ -740,7 +744,7 @@ }, { "name": "enable-android-spellchecker", - // "owners": [ "your-team" ], + "owners": [ "timvolodine" ], "expiry_milestone": 76 }, { @@ -836,6 +840,9 @@ { "name": "enable-autofill-credit-card-upload", "owners": [ "jsaul@google.com" ], + // This flag is heavily used by the testing team that can't easily use the + // commandline, and can't be enabled by default. + // http://g/chrome-flags/s2RTQCvcRRs "expiry_milestone": -1 }, { @@ -1081,6 +1088,7 @@ { "name": "enable-devtools-experiments", "owners": [ "//third_party/blink/renderer/devtools/OWNERS" ], + // This is a catch-all for ongoing devtools experiments. "expiry_milestone": -1 }, { @@ -1238,11 +1246,15 @@ { "name": "enable-gpu-rasterization", "owners": [ "enne", "vmiura", "ericrk" ], + // A debugging flag intended for end-users where there may not be any other + // way to turn off graphics features. "expiry_milestone": -1 }, { "name": "enable-gpu-service-logging", "owners": [ "vikassoni", "kbr" ], + // A debugging flag intended for end-users where there may not be any other + // way to turn off graphics features. "expiry_milestone": -1 }, { @@ -1733,12 +1745,11 @@ "expiry_milestone": 76 }, { - "_comment1": "No expiry - even after shipping some form of Site Isolation", - "_comment2": "on Android, we want to give users ability to opt into a", - "_comment3": "stricter, more secure Site Isolation via", - "_comment4": "chrome://flags#enable-site-per-process.", "name": "enable-site-per-process", "owners": [ "site-isolation-dev", "creis", "lukasza" ], + // Even after shipping some form of Site Isolation on Android, we want to + // give users the ability to opt into a stricter, more secure Site + // Isolation. "expiry_milestone": -1 }, { @@ -1942,6 +1953,7 @@ { "name": "enable-web-authentication-testing-api", "owners": [ "webauthn-team@google.com" ], + // This is required for testing. "expiry_milestone": -1 }, { @@ -2172,6 +2184,8 @@ { "name": "force-show-update-menu-badge", "owners": [ "//chrome/android/java/src/org/chromium/chrome/browser/omaha/OWNERS" ], + // This is required by test teams to verify functionality on devices which + // have no access to commandline flags. "expiry_milestone": -1 }, { @@ -2192,7 +2206,9 @@ { "name": "force-update-menu-type", "owners": [ "//chrome/android/java/src/org/chromium/chrome/browser/omaha/OWNERS" ], - "expiry_milestone": -1 + // This is required by test teams to verify functionality on devices which + // have no access to commandline flags. + "expiry_milestone": -1 }, { "name": "foreground-notification-manager", @@ -2247,6 +2263,8 @@ { "name": "ignore-gpu-blacklist", "owners": [ "kbr", "zmo" ], + // A debugging flag intended for end-users where there may not be any other + // way to turn off graphics features. "expiry_milestone": -1 }, { @@ -2441,87 +2459,87 @@ }, { "name": "offline-bookmarks", - // "owners": [ "your-team" ], + "owners": [ "jianli", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offline-indicator-always-http-probe", - // "owners": [ "your-team" ], + "owners": [ "jianli", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offline-indicator-choice", - // "owners": [ "your-team" ], + "owners": [ "jianli", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offline-pages-alternate-dino-page", - // "owners": [ "your-team" ], + "owners": [ "carlosk", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offline-pages-ct", - // "owners": [ "your-team" ], + "owners": [ "dewittj", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offline-pages-ct-suppress-completed-notification", - // "owners": [ "your-team" ], + "owners": [ "dewittj", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offline-pages-ct-v2", - // "owners": [ "your-team" ], + "owners": [ "dewittj", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offline-pages-failed-download", - // "owners": [ "your-team" ], + "owners": [ "chili", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offline-pages-in-downloads-home-open-in-cct", - // "owners": [ "your-team" ], + "owners": [ "carlosk", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offline-pages-live-page-sharing", - // "owners": [ "your-team" ], + "owners": [ "petewil", "jianli", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offline-pages-load-signal-collecting", - // "owners": [ "your-team" ], + "owners": [ "petewil", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offline-pages-pending-download", - // "owners": [ "your-team" ], + "owners": [ "chili", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offline-pages-prefetching", - // "owners": [ "your-team" ], + "owners": [ "carlosk", "dewittj", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offline-pages-renovations", - // "owners": [ "your-team" ], + "owners": [ "petewil", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offline-pages-resource-based-snapshot", - // "owners": [ "your-team" ], + "owners": [ "petewil", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offline-pages-sharing", - // "owners": [ "your-team" ], + "owners": [ "petewil", "offline-dev" ], "expiry_milestone": 76 }, { "name": "offlining-recent-pages", - // "owners": [ "your-team" ], + "owners": [ "carlosk", "offline-dev" ], "expiry_milestone": 76 }, { @@ -2817,6 +2835,8 @@ { "name": "set-market-url-for-testing", "owners": [ "//chrome/android/java/src/org/chromium/chrome/browser/omaha/OWNERS" ], + // This is required by test teams to verify functionality on devices which + // have no access to commandline flags. "expiry_milestone": -1 }, { @@ -2857,6 +2877,8 @@ { "name": "show-touch-hud", "owners": [ "//ash/OWNERS" ], + // This is a debug tool to help in the field with hardware issues that + // generate spurious touch events. "expiry_milestone": -1 }, { @@ -3089,6 +3111,8 @@ { "name": "update-menu-item-custom-summary", "owners": [ "//chrome/android/java/src/org/chromium/chrome/browser/omaha/OWNERS" ], + // This is required by test teams to verify functionality on devices which + // have no access to commandline flags. "expiry_milestone": -1 }, {
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 6c48d7ff..337bff01 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -2557,10 +2557,6 @@ const char kNtpButtonDescription[] = "Displays a New Tab Page button in the toolbar if enabled."; -const char kOfflineBookmarksName[] = "Enable offline bookmarks"; -const char kOfflineBookmarksDescription[] = - "Enable saving bookmarked pages for offline viewing."; - const char kOfflineIndicatorAlwaysHttpProbeName[] = "Always http probe"; const char kOfflineIndicatorAlwaysHttpProbeDescription[] = "Always do http probe to detect network connectivity for offline indicator "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index b8d2cc25..fe02ca6 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1519,9 +1519,6 @@ extern const char kNtpButtonName[]; extern const char kNtpButtonDescription[]; -extern const char kOfflineBookmarksName[]; -extern const char kOfflineBookmarksDescription[]; - extern const char kOfflineIndicatorAlwaysHttpProbeName[]; extern const char kOfflineIndicatorAlwaysHttpProbeDescription[];
diff --git a/chrome/browser/metrics/chrome_metrics_service_accessor.h b/chrome/browser/metrics/chrome_metrics_service_accessor.h index 718c835..dc53afbc 100644 --- a/chrome/browser/metrics/chrome_metrics_service_accessor.h +++ b/chrome/browser/metrics/chrome_metrics_service_accessor.h
@@ -114,7 +114,6 @@ friend class safe_browsing::SafeBrowsingUIManager; friend class ChromeMetricsServiceClient; friend class ChromePasswordManagerClient; - friend class ChromeUnifiedConsentServiceClient; friend bool nux::IsNuxOnboardingEnabled(Profile* profile); // Testing related friends.
diff --git a/chrome/browser/net/network_context_configuration_browsertest.cc b/chrome/browser/net/network_context_configuration_browsertest.cc index ecfbd5f..a9c302e 100644 --- a/chrome/browser/net/network_context_configuration_browsertest.cc +++ b/chrome/browser/net/network_context_configuration_browsertest.cc
@@ -1576,14 +1576,8 @@ // Test that when there's a proxy configuration at startup, the initial requests // use that configuration. -// Flaky on CrOS only. http://crbug.com/922876 -#if defined(OS_CHROMEOS) -#define MAYBE_TestInitialProxyConfig DISABLED_TestInitialProxyConfig -#else -#define MAYBE_TestInitialProxyConfig TestInitialProxyConfig -#endif IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationProxyOnStartBrowserTest, - MAYBE_TestInitialProxyConfig) { + TestInitialProxyConfig) { if (IsRestartStateWithInProcessNetworkService()) return; TestProxyConfigured(/*expect_success=*/true); @@ -1888,20 +1882,10 @@ // tested, and a suffix of "/0" if the network service is disabled, "/1" if it's // enabled, and "/2" if it's enabled and restarted. -#if defined(OS_CHROMEOS) -// There's an extra network change event on ChromeOS, likely from -// NetworkChangeNotifierChromeos that makes these tests flaky on ChromeOS when -// there's an out of process network stack. -// -// TODO(https://crbug.com/927293): Fix that, and enable these tests on ChromeOS. -#define TEST_CASES(network_context_type) \ - TestCase({NetworkServiceState::kDisabled, network_context_type}) -#else // !defined(OS_CHROMEOS) #define TEST_CASES(network_context_type) \ TestCase({NetworkServiceState::kDisabled, network_context_type}), \ TestCase({NetworkServiceState::kEnabled, network_context_type}), \ TestCase({NetworkServiceState::kRestarted, network_context_type}) -#endif // !defined(OS_CHROMEOS) #if BUILDFLAG(ENABLE_EXTENSIONS) #define INSTANTIATE_EXTENSION_TESTS(TestFixture) \
diff --git a/chrome/browser/offline_pages/android/offline_page_bridge.cc b/chrome/browser/offline_pages/android/offline_page_bridge.cc index 196ae8e..b321b61 100644 --- a/chrome/browser/offline_pages/android/offline_page_bridge.cc +++ b/chrome/browser/offline_pages/android/offline_page_bridge.cc
@@ -290,10 +290,6 @@ } // namespace -static jboolean JNI_OfflinePageBridge_IsOfflineBookmarksEnabled(JNIEnv* env) { - return offline_pages::IsOfflineBookmarksEnabled(); -} - static jboolean JNI_OfflinePageBridge_IsPageSharingEnabled(JNIEnv* env) { return offline_pages::IsOfflinePagesSharingEnabled(); }
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc index 1e0834a..dc73d30 100644 --- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc +++ b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
@@ -1829,6 +1829,7 @@ content::WebContents* active_web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_NE(nullptr, active_web_contents); ASSERT_TRUE(content::ExecuteScript(active_web_contents, "video.play();")); @@ -2570,3 +2571,21 @@ content::TitleWatcher(active_web_contents, expected_title) .WaitAndGetTitle()); } + +// Tests that exiting Picture-in-Picture when the video has no source fires the +// event and resolves the callback. +IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest, + ExitFireEventAndCallbackWhenNoSource) { + LoadTabAndEnterPictureInPicture(browser()); + + content::WebContents* active_web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(content::ExecuteScript(active_web_contents, + "video.src=''; exitPictureInPicture();")); + + // 'left' is sent when the first video leaves Picture-in-Picture. + base::string16 expected_title = base::ASCIIToUTF16("left"); + EXPECT_EQ(expected_title, + content::TitleWatcher(active_web_contents, expected_title) + .WaitAndGetTitle()); +}
diff --git a/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc index 0ebe872..499d850a 100644 --- a/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc +++ b/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc
@@ -87,6 +87,13 @@ g_browser_process->browser_policy_connector() ->machine_level_user_cloud_policy_controller() ->RemoveObserver(this); + // If enrollment fails, the manager should be marked as initialized + // immediately. Otherwise, this will be done after the policy data is + // downloaded. + EXPECT_EQ(!succeeded, g_browser_process->browser_policy_connector() + ->machine_level_user_cloud_policy_manager() + ->IsInitializationComplete( + PolicyDomain::POLICY_DOMAIN_CHROME)); } void SetShouldSucceed(bool should_succeed) {
diff --git a/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc b/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc index f1a0c65..c0020108 100644 --- a/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc +++ b/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc
@@ -268,6 +268,11 @@ UMA_HISTOGRAM_TIMES( "Enterprise.MachineLevelUserCloudPolicyEnrollment.RequestFailureTime", enrollment_time); + MachineLevelUserCloudPolicyManager* policy_manager = + g_browser_process->browser_policy_connector() + ->machine_level_user_cloud_policy_manager(); + if (policy_manager) + policy_manager->store()->InitWithoutToken(); NotifyPolicyRegisterFinished(false); return; }
diff --git a/chrome/browser/prerender/prerender_util.cc b/chrome/browser/prerender/prerender_util.cc index 8451c3a..56b84b43 100644 --- a/chrome/browser/prerender/prerender_util.cc +++ b/chrome/browser/prerender/prerender_util.cc
@@ -6,8 +6,10 @@ #include "base/metrics/histogram_macros.h" #include "components/google/core/common/google_util.h" +#include "content/public/common/url_constants.h" #include "extensions/buildflags/buildflags.h" #include "url/gurl.h" +#include "url/url_constants.h" #if BUILDFLAG(ENABLE_EXTENSIONS) #include "extensions/common/constants.h" @@ -58,27 +60,27 @@ } void ReportUnsupportedPrerenderScheme(const GURL& url) { - if (url.SchemeIs("data")) { + if (url.SchemeIs(url::kDataScheme)) { ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_DATA); - } else if (url.SchemeIs("blob")) { + } else if (url.SchemeIs(url::kBlobScheme)) { ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_BLOB); } else if (url.SchemeIsFile()) { ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_FILE); } else if (url.SchemeIsFileSystem()) { ReportPrerenderSchemeCancelReason( PRERENDER_SCHEME_CANCEL_REASON_FILESYSTEM); - } else if (url.SchemeIs("ws") || url.SchemeIs("wss")) { + } else if (url.SchemeIs(url::kWsScheme) || url.SchemeIs(url::kWssScheme)) { ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_WEBSOCKET); - } else if (url.SchemeIs("ftp")) { + } else if (url.SchemeIs(url::kFtpScheme)) { ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_FTP); - } else if (url.SchemeIs("chrome")) { + } else if (url.SchemeIs(content::kChromeUIScheme)) { ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_CHROME); #if BUILDFLAG(ENABLE_EXTENSIONS) } else if (url.SchemeIs(extensions::kExtensionScheme)) { ReportPrerenderSchemeCancelReason( PRERENDER_SCHEME_CANCEL_REASON_CHROME_EXTENSION); #endif - } else if (url.SchemeIs("about")) { + } else if (url.SchemeIs(url::kAboutScheme)) { ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_ABOUT); } else { ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_UNKNOWN);
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs index e575798..f3746f1 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
@@ -1934,3 +1934,33 @@ .replay(); }); }); + +TEST_F('ChromeVoxBackgroundTest', 'AutoCompleteChanged', function() { + var mockFeedback = this.createMockFeedback(); + this.runWithLoadedTree(function() {/* + <div><input type="text" aria-autocomplete="off"></input></div> + <script> + var div = document.querySelector('div'); + var input = div.firstElementChild; + var completion = input.getAttribute('aria-autocomplete'); + div.addEventListener('click', () => { + completion = completion == 'off' ? 'both' : 'off'; + input.setAttribute('aria-autocomplete', completion); + }); + </script> + */}, function(root) { + var change = root.firstChild.doDefault.bind(root.firstChild); + mockFeedback.expectSpeech('Edit text') + .clearPendingOutput() + .call(change) + .expectSpeech('Edit text') + .call(change) + .expectSpeech('Edit text') + .call(change) + .expectNextSpeechUtteranceIsNot( + 'Press up or down arrow for auto completions.') + .expectSpeech('Edit text') + .expectSpeech('Press up or down arrow for auto completions.') + .replay(); + }); +});
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js index 4995453..641a4bf2 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
@@ -230,7 +230,9 @@ * @param {!AutomationEvent} evt */ onAriaAttributeChanged: function(evt) { - if (evt.target.state.editable) + // Don't report changes on non-focused, richly editables. + if (evt.target.state[StateType.RICHLY_EDITABLE] && + !evt.target.state[StateType.FOCUSED]) return; // Only report attribute changes on some *Option roles if it is selected.
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/language_switching_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/language_switching_test.extjs index 3419880..ac8cbd1 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/language_switching_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/language_switching_test.extjs
@@ -66,7 +66,15 @@ <p lang="en-gb">Spoken in GB English.</p> <p lang="en-us">This text should also be in GB English.</p> <p lang="en-us">So should this text.</p> -*/}, + */}, + + buttonAndLinkDoc: function() {/*! + <body lang="es"> + <p>This is a paragraph, spoken in Spanish.</p> + <button type="submit">This is a button, spoken in Spanish.</button> + <a href="https://www.google.com">This is a link, spoken in Spanish.</a> + </body> + */}, }; TEST_F('ChromeVoxLanguageSwitchingTest', 'MultipleLanguagesTest', function() { @@ -119,3 +127,20 @@ mockFeedback.replay(); }); }); + +TEST_F('ChromeVoxLanguageSwitchingTest', 'ButtonAndLinkTest', function() { + var mockFeedback = this.createMockFeedback(); + this.runWithLoadedTree(this.buttonAndLinkDoc, function(root) { + localStorage['languageSwitching'] = 'true'; + + mockFeedback.call(doCmd('jumpToTop')) + .expectSpeechWithLanguage('es', 'This is a paragraph, spoken in Spanish.') + .call(doCmd('nextObject')) + .expectSpeechWithLanguage('es', 'This is a button, spoken in Spanish.') + .expectSpeechWithLanguage(undefined, 'Button', 'Press Search+Space to activate.') + .call(doCmd('nextObject')) + .expectSpeechWithLanguage('es', 'This is a link, spoken in Spanish.') + .expectSpeechWithLanguage(undefined, 'Link'); + mockFeedback.replay(); + }); +});
diff --git a/chrome/browser/resources/chromeos/switch_access/BUILD.gn b/chrome/browser/resources/chromeos/switch_access/BUILD.gn index a73c276..d8dbec1 100644 --- a/chrome/browser/resources/chromeos/switch_access/BUILD.gn +++ b/chrome/browser/resources/chromeos/switch_access/BUILD.gn
@@ -34,13 +34,16 @@ "auto_scan_manager.js", "background.js", "commands.js", + "icons/decrement.svg", "icons/dictation.svg", + "icons/increment.svg", "icons/options.svg", - "icons/scroll_down.svg", - "icons/scroll_left.svg", - "icons/scroll_right.svg", - "icons/scroll_up.svg", + "icons/scrollDown.svg", + "icons/scrollLeft.svg", + "icons/scrollRight.svg", + "icons/scrollUp.svg", "icons/select.svg", + "icons/showContextMenu.svg", "keyboard_handler.js", "menu_manager.js", "menu_panel.css",
diff --git a/chrome/browser/resources/chromeos/switch_access/icons/decrement.svg b/chrome/browser/resources/chromeos/switch_access/icons/decrement.svg new file mode 100644 index 0000000..c7135019 --- /dev/null +++ b/chrome/browser/resources/chromeos/switch_access/icons/decrement.svg
@@ -0,0 +1,4 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="#FFFFFF"> + <path fill="none" d="M0 0h24v24H0V0z"/> + <path fill="#FFFFFF" d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"/> +</svg>
diff --git a/chrome/browser/resources/chromeos/switch_access/icons/increment.svg b/chrome/browser/resources/chromeos/switch_access/icons/increment.svg new file mode 100644 index 0000000..73b6b553 --- /dev/null +++ b/chrome/browser/resources/chromeos/switch_access/icons/increment.svg
@@ -0,0 +1,4 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="#FFFFFF"> + <path fill="none" d="M0 0h24v24H0V0z"/> + <path d="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z"/> +</svg>
diff --git a/chrome/browser/resources/chromeos/switch_access/icons/scroll_down.svg b/chrome/browser/resources/chromeos/switch_access/icons/scrollDown.svg similarity index 100% rename from chrome/browser/resources/chromeos/switch_access/icons/scroll_down.svg rename to chrome/browser/resources/chromeos/switch_access/icons/scrollDown.svg
diff --git a/chrome/browser/resources/chromeos/switch_access/icons/scroll_left.svg b/chrome/browser/resources/chromeos/switch_access/icons/scrollLeft.svg similarity index 100% rename from chrome/browser/resources/chromeos/switch_access/icons/scroll_left.svg rename to chrome/browser/resources/chromeos/switch_access/icons/scrollLeft.svg
diff --git a/chrome/browser/resources/chromeos/switch_access/icons/scroll_right.svg b/chrome/browser/resources/chromeos/switch_access/icons/scrollRight.svg similarity index 100% rename from chrome/browser/resources/chromeos/switch_access/icons/scroll_right.svg rename to chrome/browser/resources/chromeos/switch_access/icons/scrollRight.svg
diff --git a/chrome/browser/resources/chromeos/switch_access/icons/scroll_up.svg b/chrome/browser/resources/chromeos/switch_access/icons/scrollUp.svg similarity index 100% rename from chrome/browser/resources/chromeos/switch_access/icons/scroll_up.svg rename to chrome/browser/resources/chromeos/switch_access/icons/scrollUp.svg
diff --git a/chrome/browser/resources/chromeos/switch_access/icons/showContextMenu.svg b/chrome/browser/resources/chromeos/switch_access/icons/showContextMenu.svg new file mode 100644 index 0000000..706db26d --- /dev/null +++ b/chrome/browser/resources/chromeos/switch_access/icons/showContextMenu.svg
@@ -0,0 +1,4 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="#FFFFFF"> + <path d="M0 0h24v24H0z" fill="none"/> + <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/> +</svg>
diff --git a/chrome/browser/resources/chromeos/switch_access/menu_manager.js b/chrome/browser/resources/chromeos/switch_access/menu_manager.js index 7765b57..6d19575 100644 --- a/chrome/browser/resources/chromeos/switch_access/menu_manager.js +++ b/chrome/browser/resources/chromeos/switch_access/menu_manager.js
@@ -208,8 +208,6 @@ scrollableAncestor = scrollableAncestor.parent; if (scrollableAncestor.scrollable) { - // TODO(crbug/920659) This does not work for ARC++. Implement scroll - // directions via standardActions. if (scrollableAncestor.scrollX > scrollableAncestor.scrollXMin) actions.push(MenuManager.Action.SCROLL_LEFT); if (scrollableAncestor.scrollX < scrollableAncestor.scrollXMax) @@ -219,8 +217,10 @@ if (scrollableAncestor.scrollY < scrollableAncestor.scrollYMax) actions.push(MenuManager.Action.SCROLL_DOWN); } + const standardActions = /** @type {!Array<MenuManager.Action>} */ ( + node.standardActions.filter(action => action in MenuManager.Action)); - return actions; + return actions.concat(standardActions); } /** @@ -251,6 +251,8 @@ event.data === MenuManager.Action.SCROLL_LEFT || event.data === MenuManager.Action.SCROLL_RIGHT) this.navigationManager_.scroll(event.data); + else + this.navigationManager_.performActionOnCurrentNode(event.data); } /** @@ -276,18 +278,21 @@ * @const */ MenuManager.Action = { + DECREMENT: chrome.automation.ActionType.DECREMENT, DICTATION: 'dictation', + INCREMENT: chrome.automation.ActionType.INCREMENT, // This opens the Switch Access settings in a new Chrome tab. OPTIONS: 'options', - SCROLL_BACKWARD: 'scroll-backward', - SCROLL_DOWN: 'scroll-down', - SCROLL_FORWARD: 'scroll-forward', - SCROLL_LEFT: 'scroll-left', - SCROLL_RIGHT: 'scroll-right', - SCROLL_UP: 'scroll-up', + SCROLL_BACKWARD: chrome.automation.ActionType.SCROLL_BACKWARD, + SCROLL_DOWN: chrome.automation.ActionType.SCROLL_DOWN, + SCROLL_FORWARD: chrome.automation.ActionType.SCROLL_FORWARD, + SCROLL_LEFT: chrome.automation.ActionType.SCROLL_LEFT, + SCROLL_RIGHT: chrome.automation.ActionType.SCROLL_RIGHT, + SCROLL_UP: chrome.automation.ActionType.SCROLL_UP, // This either performs the default action or enters a new scope, as // applicable. - SELECT: 'select' + SELECT: 'select', + SHOW_CONTEXT_MENU: chrome.automation.ActionType.SHOW_CONTEXT_MENU }; /**
diff --git a/chrome/browser/resources/chromeos/switch_access/menu_panel.html b/chrome/browser/resources/chromeos/switch_access/menu_panel.html index 1f89f3d4..987e907 100644 --- a/chrome/browser/resources/chromeos/switch_access/menu_panel.html +++ b/chrome/browser/resources/chromeos/switch_access/menu_panel.html
@@ -18,26 +18,46 @@ <img src="icons/select.svg"> <p>Select</p> </button> - <button class="action" id="scroll-down" hidden> - <img src="icons/scroll_down.svg"> + <button class="action" id="increment"> + <img src="icons/increment.svg"> + <p>Increment</p> + </button> + <button class="action" id="decrement"> + <img src="icons/decrement.svg"> + <p>Decrement</p> + </button> + <button class="action" id="scrollDown"> + <img src="icons/scrollDown.svg"> <p>Scroll down</p> </button> - <button class="action" id="scroll-up" hidden> - <img src="icons/scroll_up.svg"> + <button class="action" id="scrollUp"> + <img src="icons/scrollUp.svg"> <p>Scroll up</p> </button> - <button class="action" id="scroll-right" hidden> - <img src="icons/scroll_right.svg"> + <button class="action" id="scrollRight"> + <img src="icons/scrollRight.svg"> <p>Scroll right</p> </button> - <button class="action" id="scroll-left" hidden> - <img src="icons/scroll_left.svg"> + <button class="action" id="scrollLeft"> + <img src="icons/scrollLeft.svg"> <p>Scroll left</p> </button> + <button class="action" id="scrollForward"> + <img src="icons/scrollDown.svg"> + <p>Scroll down</p> + </button> + <button class="action" id="scrollBackward"> + <img src="icons/scrollUp.svg"> + <p>Scroll up</p> + </button> <button class="action" id="dictation"> <img src="icons/dictation.svg"> <p>Dictation</p> </button> + <button class="action" id="showContextMenu"> + <img src="icons/showContextMenu.svg"> + <p>Show Context Menu</p> + </button> <button class="action" id="options"> <img src="icons/options.svg"> <p>Options</p>
diff --git a/chrome/browser/resources/chromeos/switch_access/navigation_manager.js b/chrome/browser/resources/chromeos/switch_access/navigation_manager.js index 7740d0e..be068070 100644 --- a/chrome/browser/resources/chromeos/switch_access/navigation_manager.js +++ b/chrome/browser/resources/chromeos/switch_access/navigation_manager.js
@@ -146,7 +146,7 @@ scroll(scrollAction) { // Find the closest ancestor to the current node that is scrollable. let scrollNode = this.node_; - while (scrollNode && scrollNode.scrollX === undefined) + while (scrollNode && !scrollNode.scrollable) scrollNode = scrollNode.parent; if (!scrollNode) return; @@ -215,6 +215,16 @@ this.node_.doDefault(); } + /** + * Performs |action| on the current node, if an appropriate action exists. + * @param {!MenuManager.Action} action + */ + performActionOnCurrentNode(action) { + if (action in chrome.automation.ActionType) + this.node_.performStandardAction( + /** @type {chrome.automation.ActionType} */ (action)); + } + // ----------------------Private Methods--------------------- /**
diff --git a/chrome/browser/resources/history/history_item.html b/chrome/browser/resources/history/history_item.html index dd709635..a57f41d 100644 --- a/chrome/browser/resources/history/history_item.html +++ b/chrome/browser/resources/history/history_item.html
@@ -71,6 +71,8 @@ flex: 1; height: var(--item-height); overflow: hidden; + /* Allows the link's focus outline to be shown completely. */ + padding-inline-start: 5px; } #checkbox {
diff --git a/chrome/browser/resources/md_extensions/detail_view.html b/chrome/browser/resources/md_extensions/detail_view.html index 4744e8c..14c4896c 100644 --- a/chrome/browser/resources/md_extensions/detail_view.html +++ b/chrome/browser/resources/md_extensions/detail_view.html
@@ -140,11 +140,10 @@ extensions-toggle-row { @apply --cr-section; box-sizing: border-box; - padding-bottom: var(--cr-section-vertical-padding); padding-inline-end: 0; padding-inline-start: 0; - padding-top: var(--cr-section-vertical-padding); - --toggle-row-label-padding: var(--cr-section-padding); + --toggle-row-label-horizontal-padding: var(--cr-section-padding); + --toggle-row-label-vertical-padding: var(--cr-section-vertical-padding); } #load-path {
diff --git a/chrome/browser/resources/md_extensions/toggle_row.html b/chrome/browser/resources/md_extensions/toggle_row.html index 6f963b43..f8cdcb4a 100644 --- a/chrome/browser/resources/md_extensions/toggle_row.html +++ b/chrome/browser/resources/md_extensions/toggle_row.html
@@ -21,7 +21,8 @@ cursor: pointer; display: flex; flex: 1; - padding: 0 var(--toggle-row-label-padding, 0); + padding: var(--toggle-row-label-vertical-padding, 0) + var(--toggle-row-label-horizontal-padding, 0); width: 100%; }
diff --git a/chrome/browser/resources/omnibox/omnibox_output.js b/chrome/browser/resources/omnibox/omnibox_output.js index 85a4a80..0550f111 100644 --- a/chrome/browser/resources/omnibox/omnibox_output.js +++ b/chrome/browser/resources/omnibox/omnibox_output.js
@@ -539,6 +539,12 @@ } class OutputProperty extends HTMLTableCellElement { + constructor() { + super(); + /** @type {string} */ + this.filterName; + } + /** * @param {Column} column * @param {!Array<*>} values @@ -547,7 +553,7 @@ static create(column, values) { const outputProperty = new column.outputClass(); outputProperty.classList.add(column.cellClassName); - outputProperty.name = column.headerText.join('.'); + outputProperty.filterName = column.tooltip.split('\n', 1)[0]; outputProperty.values = values; return outputProperty; } @@ -698,7 +704,7 @@ } get text() { - return (this.value ? 'is: ' : 'not: ') + this.name; + return (this.value ? 'is: ' : 'not: ') + this.filterName; } } @@ -933,7 +939,7 @@ ['image', 'contents', 'description', 'answer'], OutputAnswerProperty), new Column( ['D'], '', 'allowedToBeDefaultMatch', true, - 'Can Be Default\nA green checkmark indicates that the result can be ' + + 'Can be Default\nA green checkmark indicates that the result can be ' + 'the default match (i.e., can be the match that pressing enter ' + 'in the omnibox navigates to).', ['allowedToBeDefaultMatch'], OutputBooleanProperty),
diff --git a/chrome/browser/resources/pdf/pdf_viewer.js b/chrome/browser/resources/pdf/pdf_viewer.js index e04e3b5..79db54d 100644 --- a/chrome/browser/resources/pdf/pdf_viewer.js +++ b/chrome/browser/resources/pdf/pdf_viewer.js
@@ -1429,7 +1429,7 @@ this.viewer_.handleBeep(); break; case 'documentDimensions': - viewer.setDocumentDimensions(message.data); + this.viewer_.setDocumentDimensions(message.data); break; case 'email': const href = 'mailto:' + message.data.to + '?cc=' + message.data.cc +
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.html b/chrome/browser/resources/settings/internet_page/internet_detail_page.html index a9ed2ea0..907239d 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.html
@@ -70,70 +70,70 @@ <div class="start layout horizontal center"> <cr-network-icon show-technology-badge="[[showTechnologyBadge_]]" - network-state="[[networkProperties]]"> + network-state="[[networkProperties_]]"> </cr-network-icon> <div id="networkState" class="title settings-box-text" - connected$="[[isConnectedState_(networkProperties)]]" + connected$="[[isConnectedState_(networkProperties_)]]" error$="[[outOfRange_]]"> - [[getStateText_(networkProperties, outOfRange_)]] + [[getStateText_(networkProperties_, outOfRange_)]] </div> <template is="dom-if" - if="[[isPolicySource(networkProperties.Source))]]"> + if="[[isPolicySource(networkProperties_.Source))]]"> <cr-policy-indicator indicator-type="[[getIndicatorTypeForSource( - networkProperties.Source)]]"> + networkProperties_.Source)]]"> </cr-policy-indicator> </template> </div> <paper-button on-click="onForgetTap_" - hidden$="[[!showForget_(networkProperties)]]" - disabled="[[disableForget_(networkProperties, + hidden$="[[!showForget_(networkProperties_)]]" + disabled="[[disableForget_(networkProperties_, prefs.vpn_config_allowed)]]"> $i18n{networkButtonForget} </paper-button> <paper-button on-click="onViewAccountTap_" - hidden$="[[!showViewAccount_(networkProperties)]]"> + hidden$="[[!showViewAccount_(networkProperties_)]]"> $i18n{networkButtonViewAccount} </paper-button> <paper-button on-click="onActivateTap_" - hidden$="[[!showActivate_(networkProperties)]]"> + hidden$="[[!showActivate_(networkProperties_)]]"> $i18n{networkButtonActivate} </paper-button> <paper-button on-click="onConfigureTap_" - hidden$="[[!showConfigure_(networkProperties, globalPolicy, + hidden$="[[!showConfigure_(networkProperties_, globalPolicy, managedNetworkAvailable)]]" - disabled="[[disableConfigure_(networkProperties, + disabled="[[disableConfigure_(networkProperties_, prefs.vpn_config_allowed)]]"> $i18n{networkButtonConfigure} </paper-button> <controlled-button id="connect" action-button on-click="onConnectTap_" - hidden$="[[!showConnect_(networkProperties, globalPolicy, + hidden$="[[!showConnect_(networkProperties_, globalPolicy, managedNetworkAvailable)]]" - disabled="[[!enableConnect_(networkProperties, defaultNetwork, + disabled="[[!enableConnect_(networkProperties_, defaultNetwork, networkPropertiesReceived_, outOfRange_, globalPolicy, managedNetworkAvailable)]]" label="$i18n{networkButtonConnect}" - pref="[[getVpnConfigPrefFromValue_(networkProperties, + pref="[[getVpnConfigPrefFromValue_(networkProperties_, prefs.vpn_config_allowed)]]"> </controlled-button> <controlled-button id="disconnect" action-button on-click="onDisconnectTap_" - hidden$="[[!showDisconnect_(networkProperties)]]" + hidden$="[[!showDisconnect_(networkProperties_)]]" label="$i18n{networkButtonDisconnect}" - pref="[[getVpnConfigPrefFromValue_(networkProperties, + pref="[[getVpnConfigPrefFromValue_(networkProperties_, prefs.vpn_config_allowed)]]"> </controlled-button> </div> <!-- Disabled by policy / Shared messages. --> <div class="settings-box continuation" - hidden$="[[!isBlockedByPolicy_(networkProperties, globalPolicy, + hidden$="[[!isBlockedByPolicy_(networkProperties_, globalPolicy, managedNetworkAvailable)]]"> <iron-icon class="policy" icon="cr20:domain"></iron-icon> <div class="settings-box-text">$i18n{networkConnectNotAllowed}</div> </div> <div class="settings-box continuation settings-box-text" - hidden$="[[!showShared_(networkProperties, globalPolicy, + hidden$="[[!showShared_(networkProperties_, globalPolicy, managedNetworkAvailable)]]"> $i18n{networkShared} </div> @@ -153,36 +153,37 @@ <template is="dom-if" if="[[!isSecondaryUser_]]"> <!-- Prefer this network. --> <template is="dom-if" - if="[[showPreferNetwork_(networkProperties, globalPolicy, + if="[[showPreferNetwork_(networkProperties_, globalPolicy, managedNetworkAvailable)]]"> <div class="settings-box"> <div id="preferNetworkToggleLabel" class="start settings-box-text"> $i18n{networkPrefer} </div> <cr-policy-network-indicator - property="[[networkProperties.Priority]]"> + property="[[networkProperties_.Priority]]"> </cr-policy-network-indicator> <cr-toggle checked="{{preferNetwork_}}" - disabled="[[isNetworkPolicyEnforced(networkProperties.Priority)]]" + disabled="[[isNetworkPolicyEnforced( + networkProperties_.Priority)]]" aria-labelledby="preferNetworkToggleLabel"> </cr-toggle> </div> </template> <!-- Autoconnect. --> <template is="dom-if" - if="[[showAutoConnect_(networkProperties, globalPolicy, + if="[[showAutoConnect_(networkProperties_, globalPolicy, managedNetworkAvailable)]]"> <div class="settings-box"> <div id="autoConnectToggleLabel" class="start settings-box-text"> $i18n{networkAutoConnect} </div> <template is="dom-if" if="[[isAutoConnectEnforcedByPolicy( - networkProperties, globalPolicy)]]"> + networkProperties_, globalPolicy)]]"> <cr-policy-indicator indicator-type="devicePolicy"> </cr-policy-indicator> </template> <cr-toggle checked="{{autoConnect_}}" - disabled="[[isAutoConnectEnforcedByPolicy(networkProperties, + disabled="[[isAutoConnectEnforcedByPolicy(networkProperties_, globalPolicy)]]" aria-labelledby="autoConnectToggleLabel"> </cr-toggle> @@ -190,22 +191,22 @@ </template> <!-- Always-on VPN. --> <template is="dom-if" - if="[[showAlwaysOnVpn_(networkProperties)]]"> + if="[[showAlwaysOnVpn_(networkProperties_)]]"> <div class="settings-box"> <div id="AlwaysOnVpnToggleLabel" class="start settings-box-text"> $i18n{networkAlwaysOnVpn} </div> <cr-toggle checked="{{alwaysOnVpn_}}" - disabled="[[!enableAlwaysOnVpn_(networkProperties, + disabled="[[!enableAlwaysOnVpn_(networkProperties_, prefs.vpn_config_allowed)]]" aria-labelledby="AlwaysOnVpnToggleLabel" on-change="onAlwaysOnVpnChange_"> </cr-toggle> <template is="dom-if" - if="[[!enableAlwaysOnVpn_(networkProperties, + if="[[!enableAlwaysOnVpn_(networkProperties_, prefs.vpn_config_allowed)]]"> <cr-policy-pref-indicator - pref="[[getVpnConfigPrefFromValue_(networkProperties, + pref="[[getVpnConfigPrefFromValue_(networkProperties_, prefs.vpn_config_allowed)]]" on-click="onIndicatorTap_" icon-aria-label="$i18n{networkAlwaysOnVpn}"> </cr-policy-pref-indicator> @@ -213,42 +214,42 @@ </div> </template> <!-- Data roaming (Cellular only). --> - <template is="dom-if" if="[[isCellular_(networkProperties)]]"> + <template is="dom-if" if="[[isCellular_(networkProperties_)]]"> <settings-toggle-button id="allowDataRoaming" pref="{{prefs.cros.signed.data_roaming_enabled}}" label="$i18n{networkAllowDataRoaming}"> </settings-toggle-button> </template> <!-- SIM Info (Cellular only). --> - <template is="dom-if" if="[[showCellularSim_(networkProperties)]]" + <template is="dom-if" if="[[showCellularSim_(networkProperties_)]]" restamp> <div class="settings-box single-column stretch"> <network-siminfo editable on-siminfo-change="onNetworkPropertyChange_" - network-properties="[[networkProperties]]" + network-properties="[[networkProperties_]]" networking-private="[[networkingPrivate]]"> </network-siminfo> </div> </template> <!-- IP Address. --> <div class="settings-box two-line single-column stretch settings-box-text" - hidden$="[[!showIpAddress_(ipAddress_, networkProperties)]]"> + hidden$="[[!showIpAddress_(ipAddress_, networkProperties_)]]"> <div>$i18n{networkIPAddress}</div> <div class="secondary">[[ipAddress_]]</div> </div> <!-- Properties to always show if present. --> - <template is="dom-if" if="[[hasInfoFields_(networkProperties)]]"> + <template is="dom-if" if="[[hasInfoFields_(networkProperties_)]]"> <div class="settings-box single-column stretch"> <network-property-list - fields="[[getInfoFields_(networkProperties)]]" - edit-field-types="[[getInfoEditFieldTypes_(networkProperties)]]" - property-dict="[[networkProperties]]" + fields="[[getInfoFields_(networkProperties_)]]" + edit-field-types="[[getInfoEditFieldTypes_(networkProperties_)]]" + property-dict="[[networkProperties_]]" on-property-change="onNetworkPropertyChange_"> </network-property-list> </div> </template> - <template is="dom-if" if="[[showAdvanced_(networkProperties)]]"> + <template is="dom-if" if="[[showAdvanced_(networkProperties_)]]"> <!-- Advanced toggle. --> <cr-expand-button alt="$i18n{networkSectionAdvancedA11yLabel}" @@ -260,24 +261,24 @@ <!-- Advanced section --> <iron-collapse opened="[[advancedExpanded_]]"> <div class="settings-box single-column stretch indented first" - hidden$="[[!hasAdvancedOrDeviceFields_(networkProperties)]]"> + hidden$="[[!hasAdvancedOrDeviceFields_(networkProperties_)]]"> <!-- Advanced properties --> <network-property-list - hidden$="[[!hasAdvancedFields_(networkProperties)]]" - fields="[[getAdvancedFields_(networkProperties)]]" - property-dict="[[networkProperties]]"> + hidden$="[[!hasAdvancedFields_(networkProperties_)]]" + fields="[[getAdvancedFields_(networkProperties_)]]" + property-dict="[[networkProperties_]]"> </network-property-list> <!-- Device properties --> <network-property-list - hidden$="[[!hasDeviceFields_(networkProperties)]]" - fields="[[getDeviceFields_(networkProperties)]]" - property-dict="[[networkProperties]]"> + hidden$="[[!hasDeviceFields_(networkProperties_)]]" + fields="[[getDeviceFields_(networkProperties_)]]" + property-dict="[[networkProperties_]]"> </network-property-list> </div> </iron-collapse> </template> - <template is="dom-if" if="[[hasNetworkSection_(networkProperties, + <template is="dom-if" if="[[hasNetworkSection_(networkProperties_, globalPolicy, managedNetworkAvailable)]]"> <!-- Network toggle --> <cr-expand-button @@ -289,7 +290,7 @@ $i18n{networkSectionNetwork} </div> <template is="dom-if" - if="[[showScanningSpinner_(networkProperties)]]"> + if="[[showScanningSpinner_(networkProperties_)]]"> <paper-spinner-lite active></paper-spinner-lite> </template> </div> @@ -299,36 +300,36 @@ <div class="settings-box single-column stretch indented first"> <!-- Choose Mobile Network (Cellular only). --> <template is="dom-if" - if="[[showCellularChooseNetwork_(networkProperties)]]"> + if="[[showCellularChooseNetwork_(networkProperties_)]]"> <network-choose-mobile networking-private="[[networkingPrivate]]" - network-properties="[[networkProperties]]"> + network-properties="[[networkProperties_]]"> </network-choose-mobile> </template> <!-- APN --> - <template is="dom-if" if="[[isCellular_(networkProperties)]]"> + <template is="dom-if" if="[[isCellular_(networkProperties_)]]"> <network-apnlist editable on-apn-change="onNetworkPropertyChange_" - network-properties="[[networkProperties]]"> + network-properties="[[networkProperties_]]"> </network-apnlist> </template> <!-- IP Config, Nameservers --> <template is="dom-if" - if="[[isRememberedOrConnected_(networkProperties)]]"> + if="[[isRememberedOrConnected_(networkProperties_)]]"> <network-ip-config editable on-ip-change="onIPConfigChange_" - network-properties="[[networkProperties]]"> + network-properties="[[networkProperties_]]"> </network-ip-config> <network-nameservers editable on-nameservers-change="onIPConfigChange_" - network-properties="[[networkProperties]]"> + network-properties="[[networkProperties_]]"> </network-nameservers> </template> </div> </iron-collapse> </template> - <template is="dom-if" if="[[hasProxySection_(networkProperties, + <template is="dom-if" if="[[hasProxySection_(networkProperties_, globalPolicy, managedNetworkAvailable)]]"> <!-- Proxy toggle --> <cr-expand-button @@ -341,14 +342,14 @@ <iron-collapse opened="[[proxyExpanded_]]"> <network-proxy-section prefs="{{prefs}}" on-proxy-change="onProxyChange_" - network-properties="[[networkProperties]]"> + network-properties="[[networkProperties_]]"> </network-proxy-section> </iron-collapse> </template> </template> <tether-connection-dialog id="tetherDialog" - network-properties="[[networkProperties]]" + network-properties="[[networkProperties_]]" on-tether-connect="onTetherConnect_" out-of-range="[[outOfRange_]]"> </tether-connection-dialog>
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.js b/chrome/browser/resources/settings/internet_page/internet_detail_page.js index 3af1e32..e9542a6 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.js +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.js
@@ -22,15 +22,6 @@ /** The network GUID to display details for. */ guid: String, - /** - * The current properties for the network matching |guid|. - * @type {!CrOnc.NetworkProperties|undefined} - */ - networkProperties: { - type: Object, - observer: 'networkPropertiesChanged_', - }, - /** Preferences state. */ prefs: { type: Object, @@ -38,6 +29,17 @@ }, /** + * The current properties for the network matching |guid|. Note: This may + * become set to |undefined| after it is initially set if the network is no + * longer visible, so always test that it is set before accessing it. + * @private {!CrOnc.NetworkProperties|undefined} + */ + networkProperties_: { + type: Object, + observer: 'networkPropertiesChanged_', + }, + + /** * Whether the user is a secondary user. * @private */ @@ -237,7 +239,7 @@ this.guid = guid; // Set basic networkProperties until they are loaded. this.networkPropertiesReceived_ = false; - this.networkProperties = { + this.networkProperties_ = { GUID: this.guid, Type: type, ConnectionState: CrOnc.ConnectionState.NOT_CONNECTED, @@ -256,19 +258,19 @@ /** @private */ networkPropertiesChanged_: function() { - if (!this.networkProperties) { + if (!this.networkProperties_) { return; } // Update autoConnect if it has changed. Default value is false. - const autoConnect = CrOnc.getAutoConnect(this.networkProperties); + const autoConnect = CrOnc.getAutoConnect(this.networkProperties_); if (autoConnect != this.autoConnect_) { this.autoConnect_ = autoConnect; } // Update preferNetwork if it has changed. Default value is false. const priority = /** @type {number} */ ( - CrOnc.getActiveValue(this.networkProperties.Priority) || 0); + CrOnc.getActiveValue(this.networkProperties_.Priority) || 0); const preferNetwork = priority > 0; if (preferNetwork != this.preferNetwork_) { this.preferNetwork_ = preferNetwork; @@ -276,11 +278,11 @@ // Set the IPAddress property to the IPV4 Address. const ipv4 = - CrOnc.getIPConfigForType(this.networkProperties, CrOnc.IPType.IPV4); + CrOnc.getIPConfigForType(this.networkProperties_, CrOnc.IPType.IPV4); this.ipAddress_ = (ipv4 && ipv4.IPAddress) || ''; // Update the detail page title. - this.parentNode.pageTitle = CrOnc.getNetworkName(this.networkProperties); + this.parentNode.pageTitle = CrOnc.getNetworkName(this.networkProperties_); Polymer.dom.flush(); @@ -295,7 +297,7 @@ } if (this.shouldShowConfigureWhenNetworkLoaded_ && - this.networkProperties.Tether) { + this.networkProperties_.Tether) { // Set |this.shouldShowConfigureWhenNetworkLoaded_| back to false to // ensure that the Tether dialog is only shown once. this.shouldShowConfigureWhenNetworkLoaded_ = false; @@ -305,7 +307,7 @@ /** @private */ autoConnectChanged_: function() { - if (!this.networkProperties || !this.guid) { + if (!this.networkProperties_ || !this.guid) { return; } const onc = this.getEmptyNetworkProperties_(); @@ -315,7 +317,7 @@ /** @private */ preferNetworkChanged_: function() { - if (!this.networkProperties || !this.guid) { + if (!this.networkProperties_ || !this.guid) { return; } const onc = this.getEmptyNetworkProperties_(); @@ -394,7 +396,7 @@ this.close_(); } - this.networkProperties = properties; + this.networkProperties_ = properties; this.networkPropertiesReceived_ = true; this.outOfRange_ = false; }, @@ -408,10 +410,11 @@ if (!state) { // If |state| is null, the network is no longer visible, close this. console.error('Network no longer exists: ' + this.guid); - this.networkProperties = undefined; + this.networkProperties_ = undefined; this.close_(); + return; } - this.networkProperties = { + this.networkProperties_ = { GUID: state.GUID, Type: state.Type, Connectable: state.Connectable, @@ -448,8 +451,8 @@ * @private */ getEmptyNetworkProperties_: function() { - const type = - this.networkProperties ? this.networkProperties.Type : CrOnc.Type.WI_FI; + const type = this.networkProperties_ ? this.networkProperties_.Type : + CrOnc.Type.WI_FI; return {Type: type}; }, @@ -460,7 +463,7 @@ * @private */ getStateText_: function(networkProperties, outOfRange) { - if (networkProperties === undefined || !networkProperties.ConnectionState) { + if (!networkProperties || !networkProperties.ConnectionState) { return ''; } @@ -479,7 +482,8 @@ * @private */ isConnectedState_: function(networkProperties) { - return networkProperties.ConnectionState == CrOnc.ConnectionState.CONNECTED; + return !!networkProperties && + networkProperties.ConnectionState == CrOnc.ConnectionState.CONNECTED; }, /** @@ -508,7 +512,7 @@ * @private */ isCellular_: function(networkProperties) { - return networkProperties !== undefined && + return !!networkProperties && networkProperties.Type == CrOnc.Type.CELLULAR && !!networkProperties.Cellular; }, @@ -522,8 +526,7 @@ */ isBlockedByPolicy_: function( networkProperties, globalPolicy, managedNetworkAvailable) { - if (networkProperties === undefined || - networkProperties.Type != CrOnc.Type.WI_FI || + if (!networkProperties || networkProperties.Type != CrOnc.Type.WI_FI || this.isPolicySource(networkProperties.Source) || !globalPolicy) { return false; } @@ -545,7 +548,7 @@ */ showConnect_: function( networkProperties, globalPolicy, managedNetworkAvailable) { - if (networkProperties === undefined) { + if (!networkProperties) { return false; } @@ -570,7 +573,7 @@ * @private */ showDisconnect_: function(networkProperties) { - return networkProperties !== undefined && + return !!networkProperties && networkProperties.Type != CrOnc.Type.ETHERNET && networkProperties.ConnectionState != CrOnc.ConnectionState.NOT_CONNECTED; @@ -582,7 +585,7 @@ * @private */ showForget_: function(networkProperties) { - if (this.isSecondaryUser_ || networkProperties === undefined) { + if (this.isSecondaryUser_ || !networkProperties) { return false; } const type = networkProperties.Type; @@ -622,7 +625,7 @@ */ showConfigure_: function( networkProperties, globalPolicy, managedNetworkAvailable) { - if (this.isSecondaryUser_ || networkProperties === undefined) { + if (this.isSecondaryUser_ || !networkProperties) { return false; } if (this.isBlockedByPolicy_( @@ -670,8 +673,9 @@ * @private */ disableConfigure_: function(networkProperties, vpn_config_allowed) { - if (this.isVpn_(networkProperties) && vpn_config_allowed && - !vpn_config_allowed.value) { + if (!networkProperties || + (this.isVpn_(networkProperties) && vpn_config_allowed && + !vpn_config_allowed.value)) { return true; } return this.isPolicySource(networkProperties.Source) && @@ -755,7 +759,8 @@ if (!networkPropertiesReceived || outOfRange) { return false; } - if (this.isSecondaryUser_ && this.networkProperties.Connectable === false) { + if (this.isSecondaryUser_ && + this.networkProperties_.Connectable === false) { return false; } if ((networkProperties.Type == CrOnc.Type.CELLULAR) && @@ -775,7 +780,7 @@ * @private */ isVpn_: function(networkProperties) { - return networkProperties.Type == CrOnc.Type.VPN; + return !!networkProperties && networkProperties.Type == CrOnc.Type.VPN; }, /** @@ -809,18 +814,18 @@ /** @private */ onConnectTap_: function() { - if (CrOnc.shouldShowTetherDialogBeforeConnection(this.networkProperties)) { + if (CrOnc.shouldShowTetherDialogBeforeConnection(this.networkProperties_)) { this.showTetherDialog_(); return; } - this.fire('network-connect', {networkProperties: this.networkProperties}); + this.fire('network-connect', {networkProperties: this.networkProperties_}); }, /** @private */ onTetherConnect_: function() { this.getTetherDialog_().close(); this.fire('network-connect', { - networkProperties: this.networkProperties, + networkProperties: this.networkProperties_, bypassConnectionDialog: true }); }, @@ -844,14 +849,14 @@ /** @private */ onConfigureTap_: function() { - if (this.networkProperties && - (this.isThirdPartyVpn_(this.networkProperties) || - this.isArcVpn_(this.networkProperties))) { + if (this.networkProperties_ && + (this.isThirdPartyVpn_(this.networkProperties_) || + this.isArcVpn_(this.networkProperties_))) { this.browserProxy_.configureThirdPartyVpn(this.guid); return; } - this.fire('show-config', this.networkProperties); + this.fire('show-config', this.networkProperties_); }, /** @private */ @@ -877,7 +882,7 @@ * @private */ onNetworkPropertyChange_: function(e) { - if (!this.networkProperties) { + if (!this.networkProperties_) { return; } const field = e.detail.field; @@ -894,7 +899,8 @@ CrOnc.setProperty(onc, field, value); // Ensure any required configuration properties are also set. if (field.match(/^VPN/)) { - const vpnType = CrOnc.getActiveValue(this.networkProperties.VPN.Type); + const vpnType = + CrOnc.getActiveValue(this.networkProperties_.VPN.Type); assert(vpnType); CrOnc.setProperty(onc, 'VPN.Type', vpnType); } @@ -917,7 +923,7 @@ * @private */ onIPConfigChange_: function(event) { - if (!this.networkProperties) { + if (!this.networkProperties_) { return; } const field = event.detail.field; @@ -927,7 +933,7 @@ const onc = this.getEmptyNetworkProperties_(); const ipConfigType = /** @type {chrome.networkingPrivate.IPConfigType|undefined} */ ( - CrOnc.getActiveValue(this.networkProperties.IPAddressConfigType)); + CrOnc.getActiveValue(this.networkProperties_.IPAddressConfigType)); if (field == 'IPAddressConfigType') { const newIpConfigType = /** @type {chrome.networkingPrivate.IPConfigType} */ (value); @@ -939,7 +945,7 @@ const nsConfigType = /** @type {chrome.networkingPrivate.IPConfigType|undefined} */ ( CrOnc.getActiveValue( - this.networkProperties.NameServersConfigType)); + this.networkProperties_.NameServersConfigType)); const newNsConfigType = /** @type {chrome.networkingPrivate.IPConfigType} */ (value); if (newNsConfigType == nsConfigType) { @@ -948,7 +954,7 @@ onc.NameServersConfigType = newNsConfigType; } else if (field == 'StaticIPConfig') { if (ipConfigType == CrOnc.IPConfigType.STATIC) { - const staticIpConfig = this.networkProperties.StaticIPConfig; + const staticIpConfig = this.networkProperties_.StaticIPConfig; const ipConfigValue = /** @type {!Object} */ (value); if (staticIpConfig && this.allPropertiesMatch_(staticIpConfig, ipConfigValue)) { @@ -989,7 +995,7 @@ // setValidStaticIPConfig will fill in any other properties from // networkProperties. This is necessary since we update IP Address and // NameServers independently. - CrOnc.setValidStaticIPConfig(onc, this.networkProperties); + CrOnc.setValidStaticIPConfig(onc, this.networkProperties_); this.setNetworkProperties_(onc); }, @@ -1000,7 +1006,7 @@ * @private */ onProxyChange_: function(event) { - if (!this.networkProperties) { + if (!this.networkProperties_) { return; } const field = event.detail.field; @@ -1022,7 +1028,7 @@ */ showShared_: function( networkProperties, globalPolicy, managedNetworkAvailable) { - return networkProperties !== undefined && + return !!networkProperties && (networkProperties.Source == 'Device' || networkProperties.Source == 'DevicePolicy') && !this.isBlockedByPolicy_( @@ -1038,7 +1044,7 @@ */ showAutoConnect_: function( networkProperties, globalPolicy, managedNetworkAvailable) { - return networkProperties !== undefined && + return !!networkProperties && networkProperties.Type != CrOnc.Type.ETHERNET && this.isRemembered_(networkProperties) && !this.isArcVpn_(networkProperties) && @@ -1053,8 +1059,7 @@ * @private */ isAutoConnectEnforcedByPolicy: function(networkProperties, globalPolicy) { - if (networkProperties === undefined || - networkProperties.Type != CrOnc.Type.WI_FI) { + if (!networkProperties || networkProperties.Type != CrOnc.Type.WI_FI) { return false; } if (this.isPolicySource(networkProperties.Source)) { @@ -1136,7 +1141,7 @@ */ hasVisibleFields_: function(fields) { for (let i = 0; i < fields.length; ++i) { - const value = this.get(fields[i], this.networkProperties); + const value = this.get(fields[i], this.networkProperties_); if (value !== undefined && value !== '') { return true; } @@ -1158,22 +1163,22 @@ * @private */ getInfoFields_: function() { - if (this.networkProperties === undefined) { + if (!this.networkProperties_) { return []; } /** @type {!Array<string>} */ const fields = []; - const type = this.networkProperties.Type; - if (type == CrOnc.Type.CELLULAR && !!this.networkProperties.Cellular) { + const type = this.networkProperties_.Type; + if (type == CrOnc.Type.CELLULAR && !!this.networkProperties_.Cellular) { fields.push( 'Cellular.ActivationState', 'Cellular.RoamingState', 'RestrictedConnectivity', 'Cellular.ServingOperator.Name'); - } else if (type == CrOnc.Type.TETHER && !!this.networkProperties.Tether) { + } else if (type == CrOnc.Type.TETHER && !!this.networkProperties_.Tether) { fields.push( 'Tether.BatteryPercentage', 'Tether.SignalStrength', 'Tether.Carrier'); - } else if (type == CrOnc.Type.VPN && !!this.networkProperties.VPN) { - const vpnType = CrOnc.getActiveValue(this.networkProperties.VPN.Type); + } else if (type == CrOnc.Type.VPN && !!this.networkProperties_.VPN) { + const vpnType = CrOnc.getActiveValue(this.networkProperties_.VPN.Type); switch (vpnType) { case CrOnc.VPNType.THIRD_PARTY_VPN: fields.push('VPN.ThirdPartyVPN.ProviderName'); @@ -1203,14 +1208,14 @@ * @private */ getInfoEditFieldTypes_: function() { - if (this.networkProperties === undefined) { + if (!this.networkProperties_) { return []; } /** @dict */ const editFields = {}; - const type = this.networkProperties.Type; - if (type == CrOnc.Type.VPN && !!this.networkProperties.VPN) { - const vpnType = CrOnc.getActiveValue(this.networkProperties.VPN.Type); + const type = this.networkProperties_.Type; + if (type == CrOnc.Type.VPN && !!this.networkProperties_.VPN) { + const vpnType = CrOnc.getActiveValue(this.networkProperties_.VPN.Type); if (vpnType != CrOnc.VPNType.THIRD_PARTY_VPN) { editFields['VPN.Host'] = 'String'; } @@ -1227,16 +1232,16 @@ * @private */ getAdvancedFields_: function() { - if (this.networkProperties === undefined) { + if (!this.networkProperties_) { return []; } /** @type {!Array<string>} */ const fields = []; - const type = this.networkProperties.Type; + const type = this.networkProperties_.Type; if (type != CrOnc.Type.TETHER) { fields.push('MacAddress'); } - if (type == CrOnc.Type.CELLULAR && !!this.networkProperties.Cellular) { + if (type == CrOnc.Type.CELLULAR && !!this.networkProperties_.Cellular) { fields.push( 'Cellular.Carrier', 'Cellular.Family', 'Cellular.NetworkTechnology', 'Cellular.ServingOperator.Code'); @@ -1256,8 +1261,8 @@ * @private */ getDeviceFields_: function() { - if (this.networkProperties === undefined || - this.networkProperties.Type !== CrOnc.Type.CELLULAR) { + if (!this.networkProperties || + this.networkProperties_.Type !== CrOnc.Type.CELLULAR) { return []; } @@ -1276,8 +1281,7 @@ * @private */ showAdvanced_: function(networkProperties) { - if (networkProperties === undefined || - networkProperties.Type == CrOnc.Type.TETHER) { + if (!networkProperties || networkProperties.Type == CrOnc.Type.TETHER) { // These settings apply to the underlying WiFi network, not the Tether // network. return false; @@ -1320,8 +1324,7 @@ */ hasNetworkSection_: function( networkProperties, globalPolicy, managedNetworkAvailable) { - if (networkProperties === undefined || - networkProperties.Type == CrOnc.Type.TETHER) { + if (!networkProperties || networkProperties.Type == CrOnc.Type.TETHER) { // These settings apply to the underlying WiFi network, not the Tether // network. return false; @@ -1345,8 +1348,7 @@ */ hasProxySection_: function( networkProperties, globalPolicy, managedNetworkAvailable) { - if (networkProperties === undefined || - networkProperties.Type == CrOnc.Type.TETHER) { + if (!networkProperties || networkProperties.Type == CrOnc.Type.TETHER) { // Proxy settings apply to the underlying WiFi network, not the Tether // network. return false; @@ -1364,9 +1366,9 @@ * @private */ showCellularChooseNetwork_: function(networkProperties) { - return networkProperties !== undefined && + return !!networkProperties && networkProperties.Type == CrOnc.Type.CELLULAR && - !!this.get('Cellular.SupportNetworkScan', this.networkProperties); + !!this.get('Cellular.SupportNetworkScan', this.networkProperties_); }, /** @@ -1384,7 +1386,7 @@ * @private */ showCellularSim_: function(networkProperties) { - return networkProperties !== undefined && + return !!networkProperties && networkProperties.Type == CrOnc.Type.CELLULAR && !!networkProperties.Cellular && networkProperties.Cellular.Family != 'CDMA'; @@ -1396,7 +1398,7 @@ * @private */ isArcVpn_: function(networkProperties) { - return networkProperties !== undefined && !!networkProperties.VPN && + return !!networkProperties && !!networkProperties.VPN && CrOnc.getActiveValue(networkProperties.VPN.Type) == CrOnc.VPNType.ARCVPN; }, @@ -1407,7 +1409,7 @@ * @private */ isThirdPartyVpn_: function(networkProperties) { - return networkProperties !== undefined && !!networkProperties.VPN && + return !!networkProperties && !!networkProperties.VPN && CrOnc.getActiveValue(networkProperties.VPN.Type) == CrOnc.VPNType.THIRD_PARTY_VPN; },
diff --git a/chrome/browser/sessions/tab_restore_browsertest.cc b/chrome/browser/sessions/tab_restore_browsertest.cc index 2a17cd1..fcd6381 100644 --- a/chrome/browser/sessions/tab_restore_browsertest.cc +++ b/chrome/browser/sessions/tab_restore_browsertest.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/sessions/session_restore_test_helper.h" #include "chrome/browser/sessions/tab_loader_tester.h" #include "chrome/browser/sessions/tab_restore_service_factory.h" +#include "chrome/browser/sessions/tab_restore_service_load_waiter.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_list.h" @@ -50,44 +51,6 @@ #include "chrome/browser/sessions/tab_loader.h" #endif // BUILDFLAG(ENABLE_SESSION_SERVICE) -// Class used to run a message loop waiting for the TabRestoreService to finish -// loading. Does nothing if the TabRestoreService was already loaded. -class WaitForLoadObserver : public sessions::TabRestoreServiceObserver { - public: - explicit WaitForLoadObserver(Browser* browser) - : tab_restore_service_( - TabRestoreServiceFactory::GetForProfile(browser->profile())), - do_wait_(!tab_restore_service_->IsLoaded()) { - if (do_wait_) - tab_restore_service_->AddObserver(this); - } - - ~WaitForLoadObserver() override { - if (do_wait_) - tab_restore_service_->RemoveObserver(this); - } - - void Wait() { - if (do_wait_) - run_loop_.Run(); - } - - private: - // Overridden from TabRestoreServiceObserver: - void TabRestoreServiceDestroyed( - sessions::TabRestoreService* service) override {} - void TabRestoreServiceLoaded(sessions::TabRestoreService* service) override { - DCHECK(do_wait_); - run_loop_.Quit(); - } - - sessions::TabRestoreService* tab_restore_service_; - const bool do_wait_; - base::RunLoop run_loop_; - - DISALLOW_COPY_AND_ASSIGN(WaitForLoadObserver); -}; - class TabRestoreTest : public InProcessBrowserTest { public: TabRestoreTest() : active_browser_list_(NULL) { @@ -168,7 +131,7 @@ content::NOTIFICATION_LOAD_STOP, content::NotificationService::AllSources()); { - WaitForLoadObserver waiter(browser); + TabRestoreServiceLoadWaiter waiter(browser); chrome::RestoreTab(browser); waiter.Wait(); } @@ -892,3 +855,43 @@ TabLoaderTester::SetConstructionCallbackForTesting(nullptr); } #endif // BUILDFLAG(ENABLE_SESSION_SERVICE) + +IN_PROC_BROWSER_TEST_F(TabRestoreTest, PRE_GetRestoreTabType) { + // The TabRestoreService should get initialized (Loaded) + // automatically upon launch. + // Wait for robustness because InProcessBrowserTest::PreRunTestOnMainThread + // does not flush the task scheduler. + TabRestoreServiceLoadWaiter waiter(browser()); + waiter.Wait(); + + // When we start, we should get nothing. + ASSERT_EQ(chrome::GetRestoreTabType(browser()), + TabStripModelDelegate::RESTORE_NONE); + + // Add a tab and close it + AddSomeTabs(browser(), 1); + ASSERT_EQ(2, browser()->tab_strip_model()->count()); + EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); + content::WebContents* tab_to_close = + browser()->tab_strip_model()->GetActiveWebContents(); + content::WebContentsDestroyedWatcher destroyed_watcher(tab_to_close); + browser()->tab_strip_model()->CloseSelectedTabs(); + destroyed_watcher.Wait(); + + // We now should see a Tab as the restore type. + ASSERT_EQ(chrome::GetRestoreTabType(browser()), + TabStripModelDelegate::RESTORE_TAB); +} + +IN_PROC_BROWSER_TEST_F(TabRestoreTest, GetRestoreTabType) { + // The TabRestoreService should get initialized (Loaded) + // automatically upon launch. + // Wait for robustness because InProcessBrowserTest::PreRunTestOnMainThread + // does not flush the task scheduler. + TabRestoreServiceLoadWaiter waiter(browser()); + waiter.Wait(); + + // When we start this time we should get a Tab. + ASSERT_EQ(chrome::GetRestoreTabType(browser()), + TabStripModelDelegate::RESTORE_TAB); +}
diff --git a/chrome/browser/sessions/tab_restore_service_load_waiter.cc b/chrome/browser/sessions/tab_restore_service_load_waiter.cc new file mode 100644 index 0000000..d519375 --- /dev/null +++ b/chrome/browser/sessions/tab_restore_service_load_waiter.cc
@@ -0,0 +1,35 @@ +// Copyright 2019 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/sessions/tab_restore_service_load_waiter.h" + +#include "chrome/browser/sessions/tab_restore_service_factory.h" +#include "chrome/browser/ui/browser.h" +#include "components/sessions/core/tab_restore_service.h" + +// Class used to run a message loop waiting for the TabRestoreService to finish +// loading. Does nothing if the TabRestoreService was already loaded. +TabRestoreServiceLoadWaiter::TabRestoreServiceLoadWaiter(Browser* browser) + : tab_restore_service_( + TabRestoreServiceFactory::GetForProfile(browser->profile())), + do_wait_(!tab_restore_service_->IsLoaded()) { + if (do_wait_) + tab_restore_service_->AddObserver(this); +} + +TabRestoreServiceLoadWaiter::~TabRestoreServiceLoadWaiter() { + if (do_wait_) + tab_restore_service_->RemoveObserver(this); +} + +void TabRestoreServiceLoadWaiter::Wait() { + if (do_wait_) + run_loop_.Run(); +} + +void TabRestoreServiceLoadWaiter::TabRestoreServiceLoaded( + sessions::TabRestoreService* service) { + DCHECK(do_wait_); + run_loop_.Quit(); +}
diff --git a/chrome/browser/sessions/tab_restore_service_load_waiter.h b/chrome/browser/sessions/tab_restore_service_load_waiter.h new file mode 100644 index 0000000..a040ac7 --- /dev/null +++ b/chrome/browser/sessions/tab_restore_service_load_waiter.h
@@ -0,0 +1,36 @@ +// Copyright 2019 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_SESSIONS_TAB_RESTORE_SERVICE_LOAD_WAITER_H_ +#define CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_LOAD_WAITER_H_ + +#include "base/run_loop.h" +#include "components/sessions/core/tab_restore_service_observer.h" + +class Browser; + +// Class used to run a message loop waiting for the TabRestoreService to finish +// loading. Does nothing if the TabRestoreService was already loaded. +class TabRestoreServiceLoadWaiter : public sessions::TabRestoreServiceObserver { + public: + explicit TabRestoreServiceLoadWaiter(Browser* browser); + + ~TabRestoreServiceLoadWaiter() override; + + void Wait(); + + private: + // Overridden from TabRestoreServiceObserver: + void TabRestoreServiceDestroyed( + sessions::TabRestoreService* service) override {} + void TabRestoreServiceLoaded(sessions::TabRestoreService* service) override; + + sessions::TabRestoreService* const tab_restore_service_; + const bool do_wait_; + base::RunLoop run_loop_; + + DISALLOW_COPY_AND_ASSIGN(TabRestoreServiceLoadWaiter); +}; + +#endif // CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_LOAD_WAITER_H_
diff --git a/chrome/browser/speech/OWNERS b/chrome/browser/speech/OWNERS index 7cd0484..7909c02 100644 --- a/chrome/browser/speech/OWNERS +++ b/chrome/browser/speech/OWNERS
@@ -2,7 +2,8 @@ tommi@chromium.org # Text-to-speech -dmazzoni@chromium.org -dtseng@chromium.org +per-file *tts_*=dmazzoni@chromium.org +per-file *tts_*=dtseng@chromium.org +per-file *tts_*=katie@chromium.org # COMPONENT: Blink>Speech
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc index 2694317..c6b4d2b 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc +++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
@@ -68,15 +68,13 @@ void ChromeAppListModelUpdater::RemoveItem(const std::string& id) { if (app_list_controller_) app_list_controller_->RemoveItem(id); - else - RemoveChromeItem(id); + RemoveChromeItem(id); } void ChromeAppListModelUpdater::RemoveUninstalledItem(const std::string& id) { if (app_list_controller_) app_list_controller_->RemoveUninstalledItem(id); - else - RemoveChromeItem(id); + RemoveChromeItem(id); } void ChromeAppListModelUpdater::MoveItemToFolder(const std::string& id,
diff --git a/chrome/browser/ui/app_list/search/omnibox_result.cc b/chrome/browser/ui/app_list/search/omnibox_result.cc index f4825f1..20878ed 100644 --- a/chrome/browser/ui/app_list/search/omnibox_result.cc +++ b/chrome/browser/ui/app_list/search/omnibox_result.cc
@@ -249,15 +249,15 @@ case ash::OmniBoxZeroStateAction::kRemoveSuggestion: button_image = gfx::CreateVectorIcon( kSearchResultRemoveIcon, kImageButtonIconSize, kImageButtonColor); - button_tooltip = l10n_util::GetStringUTF16( - IDS_APP_LIST_REMOVE_SUGGESTION_ACCESSIBILITY_NAME); + button_tooltip = l10n_util::GetStringFUTF16( + IDS_APP_LIST_REMOVE_SUGGESTION_ACCESSIBILITY_NAME, title()); visible_on_hover = true; // visible upon hovering break; case ash::OmniBoxZeroStateAction::kAppendSuggestion: button_image = gfx::CreateVectorIcon( kSearchResultAppendIcon, kImageButtonIconSize, kImageButtonColor); - button_tooltip = l10n_util::GetStringUTF16( - IDS_APP_LIST_APPEND_SUGGESTION_ACCESSIBILITY_NAME); + button_tooltip = l10n_util::GetStringFUTF16( + IDS_APP_LIST_APPEND_SUGGESTION_ACCESSIBILITY_NAME, title()); visible_on_hover = false; // always visible break; default:
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index 2d6c070a..c395f7a 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -158,7 +158,8 @@ TabRestoreServiceFactory::GetForProfile(profile()); if (tab_restore_service) { tab_restore_service->AddObserver(this); - TabRestoreServiceChanged(tab_restore_service); + if (!tab_restore_service->IsLoaded()) + tab_restore_service->LoadTabsFromLastSession(); } }
diff --git a/chrome/browser/ui/browser_command_controller_browsertest.cc b/chrome/browser/ui/browser_command_controller_browsertest.cc index 5274479..faba3408 100644 --- a/chrome/browser/ui/browser_command_controller_browsertest.cc +++ b/chrome/browser/ui/browser_command_controller_browsertest.cc
@@ -15,6 +15,8 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_window.h" #include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/browser/sessions/tab_restore_service_factory.h" +#include "chrome/browser/sessions/tab_restore_service_load_waiter.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_finder.h" @@ -24,7 +26,10 @@ #include "chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" #include "components/search_engines/template_url_service.h" +#include "components/sessions/core/tab_restore_service.h" +#include "components/sessions/core/tab_restore_service_observer.h" #include "components/signin/core/browser/account_consistency_method.h" #include "content/public/browser/notification_service.h" #include "content/public/test/test_utils.h" @@ -168,4 +173,54 @@ } #endif +IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest, + TestTabRestoreServiceInitialized) { + // Note: The command should start out as enabled as the default. + // All the initialization happens before any test code executes, + // so we can't validate it. + + // The TabRestoreService should get initialized (Loaded) + // automatically upon launch. + // Wait for robustness because InProcessBrowserTest::PreRunTestOnMainThread + // does not flush the task scheduler. + TabRestoreServiceLoadWaiter waiter(browser()); + waiter.Wait(); + + // After initialization, the command should become disabled because there's + // nothing to restore. + chrome::BrowserCommandController* commandController = + browser()->command_controller(); + ASSERT_EQ(false, commandController->IsCommandEnabled(IDC_RESTORE_TAB)); +} + +IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest, + PRE_TestTabRestoreCommandEnabled) { + ui_test_utils::NavigateToURLWithDisposition( + browser(), GURL("about:"), WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + ASSERT_EQ(2, browser()->tab_strip_model()->count()); + EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); + content::WebContents* tab_to_close = + browser()->tab_strip_model()->GetActiveWebContents(); + content::WebContentsDestroyedWatcher destroyed_watcher(tab_to_close); + browser()->tab_strip_model()->CloseSelectedTabs(); + destroyed_watcher.Wait(); +} + +IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest, + TestTabRestoreCommandEnabled) { + // The TabRestoreService should get initialized (Loaded) + // automatically upon launch. + // Wait for robustness because InProcessBrowserTest::PreRunTestOnMainThread + // does not flush the task scheduler. + TabRestoreServiceLoadWaiter waiter(browser()); + waiter.Wait(); + + // After initialization, the command should remain enabled because there's + // one tab to restore. + chrome::BrowserCommandController* commandController = + browser()->command_controller(); + ASSERT_EQ(true, commandController->IsCommandEnabled(IDC_RESTORE_TAB)); +} + } // namespace chrome
diff --git a/chrome/browser/ui/views/frame/system_menu_model_delegate.cc b/chrome/browser/ui/views/frame/system_menu_model_delegate.cc index 0045dd6..4a23a20 100644 --- a/chrome/browser/ui/views/frame/system_menu_model_delegate.cc +++ b/chrome/browser/ui/views/frame/system_menu_model_delegate.cc
@@ -40,29 +40,7 @@ } bool SystemMenuModelDelegate::IsCommandIdEnabled(int command_id) const { - if (!chrome::IsCommandEnabled(browser_, command_id)) - return false; - - if (command_id != IDC_RESTORE_TAB) - return true; - - sessions::TabRestoreService* trs = - TabRestoreServiceFactory::GetForProfile(browser_->profile()); - - // The Service is not available in Guest Profiles or Incognito mode. - if (!trs) - return false; - - // chrome::IsCommandEnabled(IDC_RESTORE_TAB) returns true if TabRestoreService - // hasn't been loaded yet. Return false if this is the case as we don't have - // a good way to dynamically update the menu when TabRestoreService finishes - // loading. - // TODO(sky): add a way to update menu. - if (!trs->IsLoaded()) { - trs->LoadTabsFromLastSession(); - return false; - } - return true; + return chrome::IsCommandEnabled(browser_, command_id); } bool SystemMenuModelDelegate::IsCommandIdVisible(int command_id) const {
diff --git a/chrome/browser/ui/views/keyboard_access_browsertest.cc b/chrome/browser/ui/views/keyboard_access_browsertest.cc index 2a64915..827844d 100644 --- a/chrome/browser/ui/views/keyboard_access_browsertest.cc +++ b/chrome/browser/ui/views/keyboard_access_browsertest.cc
@@ -170,6 +170,7 @@ // Opens the system menu on Windows with the Alt Space combination and selects // the New Tab option from the menu. void TestSystemMenuWithKeyboard(); + void TestSystemMenuReopenClosedTabWithKeyboard(); #endif // Uses the keyboard to select the app menu i.e. with the F10 key. @@ -288,7 +289,7 @@ SystemMenuTestCBTHook, NULL, ::GetCurrentThreadId()); - ASSERT_TRUE(cbt_hook != NULL); + ASSERT_TRUE(cbt_hook); bool ret = ui_test_utils::SendKeyPressSync( browser(), ui::VKEY_SPACE, false, false, true, false); @@ -298,10 +299,74 @@ // Wait for the new tab to appear. new_tab_observer.Wait(); // Make sure that the new tab index is 1. - ASSERT_EQ(1, browser()->tab_strip_model()->active_index()); + EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); } ::UnhookWindowsHookEx(cbt_hook); } + +// This CBT hook is set for the duration of the +// TestSystemMenuReopenClosedTabWithKeyboard test +LRESULT CALLBACK SystemMenuReopenClosedTabTestCBTHook(int n_code, + WPARAM w_param, + LPARAM l_param) { + // Look for the system menu window getting created or becoming visible and + // then select the New Tab option from the menu. + if (n_code == HCBT_ACTIVATE || n_code == HCBT_CREATEWND) { + wchar_t class_name[MAX_PATH] = {0}; + GetClassName(reinterpret_cast<HWND>(w_param), class_name, + base::size(class_name)); + if (base::LowerCaseEqualsASCII(class_name, "#32768")) { + // Send 'E' for the Reopen closed tab option. + ::PostMessage(reinterpret_cast<HWND>(w_param), WM_CHAR, 'E', 0); + } + } + return ::CallNextHookEx(0, n_code, w_param, l_param); +} + +void KeyboardAccessTest::TestSystemMenuReopenClosedTabWithKeyboard() { + // Navigate to a page in the first tab, which makes sure that focus is + // set to the browser window. + ui_test_utils::NavigateToURL(browser(), GURL("about:")); + + ui_test_utils::NavigateToURLWithDisposition( + browser(), GURL("about:"), WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + + ASSERT_EQ(1, browser()->tab_strip_model()->active_index()); + content::WebContents* tab_to_close = + browser()->tab_strip_model()->GetActiveWebContents(); + content::WebContentsDestroyedWatcher destroyed_watcher(tab_to_close); + browser()->tab_strip_model()->CloseSelectedTabs(); + destroyed_watcher.Wait(); + ASSERT_EQ(1, browser()->tab_strip_model()->count()); + ASSERT_EQ(0, browser()->tab_strip_model()->active_index()); + + ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); + + content::WindowedNotificationObserver new_tab_observer( + chrome::NOTIFICATION_TAB_PARENTED, + content::NotificationService::AllSources()); + // Sending the Alt space keys to the browser will bring up the system menu + // which runs a model loop. We set a CBT hook to look for the menu and send + // keystrokes to it. + HHOOK cbt_hook = + ::SetWindowsHookEx(WH_CBT, SystemMenuReopenClosedTabTestCBTHook, NULL, + ::GetCurrentThreadId()); + ASSERT_TRUE(cbt_hook); + + bool ret = ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_SPACE, false, + false, true, false); + EXPECT_TRUE(ret); + + if (ret) { + // Wait for the new tab to appear. + new_tab_observer.Wait(); + // Make sure that the new tab index is 1. + EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); + } + + ::UnhookWindowsHookEx(cbt_hook); +} #endif void KeyboardAccessTest::TestMenuKeyboardAccessAndDismiss() { @@ -378,6 +443,11 @@ IN_PROC_BROWSER_TEST_F(KeyboardAccessTest, TestSystemMenuWithKeyboard) { TestSystemMenuWithKeyboard(); } + +IN_PROC_BROWSER_TEST_F(KeyboardAccessTest, + TestSystemMenuReopenClosedTabWithKeyboard) { + TestSystemMenuReopenClosedTabWithKeyboard(); +} #endif #if !defined(OS_WIN) && defined(USE_AURA)
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc index 4cbdf61a..f4d32ff 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -973,9 +973,15 @@ base::string16 OmniboxViewViews::GetLabelForCommandId(int command_id) const { DCHECK_EQ(IDS_PASTE_AND_GO, command_id); - return l10n_util::GetStringUTF16( - model()->ClassifiesAsSearch(GetClipboardText()) ? IDS_PASTE_AND_SEARCH - : IDS_PASTE_AND_GO); + base::string16 clipboard_text = GetClipboardText(); + // If the clipboard text is too long, this command will be disabled, so + // we skip the potentially expensive classification of the text and default to + // IDS_PASTE_AND_SEARCH. + bool paste_and_search = + clipboard_text.size() > OmniboxEditModel::kMaxPasteAndGoTextLength || + model()->ClassifiesAsSearch(clipboard_text); + return l10n_util::GetStringUTF16(paste_and_search ? IDS_PASTE_AND_SEARCH + : IDS_PASTE_AND_GO); } const char* OmniboxViewViews::GetClassName() const {
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc index 428168f..b985462c 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
@@ -97,14 +97,14 @@ // |___________________________________________ tab width // | | // pinned tab width standard tab width + if (tab_width < TabStyle::GetPinnedWidth()) + return kMinimumTriggerDelay; double logarithmic_fraction = std::log(tab_width - TabStyle::GetPinnedWidth() + 1) / std::log(TabStyle::GetStandardWidth() - TabStyle::GetPinnedWidth() + 1); base::TimeDelta scaling_factor = kMaximumTriggerDelay - kMinimumTriggerDelay; base::TimeDelta delay = logarithmic_fraction * scaling_factor + kMinimumTriggerDelay; - if (delay < kMinimumTriggerDelay) - delay = kMinimumTriggerDelay; return delay; }
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc index 489640a..346f0b5 100644 --- a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc +++ b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc
@@ -24,7 +24,6 @@ #include "chrome/browser/signin/test_signin_client_builder.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/sync/profile_sync_test_util.h" -#include "chrome/browser/unified_consent/chrome_unified_consent_service_client.h" #include "chrome/test/base/scoped_testing_local_state.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" @@ -747,23 +746,12 @@ EXPECT_CALL(*GetProfileSyncServiceMock()->GetUserSettingsMock(), SetFirstSetupComplete()) .Times(1); - using Service = UnifiedConsentServiceClient::Service; - using ServiceState = UnifiedConsentServiceClient::ServiceState; PrefService* pref_service = profile()->GetPrefs(); - ChromeUnifiedConsentServiceClient consent_service_client(pref_service); std::unique_ptr<UrlKeyedDataCollectionConsentHelper> url_keyed_collection_helper = UrlKeyedDataCollectionConsentHelper:: NewAnonymizedDataCollectionConsentHelper( pref_service, ProfileSyncServiceFactory::GetForProfile(profile())); - for (int i = 0; i <= static_cast<int>(Service::kLast); ++i) { - Service service = static_cast<Service>(i); - if (consent_service_client.IsServiceSupported(service)) { - consent_service_client.SetServiceEnabled(service, false); - EXPECT_EQ(ServiceState::kDisabled, - consent_service_client.GetServiceState(service)); - } - } EXPECT_FALSE(url_keyed_collection_helper->IsEnabled()); // Signin flow. @@ -775,13 +763,6 @@ EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(account_id())); EXPECT_EQ(account_id(), identity_manager()->GetPrimaryAccountId()); CheckDelegateCalls(); - for (int i = 0; i <= static_cast<int>(Service::kLast); ++i) { - Service service = static_cast<Service>(i); - if (consent_service_client.IsServiceSupported(service)) { - EXPECT_EQ(ServiceState::kEnabled, - consent_service_client.GetServiceState(service)); - } - } EXPECT_TRUE(url_keyed_collection_helper->IsEnabled()); }
diff --git a/chrome/browser/unified_consent/chrome_unified_consent_service_client.cc b/chrome/browser/unified_consent/chrome_unified_consent_service_client.cc deleted file mode 100644 index 4651c66d..0000000 --- a/chrome/browser/unified_consent/chrome_unified_consent_service_client.cc +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/unified_consent/chrome_unified_consent_service_client.h" - -ChromeUnifiedConsentServiceClient::ChromeUnifiedConsentServiceClient( - PrefService* pref_service) {} - -ChromeUnifiedConsentServiceClient::~ChromeUnifiedConsentServiceClient() {} - -ChromeUnifiedConsentServiceClient::ServiceState -ChromeUnifiedConsentServiceClient::GetServiceState(Service service) { - return ServiceState::kNotSupported; -} - -void ChromeUnifiedConsentServiceClient::SetServiceEnabled(Service service, - bool enabled) {}
diff --git a/chrome/browser/unified_consent/chrome_unified_consent_service_client.h b/chrome/browser/unified_consent/chrome_unified_consent_service_client.h deleted file mode 100644 index 7f39d76..0000000 --- a/chrome/browser/unified_consent/chrome_unified_consent_service_client.h +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UNIFIED_CONSENT_CHROME_UNIFIED_CONSENT_SERVICE_CLIENT_H_ -#define CHROME_BROWSER_UNIFIED_CONSENT_CHROME_UNIFIED_CONSENT_SERVICE_CLIENT_H_ - -#include "base/macros.h" -#include "components/unified_consent/unified_consent_service_client.h" - -class PrefService; - -class ChromeUnifiedConsentServiceClient - : public unified_consent::UnifiedConsentServiceClient { - public: - explicit ChromeUnifiedConsentServiceClient(PrefService* pref_service); - ~ChromeUnifiedConsentServiceClient() override; - - // unified_consent::UnifiedConsentServiceClient: - ServiceState GetServiceState(Service service) override; - void SetServiceEnabled(Service service, bool enabled) override; - - DISALLOW_COPY_AND_ASSIGN(ChromeUnifiedConsentServiceClient); -}; - -#endif // CHROME_BROWSER_UNIFIED_CONSENT_CHROME_UNIFIED_CONSENT_SERVICE_CLIENT_H_
diff --git a/chrome/browser/unified_consent/unified_consent_browsertest.cc b/chrome/browser/unified_consent/unified_consent_browsertest.cc index 0b4e105..4b25f2f 100644 --- a/chrome/browser/unified_consent/unified_consent_browsertest.cc +++ b/chrome/browser/unified_consent/unified_consent_browsertest.cc
@@ -10,7 +10,6 @@ #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sync_test.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/unified_consent/chrome_unified_consent_service_client.h" #include "chrome/browser/unified_consent/unified_consent_service_factory.h" #include "chrome/test/base/scoped_testing_local_state.h" #include "chrome/test/base/testing_profile.h" @@ -29,22 +28,6 @@ : SyncTest(SINGLE_CLIENT), scoped_unified_consent_state_(feature_state) {} ~UnifiedConsentBrowserTest() override = default; - void DisableGoogleServices() { - ChromeUnifiedConsentServiceClient consent_service_client( - browser()->profile()->GetPrefs()); - for (int i = 0; - i <= static_cast<int>(UnifiedConsentServiceClient::Service::kLast); - ++i) { - UnifiedConsentServiceClient::Service service = - static_cast<UnifiedConsentServiceClient::Service>(i); - if (consent_service_client.IsServiceSupported(service)) { - consent_service_client.SetServiceEnabled(service, false); - EXPECT_EQ(UnifiedConsentServiceClient::ServiceState::kDisabled, - consent_service_client.GetServiceState(service)); - } - } - } - void EnableSync() { Profile* profile = browser()->profile(); ProfileSyncServiceFactory::GetForProfile(profile) @@ -83,10 +66,6 @@ // Tests that the settings histogram is recorded if unified consent is enabled. // The histogram is recorded during profile initialization. -IN_PROC_BROWSER_TEST_F(UnifiedConsentBrowserTest, PRE_SettingsHistogram_None) { - DisableGoogleServices(); -} - IN_PROC_BROWSER_TEST_F(UnifiedConsentBrowserTest, SettingsHistogram_None) { histogram_tester_.ExpectUniqueSample( "UnifiedConsent.SyncAndGoogleServicesSettings", @@ -96,11 +75,6 @@ // Tests that the settings histogram is recorded if unified consent is disabled. // The histogram is recorded during profile initialization. IN_PROC_BROWSER_TEST_F(UnifiedConsentDisabledBrowserTest, - PRE_SettingsHistogram_None) { - DisableGoogleServices(); -} - -IN_PROC_BROWSER_TEST_F(UnifiedConsentDisabledBrowserTest, SettingsHistogram_None) { histogram_tester_.ExpectUniqueSample( "UnifiedConsent.SyncAndGoogleServicesSettings",
diff --git a/chrome/browser/unified_consent/unified_consent_service_factory.cc b/chrome/browser/unified_consent/unified_consent_service_factory.cc index 38a1076..3c382899 100644 --- a/chrome/browser/unified_consent/unified_consent_service_factory.cc +++ b/chrome/browser/unified_consent/unified_consent_service_factory.cc
@@ -7,7 +7,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/unified_consent/chrome_unified_consent_service_client.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" @@ -50,10 +49,8 @@ content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); PrefService* pref_service = profile->GetPrefs(); - auto service_client = - std::make_unique<ChromeUnifiedConsentServiceClient>(pref_service); // Record settings for pre- and post-UnifiedConsent users. - RecordSettingsHistogram(service_client.get(), pref_service); + RecordSettingsHistogram(pref_service); syncer::SyncService* sync_service = ProfileSyncServiceFactory::GetSyncServiceForProfile(profile); @@ -61,14 +58,13 @@ return nullptr; if (!unified_consent::IsUnifiedConsentFeatureEnabled()) { - UnifiedConsentService::RollbackIfNeeded(pref_service, sync_service, - service_client.get()); + UnifiedConsentService::RollbackIfNeeded(pref_service, sync_service); return nullptr; } return new UnifiedConsentService( - std::move(service_client), pref_service, - IdentityManagerFactory::GetForProfile(profile), sync_service); + pref_service, IdentityManagerFactory::GetForProfile(profile), + sync_service); } bool UnifiedConsentServiceFactory::ServiceIsNULLWhileTesting() const {
diff --git a/chrome/browser/unified_consent/unified_consent_test_util.cc b/chrome/browser/unified_consent/unified_consent_test_util.cc deleted file mode 100644 index 48b25df..0000000 --- a/chrome/browser/unified_consent/unified_consent_test_util.cc +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/unified_consent/unified_consent_test_util.h" - -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/identity_manager_factory.h" -#include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/unified_consent/unified_consent_service_factory.h" -#include "components/unified_consent/feature.h" -#include "components/unified_consent/unified_consent_service.h" -#include "components/unified_consent/unified_consent_service_client.h" - -namespace { - -using Service = unified_consent::UnifiedConsentServiceClient::Service; -using ServiceState = unified_consent::UnifiedConsentServiceClient::ServiceState; - -class FakeUnifiedConsentServiceClient - : public unified_consent::UnifiedConsentServiceClient { - public: - FakeUnifiedConsentServiceClient() = default; - ~FakeUnifiedConsentServiceClient() override = default; - - // UnifiedConsentServiceClient: - ServiceState GetServiceState(Service service) override { - return ServiceState::kNotSupported; - } - void SetServiceEnabled(Service service, bool enabled) override {} -}; - -} // namespace - -std::unique_ptr<KeyedService> BuildUnifiedConsentServiceForTesting( - content::BrowserContext* context) { - Profile* profile = Profile::FromBrowserContext(context); - - if (!unified_consent::IsUnifiedConsentFeatureEnabled()) - return nullptr; - - return std::make_unique<unified_consent::UnifiedConsentService>( - std::make_unique<FakeUnifiedConsentServiceClient>(), profile->GetPrefs(), - IdentityManagerFactory::GetForProfile(profile), - ProfileSyncServiceFactory::GetSyncServiceForProfile(profile)); -}
diff --git a/chrome/browser/unified_consent/unified_consent_test_util.h b/chrome/browser/unified_consent/unified_consent_test_util.h deleted file mode 100644 index 5e05422..0000000 --- a/chrome/browser/unified_consent/unified_consent_test_util.h +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UNIFIED_CONSENT_UNIFIED_CONSENT_TEST_UTIL_H_ -#define CHROME_BROWSER_UNIFIED_CONSENT_UNIFIED_CONSENT_TEST_UTIL_H_ - -#include <memory> - -namespace content { -class BrowserContext; -} -class KeyedService; - -// Helper function to be used with KeyedService::SetTestingFactory(). -std::unique_ptr<KeyedService> BuildUnifiedConsentServiceForTesting( - content::BrowserContext* context); - -#endif // CHROME_BROWSER_UNIFIED_CONSENT_UNIFIED_CONSENT_TEST_UTIL_H_
diff --git a/chrome/chrome_cleaner/os/disk_util.cc b/chrome/chrome_cleaner/os/disk_util.cc index e25257b..318e181 100644 --- a/chrome/chrome_cleaner/os/disk_util.cc +++ b/chrome/chrome_cleaner/os/disk_util.cc
@@ -62,9 +62,12 @@ // "C:\Program Files\Common Files\". const wchar_t kCommonProgramW6432[] = L"%CommonProgramW6432%"; -const wchar_t* company_white_list[] = { - L"Google Inc", L"Google Inc.", L"Intel Corporation", - L"Microsoft Corporation", +constexpr const base::char16* kCompanyWhiteList[] = { + STRING16_LITERAL("Google LLC"), + STRING16_LITERAL("Google Inc"), + STRING16_LITERAL("Google Inc."), + STRING16_LITERAL("Intel Corporation"), + STRING16_LITERAL("Microsoft Corporation"), }; // Built from various sources to try and include all the extensions that are @@ -502,18 +505,9 @@ bool IsExecutableOnDefaultReportingWhiteList(const base::FilePath& file_path) { std::unique_ptr<FileVersionInfo> file_information( FileVersionInfo::CreateFileVersionInfo(file_path)); - if (!file_information) - return false; - - bool white_listed = false; - base::string16 company_name = file_information->company_name(); - for (const base::string16& white_listed_name : company_white_list) { - if (company_name.compare(white_listed_name) == 0) { - white_listed = true; - break; - } - } - return white_listed; + return file_information && + base::ContainsValue(kCompanyWhiteList, + file_information->company_name()); } bool RetrieveDetailedFileInformation(
diff --git a/chrome/common/extensions/permissions/chrome_permission_message_provider.cc b/chrome/common/extensions/permissions/chrome_permission_message_provider.cc index 8cfa1cb..9dde408 100644 --- a/chrome/common/extensions/permissions/chrome_permission_message_provider.cc +++ b/chrome/common/extensions/permissions/chrome_permission_message_provider.cc
@@ -4,6 +4,7 @@ #include "chrome/common/extensions/permissions/chrome_permission_message_provider.h" +#include <tuple> #include <vector> #include "base/metrics/field_trial.h" @@ -27,11 +28,8 @@ explicit ComparablePermission(const PermissionMessage& msg) : msg_(&msg) {} bool operator<(const ComparablePermission& rhs) const { - if (msg_->message() < rhs.msg_->message()) - return true; - if (msg_->message() > rhs.msg_->message()) - return false; - return msg_->submessages() < rhs.msg_->submessages(); + return std::tie(msg_->message(), msg_->submessages()) < + std::tie(rhs.msg_->message(), rhs.msg_->submessages()); } bool operator==(const ComparablePermission& rhs) const {
diff --git a/chrome/credential_provider/gaiacp/os_process_manager.h b/chrome/credential_provider/gaiacp/os_process_manager.h index 61646e15..dafc4a6c 100644 --- a/chrome/credential_provider/gaiacp/os_process_manager.h +++ b/chrome/credential_provider/gaiacp/os_process_manager.h
@@ -24,7 +24,7 @@ namespace credential_provider { // Manages OS processes and process attributes. -class OSProcessManager { +class [[clang::lto_visibility_public]] OSProcessManager { public: static OSProcessManager* Get();
diff --git a/chrome/credential_provider/gaiacp/os_user_manager.h b/chrome/credential_provider/gaiacp/os_user_manager.h index ad75b14..0bb95ef 100644 --- a/chrome/credential_provider/gaiacp/os_user_manager.h +++ b/chrome/credential_provider/gaiacp/os_user_manager.h
@@ -13,7 +13,7 @@ namespace credential_provider { // Manages OS users on the system. -class OSUserManager { +class [[clang::lto_visibility_public]] OSUserManager { public: // Minimum length for password buffer when calling GenerateRandomPassword(). static const int kMinPasswordLength = 24;
diff --git a/chrome/credential_provider/gaiacp/scoped_lsa_policy.h b/chrome/credential_provider/gaiacp/scoped_lsa_policy.h index 2558abf..a350fecdf 100644 --- a/chrome/credential_provider/gaiacp/scoped_lsa_policy.h +++ b/chrome/credential_provider/gaiacp/scoped_lsa_policy.h
@@ -14,7 +14,7 @@ class FakeScopedLsaPolicyFactory; -class ScopedLsaPolicy { +class [[clang::lto_visibility_public]] ScopedLsaPolicy { public: static std::unique_ptr<ScopedLsaPolicy> Create(ACCESS_MASK mask);
diff --git a/chrome/renderer/extensions/automation_ax_tree_wrapper.cc b/chrome/renderer/extensions/automation_ax_tree_wrapper.cc index 51d2245..c315c43 100644 --- a/chrome/renderer/extensions/automation_ax_tree_wrapper.cc +++ b/chrome/renderer/extensions/automation_ax_tree_wrapper.cc
@@ -179,6 +179,7 @@ // Map these into generic attribute changes (not necessarily aria related, // but mapping for backward compat). + case ui::AXEventGenerator::Event::AUTO_COMPLETE_CHANGED: case ui::AXEventGenerator::Event::COLLAPSED: case ui::AXEventGenerator::Event::EXPANDED: case ui::AXEventGenerator::Event::LIVE_REGION_NODE_CHANGED:
diff --git a/chrome/service/service_process.cc b/chrome/service/service_process.cc index 494138da..88d7c4d 100644 --- a/chrome/service/service_process.cc +++ b/chrome/service/service_process.cc
@@ -154,19 +154,15 @@ service_process_state_ = std::move(state); // Initialize TaskScheduler. - constexpr int kMaxBackgroundThreads = 1; - constexpr int kMaxBackgroundBlockingThreads = 1; - constexpr int kMaxForegroundThreads = 3; - constexpr int kMaxForegroundBlockingThreads = 3; + constexpr int kMaxBackgroundThreads = 2; + constexpr int kMaxForegroundThreads = 6; constexpr base::TimeDelta kSuggestedReclaimTime = base::TimeDelta::FromSeconds(30); base::TaskScheduler::Create("CloudPrintServiceProcess"); base::TaskScheduler::GetInstance()->Start( {{kMaxBackgroundThreads, kSuggestedReclaimTime}, - {kMaxBackgroundBlockingThreads, kSuggestedReclaimTime}, - {kMaxForegroundThreads, kSuggestedReclaimTime}, - {kMaxForegroundBlockingThreads, kSuggestedReclaimTime, + {kMaxForegroundThreads, kSuggestedReclaimTime, base::SchedulerBackwardCompatibility::INIT_COM_STA}}); // The NetworkChangeNotifier must be created after TaskScheduler because it
diff --git a/chrome/services/noop/public/cpp/BUILD.gn b/chrome/services/noop/public/cpp/BUILD.gn index e511899..b30ae33 100644 --- a/chrome/services/noop/public/cpp/BUILD.gn +++ b/chrome/services/noop/public/cpp/BUILD.gn
@@ -22,6 +22,7 @@ deps = [ "//base", + "//chrome/services/noop/public/mojom", "//services/service_manager/public/cpp", ] }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 02570b61..2820a3c9 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -861,6 +861,8 @@ "../browser/sessions/session_restore_observer_browsertest.cc", "../browser/sessions/tab_restore_browsertest.cc", "../browser/sessions/tab_restore_service_browsertest.cc", + "../browser/sessions/tab_restore_service_load_waiter.cc", + "../browser/sessions/tab_restore_service_load_waiter.h", "../browser/site_details_browsertest.cc", "../browser/ui/bloated_renderer/bloated_renderer_tab_helper_browsertest.cc", "../browser/ui/blocked_content/popup_tracker_browsertest.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java index 7b6429b2..6ae85a7 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java
@@ -145,6 +145,10 @@ try { ApplicationTestUtils.tearDown(InstrumentationRegistry.getTargetContext()); Thread.setDefaultUncaughtExceptionHandler(mDefaultUncaughtExceptionHandler); + if (mSetActivity != null) { + // This is to ensure onDestroy() is performed before starting the next test. + ApplicationTestUtils.finishActivity(mSetActivity); + } } catch (Exception e) { throw new RuntimeException("Failed to tearDown", e); }
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index 1ab5e4a..c6944c2 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -1686,11 +1686,19 @@ def testCanSwitchToPrintPreviewDialog(self): old_handles = self._driver.GetWindowHandles() + print >> sys.stdout, "Test debug: actual len of old_handles: " \ + + str(len(old_handles)) self.assertEquals(1, len(old_handles)) self._driver.ExecuteScript('setTimeout(function(){window.print();}, 0);') new_window_handle = self.WaitForNewWindow(self._driver, old_handles) + if new_window_handle is None: + print >> sys.stdout, "Test debug: new_window_handle is None" + else: + print >> sys.stdout, "Test debug: new_window_handle is not None" self.assertNotEqual(None, new_window_handle) self._driver.SwitchToWindow(new_window_handle) + print >> sys.stdout, "Test debug: actual GetCurrentUrl: " \ + + self._driver.GetCurrentUrl() self.assertEquals('chrome://print/', self._driver.GetCurrentUrl()) def testCanClickInIframes(self):
diff --git a/chrome/test/data/webui/net_internals/domain_security_policy_view.js b/chrome/test/data/webui/net_internals/domain_security_policy_view.js index ac42d4f..13cc5cf2 100644 --- a/chrome/test/data/webui/net_internals/domain_security_policy_view.js +++ b/chrome/test/data/webui/net_internals/domain_security_policy_view.js
@@ -101,15 +101,12 @@ * @param {bool} stsSubdomains Whether or not the stsSubdomains flag is expected * to be set in the returned results. Ignored on error and not found * results. - * @param {number} stsObserved The time the STS policy was observed. * @param {QueryResultType} queryResultType The expected result type of the * results of the query. * @extends {CheckQueryResultTask} */ -function CheckHSTSQueryResultTask( - domain, stsSubdomains, stsObserved, queryResultType) { +function CheckHSTSQueryResultTask(domain, stsSubdomains, queryResultType) { this.stsSubdomains_ = stsSubdomains; - this.stsObserved_ = stsObserved; CheckQueryResultTask.call( this, domain, DomainSecurityPolicyView.QUERY_HSTS_INPUT_ID, DomainSecurityPolicyView.QUERY_HSTS_OUTPUT_DIV_ID, queryResultType); @@ -140,8 +137,6 @@ */ checkSuccess_: function(result) { expectEquals(this.stsSubdomains_, result.dynamic_sts_include_subdomains); - // Disabled because of http://crbug.com/397639 - // expectLE(this.stsObserved_, result.dynamic_sts_observed); CheckQueryResultTask.prototype.checkSuccess_.call(this, result); } }; @@ -154,13 +149,11 @@ * @param {bool} stsSubdomains Whether the HSTS subdomain checkbox should be * selected. Also the corresponding expected return value, in the success * case. - * @param {number} stsObserved The time the STS policy was observed. * @param {QueryResultType} queryResultType Expected result type. * @extends {CheckHSTSQueryResultTask} */ -function AddHSTSTask(domain, stsSubdomains, stsObserved, queryResultType) { - CheckHSTSQueryResultTask.call( - this, domain, stsSubdomains, stsObserved, queryResultType); +function AddHSTSTask(domain, stsSubdomains, queryResultType) { + CheckHSTSQueryResultTask.call(this, domain, stsSubdomains, queryResultType); } AddHSTSTask.prototype = { @@ -184,9 +177,8 @@ * query. * @extends {CheckHSTSQueryResultTask} */ -function QueryHSTSTask(domain, stsSubdomains, stsObserved, queryResultType) { - CheckHSTSQueryResultTask.call( - this, domain, stsSubdomains, stsObserved, queryResultType); +function QueryHSTSTask(domain, stsSubdomains, queryResultType) { + CheckHSTSQueryResultTask.call(this, domain, stsSubdomains, queryResultType); } QueryHSTSTask.prototype = { @@ -214,7 +206,7 @@ function DeleteTask(domain, queryResultType) { expectNotEquals(queryResultType, QueryResultType.SUCCESS); this.domain_ = domain; - QueryHSTSTask.call(this, domain, false, 0, queryResultType); + QueryHSTSTask.call(this, domain, false, queryResultType); } DeleteTask.prototype = { @@ -425,9 +417,8 @@ function() { NetInternalsTest.switchToView('hsts'); taskQueue = new NetInternalsTest.TaskQueue(true); - var now = Date.now() / 1000.0; - taskQueue.addTask(new QueryHSTSTask( - 'somewhere.com', false, now, QueryResultType.NOT_FOUND)); + taskQueue.addTask( + new QueryHSTSTask('somewhere.com', false, QueryResultType.NOT_FOUND)); taskQueue.run(); }); @@ -439,9 +430,8 @@ function() { NetInternalsTest.switchToView('hsts'); taskQueue = new NetInternalsTest.TaskQueue(true); - var now = Date.now() / 1000.0; taskQueue.addTask( - new QueryHSTSTask('\u3024', false, now, QueryResultType.ERROR)); + new QueryHSTSTask('\u3024', false, QueryResultType.ERROR)); taskQueue.run(); }); @@ -478,9 +468,8 @@ function() { NetInternalsTest.switchToView('hsts'); taskQueue = new NetInternalsTest.TaskQueue(true); - var now = Date.now() / 1000.0; - taskQueue.addTask(new AddHSTSTask( - 'somewhere.com', false, now, QueryResultType.SUCCESS)); + taskQueue.addTask( + new AddHSTSTask('somewhere.com', false, QueryResultType.SUCCESS)); taskQueue.addTask( new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND)); taskQueue.run(); @@ -494,11 +483,10 @@ function() { NetInternalsTest.switchToView('hsts'); taskQueue = new NetInternalsTest.TaskQueue(true); - var now = Date.now() / 1000.0; taskQueue.addTask(new AddHSTSTask( '0123456789012345678901234567890' + '012345678901234567890123456789012345', - false, now, QueryResultType.NOT_FOUND)); + false, QueryResultType.NOT_FOUND)); taskQueue.run(); }); @@ -511,9 +499,8 @@ function() { NetInternalsTest.switchToView('hsts'); taskQueue = new NetInternalsTest.TaskQueue(true); - var now = Date.now() / 1000.0; taskQueue.addTask( - new AddHSTSTask('\u3024', false, now, QueryResultType.ERROR)); + new AddHSTSTask('\u3024', false, QueryResultType.ERROR)); taskQueue.run(); }); @@ -525,11 +512,10 @@ function() { NetInternalsTest.switchToView('hsts'); taskQueue = new NetInternalsTest.TaskQueue(true); - var now = Date.now() / 1000.0; taskQueue.addTask( - new AddHSTSTask('somewhere.com', true, now, QueryResultType.SUCCESS)); - taskQueue.addTask(new AddHSTSTask( - 'somewhere.com', false, now, QueryResultType.SUCCESS)); + new AddHSTSTask('somewhere.com', true, QueryResultType.SUCCESS)); + taskQueue.addTask( + new AddHSTSTask('somewhere.com', false, QueryResultType.SUCCESS)); taskQueue.addTask( new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND)); taskQueue.run(); @@ -543,19 +529,18 @@ function() { NetInternalsTest.switchToView('hsts'); taskQueue = new NetInternalsTest.TaskQueue(true); - var now = Date.now() / 1000.0; - taskQueue.addTask(new AddHSTSTask( - 'somewhere.com', false, now, QueryResultType.SUCCESS)); + taskQueue.addTask( + new AddHSTSTask('somewhere.com', false, QueryResultType.SUCCESS)); taskQueue.addTask(new QueryHSTSTask( - 'somewhereelse.com', false, now, QueryResultType.NOT_FOUND)); - taskQueue.addTask(new AddHSTSTask( - 'somewhereelse.com', true, now, QueryResultType.SUCCESS)); - taskQueue.addTask(new QueryHSTSTask( - 'somewhere.com', false, now, QueryResultType.SUCCESS)); + 'somewhereelse.com', false, QueryResultType.NOT_FOUND)); + taskQueue.addTask( + new AddHSTSTask('somewhereelse.com', true, QueryResultType.SUCCESS)); + taskQueue.addTask( + new QueryHSTSTask('somewhere.com', false, QueryResultType.SUCCESS)); taskQueue.addTask( new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND)); taskQueue.addTask(new QueryHSTSTask( - 'somewhereelse.com', true, now, QueryResultType.SUCCESS)); + 'somewhereelse.com', true, QueryResultType.SUCCESS)); taskQueue.addTask( new DeleteTask('somewhereelse.com', QueryResultType.NOT_FOUND)); taskQueue.run(true); @@ -583,7 +568,6 @@ 'netInternalsDomainSecurityPolicyViewExpectCTQueryError', function() { NetInternalsTest.switchToView('hsts'); taskQueue = new NetInternalsTest.TaskQueue(true); - var now = Date.now() / 1000.0; taskQueue.addTask( new QueryExpectCTTask('\u3024', false, '', QueryResultType.ERROR)); taskQueue.run();
diff --git a/chrome/test/data/webui/settings/internet_detail_page_tests.js b/chrome/test/data/webui/settings/internet_detail_page_tests.js index 0a1b4cb..e5927cb 100644 --- a/chrome/test/data/webui/settings/internet_detail_page_tests.js +++ b/chrome/test/data/webui/settings/internet_detail_page_tests.js
@@ -96,6 +96,7 @@ assertTrue(!!internetDetailPage); api_.resetForTest(); internetDetailPage.networkingPrivate = api_; + internetDetailPage.prefs = Object.assign({}, prefs_); document.body.appendChild(internetDetailPage); return flushAsync(); }); @@ -107,6 +108,8 @@ }); suite('DetailsPage', function() { + test('LoadPage', function() {}); + test('WiFi', function() { api_.enableNetworkType('WiFi'); setNetworksForTest([{GUID: 'wifi1_guid', Name: 'wifi1', Type: 'WiFi'}]); @@ -213,7 +216,7 @@ }]); internetDetailPage.init('vpn_guid', 'VPN', 'vpn_user'); prefs_.vpn_config_allowed.value = true; - internetDetailPage.prefs = prefs_; + internetDetailPage.prefs = Object.assign({}, prefs_); return flushAsync().then(() => { const disconnectButton = getButton('disconnect'); assertFalse(disconnectButton.hasAttribute('enforced_')); @@ -230,7 +233,7 @@ }]); internetDetailPage.init('vpn_guid', 'VPN', 'vpn_user'); prefs_.vpn_config_allowed.value = false; - internetDetailPage.prefs = prefs_; + internetDetailPage.prefs = Object.assign({}, prefs_); return flushAsync().then(() => { const disconnectButton = getButton('disconnect'); assertTrue(disconnectButton.hasAttribute('enforced_'));
diff --git a/chrome/updater/updater.cc b/chrome/updater/updater.cc index dd059d8..78618a4 100644 --- a/chrome/updater/updater.cc +++ b/chrome/updater/updater.cc
@@ -47,14 +47,8 @@ base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.1, 0), base::TimeDelta::FromSeconds(30)), base::SchedulerWorkerPoolParams( - base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.1, 0), - base::TimeDelta::FromSeconds(40)), - base::SchedulerWorkerPoolParams( base::RecommendedMaxNumberOfThreadsInPool(8, 32, 0.3, 0), - base::TimeDelta::FromSeconds(30)), - base::SchedulerWorkerPoolParams( - base::RecommendedMaxNumberOfThreadsInPool(8, 32, 0.3, 0), - base::TimeDelta::FromSeconds(60))); + base::TimeDelta::FromSeconds(30))); base::TaskScheduler::GetInstance()->Start(*task_scheduler_init_params); }
diff --git a/chromecast/browser/cast_session_id_map.cc b/chromecast/browser/cast_session_id_map.cc index d26b4b8..78848dd 100644 --- a/chromecast/browser/cast_session_id_map.cc +++ b/chromecast/browser/cast_session_id_map.cc
@@ -53,7 +53,14 @@ void CastSessionIdMap::SetSessionId(std::string session_id, content::WebContents* web_contents) { base::UnguessableToken group_id = web_contents->GetAudioGroupId(); - GetInstance()->SetSessionIdInternal(session_id, group_id, web_contents); + // Unretained is safe here, because the singleton CastSessionIdMap never gets + // destroyed. + auto destroyed_callback = base::BindOnce(&CastSessionIdMap::OnGroupDestroyed, + base::Unretained(GetInstance())); + auto group_observer = std::make_unique<GroupObserver>( + web_contents, std::move(destroyed_callback)); + GetInstance()->SetSessionIdInternal(session_id, group_id, + std::move(group_observer)); } // static @@ -64,8 +71,7 @@ CastSessionIdMap::CastSessionIdMap(base::SequencedTaskRunner* task_runner) : supports_group_id_( base::FeatureList::IsEnabled(features::kAudioServiceAudioStreams)), - task_runner_(task_runner), - weak_factory_(this) { + task_runner_(task_runner) { DCHECK(task_runner_); DETACH_FROM_SEQUENCE(sequence_checker_); } @@ -75,32 +81,27 @@ void CastSessionIdMap::SetSessionIdInternal( std::string session_id, base::UnguessableToken group_id, - content::WebContents* web_contents) { + std::unique_ptr<GroupObserver> group_observer) { if (!supports_group_id_) return; if (!task_runner_->RunsTasksInCurrentSequence()) { + // Unretained is safe here, because the singleton CastSessionIdMap never + // gets destroyed. task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&CastSessionIdMap::SetSessionIdInternal, - weak_factory_.GetWeakPtr(), std::move(session_id), - group_id, web_contents)); + FROM_HERE, base::BindOnce(&CastSessionIdMap::SetSessionIdInternal, + base::Unretained(this), std::move(session_id), + group_id, std::move(group_observer))); return; } // This check is required to bind to the current sequence. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(web_contents); DCHECK(GetSessionIdInternal(group_id.ToString()).empty()); + DCHECK(group_observer); VLOG(1) << "Mapping session_id=" << session_id << " to group_id=" << group_id.ToString(); - // Unretained is safe because the GroupObserver is always owned by the - // CastSessionIdMap. - auto destroyed_callback = base::BindOnce(&CastSessionIdMap::OnGroupDestroyed, - base::Unretained(this)); - auto group_observer = std::make_unique<GroupObserver>( - web_contents, std::move(destroyed_callback)); auto group_data = std::make_pair(session_id, std::move(group_observer)); mapping_.emplace(group_id.ToString(), std::move(group_data)); } @@ -117,9 +118,11 @@ } void CastSessionIdMap::OnGroupDestroyed(base::UnguessableToken group_id) { + // Unretained is safe here, because the singleton CastSessionIdMap never gets + // destroyed. task_runner_->PostTask(FROM_HERE, base::BindOnce(&CastSessionIdMap::RemoveGroupId, - weak_factory_.GetWeakPtr(), group_id)); + base::Unretained(this), group_id)); } void CastSessionIdMap::RemoveGroupId(base::UnguessableToken group_id) {
diff --git a/chromecast/browser/cast_session_id_map.h b/chromecast/browser/cast_session_id_map.h index d65a8c2b..e83ecc75 100644 --- a/chromecast/browser/cast_session_id_map.h +++ b/chromecast/browser/cast_session_id_map.h
@@ -10,7 +10,6 @@ #include <utility> #include "base/containers/flat_map.h" -#include "base/memory/weak_ptr.h" #include "base/no_destructor.h" #include "base/sequence_checker.h" #include "base/sequenced_task_runner.h" @@ -33,6 +32,7 @@ // be specified for the instance to run on. Any subsequent calls to this // function will return the same map instance, but will not change the task // runner. + // This must be called for the first time on the browser main thread. static CastSessionIdMap* GetInstance( base::SequencedTaskRunner* task_runner = nullptr); // Map a session id to a particular group id in the provided WebContents. @@ -61,7 +61,7 @@ // This call be called on any thread. void SetSessionIdInternal(std::string session_id, base::UnguessableToken group_id, - content::WebContents* web_contents); + std::unique_ptr<GroupObserver> group_observer); // Retrieves the session id for the provided group id. // This must be called on the |task_runner_|. std::string GetSessionIdInternal(std::string group_id); @@ -73,7 +73,6 @@ mapping_; base::SequencedTaskRunner* const task_runner_; SEQUENCE_CHECKER(sequence_checker_); - base::WeakPtrFactory<CastSessionIdMap> weak_factory_; DISALLOW_COPY_AND_ASSIGN(CastSessionIdMap); };
diff --git a/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc b/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc index 99735251..2ff74c0 100644 --- a/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc +++ b/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc
@@ -180,6 +180,7 @@ // Map these into generic attribute changes (not necessarily aria related, // but mapping for backward compat). + case ui::AXEventGenerator::Event::AUTO_COMPLETE_CHANGED: case ui::AXEventGenerator::Event::COLLAPSED: case ui::AXEventGenerator::Event::EXPANDED: case ui::AXEventGenerator::Event::LIVE_REGION_NODE_CHANGED:
diff --git a/chromeos/services/device_sync/BUILD.gn b/chromeos/services/device_sync/BUILD.gn index 63ed06a9..8bd6eab 100644 --- a/chromeos/services/device_sync/BUILD.gn +++ b/chromeos/services/device_sync/BUILD.gn
@@ -20,6 +20,10 @@ "cryptauth_enroller_factory_impl.h", "cryptauth_enroller_impl.cc", "cryptauth_enroller_impl.h", + "cryptauth_key_creator.cc", + "cryptauth_key_creator.h", + "cryptauth_key_creator_impl.cc", + "cryptauth_key_creator_impl.h", "cryptauth_enrollment_manager.cc", "cryptauth_enrollment_manager.h", "cryptauth_enrollment_manager_impl.cc", @@ -152,6 +156,7 @@ "cryptauth_client_impl_unittest.cc", "cryptauth_device_manager_impl_unittest.cc", "cryptauth_enroller_impl_unittest.cc", + "cryptauth_key_creator_impl_unittest.cc", "cryptauth_enrollment_manager_impl_unittest.cc", "cryptauth_gcm_manager_impl_unittest.cc", "cryptauth_key_bundle_unittest.cc",
diff --git a/chromeos/services/device_sync/cryptauth_key_bundle.h b/chromeos/services/device_sync/cryptauth_key_bundle.h index 6000675..6b1d5f9 100644 --- a/chromeos/services/device_sync/cryptauth_key_bundle.h +++ b/chromeos/services/device_sync/cryptauth_key_bundle.h
@@ -31,6 +31,8 @@ public: // Names which uniquely define a CryptAuthKeyBundle. // TODO(nohle): Add name for DeviceSync keys. + // TODO(nohle): Add additional unit tests for CryptAuthKeyCreatorImpl when + // more Names are added. enum class Name { kUserKeyPair }; static const base::flat_set<CryptAuthKeyBundle::Name>& AllNames(); static std::string KeyBundleNameEnumToString(CryptAuthKeyBundle::Name name);
diff --git a/chromeos/services/device_sync/cryptauth_key_creator.cc b/chromeos/services/device_sync/cryptauth_key_creator.cc new file mode 100644 index 0000000..30c70ce --- /dev/null +++ b/chromeos/services/device_sync/cryptauth_key_creator.cc
@@ -0,0 +1,28 @@ +// Copyright 2019 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/device_sync/cryptauth_key_creator.h" + +namespace chromeos { + +namespace device_sync { + +CryptAuthKeyCreator::CreateKeyData::CreateKeyData( + CryptAuthKey::Status status, + cryptauthv2::KeyType type, + base::Optional<std::string> handle) + : status(status), type(type), handle(handle) {} + +CryptAuthKeyCreator::CreateKeyData::~CreateKeyData() = default; + +CryptAuthKeyCreator::CreateKeyData::CreateKeyData(const CreateKeyData&) = + default; + +CryptAuthKeyCreator::CryptAuthKeyCreator() = default; + +CryptAuthKeyCreator::~CryptAuthKeyCreator() = default; + +} // namespace device_sync + +} // namespace chromeos
diff --git a/chromeos/services/device_sync/cryptauth_key_creator.h b/chromeos/services/device_sync/cryptauth_key_creator.h new file mode 100644 index 0000000..243868d --- /dev/null +++ b/chromeos/services/device_sync/cryptauth_key_creator.h
@@ -0,0 +1,80 @@ +// Copyright 2019 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_DEVICE_SYNC_CRYPTAUTH_KEY_CREATOR_H_ +#define CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_KEY_CREATOR_H_ + +#include <string> + +#include "base/callback.h" +#include "base/containers/flat_map.h" +#include "base/macros.h" +#include "base/optional.h" +#include "chromeos/services/device_sync/cryptauth_key.h" +#include "chromeos/services/device_sync/cryptauth_key_bundle.h" +#include "chromeos/services/device_sync/proto/cryptauth_common.pb.h" + +namespace chromeos { + +namespace device_sync { + +// The lone method CreateKeys() takes a map from key-bundle name to key-creation +// data and returns a map from key-bundle name to newly created key via the +// callback, |create_keys_callback|. +// +// Requirements: +// - An instance of this class should only be used once. +// - The input map, |keys_to_create|, cannot be empty. +// - Currently, the only supported key types are RAW128 and RAW256 for +// symmetric keys and P256 for asymmetric keys. +// - If symmetric keys are being created, the CryptAuth server's +// Diffie-Hellman public key needs to be passed into |server_ephemeral_dh| +// of CreateKeys(). +// +// Note about symmetric key creation: +// The CryptAuth v2 Enrollment protocol demands that symmetric keys be derived +// from a secret key, obtained by performing a Diffie-Hellman handshake with +// the CryptAuth server. Specifically, +// +// |derived_key| = +// Hkdf(|secret|, salt="CryptAuth Enrollment", info=|derived_key_handle|). +// +// The CryptAuth server's Diffie-Hellman key is passed into CreateKeys(), +// CreateKeys() generates the client side of the Diffie-Hellman handshake, and +// this asymmetric key is returned in the callback. +class CryptAuthKeyCreator { + public: + struct CreateKeyData { + CreateKeyData(CryptAuthKey::Status status, + cryptauthv2::KeyType type, + base::Optional<std::string> handle = base::nullopt); + ~CreateKeyData(); + CreateKeyData(const CreateKeyData&); + + CryptAuthKey::Status status; + cryptauthv2::KeyType type; + base::Optional<std::string> handle; + }; + + CryptAuthKeyCreator(); + virtual ~CryptAuthKeyCreator(); + + using CreateKeysCallback = base::OnceCallback<void( + const base::flat_map<CryptAuthKeyBundle::Name, + CryptAuthKey>& /* new_keys */, + const base::Optional<CryptAuthKey>& /* client_ephemeral_dh */)>; + virtual void CreateKeys( + const base::flat_map<CryptAuthKeyBundle::Name, CreateKeyData>& + keys_to_create, + const base::Optional<CryptAuthKey>& server_ephemeral_dh, + CreateKeysCallback create_keys_callback) = 0; + + DISALLOW_COPY_AND_ASSIGN(CryptAuthKeyCreator); +}; + +} // namespace device_sync + +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_KEY_CREATOR_H_
diff --git a/chromeos/services/device_sync/cryptauth_key_creator_impl.cc b/chromeos/services/device_sync/cryptauth_key_creator_impl.cc new file mode 100644 index 0000000..998b866 --- /dev/null +++ b/chromeos/services/device_sync/cryptauth_key_creator_impl.cc
@@ -0,0 +1,235 @@ +// Copyright 2019 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/device_sync/cryptauth_key_creator_impl.h" + +#include <memory> +#include <string> +#include <utility> + +#include "base/base64.h" +#include "base/bind.h" +#include "base/containers/flat_map.h" +#include "base/memory/ptr_util.h" +#include "base/no_destructor.h" +#include "base/optional.h" +#include "base/strings/string_util.h" +#include "chromeos/components/multidevice/logging/logging.h" +#include "chromeos/components/multidevice/secure_message_delegate_impl.h" +#include "chromeos/services/device_sync/cryptauth_key.h" +#include "chromeos/services/device_sync/proto/cryptauth_common.pb.h" +#include "crypto/hkdf.h" +#include "crypto/random.h" + +namespace chromeos { + +namespace device_sync { + +namespace { + +// The salt used in HKDF to derive symmetric keys from Diffie-Hellman handshake. +// This value is part of the CryptAuth v2 Enrollment specifications. +const char kSymmetricKeyDerivationSalt[] = "CryptAuth Enrollment"; + +bool IsValidSymmetricKeyType(const cryptauthv2::KeyType& type) { + return type == cryptauthv2::KeyType::RAW128 || + type == cryptauthv2::KeyType::RAW256; +} + +bool IsValidAsymmetricKeyType(const cryptauthv2::KeyType& type) { + return type == cryptauthv2::KeyType::P256; +} + +// If we need to create any symmetric keys, we first need to generate the +// client's ephemeral Diffie-Hellman key-pair and derive the handshake secret +// from the server's public key and the client's private key. This secret is +// used to derive new symmetric keys using HKDF. +bool IsClientEphemeralDhKeyNeeded( + const base::flat_map<CryptAuthKeyBundle::Name, + CryptAuthKeyCreator::CreateKeyData>& keys_to_create) { + for (const auto& key_to_create : keys_to_create) { + if (IsValidSymmetricKeyType(key_to_create.second.type)) + return true; + } + + return false; +} + +size_t NumBytesForSymmetricKeyType(cryptauthv2::KeyType key_type) { + switch (key_type) { + case cryptauthv2::KeyType::RAW128: + return 16u; + case cryptauthv2::KeyType::RAW256: + return 32u; + default: + NOTREACHED(); + return 0u; + } +} + +// Creates a handle by base64-encoding 32 random bytes. +std::string CreateRandomHandle() { + std::string bytes(32, '\0'); + crypto::RandBytes(base::WriteInto(&bytes, bytes.size()), bytes.size()); + + std::string handle; + base::Base64Encode(bytes, &handle); + + return handle; +} + +} // namespace + +// static +CryptAuthKeyCreatorImpl::Factory* + CryptAuthKeyCreatorImpl::Factory::test_factory_ = nullptr; + +// static +CryptAuthKeyCreatorImpl::Factory* CryptAuthKeyCreatorImpl::Factory::Get() { + if (test_factory_) + return test_factory_; + + static base::NoDestructor<CryptAuthKeyCreatorImpl::Factory> factory; + return factory.get(); +} + +// static +void CryptAuthKeyCreatorImpl::Factory::SetFactoryForTesting( + Factory* test_factory) { + test_factory_ = test_factory; +} + +CryptAuthKeyCreatorImpl::Factory::~Factory() = default; + +std::unique_ptr<CryptAuthKeyCreator> +CryptAuthKeyCreatorImpl::Factory::BuildInstance() { + return base::WrapUnique(new CryptAuthKeyCreatorImpl()); +} + +CryptAuthKeyCreatorImpl::CryptAuthKeyCreatorImpl() + : secure_message_delegate_( + multidevice::SecureMessageDelegateImpl::Factory::NewInstance()) {} + +void CryptAuthKeyCreatorImpl::CreateKeys( + const base::flat_map<CryptAuthKeyBundle::Name, CreateKeyData>& + keys_to_create, + const base::Optional<CryptAuthKey>& server_ephemeral_dh, + CreateKeysCallback create_keys_callback) { + DCHECK(!keys_to_create.empty()); + + // Fail if CreateKeys() has already been called. + DCHECK(keys_to_create_.empty() && new_keys_.empty() && + !create_keys_callback_); + + keys_to_create_ = keys_to_create; + server_ephemeral_dh_ = server_ephemeral_dh; + create_keys_callback_ = std::move(create_keys_callback); + + if (IsClientEphemeralDhKeyNeeded(keys_to_create_)) { + DCHECK(server_ephemeral_dh_ && server_ephemeral_dh_->IsAsymmetricKey()); + secure_message_delegate_->GenerateKeyPair( + base::Bind(&CryptAuthKeyCreatorImpl::OnClientDiffieHellmanGenerated, + base::Unretained(this))); + return; + } + + StartKeyCreation(); +} + +CryptAuthKeyCreatorImpl::~CryptAuthKeyCreatorImpl() = default; + +void CryptAuthKeyCreatorImpl::OnClientDiffieHellmanGenerated( + const std::string& public_key, + const std::string& private_key) { + DCHECK(!public_key.empty() && !private_key.empty()); + + client_ephemeral_dh_ = + CryptAuthKey(public_key, private_key, CryptAuthKey::Status::kActive, + cryptauthv2::KeyType::P256); + + secure_message_delegate_->DeriveKey( + client_ephemeral_dh_->private_key(), server_ephemeral_dh_->public_key(), + base::Bind( + &CryptAuthKeyCreatorImpl::OnDiffieHellmanHandshakeSecretDerived, + base::Unretained(this))); +} + +void CryptAuthKeyCreatorImpl::OnDiffieHellmanHandshakeSecretDerived( + const std::string& symmetric_key) { + DCHECK(!symmetric_key.empty()); + + dh_handshake_secret_ = + CryptAuthKey(symmetric_key, CryptAuthKey::Status::kActive, + cryptauthv2::KeyType::RAW256); + + StartKeyCreation(); +} + +void CryptAuthKeyCreatorImpl::StartKeyCreation() { + for (const auto& key_to_create : keys_to_create_) { + // If the key to create is symmetric, derive a symmetric key from the + // Diffie-Hellman handshake secrect using HKDF. The CryptAuth v2 + // Enrollment protocol specifies that the salt should be "CryptAuth + // Enrollment" and the info should be the key handle. This process is + // synchronous, unlike SecureMessageDelegate calls. + if (IsValidSymmetricKeyType(key_to_create.second.type)) { + std::string handle = key_to_create.second.handle.has_value() + ? *key_to_create.second.handle + : CreateRandomHandle(); + std::string derived_symmetric_key_material = crypto::HkdfSha256( + dh_handshake_secret_->symmetric_key(), kSymmetricKeyDerivationSalt, + handle, NumBytesForSymmetricKeyType(key_to_create.second.type)); + + OnSymmetricKeyDerived(key_to_create.first, derived_symmetric_key_material, + handle); + } else { + DCHECK(IsValidAsymmetricKeyType(key_to_create.second.type)); + + secure_message_delegate_->GenerateKeyPair( + base::Bind(&CryptAuthKeyCreatorImpl::OnAsymmetricKeyPairGenerated, + base::Unretained(this), key_to_create.first)); + } + } +} + +void CryptAuthKeyCreatorImpl::OnAsymmetricKeyPairGenerated( + CryptAuthKeyBundle::Name bundle_name, + const std::string& public_key, + const std::string& private_key) { + DCHECK(keys_to_create_.size() > 0); + DCHECK(!public_key.empty() && !private_key.empty()); + + const CryptAuthKeyCreator::CreateKeyData& create_key_data = + keys_to_create_.find(bundle_name)->second; + + new_keys_.try_emplace(bundle_name, public_key, private_key, + create_key_data.status, create_key_data.type, + create_key_data.handle); + + keys_to_create_.erase(bundle_name); + if (keys_to_create_.empty()) + std::move(create_keys_callback_).Run(new_keys_, client_ephemeral_dh_); +} + +void CryptAuthKeyCreatorImpl::OnSymmetricKeyDerived( + CryptAuthKeyBundle::Name bundle_name, + const std::string& symmetric_key, + const std::string& handle) { + DCHECK(keys_to_create_.size() > 0); + DCHECK(!symmetric_key.empty()); + + const CryptAuthKeyCreator::CreateKeyData& create_key_data = + keys_to_create_.find(bundle_name)->second; + + new_keys_.try_emplace(bundle_name, symmetric_key, create_key_data.status, + create_key_data.type, handle); + + keys_to_create_.erase(bundle_name); + if (keys_to_create_.empty()) + std::move(create_keys_callback_).Run(new_keys_, client_ephemeral_dh_); +} + +} // namespace device_sync + +} // namespace chromeos
diff --git a/chromeos/services/device_sync/cryptauth_key_creator_impl.h b/chromeos/services/device_sync/cryptauth_key_creator_impl.h new file mode 100644 index 0000000..17eb0a5 --- /dev/null +++ b/chromeos/services/device_sync/cryptauth_key_creator_impl.h
@@ -0,0 +1,82 @@ +// Copyright 2019 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_DEVICE_SYNC_CRYPTAUTH_KEY_CREATOR_IMPL_H_ +#define CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_KEY_CREATOR_IMPL_H_ + +#include "chromeos/services/device_sync/cryptauth_key_creator.h" + +#include <memory> +#include <string> +#include <utility> + +#include "base/callback.h" +#include "base/containers/flat_map.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/optional.h" +#include "chromeos/services/device_sync/cryptauth_key.h" +#include "chromeos/services/device_sync/cryptauth_key_bundle.h" + +namespace chromeos { + +namespace multidevice { +class SecureMessageDelegate; +} // namespace multidevice + +namespace device_sync { + +// Implementation of CryptAuthKeyCreator. +class CryptAuthKeyCreatorImpl : public CryptAuthKeyCreator { + public: + class Factory { + public: + static Factory* Get(); + static void SetFactoryForTesting(Factory* test_factory); + virtual ~Factory(); + virtual std::unique_ptr<CryptAuthKeyCreator> BuildInstance(); + + private: + static Factory* test_factory_; + }; + + ~CryptAuthKeyCreatorImpl() override; + + // CryptAuthKeyCreator: + void CreateKeys(const base::flat_map<CryptAuthKeyBundle::Name, CreateKeyData>& + keys_to_create, + const base::Optional<CryptAuthKey>& server_ephemeral_dh, + CreateKeysCallback create_keys_callback) override; + + private: + CryptAuthKeyCreatorImpl(); + + void OnClientDiffieHellmanGenerated(const std::string& public_key, + const std::string& private_key); + void OnDiffieHellmanHandshakeSecretDerived(const std::string& symmetric_key); + void StartKeyCreation(); + void OnAsymmetricKeyPairGenerated(CryptAuthKeyBundle::Name bundle_name, + const std::string& public_key, + const std::string& private_key); + void OnSymmetricKeyDerived(CryptAuthKeyBundle::Name bundle_name, + const std::string& symmetric_key, + const std::string& handle); + + base::flat_map<CryptAuthKeyBundle::Name, CreateKeyData> keys_to_create_; + base::flat_map<CryptAuthKeyBundle::Name, CryptAuthKey> new_keys_; + base::Optional<CryptAuthKey> server_ephemeral_dh_; + base::Optional<CryptAuthKey> client_ephemeral_dh_; + base::Optional<CryptAuthKey> dh_handshake_secret_; + CreateKeysCallback create_keys_callback_; + + std::unique_ptr<multidevice::SecureMessageDelegate> secure_message_delegate_; + + DISALLOW_COPY_AND_ASSIGN(CryptAuthKeyCreatorImpl); +}; + +} // namespace device_sync + +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_KEY_CREATOR_IMPL_H_
diff --git a/chromeos/services/device_sync/cryptauth_key_creator_impl_unittest.cc b/chromeos/services/device_sync/cryptauth_key_creator_impl_unittest.cc new file mode 100644 index 0000000..39d086e --- /dev/null +++ b/chromeos/services/device_sync/cryptauth_key_creator_impl_unittest.cc
@@ -0,0 +1,192 @@ +// Copyright 2019 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/device_sync/cryptauth_key_creator_impl.h" + +#include <memory> +#include <string> +#include <utility> + +#include "base/bind.h" +#include "base/containers/flat_map.h" +#include "base/macros.h" +#include "base/optional.h" +#include "chromeos/components/multidevice/fake_secure_message_delegate.h" +#include "chromeos/components/multidevice/secure_message_delegate_impl.h" +#include "chromeos/services/device_sync/cryptauth_key.h" +#include "chromeos/services/device_sync/cryptauth_key_bundle.h" +#include "chromeos/services/device_sync/cryptauth_key_creator.h" +#include "chromeos/services/device_sync/proto/cryptauth_common.pb.h" +#include "crypto/hkdf.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { + +namespace device_sync { + +namespace { + +// The salt used in HKDF to derive symmetric keys from Diffie-Hellman handshake. +// This value is part of the CryptAuth v2 Enrollment specifications. +const char kSymmetricKeyDerivationSalt[] = "CryptAuth Enrollment"; + +const char kFakeServerEphemeralDhPublicKeyMaterial[] = "server_ephemeral_dh"; +const char kFakeClientEphemeralDhPublicKeyMaterial[] = "client_ephemeral_dh"; +const char kFakeAsymmetricKeyHandle[] = "asymmetric_key_handle"; +const char kFakePublicKeyMaterial[] = "public_key"; +const char kFakeSymmetricKeyHandle[] = "symmetric_key_handle"; + +void VerifyCreatedKeysCallback( + const base::flat_map<CryptAuthKeyBundle::Name, CryptAuthKey>& + expected_new_keys, + const base::Optional<CryptAuthKey>& expected_client_ephemeral_dh, + const base::flat_map<CryptAuthKeyBundle::Name, CryptAuthKey>& new_keys, + const base::Optional<CryptAuthKey>& client_ephemeral_dh) { + EXPECT_EQ(expected_client_ephemeral_dh, client_ephemeral_dh); + EXPECT_EQ(expected_new_keys, new_keys); +} + +class FakeSecureMessageDelegateFactory + : public multidevice::SecureMessageDelegateImpl::Factory { + public: + FakeSecureMessageDelegateFactory() = default; + + ~FakeSecureMessageDelegateFactory() override = default; + + multidevice::FakeSecureMessageDelegate* instance() { return instance_; } + + private: + // multidevice::SecureMessageDelegateImpl::Factory: + std::unique_ptr<multidevice::SecureMessageDelegate> BuildInstance() override { + auto instance = std::make_unique<multidevice::FakeSecureMessageDelegate>(); + instance_ = instance.get(); + + return instance; + } + + multidevice::FakeSecureMessageDelegate* instance_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(FakeSecureMessageDelegateFactory); +}; + +} // namespace + +class CryptAuthKeyCreatorImplTest : public testing::Test { + protected: + CryptAuthKeyCreatorImplTest() = default; + ~CryptAuthKeyCreatorImplTest() override = default; + + void SetUp() override { + fake_secure_message_delegate_factory_ = + std::make_unique<FakeSecureMessageDelegateFactory>(); + multidevice::SecureMessageDelegateImpl::Factory::SetInstanceForTesting( + fake_secure_message_delegate_factory_.get()); + + key_creator_ = CryptAuthKeyCreatorImpl::Factory::Get()->BuildInstance(); + } + + void TearDown() override { + multidevice::SecureMessageDelegateImpl::Factory::SetInstanceForTesting( + nullptr); + } + + CryptAuthKey DeriveSecret( + const base::Optional<CryptAuthKey>& server_ephemeral_dh, + const base::Optional<CryptAuthKey>& client_ephemeral_dh) { + std::string derived_key; + fake_secure_message_delegate()->DeriveKey( + client_ephemeral_dh->private_key(), server_ephemeral_dh->public_key(), + base::Bind([](std::string* derived_key, + const std::string& key) { *derived_key = key; }, + &derived_key)); + return CryptAuthKey(derived_key, CryptAuthKey::Status::kActive, + cryptauthv2::KeyType::RAW256); + } + + CryptAuthKeyCreator* key_creator() { return key_creator_.get(); } + + multidevice::FakeSecureMessageDelegate* fake_secure_message_delegate() { + return fake_secure_message_delegate_factory_->instance(); + } + + private: + std::unique_ptr<FakeSecureMessageDelegateFactory> + fake_secure_message_delegate_factory_; + + std::unique_ptr<CryptAuthKeyCreator> key_creator_; + + DISALLOW_COPY_AND_ASSIGN(CryptAuthKeyCreatorImplTest); +}; + +TEST_F(CryptAuthKeyCreatorImplTest, AsymmetricKeyCreation) { + base::flat_map<CryptAuthKeyBundle::Name, CryptAuthKeyCreator::CreateKeyData> + keys_to_create = { + {CryptAuthKeyBundle::Name::kUserKeyPair, + CryptAuthKeyCreator::CreateKeyData(CryptAuthKey::Status::kActive, + cryptauthv2::KeyType::P256, + kFakeAsymmetricKeyHandle)}}; + + CryptAuthKey expected_asymmetric_key( + kFakePublicKeyMaterial, + fake_secure_message_delegate()->GetPrivateKeyForPublicKey( + kFakePublicKeyMaterial), + CryptAuthKey::Status::kActive, cryptauthv2::KeyType::P256, + kFakeAsymmetricKeyHandle); + + base::flat_map<CryptAuthKeyBundle::Name, CryptAuthKey> expected_new_keys = { + {CryptAuthKeyBundle::Name::kUserKeyPair, expected_asymmetric_key}}; + + fake_secure_message_delegate()->set_next_public_key(kFakePublicKeyMaterial); + + key_creator()->CreateKeys( + keys_to_create, base::nullopt /* fake_server_ephemeral_dh */, + base::BindOnce(VerifyCreatedKeysCallback, expected_new_keys, + base::nullopt /* expected_client_ephemeral_dh */)); +} + +TEST_F(CryptAuthKeyCreatorImplTest, SymmetricKeyCreation) { + base::flat_map<CryptAuthKeyBundle::Name, CryptAuthKeyCreator::CreateKeyData> + keys_to_create = { + {CryptAuthKeyBundle::Name::kUserKeyPair, + CryptAuthKeyCreator::CreateKeyData(CryptAuthKey::Status::kActive, + cryptauthv2::KeyType::RAW256, + kFakeSymmetricKeyHandle)}}; + + base::Optional<CryptAuthKey> fake_server_ephemeral_dh = + CryptAuthKey(kFakeServerEphemeralDhPublicKeyMaterial, + fake_secure_message_delegate()->GetPrivateKeyForPublicKey( + kFakeServerEphemeralDhPublicKeyMaterial), + CryptAuthKey::Status::kActive, cryptauthv2::KeyType::P256); + + base::Optional<CryptAuthKey> expected_client_ephemeral_dh = + CryptAuthKey(kFakeClientEphemeralDhPublicKeyMaterial, + fake_secure_message_delegate()->GetPrivateKeyForPublicKey( + kFakeClientEphemeralDhPublicKeyMaterial), + CryptAuthKey::Status::kActive, cryptauthv2::KeyType::P256); + + CryptAuthKey expected_handshake_secret = + DeriveSecret(fake_server_ephemeral_dh, expected_client_ephemeral_dh); + std::string expected_symmetric_key_material = crypto::HkdfSha256( + expected_handshake_secret.symmetric_key(), kSymmetricKeyDerivationSalt, + kFakeSymmetricKeyHandle, 32u /* derived_key_size */); + + CryptAuthKey expected_symmetric_key( + expected_symmetric_key_material, CryptAuthKey::Status::kActive, + cryptauthv2::KeyType::RAW256, kFakeSymmetricKeyHandle); + + base::flat_map<CryptAuthKeyBundle::Name, CryptAuthKey> expected_new_keys = { + {CryptAuthKeyBundle::Name::kUserKeyPair, expected_symmetric_key}}; + + fake_secure_message_delegate()->set_next_public_key( + kFakeClientEphemeralDhPublicKeyMaterial); + + key_creator()->CreateKeys( + keys_to_create, fake_server_ephemeral_dh, + base::BindOnce(VerifyCreatedKeysCallback, expected_new_keys, + expected_client_ephemeral_dh)); +} + +} // namespace device_sync + +} // namespace chromeos
diff --git a/chromeos/services/secure_channel/ble_weave_client_connection.cc b/chromeos/services/secure_channel/ble_weave_client_connection.cc index d7472fe..c11da0e 100644 --- a/chromeos/services/secure_channel/ble_weave_client_connection.cc +++ b/chromeos/services/secure_channel/ble_weave_client_connection.cc
@@ -211,11 +211,12 @@ bluetooth_device->SetConnectionLatency( device::BluetoothDevice::ConnectionLatency::CONNECTION_LATENCY_LOW, - base::Bind(&BluetoothLowEnergyWeaveClientConnection::CreateGattConnection, - weak_ptr_factory_.GetWeakPtr()), - base::Bind( - &BluetoothLowEnergyWeaveClientConnection::OnSetConnectionLatencyError, - weak_ptr_factory_.GetWeakPtr())); + base::BindRepeating(&BluetoothLowEnergyWeaveClientConnection:: + OnSetConnectionLatencySuccess, + weak_ptr_factory_.GetWeakPtr()), + base::BindRepeating(&BluetoothLowEnergyWeaveClientConnection:: + OnSetConnectionLatencyErrorOrTimeout, + weak_ptr_factory_.GetWeakPtr())); } void BluetoothLowEnergyWeaveClientConnection::CreateGattConnection() { @@ -321,6 +322,11 @@ // Ensure that |timed_out_sub_status| is still the active status. DCHECK(timed_out_sub_status == sub_status()); + if (timed_out_sub_status == SubStatus::WAITING_CONNECTION_LATENCY) { + OnSetConnectionLatencyErrorOrTimeout(); + return; + } + PA_LOG(ERROR) << "Timed out waiting during SubStatus " << SubStatusToString(timed_out_sub_status) << ". " << "Destroying connection."; @@ -328,10 +334,6 @@ BleWeaveConnectionResult result = BleWeaveConnectionResult::BLE_WEAVE_CONNECTION_RESULT_MAX; switch (timed_out_sub_status) { - case SubStatus::WAITING_CONNECTION_LATENCY: - result = BleWeaveConnectionResult:: - BLE_WEAVE_CONNECTION_RESULT_TIMEOUT_SETTING_CONNECTION_LATENCY; - break; case SubStatus::WAITING_GATT_CONNECTION: result = BleWeaveConnectionResult:: BLE_WEAVE_CONNECTION_RESULT_TIMEOUT_CREATING_GATT_CONNECTION; @@ -483,10 +485,35 @@ SetSubStatus(SubStatus::CONNECTED_AND_IDLE); } -void BluetoothLowEnergyWeaveClientConnection::OnSetConnectionLatencyError() { +void BluetoothLowEnergyWeaveClientConnection::OnSetConnectionLatencySuccess() { + // TODO(crbug.com/929518): Record how long it took to set connection latency. + + // It's possible that we timed out when attempting to set the connection + // latency before this callback was called, resulting in this class moving + // forward with a GATT connection (i.e., in any state other than + // |SubStatus::WAITING_CONNECTION_LATENCY|). That could mean, at this point in + // time, that we're in the middle of connecting, already connected, or any + // state in between. That's fine; simply early return in order to prevent + // trying to create yet another GATT connection (which will fail). + if (sub_status() != SubStatus::WAITING_CONNECTION_LATENCY) { + PA_LOG(WARNING) << "Setting connection latency succeeded but GATT " + << "connection to " << GetDeviceInfoLogString() + << " is already in progress or complete."; + return; + } + + CreateGattConnection(); +} + +void BluetoothLowEnergyWeaveClientConnection:: + OnSetConnectionLatencyErrorOrTimeout() { + // TODO(crbug.com/929518): Record when setting connection latency fails or + // times out. + DCHECK(sub_status_ == SubStatus::WAITING_CONNECTION_LATENCY); - PA_LOG(WARNING) << "Error setting connection latency for connection to " - << GetDeviceInfoLogString() << "."; + PA_LOG(WARNING) + << "Error or timeout setting connection latency for connection to " + << GetDeviceInfoLogString() << "."; // Even if setting the connection latency fails, continue with the // connection. This is unfortunate but should not be considered a fatal error.
diff --git a/chromeos/services/secure_channel/ble_weave_client_connection.h b/chromeos/services/secure_channel/ble_weave_client_connection.h index 32df812..1f6be89 100644 --- a/chromeos/services/secure_channel/ble_weave_client_connection.h +++ b/chromeos/services/secure_channel/ble_weave_client_connection.h
@@ -111,7 +111,8 @@ protected: enum BleWeaveConnectionResult { BLE_WEAVE_CONNECTION_RESULT_CLOSED_NORMALLY = 0, - BLE_WEAVE_CONNECTION_RESULT_TIMEOUT_SETTING_CONNECTION_LATENCY = 1, + DEPRECATED_BLE_WEAVE_CONNECTION_RESULT_TIMEOUT_SETTING_CONNECTION_LATENCY = + 1, BLE_WEAVE_CONNECTION_RESULT_TIMEOUT_CREATING_GATT_CONNECTION = 2, BLE_WEAVE_CONNECTION_RESULT_TIMEOUT_STARTING_NOTIFY_SESSION = 3, BLE_WEAVE_CONNECTION_RESULT_TIMEOUT_FINDING_GATT_CHARACTERISTICS = 4, @@ -343,7 +344,8 @@ void CreateGattConnection(); void OnGattConnectionCreated( std::unique_ptr<device::BluetoothGattConnection> gatt_connection); - void OnSetConnectionLatencyError(); + void OnSetConnectionLatencySuccess(); + void OnSetConnectionLatencyErrorOrTimeout(); void OnCreateGattConnectionError( device::BluetoothDevice::ConnectErrorCode error_code); void OnCharacteristicsFound(const RemoteAttribute& service,
diff --git a/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc b/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc index 262f1877..77280a7 100644 --- a/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc +++ b/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc
@@ -1465,15 +1465,42 @@ ASSERT_FALSE(connection_latency_callback_.is_null()); ASSERT_FALSE(connection_latency_error_callback_.is_null()); + EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection(_, _)) + .WillOnce(DoAll(SaveArg<0>(&create_gatt_connection_success_callback_), + SaveArg<1>(&create_gatt_connection_error_callback_))); + // Simulate a timeout. test_timer_->Fire(); - EXPECT_EQ(connection->sub_status(), SubStatus::DISCONNECTED); - EXPECT_EQ(connection->status(), Connection::Status::DISCONNECTED); + EXPECT_FALSE(create_gatt_connection_error_callback_.is_null()); + ASSERT_FALSE(create_gatt_connection_success_callback_.is_null()); + // Robustness check: simulate the SetConnectionLatency success callback firing + // while a GATT connection is in progress. It should recognize that a GATT + // connection is in progress and not call CreateGattConnection a 2nd time. + connection_latency_callback_.Run(); + + // Preparing |connection| to run |create_gatt_connection_success_callback_|. + EXPECT_CALL(*connection, CreateCharacteristicsFinder(_, _)) + .WillOnce(DoAll( + SaveArg<0>(&characteristics_finder_success_callback_), + SaveArg<1>(&characteristics_finder_error_callback_), + Return(new NiceMock<MockBluetoothLowEnergyCharacteristicsFinder>))); + + create_gatt_connection_success_callback_.Run( + std::make_unique<NiceMock<device::MockBluetoothGattConnection>>( + adapter_, kTestRemoteDeviceBluetoothAddress)); + + CharacteristicsFound(connection.get()); + NotifySessionStarted(connection.get()); + ConnectionResponseReceived(connection.get(), kDefaultMaxPacketSize); + + VerifyGattConnectionResultSuccess(); + + DeleteConnectionWithoutCallingDisconnect(&connection); VerifyBleWeaveConnectionResult( BluetoothLowEnergyWeaveClientConnection::BleWeaveConnectionResult:: - BLE_WEAVE_CONNECTION_RESULT_TIMEOUT_SETTING_CONNECTION_LATENCY); + BLE_WEAVE_CONNECTION_RESULT_CLOSED_NORMALLY); } TEST_F(SecureChannelBluetoothLowEnergyWeaveClientConnectionTest,
diff --git a/components/OWNERS b/components/OWNERS index d2fb0cf..f9d146d 100644 --- a/components/OWNERS +++ b/components/OWNERS
@@ -19,6 +19,7 @@ per-file payments_strings.grdp=file://components/payments/OWNERS per-file pdf_strings.grdp=file://pdf/OWNERS per-file policy_strings.grdp=file://components/policy/OWNERS +per-file print_media_strings.grdp=file://components/printing/OWNERS per-file printing_component_strings.grdp=file://components/printing/OWNERS per-file reset_password_strings.grdp=file://components/safe_browsing/OWNERS per-file security_interstitials_strings.grdp=file://components/security_interstitials/OWNERS
diff --git a/components/components_strings.grd b/components/components_strings.grd index 8ad54e69..65e9453 100644 --- a/components/components_strings.grd +++ b/components/components_strings.grd
@@ -213,6 +213,7 @@ <part file="payments_strings.grdp" /> <part file="pdf_strings.grdp" /> <part file="policy_strings.grdp" /> + <part file="print_media_strings.grdp" /> <part file="printing_component_strings.grdp" /> <part file="reset_password_strings.grdp" /> <part file="safe_browsing_strings.grdp" />
diff --git a/components/crash/content/app/BUILD.gn b/components/crash/content/app/BUILD.gn index 30ba4f95..010123e8 100644 --- a/components/crash/content/app/BUILD.gn +++ b/components/crash/content/app/BUILD.gn
@@ -219,6 +219,10 @@ # Chromium Framework.framework/Versions/A/Helpers/ "-rpath", "@loader_path/../../../..", + + # The handler can be executed from headless_browsertests in Helpers/ + "-rpath", + "@loader_path/..", ] } }
diff --git a/components/cronet/native/test/url_request_test.cc b/components/cronet/native/test/url_request_test.cc index 574a8757..1dbfda0 100644 --- a/components/cronet/native/test/url_request_test.cc +++ b/components/cronet/native/test/url_request_test.cc
@@ -292,6 +292,9 @@ request = Cronet_UrlRequest_Create(); Cronet_UrlRequestParams_http_method_set(request_params, "HEAD"); + Cronet_UrlRequestParams_priority_set( + request_params, + Cronet_UrlRequestParams_REQUEST_PRIORITY_REQUEST_PRIORITY_IDLE); // Check header validation Cronet_HttpHeaderPtr http_header = Cronet_HttpHeader_Create(); Cronet_UrlRequestParams_request_headers_add(request_params, http_header); @@ -303,6 +306,9 @@ Cronet_UrlRequest_Destroy(request); request = Cronet_UrlRequest_Create(); + Cronet_UrlRequestParams_priority_set( + request_params, + Cronet_UrlRequestParams_REQUEST_PRIORITY_REQUEST_PRIORITY_LOWEST); Cronet_HttpHeader_name_set(http_header, "bad:name"); Cronet_UrlRequestParams_request_headers_add(request_params, http_header); EXPECT_EQ( @@ -313,6 +319,9 @@ Cronet_UrlRequest_Destroy(request); request = Cronet_UrlRequest_Create(); + Cronet_UrlRequestParams_priority_set( + request_params, + Cronet_UrlRequestParams_REQUEST_PRIORITY_REQUEST_PRIORITY_LOW); Cronet_HttpHeader_value_set(http_header, "header value"); Cronet_UrlRequestParams_request_headers_add(request_params, http_header); EXPECT_EQ( @@ -323,6 +332,9 @@ Cronet_UrlRequest_Destroy(request); request = Cronet_UrlRequest_Create(); + Cronet_UrlRequestParams_priority_set( + request_params, + Cronet_UrlRequestParams_REQUEST_PRIORITY_REQUEST_PRIORITY_HIGHEST); Cronet_HttpHeader_name_set(http_header, "header-name"); Cronet_UrlRequestParams_request_headers_add(request_params, http_header); EXPECT_EQ(Cronet_RESULT_SUCCESS, Cronet_UrlRequest_InitWithParams(
diff --git a/components/cronet/native/upload_data_sink.cc b/components/cronet/native/upload_data_sink.cc index 5458021..70e6e21 100644 --- a/components/cronet/native/upload_data_sink.cc +++ b/components/cronet/native/upload_data_sink.cc
@@ -78,7 +78,7 @@ Cronet_UploadDataSinkImpl::~Cronet_UploadDataSinkImpl() = default; -bool Cronet_UploadDataSinkImpl::InitRequest(CronetURLRequest* request) { +void Cronet_UploadDataSinkImpl::InitRequest(CronetURLRequest* request) { int64_t length = upload_data_provider_->GetLength(); if (length == -1) { is_chunked_ = true; @@ -90,7 +90,6 @@ request->SetUpload(std::make_unique<CronetUploadDataStream>( new NetworkTasks(this, upload_data_provider_executor_), length)); - return true; } void Cronet_UploadDataSinkImpl::OnReadSucceeded(uint64_t bytes_read,
diff --git a/components/cronet/native/upload_data_sink.h b/components/cronet/native/upload_data_sink.h index bd526be9..924534a2 100644 --- a/components/cronet/native/upload_data_sink.h +++ b/components/cronet/native/upload_data_sink.h
@@ -31,7 +31,7 @@ ~Cronet_UploadDataSinkImpl() override; // Initialize length and attach upload to request. Called on client thread. - bool InitRequest(CronetURLRequest* request); + void InitRequest(CronetURLRequest* request); // Mark stream as closed and post |Close()| callback to consumer. void PostCloseToExecutor();
diff --git a/components/cronet/native/url_request.cc b/components/cronet/native/url_request.cc index 77b2199..7a6809bf 100644 --- a/components/cronet/native/url_request.cc +++ b/components/cronet/native/url_request.cc
@@ -346,8 +346,7 @@ params->upload_data_provider_executor ? params->upload_data_provider_executor : executor); - if (!upload_data_sink_->InitRequest(request_)) - return engine_->CheckResult(Cronet_RESULT_NULL_POINTER_CALLBACK); + upload_data_sink_->InitRequest(request_); request_->SetHttpMethod("POST"); }
diff --git a/components/mirroring/browser/single_client_video_capture_host.cc b/components/mirroring/browser/single_client_video_capture_host.cc index 9c27142..f1407a6 100644 --- a/components/mirroring/browser/single_client_video_capture_host.cc +++ b/components/mirroring/browser/single_client_video_capture_host.cc
@@ -173,6 +173,13 @@ std::move(callback).Run(media::VideoCaptureFormats()); } +void SingleClientVideoCaptureHost::OnFrameDropped( + int32_t device_id, + media::VideoCaptureFrameDropReason reason) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Ignore this call. +} + void SingleClientVideoCaptureHost::OnLog(int32_t device_id, const std::string& message) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/components/mirroring/browser/single_client_video_capture_host.h b/components/mirroring/browser/single_client_video_capture_host.h index b44bdc2..dc1ece79 100644 --- a/components/mirroring/browser/single_client_video_capture_host.h +++ b/components/mirroring/browser/single_client_video_capture_host.h
@@ -65,6 +65,8 @@ void GetDeviceFormatsInUse(int32_t device_id, int32_t session_id, GetDeviceFormatsInUseCallback callback) override; + void OnFrameDropped(int32_t device_id, + media::VideoCaptureFrameDropReason reason) override; void OnLog(int32_t device_id, const std::string& message) override; // media::VideoFrameReceiver implementations
diff --git a/components/mirroring/service/fake_video_capture_host.h b/components/mirroring/service/fake_video_capture_host.h index 4d71268a..179a30f 100644 --- a/components/mirroring/service/fake_video_capture_host.h +++ b/components/mirroring/service/fake_video_capture_host.h
@@ -27,6 +27,8 @@ void(int32_t, int32_t, const media::VideoCaptureParams&)); MOCK_METHOD0(OnStopped, void()); MOCK_METHOD2(OnLog, void(int32_t, const std::string&)); + MOCK_METHOD2(OnFrameDropped, + void(int32_t, media::VideoCaptureFrameDropReason)); void Start(int32_t device_id, int32_t session_id,
diff --git a/components/offline_pages/core/offline_page_feature.cc b/components/offline_pages/core/offline_page_feature.cc index 7dbaa2a..1a2f55c 100644 --- a/components/offline_pages/core/offline_page_feature.cc +++ b/components/offline_pages/core/offline_page_feature.cc
@@ -20,9 +20,6 @@ namespace offline_pages { -const base::Feature kOfflineBookmarksFeature{"OfflineBookmarks", - base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kOffliningRecentPagesFeature{ "OfflineRecentPages", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -82,10 +79,6 @@ const char kPrefetchingOfflinePagesExperimentsOption[] = "exp"; -bool IsOfflineBookmarksEnabled() { - return base::FeatureList::IsEnabled(kOfflineBookmarksFeature); -} - bool IsOffliningRecentPagesEnabled() { return base::FeatureList::IsEnabled(kOffliningRecentPagesFeature); }
diff --git a/components/offline_pages/core/offline_page_feature.h b/components/offline_pages/core/offline_page_feature.h index 1f847d1..d1b27ef 100644 --- a/components/offline_pages/core/offline_page_feature.h +++ b/components/offline_pages/core/offline_page_feature.h
@@ -10,7 +10,6 @@ namespace offline_pages { -extern const base::Feature kOfflineBookmarksFeature; extern const base::Feature kOffliningRecentPagesFeature; extern const base::Feature kOfflinePagesSvelteConcurrentLoadingFeature; extern const base::Feature kOfflinePagesCTFeature; @@ -35,9 +34,6 @@ // pages. extern const char kPrefetchingOfflinePagesExperimentsOption[]; -// Returns true if saving bookmarked pages for offline viewing is enabled. -bool IsOfflineBookmarksEnabled(); - // Returns true if offlining of recent pages (aka 'Last N pages') is enabled. bool IsOffliningRecentPagesEnabled();
diff --git a/components/offline_pages/core/offline_page_feature_unittest.cc b/components/offline_pages/core/offline_page_feature_unittest.cc index 84592c2c..ec003c7 100644 --- a/components/offline_pages/core/offline_page_feature_unittest.cc +++ b/components/offline_pages/core/offline_page_feature_unittest.cc
@@ -10,16 +10,6 @@ namespace offline_pages { -TEST(OfflinePageFeatureTest, OfflineBookmarks) { - // Enabled by default. - EXPECT_TRUE(offline_pages::IsOfflineBookmarksEnabled()); - - // Check if helper method works correctly when the features is disabled. - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature(kOfflineBookmarksFeature); - EXPECT_FALSE(offline_pages::IsOfflineBookmarksEnabled()); -} - TEST(OfflinePageFeatureTest, OffliningRecentPages) { // Enabled by default. EXPECT_TRUE(offline_pages::IsOffliningRecentPagesEnabled());
diff --git a/components/open_from_clipboard/clipboard_recent_content_impl_ios.h b/components/open_from_clipboard/clipboard_recent_content_impl_ios.h index 0cc789a..f8963002 100644 --- a/components/open_from_clipboard/clipboard_recent_content_impl_ios.h +++ b/components/open_from_clipboard/clipboard_recent_content_impl_ios.h
@@ -40,7 +40,7 @@ // not been suppresed. Otherwise, returns nil. - (NSString*)recentTextFromClipboard; -// Returns the copied string if the clipboard contains a recent string that has +// Returns the copied image if the clipboard contains a recent image that has // not been suppressed. Otherwise, returns nil. - (UIImage*)recentImageFromClipboard;
diff --git a/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.cc b/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.cc index fdfda82..2f2b6469 100644 --- a/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.cc +++ b/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.cc
@@ -96,6 +96,10 @@ machine_client_id_ = machine_client_id; } +void MachineLevelUserCloudPolicyStore::InitWithoutToken() { + NotifyStoreError(); +} + void MachineLevelUserCloudPolicyStore::Validate( std::unique_ptr<enterprise_management::PolicyFetchResponse> policy, std::unique_ptr<enterprise_management::PolicySigningKey> key,
diff --git a/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.h b/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.h index 1e4800ea..b3ef3b8 100644 --- a/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.h +++ b/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.h
@@ -48,6 +48,10 @@ void SetupRegistration(const std::string& machine_dm_token, const std::string& machine_client_id); + // No DM token can be fetched from server or read from disk. Finish + // initialization with empty policy data. + void InitWithoutToken(); + private: // override DesktopCloudPolicyStore void Validate(
diff --git a/components/print_media_strings.grdp b/components/print_media_strings.grdp new file mode 100644 index 0000000..7dd8e5d --- /dev/null +++ b/components/print_media_strings.grdp
@@ -0,0 +1,497 @@ +<?xml version="1.0" encoding="utf-8"?> +<grit-part> + <if expr="enable_print_preview"> + <message name="PRINT_PREVIEW_MEDIA_ASME_F_28X40IN" + desc="In Title Case: Media size shown to user in print preview for media ``E1''"> + E1 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_2A0_1189X1682MM" + desc="In Title Case: Media size shown to user in print preview for media ``2A0''"> + 2A0 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_A0_841X1189MM" + desc="In Title Case: Media size shown to user in print preview for media ``A0''"> + A0 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_A10_26X37MM" + desc="In Title Case: Media size shown to user in print preview for media ``A10''"> + A10 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_A1_594X841MM" + desc="In Title Case: Media size shown to user in print preview for media ``A1''"> + A1 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_A2_420X594MM" + desc="In Title Case: Media size shown to user in print preview for media ``A2''"> + A2 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_A3_297X420MM" + desc="In Title Case: Media size shown to user in print preview for media ``A3''"> + A3 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_A4_210X297MM" + desc="In Title Case: Media size shown to user in print preview for media ``A4''"> + A4 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_A4_EXTRA_235_5X322_3MM" + desc="In Title Case: Media size shown to user in print preview for media ``A4-Extra''"> + A4-Extra + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_A4_TAB_225X297MM" + desc="In Title Case: Media size shown to user in print preview for media ``A4-Tab''"> + A4-Tab + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_A5_148X210MM" + desc="In Title Case: Media size shown to user in print preview for media ``A5''"> + A5 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_A5_EXTRA_174X235MM" + desc="In Title Case: Media size shown to user in print preview for media ``A5-Extra''"> + A5-Extra + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_A6_105X148MM" + desc="In Title Case: Media size shown to user in print preview for media ``A6''"> + A6 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_A7_74X105MM" + desc="In Title Case: Media size shown to user in print preview for media ``A7''"> + A7 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_A8_52X74MM" + desc="In Title Case: Media size shown to user in print preview for media ``A8''"> + A8 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_A9_37X52MM" + desc="In Title Case: Media size shown to user in print preview for media ``A9''"> + A9 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_B0_1000X1414MM" + desc="In Title Case: Media size shown to user in print preview for media ``B0''"> + B0 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_B10_31X44MM" + desc="In Title Case: Media size shown to user in print preview for media ``B10''"> + B10 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_B1_707X1000MM" + desc="In Title Case: Media size shown to user in print preview for media ``B1''"> + B1 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_B2_500X707MM" + desc="In Title Case: Media size shown to user in print preview for media ``B2''"> + B2 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_B3_353X500MM" + desc="In Title Case: Media size shown to user in print preview for media ``B3''"> + B3 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_B4_250X353MM" + desc="In Title Case: Media size shown to user in print preview for media ``B4 (Envelope)''"> + B4 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_B5_176X250MM" + desc="In Title Case: Media size shown to user in print preview for media ``B5 (Envelope)''"> + B5 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_B5_EXTRA_201X276MM" + desc="In Title Case: Media size shown to user in print preview for media ``B5-Extra''"> + B5-Extra + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_B6C4_125X324MM" + desc="In Title Case: Media size shown to user in print preview for media ``B6/C4 (Envelope)''"> + B6/C4 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_B6_125X176MM" + desc="In Title Case: Media size shown to user in print preview for media ``B6 (Envelope)''"> + B6 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_B7_88X125MM" + desc="In Title Case: Media size shown to user in print preview for media ``B7''"> + B7 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_B8_62X88MM" + desc="In Title Case: Media size shown to user in print preview for media ``B8''"> + B8 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_B9_44X62MM" + desc="In Title Case: Media size shown to user in print preview for media ``B9''"> + B9 + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_C0_917X1297MM" + desc="In Title Case: Media size shown to user in print preview for media ``C0 (Envelope)''"> + C0 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_C10_28X40MM" + desc="In Title Case: Media size shown to user in print preview for media ``C10 (Envelope)''"> + C10 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_C1_648X917MM" + desc="In Title Case: Media size shown to user in print preview for media ``C1 (Envelope)''"> + C1 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_C2_458X648MM" + desc="In Title Case: Media size shown to user in print preview for media ``C2 (Envelope)''"> + C2 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_C3_324X458MM" + desc="In Title Case: Media size shown to user in print preview for media ``C3 (Envelope)''"> + C3 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_C4_229X324MM" + desc="In Title Case: Media size shown to user in print preview for media ``C4 (Envelope)''"> + C4 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_C5_162X229MM" + desc="In Title Case: Media size shown to user in print preview for media ``C5 (Envelope)''"> + C5 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_C6C5_114X229MM" + desc="In Title Case: Media size shown to user in print preview for media ``C6/C5 (Envelope)''"> + C6/C5 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_C6_114X162MM" + desc="In Title Case: Media size shown to user in print preview for media ``C6 (Envelope)''"> + C6 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_C7C6_81X162MM" + desc="In Title Case: Media size shown to user in print preview for media ``C7/C6 (Envelope)''"> + C7/C6 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_C7_81X114MM" + desc="In Title Case: Media size shown to user in print preview for media ``C7 (Envelope)''"> + C7 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_C8_57X81MM" + desc="In Title Case: Media size shown to user in print preview for media ``C8 (Envelope)''"> + C8 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_C9_40X57MM" + desc="In Title Case: Media size shown to user in print preview for media ``C9 (Envelope)''"> + C9 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ISO_DL_110X220MM" + desc="In Title Case: Media size shown to user in print preview for media ``Designated-Long''"> + Designated-Long + </message> + <message name="PRINT_PREVIEW_MEDIA_JIS_EXEC_216X330MM" + desc="In Title Case: Media size shown to user in print preview for media ``Exec''"> + Exec + </message> + <message name="PRINT_PREVIEW_MEDIA_JPN_CHOU2_111_1X146MM" + desc="In Title Case: Media size shown to user in print preview for media ``Chou2 (Envelope)''"> + Chou2 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_JPN_CHOU3_120X235MM" + desc="In Title Case: Media size shown to user in print preview for media ``Chou3 (Envelope)''"> + Chou3 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_JPN_CHOU4_90X205MM" + desc="In Title Case: Media size shown to user in print preview for media ``Chou4 (Envelope)''"> + Chou4 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_JPN_HAGAKI_100X148MM" + desc="In Title Case: Media size shown to user in print preview for media ``Hagaki (Postcard)''"> + Hagaki (Postcard) + </message> + <message name="PRINT_PREVIEW_MEDIA_JPN_KAHU_240X322_1MM" + desc="In Title Case: Media size shown to user in print preview for media ``Kahu (Envelope)''"> + Kahu (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_JPN_KAKU2_240X332MM" + desc="In Title Case: Media size shown to user in print preview for media ``Kaku2 (Envelope)''"> + Kaku2 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_JPN_OUFUKU_148X200MM" + desc="In Title Case: Media size shown to user in print preview for media ``Postcard)''"> + Postcard) + </message> + <message name="PRINT_PREVIEW_MEDIA_JPN_YOU4_105X235MM" + desc="In Title Case: Media size shown to user in print preview for media ``You4 (Envelope)''"> + You4 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_10X11_10X11IN" + desc="In Title Case: Media size shown to user in print preview for media ``10x11''"> + 10x11 + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_10X13_10X13IN" + desc="In Title Case: Media size shown to user in print preview for media ``10x13 (Envelope)''"> + 10x13 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_10X14_10X14IN" + desc="In Title Case: Media size shown to user in print preview for media ``10x14 (Envelope)''"> + 10x14 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_10X15_10X15IN" + desc="In Title Case: Media size shown to user in print preview for media ``10x15 (Envelope)''"> + 10x15 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_11X12_11X12IN" + desc="In Title Case: Media size shown to user in print preview for media ``11x12''"> + 11x12 + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_11X15_11X15IN" + desc="In Title Case: Media size shown to user in print preview for media ``11x15''"> + 11x15 + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_12X19_12X19IN" + desc="In Title Case: Media size shown to user in print preview for media ``12x19''"> + 12x19 + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_5X7_5X7IN" + desc="In Title Case: Media size shown to user in print preview for media ``5x7''"> + 5x7 + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_6X9_6X9IN" + desc="In Title Case: Media size shown to user in print preview for media ``6x9 (Envelope)''"> + 6x9 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_7X9_7X9IN" + desc="In Title Case: Media size shown to user in print preview for media ``7x9 (Envelope)''"> + 7x9 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_9X11_9X11IN" + desc="In Title Case: Media size shown to user in print preview for media ``9x11 (Envelope)''"> + 9x11 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_A2_4_375X5_75IN" + desc="In Title Case: Media size shown to user in print preview for media ``A2 (Envelope)''"> + A2 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_ARCH_A_9X12IN" + desc="In Title Case: Media size shown to user in print preview for media ``Architecture-A (Envelope)''"> + Architecture-A (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_ARCH_B_12X18IN" + desc="In Title Case: Media size shown to user in print preview for media ``Architecture-B''"> + Architecture-B + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_ARCH_C_18X24IN" + desc="In Title Case: Media size shown to user in print preview for media ``Architecture-C''"> + Architecture-C + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_ARCH_D_24X36IN" + desc="In Title Case: Media size shown to user in print preview for media ``Architecture-D''"> + Architecture-D + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_ARCH_E_36X48IN" + desc="In Title Case: Media size shown to user in print preview for media ``Architecture-E''"> + Architecture-E + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_B_PLUS_12X19_17IN" + desc="In Title Case: Media size shown to user in print preview for media ``B-Plus''"> + B-Plus + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_C5_6_5X9_5IN" + desc="In Title Case: Media size shown to user in print preview for media ``C5 (Envelope)''"> + C5 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_C_17X22IN" + desc="In Title Case: Media size shown to user in print preview for media ``Engineering-C''"> + Engineering-C + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_D_22X34IN" + desc="In Title Case: Media size shown to user in print preview for media ``Engineering-D''"> + Engineering-D + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_EDP_11X14IN" + desc="In Title Case: Media size shown to user in print preview for media ``Edp''"> + Edp + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_EUR_EDP_12X14IN" + desc="In Title Case: Media size shown to user in print preview for media ``European-Edp''"> + European-Edp + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_E_34X44IN" + desc="In Title Case: Media size shown to user in print preview for media ``Engineering-E''"> + Engineering-E + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_FANFOLD_EUR_8_5X12IN" + desc="In Title Case: Media size shown to user in print preview for media ``Fanfold-European''"> + Fanfold-European + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_FANFOLD_US_11X14_875IN" + desc="In Title Case: Media size shown to user in print preview for media ``Fanfold-Us''"> + Fanfold-Us + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_FOOLSCAP_8_5X13IN" + desc="In Title Case: Media size shown to user in print preview for media ``Foolscap''"> + Foolscap + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_F_44X68IN" + desc="In Title Case: Media size shown to user in print preview for media ``F''"> + F + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_GOVT_LEGAL_8X13IN" + desc="In Title Case: Media size shown to user in print preview for media ``Government-Legal''"> + Government-Legal + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_GOVT_LETTER_8X10IN" + desc="In Title Case: Media size shown to user in print preview for media ``Government-Letter''"> + Government-Letter + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_INDEX_3X5_3X5IN" + desc="In Title Case: Media size shown to user in print preview for media ``Index-3x5''"> + Index-3x5 + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_INDEX_4X6_4X6IN" + desc="In Title Case: Media size shown to user in print preview for media ``Index-4x6 (Postcard)''"> + Index-4x6 (Postcard) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_INDEX_4X6_EXT_6X8IN" + desc="In Title Case: Media size shown to user in print preview for media ``Index-4x6-Ext''"> + Index-4x6-Ext + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_INDEX_5X8_5X8IN" + desc="In Title Case: Media size shown to user in print preview for media ``Index-5x8''"> + Index-5x8 + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_INVOICE_5_5X8_5IN" + desc="In Title Case: Media size shown to user in print preview for media ``Statement''"> + Statement + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_LEDGER_11X17IN" + desc="In Title Case: Media size shown to user in print preview for media ``Ledger''"> + Ledger + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_LEGAL_8_5X14IN" + desc="In Title Case: Media size shown to user in print preview for media ``Legal''"> + Legal + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_LEGAL_EXTRA_9_5X15IN" + desc="In Title Case: Media size shown to user in print preview for media ``Legal-Extra''"> + Legal-Extra + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_LETTER_8_5X11IN" + desc="In Title Case: Media size shown to user in print preview for media ``Letter''"> + Letter + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_LETTER_EXTRA_9_5X12IN" + desc="In Title Case: Media size shown to user in print preview for media ``Letter-Extra''"> + Letter-Extra + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_LETTER_PLUS_8_5X12_69IN" + desc="In Title Case: Media size shown to user in print preview for media ``Letter-Plus''"> + Letter-Plus + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_NUMBER_10_4_125X9_5IN" + desc="In Title Case: Media size shown to user in print preview for media ``Comm-10 (Envelope)''"> + Comm-10 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_NUMBER_11_4_5X10_375IN" + desc="In Title Case: Media size shown to user in print preview for media ``Number-11 (Envelope)''"> + Number-11 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_NUMBER_12_4_75X11IN" + desc="In Title Case: Media size shown to user in print preview for media ``Number-12 (Envelope)''"> + Number-12 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_NUMBER_14_5X11_5IN" + desc="In Title Case: Media size shown to user in print preview for media ``Number-14 (Envelope)''"> + Number-14 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_PERSONAL_3_625X6_5IN" + desc="In Title Case: Media size shown to user in print preview for media ``Personal (Envelope)''"> + Personal (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_SUPER_A_8_94X14IN" + desc="In Title Case: Media size shown to user in print preview for media ``Super-A''"> + Super-A + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_SUPER_B_13X19IN" + desc="In Title Case: Media size shown to user in print preview for media ``Super-B''"> + Super-B + </message> + <message name="PRINT_PREVIEW_MEDIA_NA_WIDE_FORMAT_30X42IN" + desc="In Title Case: Media size shown to user in print preview for media ``Wide-Format''"> + Wide-Format + </message> + <message name="PRINT_PREVIEW_MEDIA_OM_DAI_PA_KAI_275X395MM" + desc="In Title Case: Media size shown to user in print preview for media ``Dai-Pa-Kai''"> + Dai-Pa-Kai + </message> + <message name="PRINT_PREVIEW_MEDIA_OM_FOLIO_SP_215X315MM" + desc="In Title Case: Media size shown to user in print preview for media ``Folio-Sp''"> + Folio-Sp + </message> + <message name="PRINT_PREVIEW_MEDIA_OM_INVITE_220X220MM" + desc="In Title Case: Media size shown to user in print preview for media ``Invite (Envelope)''"> + Invite (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_OM_ITALIAN_110X230MM" + desc="In Title Case: Media size shown to user in print preview for media ``Italian (Envelope)''"> + Italian (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_OM_JUURO_KU_KAI_198X275MM" + desc="In Title Case: Media size shown to user in print preview for media ``Juuro-Ku-Kai''"> + Juuro-Ku-Kai + </message> + <message name="PRINT_PREVIEW_MEDIA_OM_LARGE_PHOTO_200X300" + desc="In Title Case: Media size shown to user in print preview for media ``Large-Photo''"> + Large-Photo + </message> + <message name="PRINT_PREVIEW_MEDIA_OM_PA_KAI_267X389MM" + desc="In Title Case: Media size shown to user in print preview for media ``Pa-Kai''"> + Pa-Kai + </message> + <message name="PRINT_PREVIEW_MEDIA_OM_POSTFIX_114X229MM" + desc="In Title Case: Media size shown to user in print preview for media ``Postfix (Envelope)''"> + Postfix (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_OM_SMALL_PHOTO_100X150MM" + desc="In Title Case: Media size shown to user in print preview for media ``Small-Photo''"> + Small-Photo + </message> + <message name="PRINT_PREVIEW_MEDIA_PRC_10_324X458MM" + desc="In Title Case: Media size shown to user in print preview for media ``Prc10 (Envelope)''"> + Prc10 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_PRC_16K_146X215MM" + desc="In Title Case: Media size shown to user in print preview for media ``Prc-16K''"> + Prc-16K + </message> + <message name="PRINT_PREVIEW_MEDIA_PRC_1_102X165MM" + desc="In Title Case: Media size shown to user in print preview for media ``Prc1 (Envelope)''"> + Prc1 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_PRC_2_102X176MM" + desc="In Title Case: Media size shown to user in print preview for media ``Prc2 (Envelope)''"> + Prc2 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_PRC_32K_97X151MM" + desc="In Title Case: Media size shown to user in print preview for media ``Prc-32K''"> + Prc-32K + </message> + <message name="PRINT_PREVIEW_MEDIA_PRC_3_125X176MM" + desc="In Title Case: Media size shown to user in print preview for media ``Prc3 (Envelope)''"> + Prc3 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_PRC_4_110X208MM" + desc="In Title Case: Media size shown to user in print preview for media ``Prc4 (Envelope)''"> + Prc4 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_PRC_5_110X220MM" + desc="In Title Case: Media size shown to user in print preview for media ``Prc5 (Envelope)''"> + Prc5 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_PRC_6_120X320MM" + desc="In Title Case: Media size shown to user in print preview for media ``Prc6 (Envelope)''"> + Prc6 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_PRC_7_160X230MM" + desc="In Title Case: Media size shown to user in print preview for media ``Prc7 (Envelope)''"> + Prc7 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_PRC_8_120X309MM" + desc="In Title Case: Media size shown to user in print preview for media ``Prc8 (Envelope)''"> + Prc8 (Envelope) + </message> + <message name="PRINT_PREVIEW_MEDIA_ROC_16K_7_75X10_75IN" + desc="In Title Case: Media size shown to user in print preview for media ``Roc-16K''"> + Roc-16K + </message> + <message name="PRINT_PREVIEW_MEDIA_ROC_8K_10_75X15_5IN" + desc="In Title Case: Media size shown to user in print preview for media ``Roc-8K''"> + Roc-8K + </message> + </if> +</grit-part>
diff --git a/components/printing/browser/BUILD.gn b/components/printing/browser/BUILD.gn index 9e4b076d..f2298ec 100644 --- a/components/printing/browser/BUILD.gn +++ b/components/printing/browser/BUILD.gn
@@ -2,6 +2,19 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/buildflag_header.gni") + +declare_args() { + # For now, we only enable print media localization on Chrome OS. + enable_print_media_l10n = is_chromeos +} + +buildflag_header("printing_buildflags") { + header = "printing_buildflags.h" + + flags = [ "PRINT_MEDIA_L10N_ENABLED=$enable_print_media_l10n" ] +} + static_library("browser") { sources = [ "features.cc", @@ -17,6 +30,7 @@ ] public_deps = [ + ":printing_buildflags", "//content/public/browser", ] @@ -39,6 +53,13 @@ "printer_capabilities_mac.mm", ] } + + if (enable_print_media_l10n) { + sources += [ + "print_media_l10n.cc", + "print_media_l10n.h", + ] + } } source_set("unit_tests") { @@ -58,4 +79,8 @@ if (is_mac) { sources += [ "printer_capabilities_mac_unittest.mm" ] } + + if (enable_print_media_l10n) { + sources += [ "print_media_l10n_unittest.cc" ] + } }
diff --git a/components/printing/browser/print_media_l10n.cc b/components/printing/browser/print_media_l10n.cc new file mode 100644 index 0000000..ca19d26 --- /dev/null +++ b/components/printing/browser/print_media_l10n.cc
@@ -0,0 +1,206 @@ +// Copyright 2019 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/printing/browser/print_media_l10n.h" + +#include <map> +#include <vector> + +#include "base/logging.h" +#include "base/no_destructor.h" +#include "base/strings/string_piece.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "components/strings/grit/components_strings.h" +#include "ui/base/l10n/l10n_util.h" + +namespace printing { + +namespace { + +// Return the resource ID of a media name specified by |vendor_id| +// if any is found - else return -1. The static map contained here +// is intended to reach all translated media names - see +// print_media_resources.grd. +int VendorIdToTranslatedId(const std::string& vendor_id) { + static const base::NoDestructor<std::map<std::string, int>> media_map({ + {"asme_f_28x40in", PRINT_PREVIEW_MEDIA_ASME_F_28X40IN}, + {"iso_2a0_1189x1682mm", PRINT_PREVIEW_MEDIA_ISO_2A0_1189X1682MM}, + {"iso_a0_841x1189mm", PRINT_PREVIEW_MEDIA_ISO_A0_841X1189MM}, + {"iso_a10_26x37mm", PRINT_PREVIEW_MEDIA_ISO_A10_26X37MM}, + {"iso_a1_594x841mm", PRINT_PREVIEW_MEDIA_ISO_A1_594X841MM}, + {"iso_a2_420x594mm", PRINT_PREVIEW_MEDIA_ISO_A2_420X594MM}, + {"iso_a3_297x420mm", PRINT_PREVIEW_MEDIA_ISO_A3_297X420MM}, + {"iso_a4-extra_235.5x322.3mm", + PRINT_PREVIEW_MEDIA_ISO_A4_EXTRA_235_5X322_3MM}, + {"iso_a4-tab_225x297mm", PRINT_PREVIEW_MEDIA_ISO_A4_TAB_225X297MM}, + {"iso_a4_210x297mm", PRINT_PREVIEW_MEDIA_ISO_A4_210X297MM}, + {"iso_a5-extra_174x235mm", PRINT_PREVIEW_MEDIA_ISO_A5_EXTRA_174X235MM}, + {"iso_a5_148x210mm", PRINT_PREVIEW_MEDIA_ISO_A5_148X210MM}, + {"iso_a6_105x148mm", PRINT_PREVIEW_MEDIA_ISO_A6_105X148MM}, + {"iso_a7_74x105mm", PRINT_PREVIEW_MEDIA_ISO_A7_74X105MM}, + {"iso_a8_52x74mm", PRINT_PREVIEW_MEDIA_ISO_A8_52X74MM}, + {"iso_a9_37x52mm", PRINT_PREVIEW_MEDIA_ISO_A9_37X52MM}, + {"iso_b0_1000x1414mm", PRINT_PREVIEW_MEDIA_ISO_B0_1000X1414MM}, + {"iso_b10_31x44mm", PRINT_PREVIEW_MEDIA_ISO_B10_31X44MM}, + {"iso_b1_707x1000mm", PRINT_PREVIEW_MEDIA_ISO_B1_707X1000MM}, + {"iso_b2_500x707mm", PRINT_PREVIEW_MEDIA_ISO_B2_500X707MM}, + {"iso_b3_353x500mm", PRINT_PREVIEW_MEDIA_ISO_B3_353X500MM}, + {"iso_b4_250x353mm", PRINT_PREVIEW_MEDIA_ISO_B4_250X353MM}, + {"iso_b5-extra_201x276mm", PRINT_PREVIEW_MEDIA_ISO_B5_EXTRA_201X276MM}, + {"iso_b5_176x250mm", PRINT_PREVIEW_MEDIA_ISO_B5_176X250MM}, + {"iso_b6_125x176mm", PRINT_PREVIEW_MEDIA_ISO_B6_125X176MM}, + {"iso_b6c4_125x324mm", PRINT_PREVIEW_MEDIA_ISO_B6C4_125X324MM}, + {"iso_b7_88x125mm", PRINT_PREVIEW_MEDIA_ISO_B7_88X125MM}, + {"iso_b8_62x88mm", PRINT_PREVIEW_MEDIA_ISO_B8_62X88MM}, + {"iso_b9_44x62mm", PRINT_PREVIEW_MEDIA_ISO_B9_44X62MM}, + {"iso_c0_917x1297mm", PRINT_PREVIEW_MEDIA_ISO_C0_917X1297MM}, + {"iso_c10_28x40mm", PRINT_PREVIEW_MEDIA_ISO_C10_28X40MM}, + {"iso_c1_648x917mm", PRINT_PREVIEW_MEDIA_ISO_C1_648X917MM}, + {"iso_c2_458x648mm", PRINT_PREVIEW_MEDIA_ISO_C2_458X648MM}, + {"iso_c3_324x458mm", PRINT_PREVIEW_MEDIA_ISO_C3_324X458MM}, + {"iso_c4_229x324mm", PRINT_PREVIEW_MEDIA_ISO_C4_229X324MM}, + {"iso_c5_162x229mm", PRINT_PREVIEW_MEDIA_ISO_C5_162X229MM}, + {"iso_c6_114x162mm", PRINT_PREVIEW_MEDIA_ISO_C6_114X162MM}, + {"iso_c6c5_114x229mm", PRINT_PREVIEW_MEDIA_ISO_C6C5_114X229MM}, + {"iso_c7_81x114mm", PRINT_PREVIEW_MEDIA_ISO_C7_81X114MM}, + {"iso_c7c6_81x162mm", PRINT_PREVIEW_MEDIA_ISO_C7C6_81X162MM}, + {"iso_c8_57x81mm", PRINT_PREVIEW_MEDIA_ISO_C8_57X81MM}, + {"iso_c9_40x57mm", PRINT_PREVIEW_MEDIA_ISO_C9_40X57MM}, + {"iso_dl_110x220mm", PRINT_PREVIEW_MEDIA_ISO_DL_110X220MM}, + {"jis_exec_216x330mm", PRINT_PREVIEW_MEDIA_JIS_EXEC_216X330MM}, + {"jpn_chou2_111.1x146mm", PRINT_PREVIEW_MEDIA_JPN_CHOU2_111_1X146MM}, + {"jpn_chou3_120x235mm", PRINT_PREVIEW_MEDIA_JPN_CHOU3_120X235MM}, + {"jpn_chou4_90x205mm", PRINT_PREVIEW_MEDIA_JPN_CHOU4_90X205MM}, + {"jpn_hagaki_100x148mm", PRINT_PREVIEW_MEDIA_JPN_HAGAKI_100X148MM}, + {"jpn_kahu_240x322.1mm", PRINT_PREVIEW_MEDIA_JPN_KAHU_240X322_1MM}, + {"jpn_kaku2_240x332mm", PRINT_PREVIEW_MEDIA_JPN_KAKU2_240X332MM}, + {"jpn_oufuku_148x200mm", PRINT_PREVIEW_MEDIA_JPN_OUFUKU_148X200MM}, + {"jpn_you4_105x235mm", PRINT_PREVIEW_MEDIA_JPN_YOU4_105X235MM}, + {"na_10x11_10x11in", PRINT_PREVIEW_MEDIA_NA_10X11_10X11IN}, + {"na_10x13_10x13in", PRINT_PREVIEW_MEDIA_NA_10X13_10X13IN}, + {"na_10x14_10x14in", PRINT_PREVIEW_MEDIA_NA_10X14_10X14IN}, + {"na_10x15_10x15in", PRINT_PREVIEW_MEDIA_NA_10X15_10X15IN}, + {"na_11x12_11x12in", PRINT_PREVIEW_MEDIA_NA_11X12_11X12IN}, + {"na_11x15_11x15in", PRINT_PREVIEW_MEDIA_NA_11X15_11X15IN}, + {"na_12x19_12x19in", PRINT_PREVIEW_MEDIA_NA_12X19_12X19IN}, + {"na_5x7_5x7in", PRINT_PREVIEW_MEDIA_NA_5X7_5X7IN}, + {"na_6x9_6x9in", PRINT_PREVIEW_MEDIA_NA_6X9_6X9IN}, + {"na_7x9_7x9in", PRINT_PREVIEW_MEDIA_NA_7X9_7X9IN}, + {"na_9x11_9x11in", PRINT_PREVIEW_MEDIA_NA_9X11_9X11IN}, + {"na_a2_4.375x5.75in", PRINT_PREVIEW_MEDIA_NA_A2_4_375X5_75IN}, + {"na_arch-a_9x12in", PRINT_PREVIEW_MEDIA_NA_ARCH_A_9X12IN}, + {"na_arch-b_12x18in", PRINT_PREVIEW_MEDIA_NA_ARCH_B_12X18IN}, + {"na_arch-c_18x24in", PRINT_PREVIEW_MEDIA_NA_ARCH_C_18X24IN}, + {"na_arch-d_24x36in", PRINT_PREVIEW_MEDIA_NA_ARCH_D_24X36IN}, + {"na_arch-e_36x48in", PRINT_PREVIEW_MEDIA_NA_ARCH_E_36X48IN}, + {"na_b-plus_12x19.17in", PRINT_PREVIEW_MEDIA_NA_B_PLUS_12X19_17IN}, + {"na_c5_6.5x9.5in", PRINT_PREVIEW_MEDIA_NA_C5_6_5X9_5IN}, + {"na_c_17x22in", PRINT_PREVIEW_MEDIA_NA_C_17X22IN}, + {"na_d_22x34in", PRINT_PREVIEW_MEDIA_NA_D_22X34IN}, + {"na_e_34x44in", PRINT_PREVIEW_MEDIA_NA_E_34X44IN}, + {"na_edp_11x14in", PRINT_PREVIEW_MEDIA_NA_EDP_11X14IN}, + {"na_eur-edp_12x14in", PRINT_PREVIEW_MEDIA_NA_EUR_EDP_12X14IN}, + {"na_f_44x68in", PRINT_PREVIEW_MEDIA_NA_F_44X68IN}, + {"na_fanfold-eur_8.5x12in", PRINT_PREVIEW_MEDIA_NA_FANFOLD_EUR_8_5X12IN}, + {"na_fanfold-us_11x14.875in", + PRINT_PREVIEW_MEDIA_NA_FANFOLD_US_11X14_875IN}, + {"na_foolscap_8.5x13in", PRINT_PREVIEW_MEDIA_NA_FOOLSCAP_8_5X13IN}, + {"na_govt-legal_8x13in", PRINT_PREVIEW_MEDIA_NA_GOVT_LEGAL_8X13IN}, + {"na_govt-letter_8x10in", PRINT_PREVIEW_MEDIA_NA_GOVT_LETTER_8X10IN}, + {"na_index-3x5_3x5in", PRINT_PREVIEW_MEDIA_NA_INDEX_3X5_3X5IN}, + {"na_index-4x6-ext_6x8in", PRINT_PREVIEW_MEDIA_NA_INDEX_4X6_EXT_6X8IN}, + {"na_index-4x6_4x6in", PRINT_PREVIEW_MEDIA_NA_INDEX_4X6_4X6IN}, + {"na_index-5x8_5x8in", PRINT_PREVIEW_MEDIA_NA_INDEX_5X8_5X8IN}, + {"na_invoice_5.5x8.5in", PRINT_PREVIEW_MEDIA_NA_INVOICE_5_5X8_5IN}, + {"na_ledger_11x17in", PRINT_PREVIEW_MEDIA_NA_LEDGER_11X17IN}, + {"na_legal-extra_9.5x15in", PRINT_PREVIEW_MEDIA_NA_LEGAL_EXTRA_9_5X15IN}, + {"na_legal_8.5x14in", PRINT_PREVIEW_MEDIA_NA_LEGAL_8_5X14IN}, + {"na_letter-extra_9.5x12in", + PRINT_PREVIEW_MEDIA_NA_LETTER_EXTRA_9_5X12IN}, + {"na_letter-plus_8.5x12.69in", + PRINT_PREVIEW_MEDIA_NA_LETTER_PLUS_8_5X12_69IN}, + {"na_letter_8.5x11in", PRINT_PREVIEW_MEDIA_NA_LETTER_8_5X11IN}, + {"na_number-10_4.125x9.5in", + PRINT_PREVIEW_MEDIA_NA_NUMBER_10_4_125X9_5IN}, + {"na_number-11_4.5x10.375in", + PRINT_PREVIEW_MEDIA_NA_NUMBER_11_4_5X10_375IN}, + {"na_number-12_4.75x11in", PRINT_PREVIEW_MEDIA_NA_NUMBER_12_4_75X11IN}, + {"na_number-14_5x11.5in", PRINT_PREVIEW_MEDIA_NA_NUMBER_14_5X11_5IN}, + {"na_personal_3.625x6.5in", PRINT_PREVIEW_MEDIA_NA_PERSONAL_3_625X6_5IN}, + {"na_super-a_8.94x14in", PRINT_PREVIEW_MEDIA_NA_SUPER_A_8_94X14IN}, + {"na_super-b_13x19in", PRINT_PREVIEW_MEDIA_NA_SUPER_B_13X19IN}, + {"na_wide-format_30x42in", PRINT_PREVIEW_MEDIA_NA_WIDE_FORMAT_30X42IN}, + {"om_dai-pa-kai_275x395mm", PRINT_PREVIEW_MEDIA_OM_DAI_PA_KAI_275X395MM}, + {"om_folio-sp_215x315mm", PRINT_PREVIEW_MEDIA_OM_FOLIO_SP_215X315MM}, + {"om_invite_220x220mm", PRINT_PREVIEW_MEDIA_OM_INVITE_220X220MM}, + {"om_italian_110x230mm", PRINT_PREVIEW_MEDIA_OM_ITALIAN_110X230MM}, + {"om_juuro-ku-kai_198x275mm", + PRINT_PREVIEW_MEDIA_OM_JUURO_KU_KAI_198X275MM}, + {"om_large-photo_200x300", PRINT_PREVIEW_MEDIA_OM_LARGE_PHOTO_200X300}, + {"om_pa-kai_267x389mm", PRINT_PREVIEW_MEDIA_OM_PA_KAI_267X389MM}, + {"om_postfix_114x229mm", PRINT_PREVIEW_MEDIA_OM_POSTFIX_114X229MM}, + {"om_small-photo_100x150mm", + PRINT_PREVIEW_MEDIA_OM_SMALL_PHOTO_100X150MM}, + {"prc_10_324x458mm", PRINT_PREVIEW_MEDIA_PRC_10_324X458MM}, + {"prc_16k_146x215mm", PRINT_PREVIEW_MEDIA_PRC_16K_146X215MM}, + {"prc_1_102x165mm", PRINT_PREVIEW_MEDIA_PRC_1_102X165MM}, + {"prc_2_102x176mm", PRINT_PREVIEW_MEDIA_PRC_2_102X176MM}, + {"prc_32k_97x151mm", PRINT_PREVIEW_MEDIA_PRC_32K_97X151MM}, + {"prc_3_125x176mm", PRINT_PREVIEW_MEDIA_PRC_3_125X176MM}, + {"prc_4_110x208mm", PRINT_PREVIEW_MEDIA_PRC_4_110X208MM}, + {"prc_5_110x220mm", PRINT_PREVIEW_MEDIA_PRC_5_110X220MM}, + {"prc_6_120x320mm", PRINT_PREVIEW_MEDIA_PRC_6_120X320MM}, + {"prc_7_160x230mm", PRINT_PREVIEW_MEDIA_PRC_7_160X230MM}, + {"prc_8_120x309mm", PRINT_PREVIEW_MEDIA_PRC_8_120X309MM}, + {"roc_16k_7.75x10.75in", PRINT_PREVIEW_MEDIA_ROC_16K_7_75X10_75IN}, + {"roc_8k_10.75x15.5in", PRINT_PREVIEW_MEDIA_ROC_8K_10_75X15_5IN}, + }); + + auto it = media_map->find(vendor_id); + return it != media_map->end() ? it->second : -1; +} + +std::string SplitMediaName(const base::StringPiece& vendor_id) { + // <name>_<width>x<height>{in,mm} + // e.g. na_letter_8.5x11in, iso_a4_210x297mm + std::vector<base::StringPiece> pieces = base::SplitStringPiece( + vendor_id, "_", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + if (pieces.size() < 2) + return std::string(); + + // Append all tokens split out of the vendor ID. The last token is + // usually the <width>x<height> token, so skip it. + pieces.pop_back(); + return base::JoinString(pieces, " "); +} + +} // namespace + +std::string LocalizePaperDisplayName(const std::string& vendor_id) { + std::string localized; + // We can't do anything without a vendor ID. + if (vendor_id.empty()) { + return localized; + } + + int translation_id = VendorIdToTranslatedId(vendor_id); + // If we can't get a localized media name, we do our best to parse it + // on our own. + if (translation_id < 0) { + localized = SplitMediaName(base::StringPiece(vendor_id)); + } else { + localized = l10n_util::GetStringUTF8(translation_id); + } + + // If we still don't have a sane display name, fall back on showing + // the vendor ID. + if (localized.empty()) { + VLOG(1) << "No display name for " << vendor_id; + localized = vendor_id; + } + return localized; +} + +} // namespace printing
diff --git a/components/printing/browser/print_media_l10n.h b/components/printing/browser/print_media_l10n.h new file mode 100644 index 0000000..e012b99 --- /dev/null +++ b/components/printing/browser/print_media_l10n.h
@@ -0,0 +1,17 @@ +// Copyright 2019 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_PRINTING_BROWSER_PRINT_MEDIA_L10N_H_ +#define COMPONENTS_PRINTING_BROWSER_PRINT_MEDIA_L10N_H_ + +#include <string> + +namespace printing { + +// Map a paper vendor ID to a localized name. +std::string LocalizePaperDisplayName(const std::string& vendor_id); + +} // namespace printing + +#endif // COMPONENTS_PRINTING_BROWSER_PRINT_MEDIA_L10N_H_
diff --git a/components/printing/browser/print_media_l10n_unittest.cc b/components/printing/browser/print_media_l10n_unittest.cc new file mode 100644 index 0000000..226d365b --- /dev/null +++ b/components/printing/browser/print_media_l10n_unittest.cc
@@ -0,0 +1,60 @@ +// Copyright 2019 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. + +// This test is only built and run on platforms allowing print media +// localization. + +#include <string> +#include <vector> + +#include "components/printing/browser/print_media_l10n.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace printing { + +// Verify that we localize some common names. +TEST(PrintMediaL10N, LocalizeSomeCommonNames) { + const struct { + const char* vendor_id; + const char* expected_localized_name; + } kTestCases[] = { + {"na_c_17x22in", "Engineering-C"}, + {"iso_a0_841x1189mm", "A0"}, + {"iso_a1_594x841mm", "A1"}, + {"iso_a4_210x297mm", "A4"}, + }; + + for (const auto& test_case : kTestCases) { + EXPECT_EQ(LocalizePaperDisplayName(test_case.vendor_id), + test_case.expected_localized_name); + } +} + +// Verify that we attempt to split and prettify a vendor ID for which +// we don't have a localization. +TEST(PrintMediaL10N, DoWithoutCommonName) { + const struct { + const char* vendor_id; + const char* expected_localized_name; + } kTestCases[] = { + {"lorem_ipsum_8x10in", "lorem ipsum"}, + {"q_e_d_130x200mm", "q e d"}, + }; + + for (const auto& test_case : kTestCases) { + EXPECT_EQ(LocalizePaperDisplayName(test_case.vendor_id), + test_case.expected_localized_name); + } +} + +// Verify that we return the vendor ID itself +// 1. when we don't have a localization and +// 2. when we don't see it split into at least 2 tokens (for name and +// dimensions). +TEST(PrintMediaL10N, FallbackToVendorId) { + const std::string no_dim = "I-BE-NAME-SANS-DIMENSIONS"; + EXPECT_EQ(LocalizePaperDisplayName(no_dim), no_dim); +} + +} // namespace printing
diff --git a/components/printing/browser/printer_capabilities.cc b/components/printing/browser/printer_capabilities.cc index 382db0a..2df1518c 100644 --- a/components/printing/browser/printer_capabilities.cc +++ b/components/printing/browser/printer_capabilities.cc
@@ -15,7 +15,9 @@ #include "base/threading/scoped_blocking_call.h" #include "base/values.h" #include "build/build_config.h" +#include "build/buildflag.h" #include "components/crash/core/common/crash_keys.h" +#include "components/printing/browser/printing_buildflags.h" #include "components/printing/common/cloud_print_cdd_conversion.h" #include "printing/backend/print_backend.h" #include "printing/backend/print_backend_consts.h" @@ -28,12 +30,28 @@ #include "ui/base/l10n/l10n_util.h" #endif +#if BUILDFLAG(PRINT_MEDIA_L10N_ENABLED) +#include "components/printing/browser/print_media_l10n.h" +#endif + namespace printing { const char kPrinter[] = "printer"; namespace { +#if BUILDFLAG(PRINT_MEDIA_L10N_ENABLED) +// Iterate on the Papers of a given printer |info| and set the +// display_name members, localizing where possible. +void PopulateAllPaperDisplayNames(PrinterSemanticCapsAndDefaults* info) { + info->default_paper.display_name = + LocalizePaperDisplayName(info->default_paper.vendor_id); + for (PrinterSemanticCapsAndDefaults::Paper& paper : info->papers) { + paper.display_name = LocalizePaperDisplayName(paper.vendor_id); + } +} +#endif // BUILDFLAG(PRINT_MEDIA_L10N_ENABLED) + // Returns a dictionary representing printer capabilities as CDD. Returns // an empty dictionary if a dictionary could not be generated. base::Value GetPrinterCapabilitiesOnBlockingPoolThread( @@ -61,6 +79,9 @@ return base::Value(base::Value::Type::DICTIONARY); } +#if BUILDFLAG(PRINT_MEDIA_L10N_ENABLED) + PopulateAllPaperDisplayNames(&info); +#endif info.papers.insert(info.papers.end(), additional_papers.begin(), additional_papers.end()); return cloud_print::PrinterSemanticCapsAndDefaultsToCdd(info);
diff --git a/components/safe_browsing/password_protection/password_protection_request.cc b/components/safe_browsing/password_protection/password_protection_request.cc index 1259f57..7402f85 100644 --- a/components/safe_browsing/password_protection/password_protection_request.cc +++ b/components/safe_browsing/password_protection/password_protection_request.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/memory/weak_ptr.h" +#include "base/metrics/histogram_macros.h" #include "base/task/post_task.h" #include "components/data_use_measurement/core/data_use_user_data.h" #include "components/password_manager/core/browser/password_reuse_detector.h" @@ -249,6 +250,8 @@ if (!view) SendRequest(); + visual_feature_start_time_ = base::TimeTicks::Now(); + view->CopyFromSurface( gfx::Rect(), gfx::Size(), base::BindOnce(&PasswordProtectionRequest::OnScreenshotTaken, @@ -271,6 +274,10 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); request_proto_->mutable_visual_features()->Swap(visual_features.get()); + + UMA_HISTOGRAM_TIMES("PasswordProtection.VisualFeatureExtractionDuration", + base::TimeTicks::Now() - visual_feature_start_time_); + SendRequest(); }
diff --git a/components/safe_browsing/password_protection/password_protection_request.h b/components/safe_browsing/password_protection/password_protection_request.h index 8c086f4..ffed9df 100644 --- a/components/safe_browsing/password_protection/password_protection_request.h +++ b/components/safe_browsing/password_protection/password_protection_request.h
@@ -212,6 +212,9 @@ // If a request is sent, this is the token returned by the WebUI. int web_ui_token_; + // When we start extracting visual features. + base::TimeTicks visual_feature_start_time_; + base::WeakPtrFactory<PasswordProtectionRequest> weakptr_factory_; DISALLOW_COPY_AND_ASSIGN(PasswordProtectionRequest); };
diff --git a/components/safe_browsing/proto/csd.proto b/components/safe_browsing/proto/csd.proto index 037366a..9848d83 100644 --- a/components/safe_browsing/proto/csd.proto +++ b/components/safe_browsing/proto/csd.proto
@@ -681,7 +681,12 @@ // protection for Advanced Protection users. optional bool request_ap_verdicts = 67; - // next available tag number: 68; + // For archives files the number of files and directories contained within the + // archive. + optional int32 archive_file_count = 68; + optional int32 archive_directory_count = 69; + + // next available tag number: 70; } message ReferrerChainOptions {
diff --git a/components/safe_browsing/web_ui/safe_browsing_ui.cc b/components/safe_browsing/web_ui/safe_browsing_ui.cc index c38323b9..fdacc28 100644 --- a/components/safe_browsing/web_ui/safe_browsing_ui.cc +++ b/components/safe_browsing/web_ui/safe_browsing_ui.cc
@@ -488,6 +488,9 @@ dict.SetBoolean("request_ap_verdicts", cdr.request_ap_verdicts()); + dict.SetInteger("archive_file_count", cdr.archive_file_count()); + dict.SetInteger("archive_directory_count", cdr.archive_directory_count()); + base::Value* request_tree = &dict; std::string request_serialized; JSONStringValueSerializer serializer(&request_serialized);
diff --git a/components/sync/device_info/device_count_metrics_provider.cc b/components/sync/device_info/device_count_metrics_provider.cc index 3090da1e0..7643d43 100644 --- a/components/sync/device_info/device_count_metrics_provider.cc +++ b/components/sync/device_info/device_count_metrics_provider.cc
@@ -29,7 +29,7 @@ void DeviceCountMetricsProvider::ProvideCurrentSessionData( metrics::ChromeUserMetricsExtension* uma_proto) { - base::UmaHistogramSparse("Sync.DeviceCount", + base::UmaHistogramSparse("Sync.DeviceCount2", std::min(MaxActiveDeviceCount(), 100)); }
diff --git a/components/sync/device_info/device_count_metrics_provider_unittest.cc b/components/sync/device_info/device_count_metrics_provider_unittest.cc index 04ea7e71..26ec1411 100644 --- a/components/sync/device_info/device_count_metrics_provider_unittest.cc +++ b/components/sync/device_info/device_count_metrics_provider_unittest.cc
@@ -59,7 +59,7 @@ void TestProvider(int expected_device_count) { base::HistogramTester histogram_tester; metrics_provider_.ProvideCurrentSessionData(nullptr); - histogram_tester.ExpectUniqueSample("Sync.DeviceCount", + histogram_tester.ExpectUniqueSample("Sync.DeviceCount2", expected_device_count, 1); }
diff --git a/components/sync/device_info/device_info_sync_bridge.cc b/components/sync/device_info/device_info_sync_bridge.cc index 57fe59bf..f28e009 100644 --- a/components/sync/device_info/device_info_sync_bridge.cc +++ b/components/sync/device_info/device_info_sync_bridge.cc
@@ -7,6 +7,7 @@ #include <stdint.h> #include <algorithm> +#include <map> #include <set> #include <utility> @@ -478,11 +479,46 @@ } int DeviceInfoSyncBridge::CountActiveDevices(const Time now) const { - return std::count_if(all_data_.begin(), all_data_.end(), - [now](ClientIdToSpecifics::const_reference pair) { - return DeviceInfoUtil::IsActive( - GetLastUpdateTime(*pair.second), now); - }); + // The algorithm below leverages sync timestamps to give a tight lower bound + // (modulo clock skew) on how many distinct devices are currently active + // (where active means being used recently enough as specified by + // DeviceInfoUtil::kActiveThreshold). + // + // Devices of the same type that have no overlap between their time-of-use are + // likely to be the same device (just with a different cache GUID). Thus, the + // algorithm counts, for each device type separately, the maximum number of + // devices observed concurrently active. Then returns the maximum. + + // The series of relevant events over time, the value being +1 when a device + // was seen for the first time, and -1 when a device was seen last. + std::map<sync_pb::SyncEnums_DeviceType, std::multimap<base::Time, int>> + relevant_events; + + for (const auto& pair : all_data_) { + if (DeviceInfoUtil::IsActive(GetLastUpdateTime(*pair.second), now)) { + base::Time begin = change_processor()->GetEntityCreationTime(pair.first); + base::Time end = + change_processor()->GetEntityModificationTime(pair.first); + DCHECK_LE(begin, end); + relevant_events[pair.second->device_type()].emplace(begin, 1); + relevant_events[pair.second->device_type()].emplace(end, -1); + } + } + + int max_overlapping_sum = 0; + for (const auto& type_and_events : relevant_events) { + int max_overlapping = 0; + int overlapping = 0; + for (const auto& event : type_and_events.second) { + overlapping += event.second; + DCHECK_LE(0, overlapping); + max_overlapping = std::max(max_overlapping, overlapping); + } + DCHECK_EQ(overlapping, 0); + max_overlapping_sum += max_overlapping; + } + + return max_overlapping_sum; } } // namespace syncer
diff --git a/components/sync/device_info/device_info_sync_bridge_unittest.cc b/components/sync/device_info/device_info_sync_bridge_unittest.cc index 79a3900..b856d1f3 100644 --- a/components/sync/device_info/device_info_sync_bridge_unittest.cc +++ b/components/sync/device_info/device_info_sync_bridge_unittest.cc
@@ -12,7 +12,6 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/test/scoped_task_environment.h" -#include "base/timer/timer.h" #include "components/sync/base/time.h" #include "components/sync/device_info/local_device_info_provider_mock.h" #include "components/sync/model/data_batch.h" @@ -37,6 +36,7 @@ using testing::Matcher; using testing::NotNull; using testing::Pair; +using testing::Return; using testing::UnorderedElementsAre; using DeviceInfoList = std::vector<std::unique_ptr<DeviceInfo>>; @@ -178,8 +178,7 @@ provider_(new LocalDeviceInfoProviderMock()) { provider_->Initialize(CreateModel(kDefaultLocalSuffix)); - ON_CALL(*processor(), IsTrackingMetadata()) - .WillByDefault(testing::Return(true)); + ON_CALL(*processor(), IsTrackingMetadata()).WillByDefault(Return(true)); } ~DeviceInfoSyncBridgeTest() override { @@ -675,6 +674,11 @@ InitializeAndPump(); EXPECT_EQ(1, bridge()->CountActiveDevices()); + ON_CALL(*processor(), GetEntityCreationTime(_)) + .WillByDefault(Return(base::Time::Now())); + ON_CALL(*processor(), GetEntityModificationTime(_)) + .WillByDefault(Return(base::Time::Now())); + // Regardless of the time, these following two ApplySyncChanges(...) calls // have the same guid as the local device. bridge()->ApplySyncChanges( @@ -700,6 +704,131 @@ EXPECT_EQ(1, bridge()->CountActiveDevices()); } +TEST_F(DeviceInfoSyncBridgeTest, CountActiveDevicesWithOverlappingTime) { + InitializeAndPump(); + // Local device. + ASSERT_EQ(1, bridge()->CountActiveDevices()); + + const DeviceInfoSpecifics specifics1 = CreateSpecifics(1); + const DeviceInfoSpecifics specifics2 = CreateSpecifics(2); + const DeviceInfoSpecifics specifics3 = CreateSpecifics(3); + + // Time ranges are overlapping. + ON_CALL(*processor(), GetEntityCreationTime(specifics1.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(1))); + ON_CALL(*processor(), GetEntityModificationTime(specifics1.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(3))); + ON_CALL(*processor(), GetEntityCreationTime(specifics2.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(2))); + ON_CALL(*processor(), GetEntityModificationTime(specifics2.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(4))); + ON_CALL(*processor(), GetEntityCreationTime(specifics3.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(2))); + ON_CALL(*processor(), GetEntityModificationTime(specifics3.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(5))); + + // With two devices, the local device gets ignored because it doesn't overlap. + bridge()->ApplySyncChanges(bridge()->CreateMetadataChangeList(), + EntityAddList({specifics1, specifics2})); + + ASSERT_EQ(3u, bridge()->GetAllDeviceInfo().size()); + EXPECT_EQ(2, bridge()->CountActiveDevices()); + + // The third device is also overlapping with the first two (and the local one + // is still excluded). + bridge()->ApplySyncChanges(bridge()->CreateMetadataChangeList(), + EntityAddList({specifics3})); + + ASSERT_EQ(4u, bridge()->GetAllDeviceInfo().size()); + EXPECT_EQ(3, bridge()->CountActiveDevices()); +} + +TEST_F(DeviceInfoSyncBridgeTest, CountActiveDevicesWithNonOverlappingTime) { + InitializeAndPump(); + // Local device. + ASSERT_EQ(1, bridge()->CountActiveDevices()); + + const DeviceInfoSpecifics specifics1 = CreateSpecifics(1); + const DeviceInfoSpecifics specifics2 = CreateSpecifics(2); + const DeviceInfoSpecifics specifics3 = CreateSpecifics(3); + + // Time ranges are non-overlapping. + ON_CALL(*processor(), GetEntityCreationTime(specifics1.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(1))); + ON_CALL(*processor(), GetEntityModificationTime(specifics1.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(2))); + ON_CALL(*processor(), GetEntityCreationTime(specifics2.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(3))); + ON_CALL(*processor(), GetEntityModificationTime(specifics2.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(4))); + ON_CALL(*processor(), GetEntityCreationTime(specifics3.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(5))); + ON_CALL(*processor(), GetEntityModificationTime(specifics3.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(6))); + + bridge()->ApplySyncChanges( + bridge()->CreateMetadataChangeList(), + EntityAddList({specifics1, specifics2, specifics3})); + + ASSERT_EQ(4u, bridge()->GetAllDeviceInfo().size()); + EXPECT_EQ(1, bridge()->CountActiveDevices()); +} + +TEST_F(DeviceInfoSyncBridgeTest, + CountActiveDevicesWithNonOverlappingTimeAndDistictType) { + InitializeAndPump(); + // Local device. + ASSERT_EQ(1, bridge()->CountActiveDevices()); + + DeviceInfoSpecifics specifics1 = CreateSpecifics(1); + DeviceInfoSpecifics specifics2 = CreateSpecifics(2); + DeviceInfoSpecifics specifics3 = CreateSpecifics(3); + // We avoid TYPE_LINUX below to prevent collisions with the local device, + // exposed as Linux by LocalDeviceInfoProviderMock. + specifics1.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_PHONE); + specifics2.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_CROS); + specifics3.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_WIN); + + // Time ranges are non-overlapping. + ON_CALL(*processor(), GetEntityCreationTime(specifics1.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(1))); + ON_CALL(*processor(), GetEntityModificationTime(specifics1.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(2))); + ON_CALL(*processor(), GetEntityCreationTime(specifics2.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(3))); + ON_CALL(*processor(), GetEntityModificationTime(specifics2.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(4))); + ON_CALL(*processor(), GetEntityCreationTime(specifics3.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(5))); + ON_CALL(*processor(), GetEntityModificationTime(specifics3.cache_guid())) + .WillByDefault( + Return(base::Time::UnixEpoch() + base::TimeDelta::FromMinutes(6))); + + bridge()->ApplySyncChanges( + bridge()->CreateMetadataChangeList(), + EntityAddList({specifics1, specifics2, specifics3})); + + ASSERT_EQ(4u, bridge()->GetAllDeviceInfo().size()); + EXPECT_EQ(4, bridge()->CountActiveDevices()); +} + TEST_F(DeviceInfoSyncBridgeTest, MultipleOnProviderInitialized) { EXPECT_CALL(*processor(), ModelReadyToSync(_)).Times(0); set_provider(std::make_unique<LocalDeviceInfoProviderMock>());
diff --git a/components/sync/device_info/device_info_tracker.h b/components/sync/device_info/device_info_tracker.h index b625df8fc..88b39e2a 100644 --- a/components/sync/device_info/device_info_tracker.h +++ b/components/sync/device_info/device_info_tracker.h
@@ -37,7 +37,9 @@ virtual void AddObserver(Observer* observer) = 0; // Unregisters an observer. virtual void RemoveObserver(Observer* observer) = 0; - // Returns the count of active devices. + // Returns the count of active devices. Deduping logic may be used internally + // to prevent double counting for devices that disable sync and reenable it, + // but callers should nevertheless consider this an upper bound. virtual int CountActiveDevices() const = 0; };
diff --git a/components/sync_bookmarks/bookmark_local_changes_builder.cc b/components/sync_bookmarks/bookmark_local_changes_builder.cc index 32940a8..92bda903 100644 --- a/components/sync_bookmarks/bookmark_local_changes_builder.cc +++ b/components/sync_bookmarks/bookmark_local_changes_builder.cc
@@ -10,6 +10,7 @@ #include "base/strings/utf_string_conversions.h" #include "components/bookmarks/browser/bookmark_node.h" #include "components/sync/base/time.h" +#include "components/sync/engine/engine_util.h" #include "components/sync/protocol/bookmark_model_metadata.pb.h" #include "components/sync_bookmarks/bookmark_specifics_conversions.h" #include "components/sync_bookmarks/synced_bookmark_tracker.h" @@ -60,10 +61,13 @@ // 2. Bookmarks (maybe ancient legacy bookmarks only?) use/used |name| to // encode the title. data.is_folder = node->is_folder(); - // TODO(crbug.com/516866): Set the non_unique_name similar to directory - // implementation. - // https://cs.chromium.org/chromium/src/components/sync/syncable/write_node.cc?l=41&rcl=1675007db1e0eb03417e81442688bb11cd181f58 - data.non_unique_name = base::UTF16ToUTF8(node->GetTitle()); + // Adjust the non_unique_name for backward compatibility with legacy + // clients. + std::string new_legal_title; + syncer::SyncAPINameToServerName(base::UTF16ToUTF8(node->GetTitle()), + &new_legal_title); + base::TruncateUTF8ToByteSize(new_legal_title, 255, &new_legal_title); + data.non_unique_name = new_legal_title; data.unique_position = metadata->unique_position(); // Assign specifics only for the non-deletion case. In case of deletion, // EntityData should contain empty specifics to indicate deletion.
diff --git a/components/task_scheduler_util/variations_util.cc b/components/task_scheduler_util/variations_util.cc index cff79ac..d7b3e7a 100644 --- a/components/task_scheduler_util/variations_util.cc +++ b/components/task_scheduler_util/variations_util.cc
@@ -98,23 +98,14 @@ const auto background_worker_pool_params = GetWorkerPoolParams("Background", variation_params); - const auto background_blocking_worker_pool_params = - GetWorkerPoolParams("BackgroundBlocking", variation_params); const auto foreground_worker_pool_params = GetWorkerPoolParams("Foreground", variation_params); - const auto foreground_blocking_worker_pool_params = - GetWorkerPoolParams("ForegroundBlocking", variation_params); - if (!background_worker_pool_params || - !background_blocking_worker_pool_params || - !foreground_worker_pool_params || - !foreground_blocking_worker_pool_params) { + if (!background_worker_pool_params || !foreground_worker_pool_params) return nullptr; - } return std::make_unique<base::TaskScheduler::InitParams>( - *background_worker_pool_params, *background_blocking_worker_pool_params, - *foreground_worker_pool_params, *foreground_blocking_worker_pool_params); + *background_worker_pool_params, *foreground_worker_pool_params); } std::unique_ptr<base::TaskScheduler::InitParams>
diff --git a/components/task_scheduler_util/variations_util_unittest.cc b/components/task_scheduler_util/variations_util_unittest.cc index 7193ca8..d5aaffb 100644 --- a/components/task_scheduler_util/variations_util_unittest.cc +++ b/components/task_scheduler_util/variations_util_unittest.cc
@@ -41,9 +41,7 @@ TEST_F(TaskSchedulerUtilVariationsUtilTest, OrderingParams5) { std::map<std::string, std::string> variation_params; variation_params["Background"] = "1;1;1;0;42"; - variation_params["BackgroundBlocking"] = "2;2;1;0;52"; variation_params["Foreground"] = "4;4;1;0;62"; - variation_params["ForegroundBlocking"] = "8;8;1;0;72"; SetVariationParams(variation_params); auto init_params = GetTaskSchedulerInitParams(kRendererSchedulerInitParams); @@ -57,14 +55,6 @@ base::SchedulerBackwardCompatibility::DISABLED, init_params->background_worker_pool_params.backward_compatibility()); - EXPECT_EQ(2, init_params->background_blocking_worker_pool_params.max_tasks()); - EXPECT_EQ(base::TimeDelta::FromMilliseconds(52), - init_params->background_blocking_worker_pool_params - .suggested_reclaim_time()); - EXPECT_EQ(base::SchedulerBackwardCompatibility::DISABLED, - init_params->background_blocking_worker_pool_params - .backward_compatibility()); - EXPECT_EQ(4, init_params->foreground_worker_pool_params.max_tasks()); EXPECT_EQ( base::TimeDelta::FromMilliseconds(62), @@ -72,14 +62,6 @@ EXPECT_EQ( base::SchedulerBackwardCompatibility::DISABLED, init_params->foreground_worker_pool_params.backward_compatibility()); - - EXPECT_EQ(8, init_params->foreground_blocking_worker_pool_params.max_tasks()); - EXPECT_EQ(base::TimeDelta::FromMilliseconds(72), - init_params->foreground_blocking_worker_pool_params - .suggested_reclaim_time()); - EXPECT_EQ(base::SchedulerBackwardCompatibility::DISABLED, - init_params->foreground_blocking_worker_pool_params - .backward_compatibility()); } TEST_F(TaskSchedulerUtilVariationsUtilTest, NoData) { @@ -89,9 +71,7 @@ TEST_F(TaskSchedulerUtilVariationsUtilTest, IncompleteParameters) { std::map<std::string, std::string> variation_params; variation_params["Background"] = "1;1;1;0"; - variation_params["BackgroundBlocking"] = "2;2;1;0"; variation_params["Foreground"] = "4;4;1;0"; - variation_params["ForegroundBlocking"] = "8;8;1;0"; SetVariationParams(variation_params); EXPECT_FALSE(GetTaskSchedulerInitParams(kRendererSchedulerInitParams)); } @@ -99,9 +79,7 @@ TEST_F(TaskSchedulerUtilVariationsUtilTest, InvalidParametersFormat) { std::map<std::string, std::string> variation_params; variation_params["Background"] = "a;b;c;d;e"; - variation_params["BackgroundBlocking"] = "a;b;c;d;e"; variation_params["Foreground"] = "a;b;c;d;e"; - variation_params["ForegroundBlocking"] = "a;b;c;d;e"; SetVariationParams(variation_params); EXPECT_FALSE(GetTaskSchedulerInitParams(kRendererSchedulerInitParams)); } @@ -111,9 +89,7 @@ // invalid. std::map<std::string, std::string> variation_params; variation_params["Background"] = "0;0;0;0;0"; - variation_params["BackgroundBlocking"] = "2;2;1;0;52"; variation_params["Foreground"] = "4;4;1;0;62"; - variation_params["ForegroundBlocking"] = "8;8;1;0;72"; SetVariationParams(variation_params); EXPECT_FALSE(GetTaskSchedulerInitParams(kRendererSchedulerInitParams)); } @@ -123,9 +99,7 @@ // invalid. std::map<std::string, std::string> variation_params; variation_params["Background"] = "-5;-5;0;0;0"; - variation_params["BackgroundBlocking"] = "2;2;1;0;52"; variation_params["Foreground"] = "4;4;1;0;62"; - variation_params["ForegroundBlocking"] = "8;8;1;0;72"; SetVariationParams(variation_params); EXPECT_FALSE(GetTaskSchedulerInitParams(kRendererSchedulerInitParams)); } @@ -135,9 +109,7 @@ // invalid. std::map<std::string, std::string> variation_params; variation_params["Background"] = "1;1;1;0;-5"; - variation_params["BackgroundBlocking"] = "2;2;1;0;52"; variation_params["Foreground"] = "4;4;1;0;62"; - variation_params["ForegroundBlocking"] = "8;8;1;0;72"; SetVariationParams(variation_params); EXPECT_FALSE(GetTaskSchedulerInitParams(kRendererSchedulerInitParams)); }
diff --git a/components/unified_consent/BUILD.gn b/components/unified_consent/BUILD.gn index 36fd403b..f10f307 100644 --- a/components/unified_consent/BUILD.gn +++ b/components/unified_consent/BUILD.gn
@@ -12,8 +12,6 @@ "unified_consent_metrics.h", "unified_consent_service.cc", "unified_consent_service.h", - "unified_consent_service_client.cc", - "unified_consent_service_client.h", "url_keyed_data_collection_consent_helper.cc", "url_keyed_data_collection_consent_helper.h", ] @@ -21,7 +19,6 @@ "//base", "//components/autofill/core/common", "//components/browser_sync", - "//components/contextual_search/core:browser", "//components/pref_registry", "//components/signin/core/browser", "//components/sync", @@ -58,8 +55,6 @@ ":test_support", ":unified_consent", "//base/test:test_support", - "//components/autofill/core/common", - "//components/contextual_search/core:browser", "//components/sync", "//components/sync:test_support_driver", "//components/sync_preferences:test_support",
diff --git a/components/unified_consent/unified_consent_metrics.cc b/components/unified_consent/unified_consent_metrics.cc index 7bc53b2..45707e86 100644 --- a/components/unified_consent/unified_consent_metrics.cc +++ b/components/unified_consent/unified_consent_metrics.cc
@@ -40,22 +40,6 @@ return true; } -// Checks if a service is enabled and if so, records a sample in the -// SyncAndGoogleServicesSettings histogram. Returns true if a sample was -// recorded. -bool RecordSettingsHistogramFromService( - UnifiedConsentServiceClient* client, - UnifiedConsentServiceClient::Service service, - SettingsHistogramValue value) { - if (client->GetServiceState(service) != - UnifiedConsentServiceClient::ServiceState::kEnabled) { - return false; - } - - RecordSettingsHistogramSample(value); - return true; -} - void RecordSyncDataTypeSample(SyncDataType data_type) { UMA_HISTOGRAM_ENUMERATION( "UnifiedConsent.SyncAndGoogleServicesSettings.AfterAdvancedOptIn." @@ -65,8 +49,7 @@ } // namespace -void RecordSettingsHistogram(UnifiedConsentServiceClient* service_client, - PrefService* pref_service) { +void RecordSettingsHistogram(PrefService* pref_service) { bool metric_recorded = false; metric_recorded |= RecordSettingsHistogramFromPref( @@ -75,14 +58,6 @@ metric_recorded |= RecordSettingsHistogramFromPref( prefs::kUrlKeyedAnonymizedDataCollectionEnabled, pref_service, metrics::SettingsHistogramValue::kUrlKeyedAnonymizedDataCollection); - metric_recorded |= RecordSettingsHistogramFromService( - service_client, - UnifiedConsentServiceClient::Service::kSafeBrowsingExtendedReporting, - metrics::SettingsHistogramValue::kSafeBrowsingExtendedReporting); - metric_recorded |= RecordSettingsHistogramFromService( - service_client, UnifiedConsentServiceClient::Service::kSpellCheck, - metrics::SettingsHistogramValue::kSpellCheck); - if (!metric_recorded) RecordSettingsHistogramSample(metrics::SettingsHistogramValue::kNone); }
diff --git a/components/unified_consent/unified_consent_metrics.h b/components/unified_consent/unified_consent_metrics.h index 9b16c624..7e44105 100644 --- a/components/unified_consent/unified_consent_metrics.h +++ b/components/unified_consent/unified_consent_metrics.h
@@ -5,7 +5,7 @@ #ifndef COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_METRICS_H_ #define COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_METRICS_H_ -#include "components/unified_consent/unified_consent_service_client.h" +class PrefService; namespace syncer { class SyncUserSettings; @@ -51,8 +51,7 @@ // Records settings entries in the SyncAndGoogleServicesSettings. // kNone is recorded when none of the settings is enabled. -void RecordSettingsHistogram(UnifiedConsentServiceClient* service_client, - PrefService* pref_service); +void RecordSettingsHistogram(PrefService* pref_service); // Records the sync data types that were turned off during the advanced sync // opt-in flow. When none of the data types were turned off, kNone is recorded.
diff --git a/components/unified_consent/unified_consent_service.cc b/components/unified_consent/unified_consent_service.cc index 1ccfff8..5792d4d0 100644 --- a/components/unified_consent/unified_consent_service.cc +++ b/components/unified_consent/unified_consent_service.cc
@@ -9,7 +9,6 @@ #include "base/scoped_observer.h" #include "base/threading/sequenced_task_runner_handle.h" #include "build/build_config.h" -#include "components/autofill/core/common/autofill_prefs.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" #include "components/sync/base/model_type.h" @@ -21,15 +20,12 @@ namespace unified_consent { UnifiedConsentService::UnifiedConsentService( - std::unique_ptr<UnifiedConsentServiceClient> service_client, PrefService* pref_service, identity::IdentityManager* identity_manager, syncer::SyncService* sync_service) - : service_client_(std::move(service_client)), - pref_service_(pref_service), + : pref_service_(pref_service), identity_manager_(identity_manager), sync_service_(sync_service) { - DCHECK(service_client_); DCHECK(pref_service_); DCHECK(identity_manager_); DCHECK(sync_service_); @@ -58,10 +54,8 @@ // static void UnifiedConsentService::RollbackIfNeeded( PrefService* user_pref_service, - syncer::SyncService* sync_service, - UnifiedConsentServiceClient* service_client) { + syncer::SyncService* sync_service) { DCHECK(user_pref_service); - DCHECK(service_client); if (user_pref_service->GetInteger(prefs::kUnifiedConsentMigrationState) == static_cast<int>(MigrationState::kNotInitialized)) { @@ -69,16 +63,6 @@ return; } - // Turn off all off-by-default services if services were enabled due to - // unified consent. - if (user_pref_service->GetBoolean( - prefs::kAllUnifiedConsentServicesWereEnabled)) { - service_client->SetServiceEnabled(Service::kSafeBrowsingExtendedReporting, - false); - service_client->SetServiceEnabled(Service::kSpellCheck, false); - service_client->SetServiceEnabled(Service::kContextualSearch, false); - } - // Clear all unified consent prefs. user_pref_service->ClearPref(prefs::kUrlKeyedAnonymizedDataCollectionEnabled); user_pref_service->ClearPref(prefs::kUnifiedConsentMigrationState); @@ -97,14 +81,6 @@ // Enable all Google services except sync. pref_service_->SetBoolean(prefs::kUrlKeyedAnonymizedDataCollectionEnabled, true); - for (int i = 0; i <= static_cast<int>(Service::kLast); ++i) { - Service service = static_cast<Service>(i); - if (service_client_->GetServiceState(service) != - ServiceState::kNotSupported) { - service_client_->SetServiceEnabled(service, true); - } - } - pref_service_->SetBoolean(prefs::kAllUnifiedConsentServicesWereEnabled, true); } @@ -122,11 +98,6 @@ // services. pref_service_->SetBoolean(prefs::kUrlKeyedAnonymizedDataCollectionEnabled, false); - service_client_->SetServiceEnabled(Service::kSafeBrowsingExtendedReporting, - false); - service_client_->SetServiceEnabled(Service::kSpellCheck, false); - service_client_->SetServiceEnabled(Service::kContextualSearch, false); - if (GetMigrationState() != MigrationState::kCompleted) { // When the user signs out, the migration is complete. SetMigrationState(MigrationState::kCompleted);
diff --git a/components/unified_consent/unified_consent_service.h b/components/unified_consent/unified_consent_service.h index 018d032f..fcb60906 100644 --- a/components/unified_consent/unified_consent_service.h +++ b/components/unified_consent/unified_consent_service.h
@@ -13,7 +13,6 @@ #include "components/sync/base/model_type.h" #include "components/sync/driver/sync_service_observer.h" #include "components/unified_consent/unified_consent_metrics.h" -#include "components/unified_consent/unified_consent_service_client.h" #include "services/identity/public/cpp/identity_manager.h" namespace user_prefs { @@ -28,9 +27,6 @@ namespace unified_consent { -using Service = UnifiedConsentServiceClient::Service; -using ServiceState = UnifiedConsentServiceClient::ServiceState; - enum class MigrationState : int { kNotInitialized = 0, kInProgressWaitForSyncInit = 1, @@ -45,7 +41,6 @@ public syncer::SyncServiceObserver { public: UnifiedConsentService( - std::unique_ptr<UnifiedConsentServiceClient> service_client, PrefService* pref_service, identity::IdentityManager* identity_manager, syncer::SyncService* sync_service); @@ -57,8 +52,7 @@ // Rolls back changes made during migration. This method does nothing if the // user hasn't migrated to unified consent yet. static void RollbackIfNeeded(PrefService* user_pref_service, - syncer::SyncService* sync_service, - UnifiedConsentServiceClient* service_client); + syncer::SyncService* sync_service); // Enables all Google services tied to unified consent. // Note: Sync has to be enabled through the SyncService. It is *not* enabled @@ -88,7 +82,6 @@ // |OnStateChanged| when the sync engine is initialized. void UpdateSettingsForMigration(); - std::unique_ptr<UnifiedConsentServiceClient> service_client_; PrefService* pref_service_; identity::IdentityManager* identity_manager_; syncer::SyncService* sync_service_;
diff --git a/components/unified_consent/unified_consent_service_client.cc b/components/unified_consent/unified_consent_service_client.cc deleted file mode 100644 index 87d3771..0000000 --- a/components/unified_consent/unified_consent_service_client.cc +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/unified_consent/unified_consent_service_client.h" - -#include "base/bind.h" - -namespace unified_consent { - -UnifiedConsentServiceClient::UnifiedConsentServiceClient() {} -UnifiedConsentServiceClient::~UnifiedConsentServiceClient() {} - -bool UnifiedConsentServiceClient::IsServiceSupported(Service service) { - return GetServiceState(service) != ServiceState::kNotSupported; -} - -void UnifiedConsentServiceClient::AddObserver(Observer* observer) { - observer_list_.AddObserver(observer); -} - -void UnifiedConsentServiceClient::RemoveObserver(Observer* observer) { - observer_list_.RemoveObserver(observer); -} - -void UnifiedConsentServiceClient::ObserveServicePrefChange( - Service service, - const std::string& pref_name, - PrefService* pref_service) { - service_prefs_[pref_name] = service; - - // First access to the pref registrar of |pref_service| in the map - // automatically creates an entry for it. - PrefChangeRegistrar* pref_change_registrar = - &(pref_change_registrars_[pref_service]); - if (!pref_change_registrar->prefs()) - pref_change_registrar->Init(pref_service); - pref_change_registrar->Add( - pref_name, - base::BindRepeating(&UnifiedConsentServiceClient::OnPrefChanged, - base::Unretained(this))); -} - -void UnifiedConsentServiceClient::FireOnServiceStateChanged(Service service) { - for (auto& observer : observer_list_) - observer.OnServiceStateChanged(service); -} - -void UnifiedConsentServiceClient::OnPrefChanged(const std::string& pref_name) { - DCHECK(service_prefs_.count(pref_name)); - FireOnServiceStateChanged(service_prefs_[pref_name]); -} - -} // namespace unified_consent
diff --git a/components/unified_consent/unified_consent_service_client.h b/components/unified_consent/unified_consent_service_client.h deleted file mode 100644 index 5391429..0000000 --- a/components/unified_consent/unified_consent_service_client.h +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_SERVICE_CLIENT_H_ -#define COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_SERVICE_CLIENT_H_ - -#include <map> -#include <string> - -#include "base/observer_list.h" -#include "components/prefs/pref_change_registrar.h" - -class PrefService; - -namespace unified_consent { - -class UnifiedConsentServiceClient { - public: - enum class Service { - // Extended safe browsing. - kSafeBrowsingExtendedReporting, - // Spell checking. - kSpellCheck, - // Contextual search. - kContextualSearch, - - // Last element of the enum, used for iteration. - kLast = kContextualSearch, - }; - - enum class ServiceState { - // The service is not supported on this platform. - kNotSupported, - // The service is supported, but disabled. - kDisabled, - // The service is enabled. - kEnabled - }; - - class Observer { - public: - // Called when the service state of |service| changes. - virtual void OnServiceStateChanged(Service service) = 0; - }; - - UnifiedConsentServiceClient(); - virtual ~UnifiedConsentServiceClient(); - - // Returns the ServiceState for |service|. - virtual ServiceState GetServiceState(Service service) = 0; - // Sets |service| enabled if it is supported on this platform. - virtual void SetServiceEnabled(Service service, bool enabled) = 0; - - // Returns whether |service| is supported on this platform. - bool IsServiceSupported(Service service); - - // Methods to register or remove observers. - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - - protected: - // This method adds |pref_name| to the list of prefs that will be observed for - // changes. Whenever there's a change in the pref, all - // |UnifiedConsentServiceClient::Observer|s are fired. - void ObserveServicePrefChange(Service service, - const std::string& pref_name, - PrefService* pref_service); - - // Fires |OnServiceStateChanged| on all observers. - void FireOnServiceStateChanged(Service service); - - private: - // Callback for the pref change registrars. - void OnPrefChanged(const std::string& pref_name); - - base::ObserverList<Observer, true>::Unchecked observer_list_; - - // Matches the pref name to it's service. - std::map<std::string, Service> service_prefs_; - // Matches pref service to it's change registrar. - std::map<PrefService*, PrefChangeRegistrar> pref_change_registrars_; - - DISALLOW_COPY_AND_ASSIGN(UnifiedConsentServiceClient); -}; - -} // namespace unified_consent - -#endif // COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_SERVICE_CLIENT_H_
diff --git a/components/unified_consent/unified_consent_service_unittest.cc b/components/unified_consent/unified_consent_service_unittest.cc index 3fe2142..dd3a25f 100644 --- a/components/unified_consent/unified_consent_service_unittest.cc +++ b/components/unified_consent/unified_consent_service_unittest.cc
@@ -11,7 +11,6 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_task_environment.h" #include "build/build_config.h" -#include "components/autofill/core/common/autofill_prefs.h" #include "components/sync/base/sync_prefs.h" #include "components/sync/driver/sync_user_settings.h" #include "components/sync/driver/test_sync_service.h" @@ -19,7 +18,6 @@ #include "components/unified_consent/pref_names.h" #include "components/unified_consent/scoped_unified_consent.h" #include "components/unified_consent/unified_consent_metrics.h" -#include "components/unified_consent/unified_consent_service_client.h" #include "services/identity/public/cpp/identity_test_environment.h" #include "testing/gtest/include/gtest/gtest.h" @@ -45,83 +43,13 @@ DISALLOW_COPY_AND_ASSIGN(TestSyncService); }; -const char kSpellCheckDummyEnabled[] = "spell_check_dummy.enabled"; - -class FakeUnifiedConsentServiceClient : public UnifiedConsentServiceClient { - public: - FakeUnifiedConsentServiceClient(PrefService* pref_service) - : pref_service_(pref_service) { - // When the |kSpellCheckDummyEnabled| pref is changed, all observers should - // be fired. - ObserveServicePrefChange(Service::kSpellCheck, kSpellCheckDummyEnabled, - pref_service); - } - ~FakeUnifiedConsentServiceClient() override = default; - - // UnifiedConsentServiceClient: - ServiceState GetServiceState(Service service) override { - if (is_not_supported_[service]) - return ServiceState::kNotSupported; - bool enabled; - // Special treatment for spell check. - if (service == Service::kSpellCheck) { - enabled = pref_service_->GetBoolean(kSpellCheckDummyEnabled); - } else { - enabled = service_enabled_[service]; - } - return enabled ? ServiceState::kEnabled : ServiceState::kDisabled; - } - void SetServiceEnabled(Service service, bool enabled) override { - if (is_not_supported_[service]) - return; - // Special treatment for spell check. - if (service == Service::kSpellCheck) { - pref_service_->SetBoolean(kSpellCheckDummyEnabled, enabled); - return; - } - bool should_notify_observers = service_enabled_[service] != enabled; - service_enabled_[service] = enabled; - if (should_notify_observers) - FireOnServiceStateChanged(service); - } - - void SetServiceNotSupported(Service service) { - is_not_supported_[service] = true; - } - - static void ClearServiceStates() { - service_enabled_.clear(); - is_not_supported_.clear(); - } - - private: - // Service states are shared between multiple instances of this class. - static std::map<Service, bool> service_enabled_; - static std::map<Service, bool> is_not_supported_; - - PrefService* pref_service_; - - DISALLOW_COPY_AND_ASSIGN(FakeUnifiedConsentServiceClient); -}; - -std::map<Service, bool> FakeUnifiedConsentServiceClient::service_enabled_; -std::map<Service, bool> FakeUnifiedConsentServiceClient::is_not_supported_; - } // namespace class UnifiedConsentServiceTest : public testing::Test { public: UnifiedConsentServiceTest() { - pref_service_.registry()->RegisterBooleanPref( - autofill::prefs::kAutofillWalletImportEnabled, false); UnifiedConsentService::RegisterPrefs(pref_service_.registry()); syncer::SyncPrefs::RegisterProfilePrefs(pref_service_.registry()); - pref_service_.registry()->RegisterBooleanPref(kSpellCheckDummyEnabled, - false); - - FakeUnifiedConsentServiceClient::ClearServiceStates(); - service_client_ = - std::make_unique<FakeUnifiedConsentServiceClient>(&pref_service_); } ~UnifiedConsentServiceTest() override { @@ -129,25 +57,15 @@ consent_service_->Shutdown(); } - void CreateConsentService(bool client_services_on_by_default = false) { + void CreateConsentService() { if (!scoped_unified_consent_) { SetUnifiedConsentFeatureState( unified_consent::UnifiedConsentFeatureState::kEnabled); } - auto client = - std::make_unique<FakeUnifiedConsentServiceClient>(&pref_service_); - if (client_services_on_by_default) { - for (int i = 0; i <= static_cast<int>(Service::kLast); ++i) { - Service service = static_cast<Service>(i); - client->SetServiceEnabled(service, true); - } - pref_service_.SetBoolean(prefs::kUrlKeyedAnonymizedDataCollectionEnabled, - true); - } consent_service_ = std::make_unique<UnifiedConsentService>( - std::move(client), &pref_service_, - identity_test_environment_.identity_manager(), &sync_service_); + &pref_service_, identity_test_environment_.identity_manager(), + &sync_service_); sync_service_.FireStateChanged(); // Run until idle so the migration can finish. @@ -165,16 +83,8 @@ } bool AreAllGoogleServicesEnabled() { - for (int i = 0; i <= static_cast<int>(Service::kLast); ++i) { - Service service = static_cast<Service>(i); - if (service_client_->GetServiceState(service) == ServiceState::kDisabled) - return false; - } - if (!pref_service_.GetBoolean( - prefs::kUrlKeyedAnonymizedDataCollectionEnabled)) - return false; - - return true; + return pref_service_.GetBoolean( + prefs::kUrlKeyedAnonymizedDataCollectionEnabled); } unified_consent::MigrationState GetMigrationState() { @@ -189,8 +99,6 @@ identity::IdentityTestEnvironment identity_test_environment_; TestSyncService sync_service_; std::unique_ptr<UnifiedConsentService> consent_service_; - std::unique_ptr<FakeUnifiedConsentServiceClient> service_client_; - std::unique_ptr<ScopedUnifiedConsent> scoped_unified_consent_; DISALLOW_COPY_AND_ASSIGN(UnifiedConsentServiceTest); @@ -219,9 +127,6 @@ identity_test_environment_.SetPrimaryAccount("testaccount"); EXPECT_FALSE(pref_service_.GetBoolean( prefs::kUrlKeyedAnonymizedDataCollectionEnabled)); - service_client_->SetServiceNotSupported(Service::kSpellCheck); - EXPECT_EQ(service_client_->GetServiceState(Service::kSpellCheck), - ServiceState::kNotSupported); EXPECT_FALSE(AreAllGoogleServicesEnabled()); // Enable services and check expectations. @@ -263,13 +168,6 @@ EXPECT_FALSE(AreAllGoogleServicesEnabled()); EXPECT_FALSE(pref_service_.GetBoolean( prefs::kUrlKeyedAnonymizedDataCollectionEnabled)); - EXPECT_EQ(service_client_->GetServiceState(Service::kSpellCheck), - ServiceState::kDisabled); - EXPECT_EQ( - service_client_->GetServiceState(Service::kSafeBrowsingExtendedReporting), - ServiceState::kDisabled); - EXPECT_EQ(service_client_->GetServiceState(Service::kContextualSearch), - ServiceState::kDisabled); } TEST_F(UnifiedConsentServiceTest, Migration_NotSignedIn) { @@ -299,20 +197,11 @@ SetUnifiedConsentFeatureState(UnifiedConsentFeatureState::kDisabled); // Rollback - UnifiedConsentService::RollbackIfNeeded(&pref_service_, &sync_service_, - service_client_.get()); + UnifiedConsentService::RollbackIfNeeded(&pref_service_, &sync_service_); // Unified consent prefs should be cleared. EXPECT_EQ(unified_consent::MigrationState::kNotInitialized, GetMigrationState()); - // Off-by-default services should be turned off. - EXPECT_NE(ServiceState::kEnabled, - service_client_->GetServiceState( - Service::kSafeBrowsingExtendedReporting)); - EXPECT_NE(ServiceState::kEnabled, - service_client_->GetServiceState(Service::kSpellCheck)); - EXPECT_NE(ServiceState::kEnabled, - service_client_->GetServiceState(Service::kContextualSearch)); } } // namespace unified_consent
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 9bcbb0a..46d8b92c 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1288,6 +1288,8 @@ "permissions/permission_service_impl.h", "picture_in_picture/overlay_surface_embedder.cc", "picture_in_picture/overlay_surface_embedder.h", + "picture_in_picture/picture_in_picture_service_impl.cc", + "picture_in_picture/picture_in_picture_service_impl.h", "picture_in_picture/picture_in_picture_window_controller_impl.cc", "picture_in_picture/picture_in_picture_window_controller_impl.h", "portal/portal.cc",
diff --git a/content/browser/DEPS b/content/browser/DEPS index cbadf36..7b0078f3 100644 --- a/content/browser/DEPS +++ b/content/browser/DEPS
@@ -116,7 +116,6 @@ "+third_party/blink/public/web/web_device_emulation_params.h", "+third_party/blink/public/web/web_drag_status.h", "+third_party/blink/public/web/web_fullscreen_options.h", - "+third_party/blink/public/web/web_frame_serializer_cache_control_policy.h", "+third_party/blink/public/web/web_ime_text_span.h", "+third_party/blink/public/web/web_media_player_action.h", "+third_party/blink/public/web/web_plugin_action.h",
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc index 5065ad60..7cb40422 100644 --- a/content/browser/accessibility/browser_accessibility_manager_android.cc +++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -197,6 +197,7 @@ } break; case ui::AXEventGenerator::Event::ACTIVE_DESCENDANT_CHANGED: + case ui::AXEventGenerator::Event::AUTO_COMPLETE_CHANGED: case ui::AXEventGenerator::Event::CHILDREN_CHANGED: case ui::AXEventGenerator::Event::COLLAPSED: case ui::AXEventGenerator::Event::DESCRIPTION_CHANGED:
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm index 242a86dd..ab88c41 100644 --- a/content/browser/accessibility/browser_accessibility_manager_mac.mm +++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -375,6 +375,7 @@ case ui::AXEventGenerator::Event::MENU_ITEM_SELECTED: mac_notification = NSAccessibilityMenuItemSelectedNotification; break; + case ui::AXEventGenerator::Event::AUTO_COMPLETE_CHANGED: case ui::AXEventGenerator::Event::CHILDREN_CHANGED: case ui::AXEventGenerator::Event::DESCRIPTION_CHANGED: case ui::AXEventGenerator::Event::DOCUMENT_TITLE_CHANGED:
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc index 75d206d..647c9bd 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.cc +++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -166,6 +166,7 @@ FireWinAccessibilityEvent(IA2_EVENT_TEXT_CARET_MOVED, focus_object); break; } + case ui::AXEventGenerator::Event::AUTO_COMPLETE_CHANGED: case ui::AXEventGenerator::Event::CHECKED_STATE_CHANGED: case ui::AXEventGenerator::Event::COLLAPSED: case ui::AXEventGenerator::Event::DESCRIPTION_CHANGED:
diff --git a/content/browser/code_cache/generated_code_cache.cc b/content/browser/code_cache/generated_code_cache.cc index 2e56de9..733bf67 100644 --- a/content/browser/code_cache/generated_code_cache.cc +++ b/content/browser/code_cache/generated_code_cache.cc
@@ -422,6 +422,11 @@ } void GeneratedCodeCache::WriteDataCompleted(const std::string& key, int rv) { + if (rv < 0) { + CollectStatistics(CacheEntryStatus::kWriteFailed); + // The write failed; we should delete the entry. + DeleteEntryImpl(key); + } IssueQueuedOperationForEntry(key); } @@ -490,17 +495,18 @@ } else { // DiskCache ensures that the operations that are queued for an entry // go in order. Hence, we would either read an empty data or read the full - // data. + // data. Note that if WriteData failed, buffer->size() is 0 so we handle + // that case here. CollectStatistics(CacheEntryStatus::kHit); - DCHECK_GE(buffer->size(), kResponseTimeSizeInBytes); - int64_t raw_response_time = *(reinterpret_cast<int64_t*>(buffer->data())); - base::Time response_time = base::Time::FromDeltaSinceWindowsEpoch( - base::TimeDelta::FromMicroseconds(raw_response_time)); + int64_t raw_response_time = 0; std::vector<uint8_t> data; - if (buffer->size() > kResponseTimeSizeInBytes) { + if (buffer->size() >= kResponseTimeSizeInBytes) { + raw_response_time = *(reinterpret_cast<int64_t*>(buffer->data())); data = std::vector<uint8_t>(buffer->data() + kResponseTimeSizeInBytes, buffer->data() + buffer->size()); } + base::Time response_time = base::Time::FromDeltaSinceWindowsEpoch( + base::TimeDelta::FromMicroseconds(raw_response_time)); std::move(callback).Run(response_time, data); } IssueQueuedOperationForEntry(key);
diff --git a/content/browser/code_cache/generated_code_cache.h b/content/browser/code_cache/generated_code_cache.h index 989534b..a91e888 100644 --- a/content/browser/code_cache/generated_code_cache.h +++ b/content/browser/code_cache/generated_code_cache.h
@@ -61,7 +61,8 @@ kCreate, kError, kIncompleteEntry, - kMaxValue = kIncompleteEntry + kWriteFailed, + kMaxValue = kWriteFailed }; // Returns the resource URL from the key. The key has the format prefix +
diff --git a/content/browser/code_cache/generated_code_cache_unittest.cc b/content/browser/code_cache/generated_code_cache_unittest.cc index 0d61bdd..41cddee 100644 --- a/content/browser/code_cache/generated_code_cache_unittest.cc +++ b/content/browser/code_cache/generated_code_cache_unittest.cc
@@ -181,6 +181,24 @@ EXPECT_EQ(response_time, received_response_time_); } +TEST_F(GeneratedCodeCacheTest, WriteEntryFailure) { + GURL url(kInitialUrl); + GURL origin_lock = GURL(kInitialOrigin); + + InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript); + base::Time response_time = base::Time::Now(); + std::string too_big_data(kMaxSizeInBytes * 8, 0); + WriteToCache(url, origin_lock, too_big_data, response_time); + scoped_task_environment_.RunUntilIdle(); + FetchFromCache(url, origin_lock); + scoped_task_environment_.RunUntilIdle(); + + // Fetch should return empty data, with invalid response time. + ASSERT_TRUE(received_); + ASSERT_TRUE(received_null_); + EXPECT_EQ(base::Time(), received_response_time_); +} + TEST_F(GeneratedCodeCacheTest, FetchEntryPendingOp) { GURL url(kInitialUrl); GURL origin_lock = GURL(kInitialOrigin);
diff --git a/content/browser/download/mhtml_generation_browsertest.cc b/content/browser/download/mhtml_generation_browsertest.cc index 2914f58..0c6d9bd45 100644 --- a/content/browser/download/mhtml_generation_browsertest.cc +++ b/content/browser/download/mhtml_generation_browsertest.cc
@@ -37,7 +37,6 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/frame/find_in_page.mojom.h" -#include "third_party/blink/public/web/web_frame_serializer_cache_control_policy.h" using testing::ContainsRegex; using testing::HasSubstr; @@ -476,26 +475,21 @@ // TODO(crbug.com/615291): These fail on Android under some circumstances. #if defined(OS_ANDROID) -#define MAYBE_ViewedMHTMLContainsNoStoreContentIfNoCacheControlPolicy \ - DISABLED_ViewedMHTMLContainsNoStoreContentIfNoCacheControlPolicy -#define MAYBE_ViewedMHTMLDoesNotContainNoStoreContent \ - DISABLED_ViewedMHTMLDoesNotContainNoStoreContent +#define MAYBE_ViewedMHTMLContainsNoStoreContent \ + DISABLED_ViewedMHTMLContainsNoStoreContent #else -#define MAYBE_ViewedMHTMLContainsNoStoreContentIfNoCacheControlPolicy \ - ViewedMHTMLContainsNoStoreContentIfNoCacheControlPolicy -#define MAYBE_ViewedMHTMLDoesNotContainNoStoreContent \ - ViewedMHTMLDoesNotContainNoStoreContent +#define MAYBE_ViewedMHTMLContainsNoStoreContent \ + ViewedMHTMLContainsNoStoreContent #endif -IN_PROC_BROWSER_TEST_F( - MHTMLGenerationTest, - MAYBE_ViewedMHTMLContainsNoStoreContentIfNoCacheControlPolicy) { - // Generate MHTML, specifying the FailForNoStoreMainFrame policy. +IN_PROC_BROWSER_TEST_F(MHTMLGenerationTest, + MAYBE_ViewedMHTMLContainsNoStoreContent) { + // Generate MHTML. base::FilePath path(temp_dir_.GetPath()); path = path.Append(FILE_PATH_LITERAL("test.mht")); MHTMLGenerationParams params(path); - // No special cache control options so we should see both frames. + // We should see both frames. std::vector<std::string> expectations = { "Main Frame, normal headers.", "Cache-Control: no-store test body", }; @@ -503,12 +497,6 @@ TestOriginalVsSavedPage( embedded_test_server()->GetURL("/page_with_nostore_iframe.html"), params, 2 /* expected number of frames */, expectations, forbidden); - - std::string mhtml; - { - base::ScopedAllowBlockingForTesting allow_blocking; - ASSERT_TRUE(base::ReadFileToString(params.file_path, &mhtml)); - } } // Test suite that allows testing --site-per-process against cross-site frames.
diff --git a/content/browser/download/mhtml_generation_manager.cc b/content/browser/download/mhtml_generation_manager.cc index d619c36..61d87ed 100644 --- a/content/browser/download/mhtml_generation_manager.cc +++ b/content/browser/download/mhtml_generation_manager.cc
@@ -141,8 +141,7 @@ base::TimeDelta longest_renderer_main_thread_time_; // User-configurable parameters. Includes the file location, binary encoding - // choices, and whether to skip storing resources marked - // Cache-Control: no-store. + // choices. MHTMLGenerationParams params_; // The IDs of frames that still need to be processed.
diff --git a/content/browser/frame_host/navigator_impl_unittest.cc b/content/browser/frame_host/navigator_impl_unittest.cc index 80de540b..cc26ba06 100644 --- a/content/browser/frame_host/navigator_impl_unittest.cc +++ b/content/browser/frame_host/navigator_impl_unittest.cc
@@ -59,19 +59,6 @@ return static_cast<TestNavigationURLLoader*>(request->loader_for_testing()); } - // Requests a navigation of the specified FrameTreeNode to the specified URL. - // Returns the unique ID of the pending NavigationEntry. - // TODO(ahemery): Convert this usage to NavigationSimulator. - int RequestNavigation(FrameTreeNode* node, const GURL& url) { - NavigationController::LoadURLParams load_url_params(url); - load_url_params.frame_tree_node_id = node->frame_tree_node_id(); - load_url_params.referrer = Referrer(); - load_url_params.transition_type = ui::PAGE_TRANSITION_LINK; - - controller().LoadURLWithParams(load_url_params); - return controller().GetPendingEntry()->GetUniqueID(); - } - TestRenderFrameHost* GetSpeculativeRenderFrameHost(FrameTreeNode* node) { return static_cast<TestRenderFrameHost*>( node->render_manager()->speculative_render_frame_host_.get()); @@ -245,7 +232,9 @@ // Start a new navigation. FrameTreeNode* node = main_test_rfh()->frame_tree_node(); - RequestNavigation(node, kUrl2); + auto navigation = + NavigationSimulatorImpl::CreateBrowserInitiated(kUrl2, contents()); + navigation->BrowserInitiatedStartAndWaitBeforeUnload(); NavigationRequest* request = node->navigation_request(); ASSERT_TRUE(request); EXPECT_TRUE(request->browser_initiated()); @@ -261,8 +250,7 @@ EXPECT_TRUE(rfh_deleted_observer.deleted()); } -// PlzNavigate: Test that a proper NavigationRequest is created by -// RequestNavigation. +// Test that a proper NavigationRequest is created at navigation start. TEST_F(NavigatorTestWithBrowserSideNavigation, BeginNavigation) { const GURL kUrl1("http://www.google.com/"); const GURL kUrl2("http://www.chromium.org/"); @@ -277,7 +265,12 @@ // Start a navigation at the subframe. FrameTreeNode* subframe_node = subframe_rfh->frame_tree_node(); - RequestNavigation(subframe_node, kUrl2); + auto navigation = + NavigationSimulatorImpl::CreateBrowserInitiated(kUrl2, contents()); + NavigationController::LoadURLParams load_url_params(kUrl2); + load_url_params.frame_tree_node_id = subframe_node->frame_tree_node_id(); + navigation->SetLoadURLParams(&load_url_params); + navigation->BrowserInitiatedStartAndWaitBeforeUnload(); NavigationRequest* subframe_request = subframe_node->navigation_request(); // We should be waiting for the BeforeUnload event to execute in the subframe. @@ -286,8 +279,9 @@ subframe_request->state()); EXPECT_TRUE(subframe_rfh->is_waiting_for_beforeunload_ack()); - // Simulate the BeforeUnload ACK. The navigation should start. - subframe_rfh->SendBeforeUnloadACK(true); + // Start the navigation, which will internally simulate that the beforeUnload + // ACK has been received. + navigation->Start(); TestNavigationURLLoader* subframe_loader = GetLoaderForNavigationRequest(subframe_request); ASSERT_TRUE(subframe_loader); @@ -313,7 +307,9 @@ } // Now start a navigation at the root node. - RequestNavigation(root_node, kUrl3); + auto navigation2 = + NavigationSimulatorImpl::CreateBrowserInitiated(kUrl3, contents()); + navigation2->BrowserInitiatedStartAndWaitBeforeUnload(); NavigationRequest* main_request = root_node->navigation_request(); ASSERT_TRUE(main_request); EXPECT_EQ(NavigationRequest::WAITING_FOR_RENDERER_RESPONSE, @@ -323,8 +319,9 @@ // RenderFrameHost. EXPECT_TRUE(GetSpeculativeRenderFrameHost(root_node)); - // Simulate a BeforeUnloadACK IPC on the main frame. - main_test_rfh()->SendBeforeUnloadACK(true); + // Start the navigation, which will internally simulate that the beforeUnload + // ACK has been received. + navigation2->Start(); TestNavigationURLLoader* main_loader = GetLoaderForNavigationRequest(main_request); EXPECT_EQ(kUrl3, main_request->common_params().url); @@ -359,8 +356,9 @@ // Navigate to a different site. EXPECT_FALSE(main_test_rfh()->navigation_request()); - RequestNavigation(node, kUrl2); - main_test_rfh()->SendBeforeUnloadACK(true); + auto navigation = + NavigationSimulator::CreateBrowserInitiated(kUrl2, contents()); + navigation->Start(); NavigationRequest* main_request = node->navigation_request(); ASSERT_TRUE(main_request); @@ -387,8 +385,9 @@ // Navigate to a different site again. EXPECT_FALSE(main_test_rfh()->navigation_request()); - RequestNavigation(node, kUrl2); - main_test_rfh()->SendBeforeUnloadACK(true); + auto navigation2 = + NavigationSimulator::CreateBrowserInitiated(kUrl2, contents()); + navigation2->Start(); main_request = node->navigation_request(); ASSERT_TRUE(main_request); @@ -570,8 +569,9 @@ // Start a browser-initiated navigation to the 1st URL and receive its // beforeUnload ACK. EXPECT_FALSE(main_test_rfh()->navigation_request()); - RequestNavigation(node, kUrl1); - main_test_rfh()->SendBeforeUnloadACK(true); + auto navigation2 = + NavigationSimulator::CreateBrowserInitiated(kUrl1, contents()); + navigation2->Start(); NavigationRequest* request1 = node->navigation_request(); ASSERT_TRUE(request1); EXPECT_EQ(kUrl1, request1->common_params().url); @@ -923,16 +923,18 @@ // Navigate to a data url. The request should have been sent to the IO // thread and not committed immediately. - int entry_id = RequestNavigation(node, kUrl2); + auto navigation = + NavigationSimulator::CreateBrowserInitiated(kUrl2, contents()); + navigation->Start(); TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node); ASSERT_TRUE(speculative_rfh); EXPECT_FALSE(speculative_rfh->is_loading()); EXPECT_TRUE(node->navigation_request()); - speculative_rfh->PrepareForCommit(); + navigation->ReadyToCommit(); EXPECT_TRUE(speculative_rfh->is_loading()); EXPECT_FALSE(node->navigation_request()); EXPECT_NE(main_test_rfh(), speculative_rfh); - speculative_rfh->SendNavigate(entry_id, true, kUrl2); + navigation->Commit(); EXPECT_EQ(main_test_rfh(), speculative_rfh); // Go back to the initial site. @@ -1110,22 +1112,25 @@ FrameTreeNode* node = main_test_rfh()->frame_tree_node(); // Navigate same-site. - int entry_id = RequestNavigation(node, kUrl2); - main_test_rfh()->PrepareForCommit(); + auto navigation = + NavigationSimulator::CreateBrowserInitiated(kUrl2, contents()); + navigation->ReadyToCommit(); EXPECT_TRUE(main_test_rfh()->is_loading()); EXPECT_FALSE(node->navigation_request()); // Start a new cross-site navigation. The current RFH should still be trying // to commit the previous navigation, but we create a NavigationRequest in the // FrameTreeNode. - RequestNavigation(node, kUrl3); + auto navigation2 = + NavigationSimulator::CreateBrowserInitiated(kUrl3, contents()); + navigation2->Start(); EXPECT_TRUE(main_test_rfh()->is_loading()); EXPECT_TRUE(node->navigation_request()); EXPECT_TRUE(GetSpeculativeRenderFrameHost(node)); // The first navigation commits. This should clear up the speculative RFH and // the ongoing NavigationRequest. - main_test_rfh()->SendNavigate(entry_id, true, kUrl2); + navigation->Commit(); EXPECT_FALSE(node->navigation_request()); EXPECT_FALSE(GetSpeculativeRenderFrameHost(node)); } @@ -1142,8 +1147,9 @@ FrameTreeNode* node = main_test_rfh()->frame_tree_node(); // Navigate cross-site. - int entry_id = RequestNavigation(node, kUrl2); - main_test_rfh()->PrepareForCommit(); + auto navigation = + NavigationSimulator::CreateBrowserInitiated(kUrl2, contents()); + navigation->ReadyToCommit(); TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node); ASSERT_TRUE(speculative_rfh); EXPECT_TRUE(speculative_rfh->is_loading()); @@ -1153,7 +1159,9 @@ // navigation. The speculative RFH should still be live and trying // to commit the previous navigation, and we create a NavigationRequest in the // FrameTreeNode. - RequestNavigation(node, kUrl3); + auto navigation2 = + NavigationSimulator::CreateBrowserInitiated(kUrl3, contents()); + navigation2->Start(); TestRenderFrameHost* speculative_rfh_2 = GetSpeculativeRenderFrameHost(node); ASSERT_TRUE(speculative_rfh_2); EXPECT_EQ(speculative_rfh_2, speculative_rfh); @@ -1162,7 +1170,7 @@ // The first navigation commits. This should clear up the speculative RFH and // the ongoing NavigationRequest. - speculative_rfh->SendNavigate(entry_id, true, kUrl2); + navigation->Commit(); EXPECT_FALSE(node->navigation_request()); EXPECT_FALSE(GetSpeculativeRenderFrameHost(node)); EXPECT_EQ(speculative_rfh, main_test_rfh());
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 16c5873..62c0957 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -73,6 +73,7 @@ #include "content/browser/permissions/permission_controller_impl.h" #include "content/browser/permissions/permission_service_context.h" #include "content/browser/permissions/permission_service_impl.h" +#include "content/browser/picture_in_picture/picture_in_picture_service_impl.h" #include "content/browser/portal/portal.h" #include "content/browser/presentation/presentation_service_impl.h" #include "content/browser/quota_dispatcher_host.h" @@ -4083,6 +4084,9 @@ registry_->AddInterface(base::BindRepeating(&WakeLockServiceImpl::Create, base::Unretained(this))); + + registry_->AddInterface(base::BindRepeating( + &PictureInPictureServiceImpl::Create, base::Unretained(this))); } void RenderFrameHostImpl::ResetWaitingState() {
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index a6d373e19..b39aa13 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -252,7 +252,6 @@ switches::kUseCmdDecoder, switches::kForceVideoOverlays, #if defined(OS_ANDROID) - switches::kEnableReachedCodeProfiler, switches::kOrderfileMemoryOptimization, #endif switches::kWebglAntialiasingMode,
diff --git a/content/browser/media/media_web_contents_observer.cc b/content/browser/media/media_web_contents_observer.cc index 6e29f3c..740bdc6 100644 --- a/content/browser/media/media_web_contents_observer.cc +++ b/content/browser/media/media_web_contents_observer.cc
@@ -77,11 +77,6 @@ picture_in_picture_allowed_in_fullscreen_.reset(); fullscreen_player_.reset(); } - - // Usually the frame will exit PIP before it is deleted but for OOPIF, it - // seems that the player never notifies the browser process. - if (pip_player_ && pip_player_->render_frame_host == render_frame_host) - ExitPictureInPictureInternal(); } void MediaWebContentsObserver::MaybeUpdateAudibleState() { @@ -120,15 +115,6 @@ return fullscreen_player_; } -const base::Optional<WebContentsObserver::MediaPlayerId>& -MediaWebContentsObserver::GetPictureInPictureVideoMediaPlayerId() const { - return pip_player_; -} - -void MediaWebContentsObserver::ResetPictureInPictureVideoMediaPlayerId() { - pip_player_.reset(); -} - bool MediaWebContentsObserver::OnMessageReceived( const IPC::Message& msg, RenderFrameHost* render_frame_host) { @@ -148,16 +134,8 @@ IPC_MESSAGE_HANDLER(MediaPlayerDelegateHostMsg_OnMediaSizeChanged, OnMediaSizeChanged) IPC_MESSAGE_HANDLER( - MediaPlayerDelegateHostMsg_OnPictureInPictureModeStarted, - OnPictureInPictureModeStarted) - IPC_MESSAGE_HANDLER(MediaPlayerDelegateHostMsg_OnPictureInPictureModeEnded, - OnPictureInPictureModeEnded) - IPC_MESSAGE_HANDLER( MediaPlayerDelegateHostMsg_OnSetPictureInPictureCustomControls, OnSetPictureInPictureCustomControls) - IPC_MESSAGE_HANDLER( - MediaPlayerDelegateHostMsg_OnPictureInPictureSurfaceChanged, - OnPictureInPictureSurfaceChanged) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -187,16 +165,6 @@ return MediaPlayerEntryExists(player_id, active_audio_players_); } -void MediaWebContentsObserver::OnPictureInPictureWindowResize( - const gfx::Size& window_size) { - DCHECK(pip_player_.has_value()); - - pip_player_->render_frame_host->Send( - new MediaPlayerDelegateMsg_OnPictureInPictureWindowResize( - pip_player_->render_frame_host->GetRoutingID(), - pip_player_->delegate_id, window_size)); -} - void MediaWebContentsObserver::OnMediaDestroyed( RenderFrameHost* render_frame_host, int delegate_id) { @@ -212,16 +180,6 @@ const bool removed_video = RemoveMediaPlayerEntry(player_id, &active_video_players_); - if (!web_contents()->IsBeingDestroyed() && pip_player_ == player_id) { - PictureInPictureWindowControllerImpl* pip_controller = - PictureInPictureWindowControllerImpl::FromWebContents( - web_contents_impl()); - if (pip_controller) { - pip_controller->UpdatePlaybackState(false /* is not playing */, - reached_end_of_stream); - } - } - if (removed_audio || removed_video) { // Notify observers the player has been "paused". web_contents_impl()->MediaStoppedPlaying( @@ -263,16 +221,6 @@ return; } - if (!web_contents()->IsBeingDestroyed() && pip_player_ == id) { - PictureInPictureWindowControllerImpl* pip_controller = - PictureInPictureWindowControllerImpl::FromWebContents( - web_contents_impl()); - if (pip_controller) { - pip_controller->UpdatePlaybackState(true /* is not playing */, - false /* reached_end_of_stream */); - } - } - // Notify observers of the new player. web_contents_impl()->MediaStartedPlaying( WebContentsObserver::MediaPlayerInfo(has_video, has_audio), id); @@ -317,41 +265,6 @@ web_contents_impl()->MediaResized(size, id); } -void MediaWebContentsObserver::OnPictureInPictureModeStarted( - RenderFrameHost* render_frame_host, - int delegate_id, - const viz::SurfaceId& surface_id, - const gfx::Size& natural_size, - int request_id, - bool show_play_pause_button) { - DCHECK(surface_id.is_valid()); - pip_player_ = MediaPlayerId(render_frame_host, delegate_id); - - gfx::Size window_size = - web_contents_impl()->EnterPictureInPicture(surface_id, natural_size); - - if (auto* pip_controller = - PictureInPictureWindowControllerImpl::FromWebContents( - web_contents_impl())) - pip_controller->SetAlwaysHidePlayPauseButton(show_play_pause_button); - - render_frame_host->Send( - new MediaPlayerDelegateMsg_OnPictureInPictureModeStarted_ACK( - render_frame_host->GetRoutingID(), delegate_id, request_id, - window_size)); -} - -void MediaWebContentsObserver::OnPictureInPictureModeEnded( - RenderFrameHost* render_frame_host, - int delegate_id, - int request_id) { - ExitPictureInPictureInternal(); - - render_frame_host->Send( - new MediaPlayerDelegateMsg_OnPictureInPictureModeEnded_ACK( - render_frame_host->GetRoutingID(), delegate_id, request_id)); -} - void MediaWebContentsObserver::OnSetPictureInPictureCustomControls( RenderFrameHost* render_frame_host, int delegate_id, @@ -363,26 +276,6 @@ pip_controller->SetPictureInPictureCustomControls(controls); } -void MediaWebContentsObserver::OnPictureInPictureSurfaceChanged( - RenderFrameHost* render_frame_host, - int delegate_id, - const viz::SurfaceId& surface_id, - const gfx::Size& natural_size, - bool show_play_pause_button) { - DCHECK(surface_id.is_valid()); - - pip_player_ = MediaPlayerId(render_frame_host, delegate_id); - - // The PictureInPictureWindowController instance may not have been created by - // the embedder. - if (auto* pip_controller = - PictureInPictureWindowControllerImpl::FromWebContents( - web_contents_impl())) { - pip_controller->EmbedSurface(surface_id, natural_size); - pip_controller->SetAlwaysHidePlayPauseButton(show_play_pause_button); - } -} - void MediaWebContentsObserver::ClearWakeLocks( RenderFrameHost* render_frame_host) { std::set<MediaPlayerId> video_players; @@ -482,16 +375,6 @@ player_map->erase(it); } -void MediaWebContentsObserver::ExitPictureInPictureInternal() { - DCHECK(pip_player_); - - web_contents_impl()->ExitPictureInPicture(); - - // Reset must happen after notifying the WebContents because it may interact - // with it. - ResetPictureInPictureVideoMediaPlayerId(); -} - WebContentsImpl* MediaWebContentsObserver::web_contents_impl() const { return static_cast<WebContentsImpl*>(web_contents()); }
diff --git a/content/browser/media/media_web_contents_observer.h b/content/browser/media/media_web_contents_observer.h index d1eb2af..788c018 100644 --- a/content/browser/media/media_web_contents_observer.h +++ b/content/browser/media/media_web_contents_observer.h
@@ -34,10 +34,6 @@ class Size; } // namespace size -namespace viz { -class SurfaceId; -} // namespace viz - namespace content { class AudibleMetrics; @@ -72,14 +68,6 @@ // Gets the MediaPlayerId of the fullscreen video if it exists. const base::Optional<MediaPlayerId>& GetFullscreenVideoMediaPlayerId() const; - // Gets the MediaPlayerId of the picture in picture video if it exists. - const base::Optional<MediaPlayerId>& GetPictureInPictureVideoMediaPlayerId() - const; - - // Reset the MediaPlayerId of the picture in picture video when user closes - // Picture-in-Picture window manually. - void ResetPictureInPictureVideoMediaPlayerId(); - // WebContentsObserver implementation. void WebContentsDestroyed() override; void RenderFrameDeleted(RenderFrameHost* render_frame_host) override; @@ -96,11 +84,6 @@ // Returns whether or not the given player id is active. bool IsPlayerActive(const MediaPlayerId& player_id) const; - // Called by the Picture-in-Picture controller when the associated window is - // resized. |window_size| represents the new size of the window. It MUST be - // called when there is a player in Picture-in-Picture. - void OnPictureInPictureWindowResize(const gfx::Size& window_size); - bool has_audio_wake_lock_for_testing() const { return has_audio_wake_lock_for_testing_; } @@ -135,24 +118,10 @@ void OnMediaMutedStatusChanged(RenderFrameHost* render_frame_host, int delegate_id, bool muted); - void OnPictureInPictureModeStarted(RenderFrameHost* render_frame_host, - int delegate_id, - const viz::SurfaceId&, - const gfx::Size& natural_size, - int request_id, - bool show_play_pause_button); - void OnPictureInPictureModeEnded(RenderFrameHost* render_frame_host, - int delegate_id, - int request_id); void OnSetPictureInPictureCustomControls( RenderFrameHost* render_frame_host, int delegate_id, const std::vector<blink::PictureInPictureControlInfo>& controls); - void OnPictureInPictureSurfaceChanged(RenderFrameHost*, - int delegate_id, - const viz::SurfaceId&, - const gfx::Size&, - bool show_play_pause_button); // Clear |render_frame_host|'s tracking entry for its WakeLocks. void ClearWakeLocks(RenderFrameHost* render_frame_host); @@ -176,10 +145,6 @@ ActiveMediaPlayerMap* player_map, std::set<MediaPlayerId>* removed_players); - // Internal method to exit Picture-in-Picture from an event received from the - // renderer process. - void ExitPictureInPictureInternal(); - // Convenience method that casts web_contents() to a WebContentsImpl*. WebContentsImpl* web_contents_impl() const; @@ -191,7 +156,6 @@ ActiveMediaPlayerMap active_video_players_; device::mojom::WakeLockPtr audio_wake_lock_; base::Optional<MediaPlayerId> fullscreen_player_; - base::Optional<MediaPlayerId> pip_player_; base::Optional<bool> picture_in_picture_allowed_in_fullscreen_; bool has_audio_wake_lock_for_testing_ = false;
diff --git a/content/browser/picture_in_picture/picture_in_picture_service_impl.cc b/content/browser/picture_in_picture/picture_in_picture_service_impl.cc new file mode 100644 index 0000000..4d3bc41b --- /dev/null +++ b/content/browser/picture_in_picture/picture_in_picture_service_impl.cc
@@ -0,0 +1,130 @@ +// Copyright 2019 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 "content/browser/picture_in_picture/picture_in_picture_service_impl.h" + +#include <utility> + +#include "content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h" +#include "content/browser/web_contents/web_contents_impl.h" + +namespace content { + +// static +void PictureInPictureServiceImpl::Create( + RenderFrameHost* render_frame_host, + blink::mojom::PictureInPictureServiceRequest request) { + DCHECK(render_frame_host); + new PictureInPictureServiceImpl(render_frame_host, std::move(request)); +} + +// static +PictureInPictureServiceImpl* PictureInPictureServiceImpl::CreateForTesting( + RenderFrameHost* render_frame_host, + blink::mojom::PictureInPictureServiceRequest request) { + return new PictureInPictureServiceImpl(render_frame_host, std::move(request)); +} + +void PictureInPictureServiceImpl::StartSession( + uint32_t player_id, + const base::Optional<viz::SurfaceId>& surface_id, + const gfx::Size& natural_size, + bool show_play_pause_button, + StartSessionCallback callback) { + player_id_ = MediaPlayerId(render_frame_host_, player_id); + + auto* pip_controller = GetController(); + if (pip_controller) + pip_controller->set_service(this); + + gfx::Size window_size = web_contents_impl()->EnterPictureInPicture( + surface_id.value(), natural_size); + + if (pip_controller) + pip_controller->SetAlwaysHidePlayPauseButton(show_play_pause_button); + + std::move(callback).Run(window_size); +} + +void PictureInPictureServiceImpl::EndSession(EndSessionCallback callback) { + DCHECK(player_id_); + + ExitPictureInPictureInternal(); + + std::move(callback).Run(); +} + +void PictureInPictureServiceImpl::UpdateSession( + uint32_t player_id, + const base::Optional<viz::SurfaceId>& surface_id, + const gfx::Size& natural_size, + bool show_play_pause_button) { + player_id_ = MediaPlayerId(render_frame_host_, player_id); + + // The PictureInPictureWindowController instance may not have been created by + // the embedder. + if (auto* pip_controller = GetController()) { + pip_controller->EmbedSurface(surface_id.value(), natural_size); + pip_controller->SetAlwaysHidePlayPauseButton(show_play_pause_button); + pip_controller->set_service(this); + } +} + +void PictureInPictureServiceImpl::SetDelegate( + blink::mojom::PictureInPictureDelegatePtr delegate) { + delegate.set_connection_error_handler( + base::BindOnce(&PictureInPictureServiceImpl::OnDelegateDisconnected, + // delegate is held by |this|. + base::Unretained(this))); + + if (delegate_) + mojo::ReportBadMessage("SetDelegate() should only be called once."); + + delegate_ = std::move(delegate); +} + +void PictureInPictureServiceImpl::NotifyWindowResized(const gfx::Size& size) { + if (delegate_) + delegate_->PictureInPictureWindowSizeChanged(size); +} + +PictureInPictureServiceImpl::PictureInPictureServiceImpl( + RenderFrameHost* render_frame_host, + blink::mojom::PictureInPictureServiceRequest request) + : FrameServiceBase(render_frame_host, std::move(request)), + render_frame_host_(render_frame_host) {} + +PictureInPictureServiceImpl::~PictureInPictureServiceImpl() { + if (player_id_) + ExitPictureInPictureInternal(); + if (GetController()) + GetController()->set_service(nullptr); +} + +PictureInPictureWindowControllerImpl* +PictureInPictureServiceImpl::GetController() { + return PictureInPictureWindowControllerImpl::GetOrCreateForWebContents( + web_contents_impl()); +} + +void PictureInPictureServiceImpl::OnDelegateDisconnected() { + delegate_ = nullptr; +} + +void PictureInPictureServiceImpl::ExitPictureInPictureInternal() { + web_contents_impl()->ExitPictureInPicture(); + + // Reset must happen after notifying the WebContents because it may interact + // with it. + player_id_.reset(); + + if (auto* controller = GetController()) + controller->set_service(nullptr); +} + +WebContentsImpl* PictureInPictureServiceImpl::web_contents_impl() { + return static_cast<WebContentsImpl*>(web_contents()); +} + +} // namespace content
diff --git a/content/browser/picture_in_picture/picture_in_picture_service_impl.h b/content/browser/picture_in_picture/picture_in_picture_service_impl.h new file mode 100644 index 0000000..28710e3 --- /dev/null +++ b/content/browser/picture_in_picture/picture_in_picture_service_impl.h
@@ -0,0 +1,78 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_SERVICE_IMPL_H_ +#define CONTENT_BROWSER_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_SERVICE_IMPL_H_ + +#include "base/containers/unique_ptr_adapters.h" +#include "content/common/content_export.h" +#include "content/public/browser/frame_service_base.h" +#include "third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom.h" + +namespace content { + +class PictureInPictureWindowControllerImpl; + +// Receives Picture-in-Picture messages from a given RenderFrame. There is one +// PictureInPictureServiceImpl per RenderFrameHost. It talks directly to the +// PictureInPictureWindowControllerImpl. Only one service interacts with the +// window at a given time. +class CONTENT_EXPORT PictureInPictureServiceImpl final + : public content::FrameServiceBase<blink::mojom::PictureInPictureService> { + public: + static void Create(RenderFrameHost*, + blink::mojom::PictureInPictureServiceRequest); + static PictureInPictureServiceImpl* CreateForTesting( + RenderFrameHost*, + blink::mojom::PictureInPictureServiceRequest); + + // PictureInPictureService implementation. + void StartSession(uint32_t player_id, + const base::Optional<viz::SurfaceId>& surface_id, + const gfx::Size& natural_size, + bool show_play_pause_button, + StartSessionCallback) final; + void EndSession(EndSessionCallback) final; + void UpdateSession(uint32_t player_id, + const base::Optional<viz::SurfaceId>& surface_id, + const gfx::Size& natural_size, + bool show_play_pause_button) final; + void SetDelegate(blink::mojom::PictureInPictureDelegatePtr) final; + + void NotifyWindowResized(const gfx::Size&); + + // Returns the player that is currently in Picture-in-Picture in the context + // of the frame associated with the service. Returns nullopt if there are + // none. + const base::Optional<MediaPlayerId>& player_id() const { return player_id_; } + void ResetPlayerId() { player_id_.reset(); } + + private: + PictureInPictureServiceImpl(RenderFrameHost*, + blink::mojom::PictureInPictureServiceRequest); + ~PictureInPictureServiceImpl() override; + + // Returns the PictureInPictureWindowControllerImpl associated with the + // WebContents. Can be null. + PictureInPictureWindowControllerImpl* GetController(); + + // Callack run when the delegate is disconnected. Only one delegate should be + // set at any given time. + void OnDelegateDisconnected(); + + // Implementation of ExitPictureInPicture without callback handling. + void ExitPictureInPictureInternal(); + + WebContentsImpl* web_contents_impl(); + + blink::mojom::PictureInPictureDelegatePtr delegate_ = nullptr; + RenderFrameHost* render_frame_host_ = nullptr; + base::Optional<MediaPlayerId> player_id_; + + DISALLOW_COPY_AND_ASSIGN(PictureInPictureServiceImpl); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_SERVICE_IMPL_H_
diff --git a/content/browser/picture_in_picture/picture_in_picture_service_impl_unittest.cc b/content/browser/picture_in_picture/picture_in_picture_service_impl_unittest.cc new file mode 100644 index 0000000..4c8a5b723 --- /dev/null +++ b/content/browser/picture_in_picture/picture_in_picture_service_impl_unittest.cc
@@ -0,0 +1,145 @@ +// Copyright 2019 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 "content/browser/picture_in_picture/picture_in_picture_service_impl.h" + +#include <memory> +#include <utility> +#include <vector> + +#include "content/common/media/media_player_delegate_messages.h" +#include "content/public/browser/overlay_window.h" +#include "content/public/browser/web_contents_delegate.h" +#include "content/test/test_content_browser_client.h" +#include "content/test/test_render_frame_host.h" +#include "content/test/test_render_view_host.h" +#include "content/test/test_web_contents.h" +#include "mojo/public/cpp/bindings/interface_ptr.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace content { + +class PictureInPictureDelegate : public WebContentsDelegate { + public: + PictureInPictureDelegate() = default; + + MOCK_METHOD3(EnterPictureInPicture, + gfx::Size(WebContents*, + const viz::SurfaceId&, + const gfx::Size&)); + + private: + DISALLOW_COPY_AND_ASSIGN(PictureInPictureDelegate); +}; + +class TestOverlayWindow : public OverlayWindow { + public: + TestOverlayWindow() = default; + ~TestOverlayWindow() override{}; + + static std::unique_ptr<OverlayWindow> Create( + PictureInPictureWindowController* controller) { + return std::unique_ptr<OverlayWindow>(new TestOverlayWindow()); + } + + bool IsActive() const override { return false; } + void Close() override {} + void Show() override {} + void Hide() override {} + void SetPictureInPictureCustomControls( + const std::vector<blink::PictureInPictureControlInfo>& controls) + override {} + bool IsVisible() const override { return false; } + bool IsAlwaysOnTop() const override { return false; } + ui::Layer* GetLayer() override { return nullptr; } + gfx::Rect GetBounds() const override { return gfx::Rect(); } + void UpdateVideoSize(const gfx::Size& natural_size) override {} + void SetPlaybackState(PlaybackState playback_state) override {} + void SetAlwaysHidePlayPauseButton(bool is_visible) override {} + ui::Layer* GetWindowBackgroundLayer() override { return nullptr; } + ui::Layer* GetVideoLayer() override { return nullptr; } + gfx::Rect GetVideoBounds() override { return gfx::Rect(); } + void SetSkipAdButtonVisibility(bool is_visible) override {} + + private: + DISALLOW_COPY_AND_ASSIGN(TestOverlayWindow); +}; + +class PictureInPictureTestBrowserClient : public TestContentBrowserClient { + public: + PictureInPictureTestBrowserClient() = default; + ~PictureInPictureTestBrowserClient() override = default; + + std::unique_ptr<OverlayWindow> CreateWindowForPictureInPicture( + PictureInPictureWindowController* controller) override { + return TestOverlayWindow::Create(controller); + } +}; + +class PictureInPictureServiceImplTest : public RenderViewHostImplTestHarness { + public: + void SetUp() override { + RenderViewHostImplTestHarness::SetUp(); + // WebUIControllerFactory::RegisterFactory( + // ContentWebUIControllerFactory::GetInstance()); + + SetBrowserClientForTesting(&browser_client_); + + TestRenderFrameHost* render_frame_host = contents()->GetMainFrame(); + render_frame_host->InitializeRenderFrameIfNeeded(); + + contents()->SetDelegate(&delegate_); + + blink::mojom::PictureInPictureServiceRequest request; + service_impl_ = PictureInPictureServiceImpl::CreateForTesting( + render_frame_host, std::move(request)); + } + + void TearDown() override { + // WebUIControllerFactory::UnregisterFactoryForTesting( + // ContentWebUIControllerFactory::GetInstance()); + RenderViewHostImplTestHarness::TearDown(); + } + + PictureInPictureServiceImpl& service() { return *service_impl_; } + + PictureInPictureDelegate& delegate() { return delegate_; } + + private: + PictureInPictureTestBrowserClient browser_client_; + PictureInPictureDelegate delegate_; + // Will be deleted when the frame is destroyed. + PictureInPictureServiceImpl* service_impl_; +}; + +TEST_F(PictureInPictureServiceImplTest, EnterPictureInPicture) { + const int kPlayerVideoOnlyId = 30; + + // If Picture-in-Picture was never triggered, the media player id would not be + // set. + EXPECT_FALSE(service().player_id().has_value()); + + viz::SurfaceId surface_id = + viz::SurfaceId(viz::FrameSinkId(1, 1), + viz::LocalSurfaceId( + 11, base::UnguessableToken::Deserialize(0x111111, 0))); + + EXPECT_CALL(delegate(), + EnterPictureInPicture(contents(), surface_id, gfx::Size(42, 42))); + + service().StartSession(kPlayerVideoOnlyId, surface_id, gfx::Size(42, 42), + true /* show_play_pause_button */, base::DoNothing()); + EXPECT_TRUE(service().player_id().has_value()); + EXPECT_EQ(kPlayerVideoOnlyId, service().player_id()->delegate_id); + + // Picture-in-Picture media player id should not be reset when the media is + // destroyed (e.g. video stops playing). This allows the Picture-in-Picture + // window to continue to control the media. + contents()->GetMainFrame()->OnMessageReceived( + MediaPlayerDelegateHostMsg_OnMediaDestroyed( + contents()->GetMainFrame()->GetRoutingID(), kPlayerVideoOnlyId)); + EXPECT_TRUE(service().player_id().has_value()); +} + +} // namespace content
diff --git a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc index a0096ef..01f7ae73 100644 --- a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc +++ b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
@@ -10,6 +10,7 @@ #include "content/browser/media/media_web_contents_observer.h" #include "content/browser/media/session/media_session_impl.h" #include "content/browser/picture_in_picture/overlay_surface_embedder.h" +#include "content/browser/picture_in_picture/picture_in_picture_service_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/media/media_player_delegate_messages.h" #include "content/public/browser/content_browser_client.h" @@ -57,7 +58,8 @@ PictureInPictureWindowControllerImpl::PictureInPictureWindowControllerImpl( WebContents* initiator) - : initiator_(static_cast<WebContentsImpl* const>(initiator)) { + : WebContentsObserver(initiator), + initiator_(static_cast<WebContentsImpl* const>(initiator)) { DCHECK(initiator_); media_web_contents_observer_ = initiator_->media_web_contents_observer(); @@ -126,9 +128,7 @@ // surface id was updated for the same video, this is a no-op. This could // be updated for a different video if another media player on the same // |initiator_| enters Picture-in-Picture mode. - media_player_id_ = - media_web_contents_observer_->GetPictureInPictureVideoMediaPlayerId(); - UpdatePlaybackState(IsPlayerActive(), !media_player_id_.has_value()); + UpdateMediaPlayerId(); window_->UpdateVideoSize(natural_size); @@ -142,9 +142,9 @@ } void PictureInPictureWindowControllerImpl::UpdateLayerBounds() { - if (media_player_id_.has_value() && window_ && window_->IsVisible()) { - media_web_contents_observer_->OnPictureInPictureWindowResize( - window_->GetBounds().size()); + if (media_player_id_.has_value() && service_ && window_ && + window_->IsVisible()) { + service_->NotifyWindowResized(window_->GetBounds().size()); } if (embedder_) @@ -152,10 +152,12 @@ } bool PictureInPictureWindowControllerImpl::IsPlayerActive() { - if (!media_player_id_.has_value()) { - media_player_id_ = - media_web_contents_observer_->GetPictureInPictureVideoMediaPlayerId(); - } + if (!media_player_id_.has_value()) + media_player_id_ = service_ ? service_->player_id() : base::nullopt; + + // At creation time, the player id may not be set. + if (!media_player_id_.has_value()) + return false; return media_player_id_.has_value() && media_web_contents_observer_->IsPlayerActive(*media_player_id_); @@ -219,6 +221,11 @@ media_player_id_->delegate_id, control_id)); } +void PictureInPictureWindowControllerImpl::UpdateMediaPlayerId() { + media_player_id_ = service_ ? service_->player_id() : base::nullopt; + UpdatePlaybackState(IsPlayerActive(), !media_player_id_.has_value()); +} + void PictureInPictureWindowControllerImpl::SetAlwaysHidePlayPauseButton( bool is_visible) { always_hide_play_pause_button_ = is_visible; @@ -254,6 +261,33 @@ window_->SetSkipAdButtonVisibility(media_session_action_skip_ad_handled_); } +void PictureInPictureWindowControllerImpl::MediaStartedPlaying( + const MediaPlayerInfo&, + const MediaPlayerId& media_player_id) { + if (initiator_->IsBeingDestroyed()) + return; + + if (media_player_id_ != media_player_id) + return; + + UpdatePlaybackState(true /* is_playing */, false /* reached_end_of_stream */); +} + +void PictureInPictureWindowControllerImpl::MediaStoppedPlaying( + const MediaPlayerInfo&, + const MediaPlayerId& media_player_id, + WebContentsObserver::MediaStoppedReason reason) { + if (initiator_->IsBeingDestroyed()) + return; + + if (media_player_id_ != media_player_id) + return; + + UpdatePlaybackState( + false /* is_playing */, + reason == WebContentsObserver::MediaStoppedReason::kReachedEndOfStream); +} + void PictureInPictureWindowControllerImpl::OnLeavingPictureInPicture( bool should_pause_video, bool should_reset_pip_player) { @@ -269,8 +303,12 @@ new MediaPlayerDelegateMsg_EndPictureInPictureMode( media_player_id_->render_frame_host->GetRoutingID(), media_player_id_->delegate_id)); - if (should_reset_pip_player) - media_web_contents_observer_->ResetPictureInPictureVideoMediaPlayerId(); + + if (should_reset_pip_player) { + DCHECK(service_); + service_->ResetPlayerId(); + media_player_id_.reset(); + } } }
diff --git a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h index f44a7ca..91701f7 100644 --- a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h +++ b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h
@@ -14,10 +14,11 @@ namespace content { +class MediaWebContentsObserver; class OverlaySurfaceEmbedder; +class PictureInPictureServiceImpl; class WebContents; class WebContentsImpl; -class MediaWebContentsObserver; // TODO(thakis,mlamouri): PictureInPictureWindowControllerImpl isn't // CONTENT_EXPORT'd because it creates complicated build issues with @@ -27,7 +28,8 @@ // work with it. https://crbug.com/589840. class PictureInPictureWindowControllerImpl : public PictureInPictureWindowController, - public WebContentsUserData<PictureInPictureWindowControllerImpl> { + public WebContentsUserData<PictureInPictureWindowControllerImpl>, + public WebContentsObserver { public: // Gets a reference to the controller associated with |initiator| and creates // one if it does not exist. The returned pointer is guaranteed to be @@ -62,6 +64,22 @@ CONTENT_EXPORT void MediaSessionActionsChanged( const std::set<media_session::mojom::MediaSessionAction>& actions); + // WebContentsObserver: + void MediaStartedPlaying(const MediaPlayerInfo&, + const MediaPlayerId&) override; + void MediaStoppedPlaying(const MediaPlayerInfo&, + const MediaPlayerId&, + WebContentsObserver::MediaStoppedReason) override; + + // TODO(mlamouri): temporary method used because of the media player id is + // stored in a different location from the one that is used to update the + // state of this object. + void UpdateMediaPlayerId(); + + void set_service(PictureInPictureServiceImpl* service) { + service_ = service; + }; + private: friend class WebContentsUserData<PictureInPictureWindowControllerImpl>; @@ -89,6 +107,7 @@ std::unique_ptr<OverlayWindow> window_; std::unique_ptr<OverlaySurfaceEmbedder> embedder_; + // TODO(929156): remove this as it should be accessible via `web_contents()`. WebContentsImpl* const initiator_; // Used to determine the state of the media player and route messages to @@ -109,6 +128,11 @@ // Session API in UpdatePlayPauseButtonVisibility(). bool always_hide_play_pause_button_ = false; + // Service currently associated with the Picture-in-Picture window. The + // service makes the bridge with the renderer process by sending enter/exit + // requests. It is also holding the Picture-in-Picture MediaPlayerId. + PictureInPictureServiceImpl* service_ = nullptr; + WEB_CONTENTS_USER_DATA_KEY_DECL(); DISALLOW_COPY_AND_ASSIGN(PictureInPictureWindowControllerImpl);
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc index febedb5..379a83bf 100644 --- a/content/browser/renderer_host/delegated_frame_host.cc +++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -39,7 +39,7 @@ // Normalized value [0..1] where 1 is full quality and 0 is empty. This sets // the quality of the captured texture by reducing its dimensions by this // factor. -constexpr float kFrameContentCaptureQuality = 0.5f; +constexpr float kFrameContentCaptureQuality = 0.4f; } // namespace @@ -78,6 +78,7 @@ stale_content_layer_ = std::make_unique<ui::Layer>(ui::LayerType::LAYER_SOLID_COLOR); stale_content_layer_->SetVisible(false); + stale_content_layer_->SetColor(SK_ColorTRANSPARENT); } DelegatedFrameHost::~DelegatedFrameHost() { @@ -428,10 +429,9 @@ DCHECK_EQ(result->format(), viz::CopyOutputResult::Format::RGBA_TEXTURE); - if (frame_eviction_state_ == FrameEvictionState::kPendingEvictionRequests) { - frame_eviction_state_ = FrameEvictionState::kNotStarted; - ContinueDelegatedFrameEviction(); - } + DCHECK_NE(frame_eviction_state_, FrameEvictionState::kNotStarted); + frame_eviction_state_ = FrameEvictionState::kNotStarted; + ContinueDelegatedFrameEviction(); auto transfer_resource = viz::TransferableResource::MakeGL( result->GetTextureResult()->mailbox, GL_LINEAR, GL_TEXTURE_2D,
diff --git a/content/browser/renderer_host/media/video_capture_host.cc b/content/browser/renderer_host/media/video_capture_host.cc index 23e7ae3..8736e10 100644 --- a/content/browser/renderer_host/media/video_capture_host.cc +++ b/content/browser/renderer_host/media/video_capture_host.cc
@@ -319,6 +319,21 @@ std::move(callback).Run(formats_in_use); } +void VideoCaptureHost::OnFrameDropped( + int32_t device_id, + media::VideoCaptureFrameDropReason reason) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + VideoCaptureControllerID controller_id(device_id); + auto it = controllers_.find(controller_id); + if (it == controllers_.end()) + return; + + const base::WeakPtr<VideoCaptureController>& controller = it->second; + if (controller) + controller->OnFrameDropped(reason); +} + void VideoCaptureHost::OnLog(int32_t device_id, const std::string& message) { DCHECK_CURRENTLY_ON(BrowserThread::IO);
diff --git a/content/browser/renderer_host/media/video_capture_host.h b/content/browser/renderer_host/media/video_capture_host.h index 7f8871d..95c9678 100644 --- a/content/browser/renderer_host/media/video_capture_host.h +++ b/content/browser/renderer_host/media/video_capture_host.h
@@ -90,6 +90,8 @@ void GetDeviceFormatsInUse(int32_t device_id, int32_t session_id, GetDeviceFormatsInUseCallback callback) override; + void OnFrameDropped(int32_t device_id, + media::VideoCaptureFrameDropReason reason) override; void OnLog(int32_t device_id, const std::string& message) override; void DoError(VideoCaptureControllerID id, media::VideoCaptureError error);
diff --git a/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc b/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc index 3e9d849..0ec4233 100644 --- a/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc +++ b/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc
@@ -5,6 +5,7 @@ #include "content/browser/renderer_host/pepper/pepper_network_monitor_host.h" #include <stddef.h> +#include <utility> #include "base/bind.h" #include "base/bind_helpers.h" @@ -18,6 +19,7 @@ #include "content/public/common/socket_permission_request.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/private/net_address_private_impl.h" +#include "services/network/public/mojom/network_service.mojom.h" namespace content { @@ -37,11 +39,23 @@ render_frame_id); } -std::unique_ptr<net::NetworkInterfaceList> GetNetworkList() { - std::unique_ptr<net::NetworkInterfaceList> list( - new net::NetworkInterfaceList()); - net::GetNetworkList(list.get(), net::INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES); - return list; +void OnGetNetworkList( + base::OnceCallback<void(const net::NetworkInterfaceList&)> callback, + const base::Optional<net::NetworkInterfaceList>& networks) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::IO}, + base::BindOnce(std::move(callback), networks.has_value() + ? *networks + : net::NetworkInterfaceList())); +} + +void GetNetworkList( + base::OnceCallback<void(const net::NetworkInterfaceList&)> callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + content::GetNetworkService()->GetNetworkList( + net::INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, + base::BindOnce(&OnGetNetworkList, std::move(callback))); } } // namespace @@ -104,23 +118,21 @@ void PepperNetworkMonitorHost::GetAndSendNetworkList() { DCHECK_CURRENTLY_ON(BrowserThread::IO); - - // Call GetNetworkList() on a thread that allows blocking IO. - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, - base::Bind(&GetNetworkList), - base::Bind(&PepperNetworkMonitorHost::SendNetworkList, - weak_factory_.GetWeakPtr())); + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&GetNetworkList, + base::BindOnce(&PepperNetworkMonitorHost::SendNetworkList, + weak_factory_.GetWeakPtr()))); } void PepperNetworkMonitorHost::SendNetworkList( - std::unique_ptr<net::NetworkInterfaceList> list) { + const net::NetworkInterfaceList& list) { DCHECK_CURRENTLY_ON(BrowserThread::IO); std::unique_ptr<ppapi::proxy::SerializedNetworkList> list_copy( - new ppapi::proxy::SerializedNetworkList(list->size())); - for (size_t i = 0; i < list->size(); ++i) { - const net::NetworkInterface& network = list->at(i); + new ppapi::proxy::SerializedNetworkList(list.size())); + for (size_t i = 0; i < list.size(); ++i) { + const net::NetworkInterface& network = list.at(i); ppapi::proxy::SerializedNetworkInfo& network_copy = list_copy->at(i); network_copy.name = network.name;
diff --git a/content/browser/renderer_host/pepper/pepper_network_monitor_host.h b/content/browser/renderer_host/pepper/pepper_network_monitor_host.h index 6cf89098..af48b4bc 100644 --- a/content/browser/renderer_host/pepper/pepper_network_monitor_host.h +++ b/content/browser/renderer_host/pepper/pepper_network_monitor_host.h
@@ -38,7 +38,7 @@ network::NetworkConnectionTracker* network_connection_tracker); void GetAndSendNetworkList(); - void SendNetworkList(std::unique_ptr<net::NetworkInterfaceList> list); + void SendNetworkList(const net::NetworkInterfaceList& list); ppapi::host::ReplyMessageContext reply_context_;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 54eb543..9045c813 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3084,7 +3084,6 @@ switches::kDisallowNonExactResourceReuse, #if defined(OS_ANDROID) switches::kDisableMediaSessionAPI, - switches::kEnableReachedCodeProfiler, switches::kOrderfileMemoryOptimization, switches::kRendererWaitForJavaDebugger, #endif
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 73fe6f8..26b9b6f 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -631,30 +631,6 @@ DISALLOW_COPY_AND_ASSIGN(UpdateViewportIntersectionMessageFilter); }; -void UnloadPrint(FrameTreeNode* node, const char* message) { - EXPECT_TRUE( - ExecJs(node, JsReplace("window.onunload = function() { " - " window.domAutomationController.send($1);" - "}", - message))); -} - -// A BrowserMessageFilter that drops FrameHostMsg_Detach messages. -class DetachMessageFilter : public BrowserMessageFilter { - public: - DetachMessageFilter() : BrowserMessageFilter(FrameMsgStart) {} - - protected: - ~DetachMessageFilter() override {} - - private: - // BrowserMessageFilter: - bool OnMessageReceived(const IPC::Message& message) override { - return message.type() == FrameHostMsg_Detach::ID; - } - DISALLOW_COPY_AND_ASSIGN(DetachMessageFilter); -}; - } // namespace // @@ -5384,7 +5360,8 @@ // Install a BrowserMessageFilter to drop SwapOut ACK messages in A's // process. - scoped_refptr<SwapoutACKMessageFilter> filter = new SwapoutACKMessageFilter(); + auto filter = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID); rfh->GetProcess()->AddFilter(filter.get()); rfh->DisableSwapOutTimerForTesting(); @@ -7652,54 +7629,6 @@ EXPECT_EQ(orig_site_instance, child->current_frame_host()->GetSiteInstance()); } -// Tests that there are no crashes if a subframe is detached in its unload -// handler. See https://crbug.com/590054. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, DetachInUnloadHandler) { - GURL main_url(embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(b(b))")); - EXPECT_TRUE(NavigateToURL(shell(), main_url)); - - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetFrameTree() - ->root(); - - EXPECT_EQ( - " Site A ------------ proxies for B\n" - " +--Site B ------- proxies for A\n" - " +--Site B -- proxies for A\n" - "Where A = http://a.com/\n" - " B = http://b.com/", - DepictFrameTree(root)); - - EXPECT_EQ(1, EvalJs(root->child_at(0), "frames.length;")); - - RenderFrameDeletedObserver deleted_observer( - root->child_at(0)->child_at(0)->current_frame_host()); - - // Add an unload handler to the grandchild that causes it to be synchronously - // detached, then navigate it. - EXPECT_TRUE(ExecuteScript( - root->child_at(0)->child_at(0), - "window.onunload=function(e){\n" - " window.parent.document.getElementById('child-0').remove();\n" - "};\n")); - auto script = JsReplace("window.document.getElementById('child-0').src = $1", - embedded_test_server()->GetURL( - "c.com", "/cross_site_iframe_factory.html?c")); - EXPECT_TRUE(ExecuteScript(root->child_at(0), script)); - - deleted_observer.WaitUntilDeleted(); - - EXPECT_EQ(0, EvalJs(root->child_at(0), "frames.length;")); - - EXPECT_EQ( - " Site A ------------ proxies for B\n" - " +--Site B ------- proxies for A\n" - "Where A = http://a.com/\n" - " B = http://b.com/", - DepictFrameTree(root)); -} - // Helper filter class to wait for a ShowCreatedWindow or ShowWidget message, // record the routing ID from the message, and then drop the message. const uint32_t kMessageClasses[] = {ViewMsgStart, FrameMsgStart}; @@ -8269,61 +8198,6 @@ EXPECT_TRUE(ExecuteScript(popup_shell->web_contents(), "true")); } -// Tests that trying to navigate in the unload handler doesn't crash the -// browser. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, NavigateInUnloadHandler) { - GURL main_url(embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(b(b))")); - EXPECT_TRUE(NavigateToURL(shell(), main_url)); - - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetFrameTree() - ->root(); - - EXPECT_EQ( - " Site A ------------ proxies for B\n" - " +--Site B ------- proxies for A\n" - " +--Site B -- proxies for A\n" - "Where A = http://a.com/\n" - " B = http://b.com/", - DepictFrameTree(root)); - - EXPECT_EQ(1, - EvalJs(root->child_at(0)->current_frame_host(), "frames.length;")); - - // Add an unload handler to B's subframe. - EXPECT_TRUE( - ExecuteScript(root->child_at(0)->child_at(0)->current_frame_host(), - "window.onunload=function(e){\n" - " window.location = '#navigate';\n" - "};\n")); - - // Navigate B's subframe to a cross-site C. - RenderFrameDeletedObserver deleted_observer( - root->child_at(0)->child_at(0)->current_frame_host()); - auto script = JsReplace("window.document.getElementById('child-0').src = $1", - embedded_test_server()->GetURL( - "c.com", "/cross_site_iframe_factory.html")); - EXPECT_TRUE(ExecuteScript(root->child_at(0)->current_frame_host(), script)); - - // Wait until B's subframe RenderFrameHost is destroyed. - deleted_observer.WaitUntilDeleted(); - - // Check that C's subframe is alive and the navigation in the unload handler - // was ignored. - EXPECT_EQ(0, EvalJs(root->child_at(0)->child_at(0)->current_frame_host(), - "frames.length;")); - - EXPECT_EQ( - " Site A ------------ proxies for B C\n" - " +--Site B ------- proxies for A C\n" - " +--Site C -- proxies for A B\n" - "Where A = http://a.com/\n" - " B = http://b.com/\n" - " C = http://c.com/", - DepictFrameTree(root)); -} - IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, RFHTransfersWhilePendingDeletion) { GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html")); @@ -8900,7 +8774,8 @@ // Disable the swapout ACK and the swapout timer. RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>( shell()->web_contents()->GetMainFrame()); - scoped_refptr<SwapoutACKMessageFilter> filter = new SwapoutACKMessageFilter(); + auto filter = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID); rfh->GetProcess()->AddFilter(filter.get()); rfh->DisableSwapOutTimerForTesting(); @@ -10877,8 +10752,9 @@ // This test verifies that the main-frame's page scale factor propagates to // the compositor layertrees in each of the child processes. +// TODO(crbug.com/923226): Disabled due to flakiness. IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - PageScaleFactorPropagatesToOOPIFs) { + DISABLED_PageScaleFactorPropagatesToOOPIFs) { GURL main_url(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(b(c),d)")); EXPECT_TRUE(NavigateToURL(shell(), main_url)); @@ -11734,75 +11610,6 @@ } } -// Verifies that when navigating an OOPIF to same site and then canceling -// navigation from beforeunload handler popup will not remove the -// RemoteFrameView from OOPIF's owner element in the parent process. This test -// uses OOPIF visibility to make sure RemoteFrameView exists after beforeunload -// is handled. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - CanceledBeforeUnloadShouldNotClearRemoteFrameView) { - GURL a_url(embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(b)")); - EXPECT_TRUE(NavigateToURL(shell(), a_url)); - - FrameTreeNode* child_node = - web_contents()->GetFrameTree()->root()->child_at(0); - GURL b_url(embedded_test_server()->GetURL( - "b.com", "/render_frame_host/beforeunload.html")); - NavigateFrameToURL(child_node, b_url); - FrameConnectorDelegate* frame_connector_delegate = - static_cast<RenderWidgetHostViewChildFrame*>( - child_node->current_frame_host()->GetView()) - ->FrameConnectorForTesting(); - - // Need user gesture for 'beforeunload' to fire. - PrepContentsForBeforeUnloadTest(web_contents()); - - // Simulate user choosing to stay on the page after beforeunload fired. - SetShouldProceedOnBeforeUnload(shell(), true /* proceed */, - false /* success */); - - // First, hide the <iframe>. This goes through RemoteFrameView::Hide() and - // eventually updates the FrameConnectorDelegate. Also, - // RemoteFrameView::self_visible_ will be set to false which can only be - // undone by calling RemoteFrameView::Show. Therefore, potential calls to - // RemoteFrameView::SetParentVisible(true) would not update the visibility at - // the browser side. - ASSERT_TRUE(ExecuteScript( - web_contents(), - "document.querySelector('iframe').style.visibility = 'hidden';")); - while (!frame_connector_delegate->IsHidden()) { - base::RunLoop run_loop; - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout()); - run_loop.Run(); - } - - // Now we navigate the child to about:blank, but since we do not proceed with - // the navigation, the OOPIF should stay alive and RemoteFrameView intact. - ASSERT_TRUE(ExecuteScript( - web_contents(), "document.querySelector('iframe').src = 'about:blank';")); - WaitForAppModalDialog(shell()); - - // Sanity check: We should still have an OOPIF and hence a RWHVCF. - ASSERT_TRUE(static_cast<RenderWidgetHostViewBase*>( - child_node->current_frame_host()->GetView()) - ->IsRenderWidgetHostViewChildFrame()); - - // Now make the <iframe> visible again. This calls RemoteFrameView::Show() - // only if the RemoteFrameView is the EmbeddedContentView of the corresponding - // HTMLFrameOwnerElement. - ASSERT_TRUE(ExecuteScript( - web_contents(), - "document.querySelector('iframe').style.visibility = 'visible';")); - while (frame_connector_delegate->IsHidden()) { - base::RunLoop run_loop; - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout()); - run_loop.Run(); - } -} - // Verifies the the renderer has the size of the frame after commit. // https://crbug/804046, https://crbug.com/801091 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, SizeAvailableAfterCommit) { @@ -11845,7 +11652,8 @@ RenderViewHostImpl* rvh = rfh->render_view_host(); // Disable the swapout ACK and the swapout timer. - scoped_refptr<SwapoutACKMessageFilter> filter = new SwapoutACKMessageFilter(); + auto filter = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID); rfh->GetProcess()->AddFilter(filter.get()); rfh->DisableSwapOutTimerForTesting(); @@ -12126,55 +11934,6 @@ } } -// Ensure that after a main frame with an OOPIF is navigated cross-site, the -// unload handler in the OOPIF sees correct main frame origin, namely the old -// and not the new origin. See https://crbug.com/825283. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - ParentOriginDoesNotChangeInUnloadHandler) { - GURL main_url(embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(b)")); - EXPECT_TRUE(NavigateToURL(shell(), main_url)); - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetFrameTree() - ->root(); - - // Open a popup on b.com. The b.com subframe on the main frame will use this - // in its unload handler. - GURL b_url(embedded_test_server()->GetURL("b.com", "/title1.html")); - EXPECT_TRUE(OpenPopup(shell()->web_contents(), b_url, "popup")); - - // Add an unload handler to b.com subframe, which will look up the top - // frame's origin and send it via domAutomationController. Unfortunately, - // the subframe's browser-side state will have been torn down when it runs - // the unload handler, so to ensure that the message can be received, send it - // through the popup. - EXPECT_TRUE( - ExecuteScript(root->child_at(0), - "window.onunload = function(e) {" - " window.open('','popup').domAutomationController.send(" - " 'top-origin ' + location.ancestorOrigins[0]);" - "};")); - - // Navigate the main frame to c.com and wait for the message from the - // subframe's unload handler. - GURL c_url(embedded_test_server()->GetURL("c.com", "/title1.html")); - DOMMessageQueue msg_queue; - EXPECT_TRUE(NavigateToURL(shell(), c_url)); - std::string message, top_origin; - while (msg_queue.WaitForMessage(&message)) { - base::TrimString(message, "\"", &message); - auto message_parts = base::SplitString(message, " ", base::TRIM_WHITESPACE, - base::SPLIT_WANT_NONEMPTY); - if (message_parts[0] == "top-origin") { - top_origin = message_parts[1]; - break; - } - } - - // The top frame's origin should be a.com, not c.com. - EXPECT_EQ(top_origin + "/", main_url.GetOrigin().spec()); -} - // Check that when a postMessage is called on a remote frame, it waits for the // current script block to finish executing before forwarding the postMessage, // so that if the script causes any other IPCs to be sent in the same event @@ -12248,7 +12007,8 @@ EXPECT_EQ(start_url, rfh->GetLastCommittedURL()); // Disable the swapout ACK and the swapout timer. - scoped_refptr<SwapoutACKMessageFilter> filter = new SwapoutACKMessageFilter(); + auto filter = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID); rfh->GetProcess()->AddFilter(filter.get()); rfh->DisableSwapOutTimerForTesting(); @@ -12269,64 +12029,6 @@ EXPECT_EQ(start_url, rfh->GetLastCommittedURL()); } -namespace { - -// A helper class that watches for SwapOut ACK messages, allowing them -// to go through but remembering that the message was received. -class SwapoutACKReceivedFilter : public BrowserMessageFilter { - public: - explicit SwapoutACKReceivedFilter(RenderProcessHost* process) - : BrowserMessageFilter(FrameMsgStart) { - process->AddFilter(this); - } - - bool has_received_swapout_ack() { return received_; } - - protected: - ~SwapoutACKReceivedFilter() override {} - - private: - // BrowserMessageFilter: - bool OnMessageReceived(const IPC::Message& message) override { - if (message.type() == FrameHostMsg_SwapOut_ACK::ID) { - received_ = true; - } - return false; - } - - bool received_ = false; - DISALLOW_COPY_AND_ASSIGN(SwapoutACKReceivedFilter); -}; - -} // namespace - -// Verify that when the last active frame in a process is going away as part of -// OnSwapOut, the SwapOut ACK is received prior to the process starting to shut -// down, ensuring that any related unload work also happens before shutdown. -// See https://crbug.com/867274 and https://crbug.com/794625. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - SwapOutACKArrivesPriorToProcessShutdownRequest) { - GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), start_url)); - RenderFrameHostImpl* rfh = web_contents()->GetMainFrame(); - rfh->DisableSwapOutTimerForTesting(); - - // Navigate cross-site. Since the current frame is the last active frame in - // the current process, the process will eventually shut down. Once the - // process goes away, ensure that the SwapOut ACK was received (i.e., that we - // didn't just simulate OnSwappedOut() due to the process erroneously going - // away before the SwapOut ACK was received, as in https://crbug.com/867274). - RenderProcessHostWatcher watcher( - rfh->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - scoped_refptr<SwapoutACKReceivedFilter> swapout_ack_filter = - new SwapoutACKReceivedFilter(rfh->GetProcess()); - GURL cross_site_url(embedded_test_server()->GetURL("b.com", "/title1.html")); - EXPECT_TRUE(NavigateToURLFromRenderer(shell(), cross_site_url)); - watcher.Wait(); - EXPECT_TRUE(swapout_ack_filter->has_received_swapout_ack()); - EXPECT_TRUE(watcher.did_exit_normally()); -} - // Tests that when a large OOPIF has been scaled, the compositor raster area // sent from the embedder is correct. #if defined(OS_ANDROID) || defined(OS_MACOSX) @@ -13645,37 +13347,6 @@ EXPECT_TRUE(b_process_observer.did_exit_normally()); } -// This observer waits until WebContentsObserver::OnRendererUnresponsive -// notification. -class UnresponsiveRendererObserver : public WebContentsObserver { - public: - explicit UnresponsiveRendererObserver(WebContents* web_contents) - : WebContentsObserver(web_contents) {} - - ~UnresponsiveRendererObserver() override {} - - RenderProcessHost* Wait(base::TimeDelta timeout = base::TimeDelta::Max()) { - if (!captured_render_process_host_) { - base::OneShotTimer timer; - timer.Start(FROM_HERE, timeout, run_loop_.QuitClosure()); - run_loop_.Run(); - timer.Stop(); - } - return captured_render_process_host_; - } - - private: - void OnRendererUnresponsive(RenderProcessHost* render_process_host) override { - captured_render_process_host_ = render_process_host; - run_loop_.Quit(); - } - - RenderProcessHost* captured_render_process_host_ = nullptr; - base::RunLoop run_loop_; - - DISALLOW_COPY_AND_ASSIGN(UnresponsiveRendererObserver); -}; - IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CommitTimeoutForHungRenderer) { // Navigate first tab to a.com. @@ -13769,132 +13440,6 @@ NavigationHandleImpl::SetCommitTimeoutForTesting(base::TimeDelta()); } -class TestWCBeforeUnloadDelegate : public JavaScriptDialogManager, - public WebContentsDelegate { - public: - explicit TestWCBeforeUnloadDelegate(WebContentsImpl* web_contents) - : web_contents_(web_contents) { - web_contents_->SetDelegate(this); - } - - ~TestWCBeforeUnloadDelegate() override { - if (!callback_.is_null()) - std::move(callback_).Run(true, base::string16()); - - web_contents_->SetDelegate(nullptr); - web_contents_->SetJavaScriptDialogManagerForTesting(nullptr); - } - - void Wait() { - run_loop_->Run(); - run_loop_ = std::make_unique<base::RunLoop>(); - } - - // WebContentsDelegate - - JavaScriptDialogManager* GetJavaScriptDialogManager( - WebContents* source) override { - return this; - } - - // JavaScriptDialogManager - - void RunJavaScriptDialog(WebContents* web_contents, - RenderFrameHost* render_frame_host, - JavaScriptDialogType dialog_type, - const base::string16& message_text, - const base::string16& default_prompt_text, - DialogClosedCallback callback, - bool* did_suppress_message) override { - NOTREACHED(); - } - - void RunBeforeUnloadDialog(WebContents* web_contents, - RenderFrameHost* render_frame_host, - bool is_reload, - DialogClosedCallback callback) override { - callback_ = std::move(callback); - run_loop_->Quit(); - } - - bool HandleJavaScriptDialog(WebContents* web_contents, - bool accept, - const base::string16* prompt_override) override { - NOTREACHED(); - return true; - } - - void CancelDialogs(WebContents* web_contents, bool reset_state) override {} - - private: - WebContentsImpl* web_contents_; - - DialogClosedCallback callback_; - - std::unique_ptr<base::RunLoop> run_loop_ = std::make_unique<base::RunLoop>(); - - DISALLOW_COPY_AND_ASSIGN(TestWCBeforeUnloadDelegate); -}; - -// This is a regression test for https://crbug.com/891423 in which tabs showing -// beforeunload dialogs stalled navigation and triggered the "hung process" -// dialog. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - NoCommitTimeoutWithBeforeUnloadDialog) { - WebContentsImpl* web_contents = - static_cast<WebContentsImpl*>(shell()->web_contents()); - - // Navigate first tab to a.com. - GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), a_url)); - RenderProcessHost* a_process = web_contents->GetMainFrame()->GetProcess(); - - // Open b.com in a second tab. Using a renderer-initiated navigation is - // important to leave a.com and b.com SiteInstances in the same - // BrowsingInstance (so the b.com -> a.com navigation in the next test step - // will reuse the process associated with the first a.com tab). - GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html")); - Shell* new_shell = OpenPopup(web_contents, b_url, "newtab"); - WebContents* new_contents = new_shell->web_contents(); - EXPECT_TRUE(WaitForLoadStop(new_contents)); - RenderProcessHost* b_process = new_contents->GetMainFrame()->GetProcess(); - EXPECT_NE(a_process, b_process); - - // Disable the beforeunload hang monitor (otherwise there will be a race - // between the beforeunload dialog and the beforeunload hang timer) and give - // the page a gesture to allow dialogs. - web_contents->GetMainFrame()->DisableBeforeUnloadHangMonitorForTesting(); - web_contents->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests( - base::string16()); - - // Hang the first contents in a beforeunload dialog. - TestWCBeforeUnloadDelegate test_delegate(web_contents); - EXPECT_TRUE( - ExecJs(web_contents, "window.onbeforeunload=function(e){ return 'x' }")); - EXPECT_TRUE(ExecJs(web_contents, - "setTimeout(function() { window.location.reload() }, 0)")); - test_delegate.Wait(); - - // Attempt to navigate the second tab to a.com. This will attempt to reuse - // the hung process. - base::TimeDelta kTimeout = base::TimeDelta::FromMilliseconds(100); - NavigationHandleImpl::SetCommitTimeoutForTesting(kTimeout); - GURL hung_url(embedded_test_server()->GetURL("a.com", "/title3.html")); - UnresponsiveRendererObserver unresponsive_renderer_observer(new_contents); - EXPECT_TRUE( - ExecJs(new_contents, JsReplace("window.location = $1", hung_url))); - - // Verify that we will not be notified about the unresponsive renderer. - // Before changes in https://crrev.com/c/1089797, the test would get notified - // and therefore |hung_process| would be non-null. - RenderProcessHost* hung_process = - unresponsive_renderer_observer.Wait(kTimeout * 10); - EXPECT_FALSE(hung_process); - - // Reset the timeout. - NavigationHandleImpl::SetCommitTimeoutForTesting(base::TimeDelta()); -} - // Tests that an inner WebContents will reattach to its outer WebContents after // a navigation that causes a process swap. IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ProcessSwapOnInnerContents) { @@ -14243,399 +13788,6 @@ EXPECT_GT(GetScrollTop(), 0); } -// Test that unload handlers in iframes are run, even when the removed subtree -// is complicated with nested iframes in different processes. -// A1 A1 -// / \ / \ -// B1 D --- Navigate ---> E D -// / \ -// C1 C2 -// | | -// B2 A2 -// | -// C3 -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, UnloadHandlerSubframes) { - GURL main_url(embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(b(c(b),c(a(c))),d)")); - EXPECT_TRUE(NavigateToURL(shell(), main_url)); - - // Add a unload handler to every frames. It notifies the browser using the - // DomAutomationController it has been executed. - FrameTreeNode* root = web_contents()->GetFrameTree()->root(); - UnloadPrint(root, "A1"); - UnloadPrint(root->child_at(0), "B1"); - UnloadPrint(root->child_at(0)->child_at(0), "C1"); - UnloadPrint(root->child_at(0)->child_at(1), "C2"); - UnloadPrint(root->child_at(0)->child_at(0)->child_at(0), "B2"); - UnloadPrint(root->child_at(0)->child_at(1)->child_at(0), "A2"); - UnloadPrint(root->child_at(0)->child_at(1)->child_at(0)->child_at(0), "C3"); - DOMMessageQueue dom_message_queue( - WebContents::FromRenderFrameHost(web_contents()->GetMainFrame())); - - // Disable the swap out timer on B1. - root->child_at(0)->current_frame_host()->DisableSwapOutTimerForTesting(); - - // Process B and C are expected to shutdown once every unload handler has - // run. - RenderProcessHostWatcher shutdown_B( - root->child_at(0)->current_frame_host()->GetProcess(), - RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - RenderProcessHostWatcher shutdown_C( - root->child_at(0)->child_at(0)->current_frame_host()->GetProcess(), - RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - - // Navigate B to E. - GURL e_url(embedded_test_server()->GetURL("e.com", "/title1.html")); - NavigateFrameToURL(root->child_at(0), e_url); - - // Collect unload handler messages. - std::string message; - std::vector<std::string> messages; - for (int i = 0; i < 6; ++i) { - EXPECT_TRUE(dom_message_queue.WaitForMessage(&message)); - base::TrimString(message, "\"", &message); - messages.push_back(message); - } - EXPECT_FALSE(dom_message_queue.PopMessage(&message)); - - // Check every frame in the replaced subtree has executed its unload handler. - EXPECT_THAT(messages, - WhenSorted(ElementsAre("A2", "B1", "B2", "C1", "C2", "C3"))); - - // In every renderer process, check ancestors have executed their unload - // handler before their children. This is a slightly less restrictive - // condition than the specification which requires it to be global instead of - // per process. - // https://html.spec.whatwg.org/multipage/browsing-the-web.html#unloading-documents - // - // In process B: - auto B1 = std::find(messages.begin(), messages.end(), "B1"); - auto B2 = std::find(messages.begin(), messages.end(), "B2"); - EXPECT_LT(B1, B2); - - // In process C: - auto C2 = std::find(messages.begin(), messages.end(), "C2"); - auto C3 = std::find(messages.begin(), messages.end(), "C3"); - EXPECT_LT(C2, C3); - - // Make sure the processes are deleted at some point. - shutdown_B.Wait(); - shutdown_C.Wait(); -} - -// Check that unload handlers in iframe don't prevents the main frame to be -// deleted after a timeout. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, SlowUnloadHandlerInIframe) { - GURL initial_url(embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(b)")); - GURL next_url(embedded_test_server()->GetURL("c.com", "/title1.html")); - - // 1) Navigate on a page with an iframe. - EXPECT_TRUE(NavigateToURL(shell(), initial_url)); - - // 2) Act as if there was an infinite unload handler in B. - auto filter = base::MakeRefCounted<DetachMessageFilter>(); - RenderFrameHost* rfh_b = - web_contents()->GetFrameTree()->root()->child_at(0)->current_frame_host(); - rfh_b->GetProcess()->AddFilter(filter.get()); - - // 3) Navigate and check the old frame is deleted after some time. - FrameTreeNode* root = web_contents()->GetFrameTree()->root(); - RenderFrameDeletedObserver deleted_observer(root->current_frame_host()); - EXPECT_TRUE(NavigateToURL(shell(), next_url)); - deleted_observer.WaitUntilDeleted(); -} - -// Navigate from A(B(A(B)) to C. Check the unload handler are executed, executed -// in the right order and the processes for A and B are removed. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, Unload_ABAB) { - GURL initial_url(embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(b(a(b)))")); - GURL next_url(embedded_test_server()->GetURL("c.com", "/title1.html")); - - // 1) Navigate on a page with an iframe. - EXPECT_TRUE(NavigateToURL(shell(), initial_url)); - - // 2) Add unload handler on every frame. - FrameTreeNode* root = web_contents()->GetFrameTree()->root(); - UnloadPrint(root, "A1"); - UnloadPrint(root->child_at(0), "B1"); - UnloadPrint(root->child_at(0)->child_at(0), "A2"); - UnloadPrint(root->child_at(0)->child_at(0)->child_at(0), "B2"); - root->current_frame_host()->DisableSwapOutTimerForTesting(); - - DOMMessageQueue dom_message_queue( - WebContents::FromRenderFrameHost(web_contents()->GetMainFrame())); - RenderProcessHostWatcher shutdown_A( - root->current_frame_host()->GetProcess(), - RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - RenderProcessHostWatcher shutdown_B( - root->child_at(0)->current_frame_host()->GetProcess(), - RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - - // 3) Navigate cross process. - EXPECT_TRUE(NavigateToURL(shell(), next_url)); - - // 4) Wait for unload handler messages and check they are sent in order. - std::vector<std::string> messages; - std::string message; - for (int i = 0; i < 4; ++i) { - EXPECT_TRUE(dom_message_queue.WaitForMessage(&message)); - base::TrimString(message, "\"", &message); - messages.push_back(message); - } - EXPECT_FALSE(dom_message_queue.PopMessage(&message)); - - EXPECT_THAT(messages, WhenSorted(ElementsAre("A1", "A2", "B1", "B2"))); - auto A1 = std::find(messages.begin(), messages.end(), "A1"); - auto A2 = std::find(messages.begin(), messages.end(), "A2"); - auto B1 = std::find(messages.begin(), messages.end(), "B1"); - auto B2 = std::find(messages.begin(), messages.end(), "B2"); - EXPECT_LT(A1, A2); - EXPECT_LT(B1, B2); - - // Make sure the processes are deleted at some point. - shutdown_A.Wait(); - shutdown_B.Wait(); -} - -// Start with A(B(C)), navigate C to D and then B to E. By emulating a slow -// unload handler in B,C and D, the end result is C is in pending deletion in B -// and B is in pending deletion in A. -// (1) (2) (3) -//| | | | -//| A | A | A | -//| | | | | \ | -//| B | B | B E | -//| | | \ | \ | -//| C | C D | C D | -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, UnloadNestedPendingDeletion) { - std::string onunload_script = "window.onunload = function(){}"; - GURL url_abc(embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(b(c))")); - GURL url_d(embedded_test_server()->GetURL("d.com", "/title1.html")); - GURL url_e(embedded_test_server()->GetURL("e.com", "/title1.html")); - - // 1) Navigate to a page with an iframe. - EXPECT_TRUE(NavigateToURL(shell(), url_abc)); - RenderFrameHostImpl* rfh_a = web_contents()->GetMainFrame(); - RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host(); - RenderFrameHostImpl* rfh_c = rfh_b->child_at(0)->current_frame_host(); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_a->unload_state_); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_b->unload_state_); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_c->unload_state_); - - // Act as if there was a slow unload handler on rfh_b and rfh_c. - // The navigating frames are waiting for FrameHostMsg_SwapoutACK. - auto swapout_ack_filter_b = base::MakeRefCounted<SwapoutACKMessageFilter>(); - auto swapout_ack_filter_c = base::MakeRefCounted<SwapoutACKMessageFilter>(); - rfh_b->GetProcess()->AddFilter(swapout_ack_filter_b.get()); - rfh_c->GetProcess()->AddFilter(swapout_ack_filter_c.get()); - EXPECT_TRUE(ExecuteScript(rfh_b->frame_tree_node(), onunload_script)); - EXPECT_TRUE(ExecuteScript(rfh_c->frame_tree_node(), onunload_script)); - rfh_b->DisableSwapOutTimerForTesting(); - rfh_c->DisableSwapOutTimerForTesting(); - - RenderFrameDeletedObserver delete_b(rfh_b), delete_c(rfh_c); - - // 2) Navigate rfh_c to D. - NavigateFrameToURL(rfh_c->frame_tree_node(), url_d); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_a->unload_state_); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_b->unload_state_); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, rfh_c->unload_state_); - RenderFrameHostImpl* rfh_d = rfh_b->child_at(0)->current_frame_host(); - - RenderFrameDeletedObserver delete_d(rfh_d); - - // Act as if there was a slow unload handler on rfh_d. - // The non navigating frames are waiting for FrameHostMsg_Detach. - auto detach_filter = base::MakeRefCounted<DetachMessageFilter>(); - rfh_d->GetProcess()->AddFilter(detach_filter.get()); - EXPECT_TRUE(ExecuteScript(rfh_d->frame_tree_node(), onunload_script)); - - // 3) Navigate rfh_b to E. - NavigateFrameToURL(rfh_b->frame_tree_node(), url_e); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_a->unload_state_); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, rfh_b->unload_state_); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, rfh_c->unload_state_); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, rfh_d->unload_state_); - - // rfh_d completes its unload event. It deletes the frame, including rfh_c. - EXPECT_FALSE(delete_c.deleted()); - EXPECT_FALSE(delete_d.deleted()); - rfh_d->OnDetach(); - EXPECT_TRUE(delete_c.deleted()); - EXPECT_TRUE(delete_d.deleted()); - - // rfh_b completes its unload event. - EXPECT_FALSE(delete_b.deleted()); - rfh_b->OnSwapOutACK(); - EXPECT_TRUE(delete_b.deleted()); -} - -// A set of nested frames A1(B1(A2)) are pending deletion because of a -// navigation. This tests what happens if only A2 has an unload handler. -// If B1 receives FrameHostMsg_OnDetach before A2, it should not destroy itself -// and its children, but rather wait for A2. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, PartialUnloadHandler) { - GURL url_aba(embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(b(a))")); - GURL url_c(embedded_test_server()->GetURL("c.com", "/title1.html")); - - // 1) Navigate to A1(B1(A2)) - EXPECT_TRUE(NavigateToURL(shell(), url_aba)); - - FrameTreeNode* root = web_contents()->GetFrameTree()->root(); - RenderFrameHostImpl* a1 = root->current_frame_host(); - RenderFrameHostImpl* b1 = a1->child_at(0)->current_frame_host(); - RenderFrameHostImpl* a2 = b1->child_at(0)->current_frame_host(); - RenderFrameDeletedObserver delete_a1(a1); - RenderFrameDeletedObserver delete_a2(a2); - RenderFrameDeletedObserver delete_b1(b1); - - // Disable Detach and Swapout ACK. They will be called manually. - auto swapout_ack_filter = base::MakeRefCounted<SwapoutACKMessageFilter>(); - auto detach_filter_a = base::MakeRefCounted<DetachMessageFilter>(); - auto detach_filter_b = base::MakeRefCounted<DetachMessageFilter>(); - a1->GetProcess()->AddFilter(swapout_ack_filter.get()); - a1->GetProcess()->AddFilter(detach_filter_a.get()); - b1->GetProcess()->AddFilter(detach_filter_b.get()); - - a1->DisableSwapOutTimerForTesting(); - - // Add unload handler on A2, but not on the other frames. - UnloadPrint(a2->frame_tree_node(), "A2"); - - DOMMessageQueue dom_message_queue( - WebContents::FromRenderFrameHost(web_contents()->GetMainFrame())); - - // 2) Navigate cross process. - EXPECT_TRUE(NavigateToURL(shell(), url_c)); - - // Check that unload handlers are executed. - std::string message, message_unused; - EXPECT_TRUE(dom_message_queue.WaitForMessage(&message)); - EXPECT_FALSE(dom_message_queue.PopMessage(&message_unused)); - EXPECT_EQ("\"A2\"", message); - - // No RenderFrameHost are deleted so far. - EXPECT_FALSE(delete_a1.deleted()); - EXPECT_FALSE(delete_b1.deleted()); - EXPECT_FALSE(delete_a2.deleted()); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, a1->unload_state_); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::Completed, b1->unload_state_); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, a2->unload_state_); - - // 3) B1 receives confirmation it has been deleted. This has no effect, - // because it is still waiting on A2 to be deleted. - b1->OnDetach(); - EXPECT_FALSE(delete_a1.deleted()); - EXPECT_FALSE(delete_b1.deleted()); - EXPECT_FALSE(delete_a2.deleted()); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, a1->unload_state_); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::Completed, b1->unload_state_); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, a2->unload_state_); - - // 4) A2 received confirmation that it has been deleted and destroy B1 and A2. - a2->OnDetach(); - EXPECT_FALSE(delete_a1.deleted()); - EXPECT_TRUE(delete_b1.deleted()); - EXPECT_TRUE(delete_a2.deleted()); - EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, a1->unload_state_); - - // 5) A1 receives SwapOutACK and deletes itself. - a1->OnSwapOutACK(); - EXPECT_TRUE(delete_a1.deleted()); -} - -// Test RenderFrameHostImpl::PendingDeletionCheckCompletedOnSubtree. -// -// After a navigation commit, some children with no unload handler may be -// eligible for immediate deletion. Several configurations are tested: -// -// Before navigation commit -// -// 0 | N : No unload handler -// ‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑ | [N] : Unload handler -// | | | | | | | | -// [1] 2 [3] 5 7 9 12 | -// | | | / \ / \ | -// 4 [6] 8 10 11 13 [14] | -// -// After navigation commit (expected) -// -// 0 | N : No unload handler -// --------------------- | [N] : Unload handler -// | | | | | -// [1] [3] 5 12 | -// | \ | -// [6] [14] | -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - PendingDeletionCheckCompletedOnSubtree) { - GURL url_1(embedded_test_server()->GetURL( - "a.com", - "/cross_site_iframe_factory.html?a(a,a,a(a),a(a),a(a),a(a,a),a(a,a))")); - GURL url_2(embedded_test_server()->GetURL("b.com", "/title1.html")); - - // 1) Navigate to 0(1,2,3(4),5(6),7(8),9(10,11),12(13,14)); - EXPECT_TRUE(NavigateToURL(shell(), url_1)); - - FrameTreeNode* root = web_contents()->GetFrameTree()->root(); - RenderFrameHostImpl* rfh_0 = root->current_frame_host(); - RenderFrameHostImpl* rfh_1 = rfh_0->child_at(0)->current_frame_host(); - RenderFrameHostImpl* rfh_2 = rfh_0->child_at(1)->current_frame_host(); - RenderFrameHostImpl* rfh_3 = rfh_0->child_at(2)->current_frame_host(); - RenderFrameHostImpl* rfh_4 = rfh_3->child_at(0)->current_frame_host(); - RenderFrameHostImpl* rfh_5 = rfh_0->child_at(3)->current_frame_host(); - RenderFrameHostImpl* rfh_6 = rfh_5->child_at(0)->current_frame_host(); - RenderFrameHostImpl* rfh_7 = rfh_0->child_at(4)->current_frame_host(); - RenderFrameHostImpl* rfh_8 = rfh_7->child_at(0)->current_frame_host(); - RenderFrameHostImpl* rfh_9 = rfh_0->child_at(5)->current_frame_host(); - RenderFrameHostImpl* rfh_10 = rfh_9->child_at(0)->current_frame_host(); - RenderFrameHostImpl* rfh_11 = rfh_9->child_at(1)->current_frame_host(); - RenderFrameHostImpl* rfh_12 = rfh_0->child_at(6)->current_frame_host(); - RenderFrameHostImpl* rfh_13 = rfh_12->child_at(0)->current_frame_host(); - RenderFrameHostImpl* rfh_14 = rfh_12->child_at(1)->current_frame_host(); - - RenderFrameDeletedObserver delete_a0(rfh_0), delete_a1(rfh_1), - delete_a2(rfh_2), delete_a3(rfh_3), delete_a4(rfh_4), delete_a5(rfh_5), - delete_a6(rfh_6), delete_a7(rfh_7), delete_a8(rfh_8), delete_a9(rfh_9), - delete_a10(rfh_10), delete_a11(rfh_11), delete_a12(rfh_12), - delete_a13(rfh_13), delete_a14(rfh_14); - - // Add the unload handlers. - UnloadPrint(rfh_1->frame_tree_node(), ""); - UnloadPrint(rfh_3->frame_tree_node(), ""); - UnloadPrint(rfh_6->frame_tree_node(), ""); - UnloadPrint(rfh_14->frame_tree_node(), ""); - - // Disable Detach and Swapout ACK. - auto swapout_ack_filter = base::MakeRefCounted<SwapoutACKMessageFilter>(); - auto detach_filter = base::MakeRefCounted<DetachMessageFilter>(); - rfh_0->GetProcess()->AddFilter(swapout_ack_filter.get()); - rfh_0->GetProcess()->AddFilter(detach_filter.get()); - rfh_0->DisableSwapOutTimerForTesting(); - - // 2) Navigate cross process and check the tree. See diagram above. - EXPECT_TRUE(NavigateToURL(shell(), url_2)); - - EXPECT_FALSE(delete_a0.deleted()); - EXPECT_FALSE(delete_a1.deleted()); - EXPECT_TRUE(delete_a2.deleted()); - EXPECT_FALSE(delete_a3.deleted()); - EXPECT_TRUE(delete_a4.deleted()); - EXPECT_FALSE(delete_a5.deleted()); - EXPECT_FALSE(delete_a6.deleted()); - EXPECT_TRUE(delete_a7.deleted()); - EXPECT_TRUE(delete_a8.deleted()); - EXPECT_TRUE(delete_a9.deleted()); - EXPECT_TRUE(delete_a10.deleted()); - EXPECT_TRUE(delete_a11.deleted()); - EXPECT_FALSE(delete_a12.deleted()); - EXPECT_TRUE(delete_a13.deleted()); - EXPECT_FALSE(delete_a14.deleted()); -} - #if !defined(OS_ANDROID) // This test verifies that after occluding a WebContents the RAF inside a // cross-process child frame is throttled. @@ -14751,137 +13903,6 @@ EXPECT_EQ(bad_message::RFH_INVALID_ORIGIN_ON_COMMIT, kill_waiter.Wait()); } -// When an iframe is detached, check that unload handlers execute in all of its -// child frames. Start from A(B(C)) and delete B from A. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - DetachedIframeUnloadHandlerABC) { - GURL initial_url(embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(b(c))")); - - // 1) Navigate to a(b(c)) - EXPECT_TRUE(NavigateToURL(shell(), initial_url)); - FrameTreeNode* root = web_contents()->GetFrameTree()->root(); - RenderFrameHostImpl* rfh_a = root->current_frame_host(); - RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host(); - RenderFrameHostImpl* rfh_c = rfh_b->child_at(0)->current_frame_host(); - - // 2) Add unload handlers on B and C. - UnloadPrint(rfh_b->frame_tree_node(), "B"); - UnloadPrint(rfh_c->frame_tree_node(), "C"); - - DOMMessageQueue dom_message_queue(web_contents()); - RenderProcessHostWatcher shutdown_B( - rfh_b->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - RenderProcessHostWatcher shutdown_C( - rfh_c->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - - // 3) Detach B from A. - ExecuteScriptAsync(root, "document.querySelector('iframe').remove();"); - - // 4) Wait for unload handler. - std::vector<std::string> messages(2); - EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[0])); - EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[1])); - std::string unused; - EXPECT_FALSE(dom_message_queue.PopMessage(&unused)); - - std::sort(messages.begin(), messages.end()); - EXPECT_EQ("\"B\"", messages[0]); - EXPECT_EQ("\"C\"", messages[1]); - - // Make sure the processes are deleted at some point. - shutdown_B.Wait(); - shutdown_C.Wait(); -} - -// When an iframe is detached, check that unload handlers execute in all of its -// child frames. Start from A(B1(C(B2))) and delete B1 from A. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - DetachedIframeUnloadHandlerABCB) { - GURL initial_url(embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(b(c(b)))")); - - // 1) Navigate to a(b(c(b))) - EXPECT_TRUE(NavigateToURL(shell(), initial_url)); - FrameTreeNode* root = web_contents()->GetFrameTree()->root(); - RenderFrameHostImpl* rfh_a = root->current_frame_host(); - RenderFrameHostImpl* rfh_b1 = rfh_a->child_at(0)->current_frame_host(); - RenderFrameHostImpl* rfh_c = rfh_b1->child_at(0)->current_frame_host(); - RenderFrameHostImpl* rfh_b2 = rfh_c->child_at(0)->current_frame_host(); - - // 2) Add unload handlers on B1, B2 and C. - UnloadPrint(rfh_b1->frame_tree_node(), "B1"); - UnloadPrint(rfh_b2->frame_tree_node(), "B2"); - UnloadPrint(rfh_c->frame_tree_node(), "C"); - - DOMMessageQueue dom_message_queue(web_contents()); - RenderProcessHostWatcher shutdown_B( - rfh_b1->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - RenderProcessHostWatcher shutdown_C( - rfh_c->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - - // 3) Detach B from A. - ExecuteScriptAsync(root, "document.querySelector('iframe').remove();"); - - // 4) Wait for unload handler. - std::vector<std::string> messages(3); - EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[0])); - EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[1])); - EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[2])); - std::string unused; - EXPECT_FALSE(dom_message_queue.PopMessage(&unused)); - - std::sort(messages.begin(), messages.end()); - EXPECT_EQ("\"B1\"", messages[0]); - EXPECT_EQ("\"B2\"", messages[1]); - EXPECT_EQ("\"C\"", messages[2]); - - // Make sure the processes are deleted at some point. - shutdown_B.Wait(); - shutdown_C.Wait(); -} - -// When an iframe is detached, check that unload handlers execute in all of its -// child frames. Start from A1(A2(B)), delete A2 from itself. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - DetachedIframeUnloadHandlerAAB) { - GURL initial_url(embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(a(b))")); - - // 1) Navigate to a(a(b)). - EXPECT_TRUE(NavigateToURL(shell(), initial_url)); - FrameTreeNode* root = web_contents()->GetFrameTree()->root(); - RenderFrameHostImpl* rfh_a1 = root->current_frame_host(); - RenderFrameHostImpl* rfh_a2 = rfh_a1->child_at(0)->current_frame_host(); - RenderFrameHostImpl* rfh_b = rfh_a2->child_at(0)->current_frame_host(); - - // 2) Add unload handlers on A2 ad B. - UnloadPrint(rfh_a2->frame_tree_node(), "A2"); - UnloadPrint(rfh_b->frame_tree_node(), "B"); - - DOMMessageQueue dom_message_queue(web_contents()); - RenderProcessHostWatcher shutdown_B( - rfh_b->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - - // 3) A2 detaches itself. - ExecuteScriptAsync(rfh_a2->frame_tree_node(), - "parent.document.querySelector('iframe').remove();"); - - // 4) Wait for unload handler. - std::vector<std::string> messages(2); - EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[0])); - EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[1])); - std::string unused; - EXPECT_FALSE(dom_message_queue.PopMessage(&unused)); - - std::sort(messages.begin(), messages.end()); - EXPECT_EQ("\"A2\"", messages[0]); - EXPECT_EQ("\"B\"", messages[1]); - - // Make sure the process is deleted at some point. - shutdown_B.Wait(); -} - // This test verifies that plugin elements containing cross-process-frames do // not become unresponsive during style changes. (see https://crbug.com/781880). IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, @@ -14950,7 +13971,8 @@ RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host(); // RFH B has an unload handler. - auto detach_filter_b = base::MakeRefCounted<DetachMessageFilter>(); + auto detach_filter_b = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_Detach::ID); rfh_b->GetProcess()->AddFilter(detach_filter_b.get()); EXPECT_TRUE(ExecJs(rfh_b, "onunload=function(){}")); @@ -15002,7 +14024,8 @@ RenderFrameHostImpl* rfh_c = rfh_b->child_at(0)->current_frame_host(); // RFH C has an unload handler. - auto detach_filter_c = base::MakeRefCounted<DetachMessageFilter>(); + auto detach_filter_c = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_Detach::ID); rfh_c->GetProcess()->AddFilter(detach_filter_c.get()); EXPECT_TRUE(ExecJs(rfh_c, "onunload=function(){}"));
diff --git a/content/browser/site_per_process_unload_browsertest.cc b/content/browser/site_per_process_unload_browsertest.cc new file mode 100644 index 0000000..a54bdaad --- /dev/null +++ b/content/browser/site_per_process_unload_browsertest.cc
@@ -0,0 +1,1020 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/site_per_process_browsertest.h" + +#include <algorithm> +#include <list> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "base/json/json_reader.h" +#include "base/location.h" +#include "base/memory/ptr_util.h" +#include "base/run_loop.h" +#include "base/scoped_observer.h" +#include "base/single_thread_task_runner.h" +#include "base/stl_util.h" +#include "base/test/test_timeouts.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "content/browser/frame_host/cross_process_frame_connector.h" +#include "content/browser/frame_host/frame_tree.h" +#include "content/browser/frame_host/navigation_controller_impl.h" +#include "content/browser/frame_host/navigator.h" +#include "content/browser/frame_host/render_frame_host_impl.h" +#include "content/browser/renderer_host/render_widget_host_view_child_frame.h" +#include "content/browser/web_contents/web_contents_impl.h" +#include "content/common/frame_messages.h" +#include "content/public/browser/javascript_dialog_manager.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/common/url_constants.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/content_browser_test_utils.h" +#include "content/shell/browser/shell.h" +#include "content/test/content_browser_test_utils_internal.h" +#include "content/test/did_commit_provisional_load_interceptor.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_request.h" +#include "net/test/embedded_test_server/http_response.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::ElementsAre; +using testing::WhenSorted; + +namespace content { + +namespace { + +void UnloadPrint(FrameTreeNode* node, const char* message) { + EXPECT_TRUE( + ExecJs(node, JsReplace("window.onunload = function() { " + " window.domAutomationController.send($1);" + "}", + message))); +} + +} // namespace + +// Tests that there are no crashes if a subframe is detached in its unload +// handler. See https://crbug.com/590054. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, DetachInUnloadHandler) { + GURL main_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b(b))")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetFrameTree() + ->root(); + + EXPECT_EQ( + " Site A ------------ proxies for B\n" + " +--Site B ------- proxies for A\n" + " +--Site B -- proxies for A\n" + "Where A = http://a.com/\n" + " B = http://b.com/", + DepictFrameTree(root)); + + EXPECT_EQ(1, EvalJs(root->child_at(0), "frames.length;")); + + RenderFrameDeletedObserver deleted_observer( + root->child_at(0)->child_at(0)->current_frame_host()); + + // Add an unload handler to the grandchild that causes it to be synchronously + // detached, then navigate it. + EXPECT_TRUE(ExecuteScript( + root->child_at(0)->child_at(0), + "window.onunload=function(e){\n" + " window.parent.document.getElementById('child-0').remove();\n" + "};\n")); + auto script = JsReplace("window.document.getElementById('child-0').src = $1", + embedded_test_server()->GetURL( + "c.com", "/cross_site_iframe_factory.html?c")); + EXPECT_TRUE(ExecuteScript(root->child_at(0), script)); + + deleted_observer.WaitUntilDeleted(); + + EXPECT_EQ(0, EvalJs(root->child_at(0), "frames.length;")); + + EXPECT_EQ( + " Site A ------------ proxies for B\n" + " +--Site B ------- proxies for A\n" + "Where A = http://a.com/\n" + " B = http://b.com/", + DepictFrameTree(root)); +} + +// Tests that trying to navigate in the unload handler doesn't crash the +// browser. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, NavigateInUnloadHandler) { + GURL main_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b(b))")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetFrameTree() + ->root(); + + EXPECT_EQ( + " Site A ------------ proxies for B\n" + " +--Site B ------- proxies for A\n" + " +--Site B -- proxies for A\n" + "Where A = http://a.com/\n" + " B = http://b.com/", + DepictFrameTree(root)); + + EXPECT_EQ(1, + EvalJs(root->child_at(0)->current_frame_host(), "frames.length;")); + + // Add an unload handler to B's subframe. + EXPECT_TRUE( + ExecuteScript(root->child_at(0)->child_at(0)->current_frame_host(), + "window.onunload=function(e){\n" + " window.location = '#navigate';\n" + "};\n")); + + // Navigate B's subframe to a cross-site C. + RenderFrameDeletedObserver deleted_observer( + root->child_at(0)->child_at(0)->current_frame_host()); + auto script = JsReplace("window.document.getElementById('child-0').src = $1", + embedded_test_server()->GetURL( + "c.com", "/cross_site_iframe_factory.html")); + EXPECT_TRUE(ExecuteScript(root->child_at(0)->current_frame_host(), script)); + + // Wait until B's subframe RenderFrameHost is destroyed. + deleted_observer.WaitUntilDeleted(); + + // Check that C's subframe is alive and the navigation in the unload handler + // was ignored. + EXPECT_EQ(0, EvalJs(root->child_at(0)->child_at(0)->current_frame_host(), + "frames.length;")); + + EXPECT_EQ( + " Site A ------------ proxies for B C\n" + " +--Site B ------- proxies for A C\n" + " +--Site C -- proxies for A B\n" + "Where A = http://a.com/\n" + " B = http://b.com/\n" + " C = http://c.com/", + DepictFrameTree(root)); +} + +// Verifies that when navigating an OOPIF to same site and then canceling +// navigation from beforeunload handler popup will not remove the +// RemoteFrameView from OOPIF's owner element in the parent process. This test +// uses OOPIF visibility to make sure RemoteFrameView exists after beforeunload +// is handled. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + CanceledBeforeUnloadShouldNotClearRemoteFrameView) { + GURL a_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b)")); + EXPECT_TRUE(NavigateToURL(shell(), a_url)); + + FrameTreeNode* child_node = + web_contents()->GetFrameTree()->root()->child_at(0); + GURL b_url(embedded_test_server()->GetURL( + "b.com", "/render_frame_host/beforeunload.html")); + NavigateFrameToURL(child_node, b_url); + FrameConnectorDelegate* frame_connector_delegate = + static_cast<RenderWidgetHostViewChildFrame*>( + child_node->current_frame_host()->GetView()) + ->FrameConnectorForTesting(); + + // Need user gesture for 'beforeunload' to fire. + PrepContentsForBeforeUnloadTest(web_contents()); + + // Simulate user choosing to stay on the page after beforeunload fired. + SetShouldProceedOnBeforeUnload(shell(), true /* proceed */, + false /* success */); + + // First, hide the <iframe>. This goes through RemoteFrameView::Hide() and + // eventually updates the FrameConnectorDelegate. Also, + // RemoteFrameView::self_visible_ will be set to false which can only be + // undone by calling RemoteFrameView::Show. Therefore, potential calls to + // RemoteFrameView::SetParentVisible(true) would not update the visibility at + // the browser side. + ASSERT_TRUE(ExecuteScript( + web_contents(), + "document.querySelector('iframe').style.visibility = 'hidden';")); + while (!frame_connector_delegate->IsHidden()) { + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout()); + run_loop.Run(); + } + + // Now we navigate the child to about:blank, but since we do not proceed with + // the navigation, the OOPIF should stay alive and RemoteFrameView intact. + ASSERT_TRUE(ExecuteScript( + web_contents(), "document.querySelector('iframe').src = 'about:blank';")); + WaitForAppModalDialog(shell()); + + // Sanity check: We should still have an OOPIF and hence a RWHVCF. + ASSERT_TRUE(static_cast<RenderWidgetHostViewBase*>( + child_node->current_frame_host()->GetView()) + ->IsRenderWidgetHostViewChildFrame()); + + // Now make the <iframe> visible again. This calls RemoteFrameView::Show() + // only if the RemoteFrameView is the EmbeddedContentView of the corresponding + // HTMLFrameOwnerElement. + ASSERT_TRUE(ExecuteScript( + web_contents(), + "document.querySelector('iframe').style.visibility = 'visible';")); + while (frame_connector_delegate->IsHidden()) { + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout()); + run_loop.Run(); + } +} + +// Ensure that after a main frame with an OOPIF is navigated cross-site, the +// unload handler in the OOPIF sees correct main frame origin, namely the old +// and not the new origin. See https://crbug.com/825283. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + ParentOriginDoesNotChangeInUnloadHandler) { + GURL main_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b)")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetFrameTree() + ->root(); + + // Open a popup on b.com. The b.com subframe on the main frame will use this + // in its unload handler. + GURL b_url(embedded_test_server()->GetURL("b.com", "/title1.html")); + EXPECT_TRUE(OpenPopup(shell()->web_contents(), b_url, "popup")); + + // Add an unload handler to b.com subframe, which will look up the top + // frame's origin and send it via domAutomationController. Unfortunately, + // the subframe's browser-side state will have been torn down when it runs + // the unload handler, so to ensure that the message can be received, send it + // through the popup. + EXPECT_TRUE( + ExecuteScript(root->child_at(0), + "window.onunload = function(e) {" + " window.open('','popup').domAutomationController.send(" + " 'top-origin ' + location.ancestorOrigins[0]);" + "};")); + + // Navigate the main frame to c.com and wait for the message from the + // subframe's unload handler. + GURL c_url(embedded_test_server()->GetURL("c.com", "/title1.html")); + DOMMessageQueue msg_queue; + EXPECT_TRUE(NavigateToURL(shell(), c_url)); + std::string message, top_origin; + while (msg_queue.WaitForMessage(&message)) { + base::TrimString(message, "\"", &message); + auto message_parts = base::SplitString(message, " ", base::TRIM_WHITESPACE, + base::SPLIT_WANT_NONEMPTY); + if (message_parts[0] == "top-origin") { + top_origin = message_parts[1]; + break; + } + } + + // The top frame's origin should be a.com, not c.com. + EXPECT_EQ(top_origin + "/", main_url.GetOrigin().spec()); +} + +// Verify that when the last active frame in a process is going away as part of +// OnSwapOut, the SwapOut ACK is received prior to the process starting to shut +// down, ensuring that any related unload work also happens before shutdown. +// See https://crbug.com/867274 and https://crbug.com/794625. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + SwapOutACKArrivesPriorToProcessShutdownRequest) { + GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), start_url)); + RenderFrameHostImpl* rfh = web_contents()->GetMainFrame(); + rfh->DisableSwapOutTimerForTesting(); + + // Navigate cross-site. Since the current frame is the last active frame in + // the current process, the process will eventually shut down. Once the + // process goes away, ensure that the SwapOut ACK was received (i.e., that we + // didn't just simulate OnSwappedOut() due to the process erroneously going + // away before the SwapOut ACK was received, as in https://crbug.com/867274). + RenderProcessHostWatcher watcher( + rfh->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + auto swapout_ack_filter = base::MakeRefCounted<ObserveMessageFilter>( + FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID); + rfh->GetProcess()->AddFilter(swapout_ack_filter.get()); + GURL cross_site_url(embedded_test_server()->GetURL("b.com", "/title1.html")); + EXPECT_TRUE(NavigateToURLFromRenderer(shell(), cross_site_url)); + watcher.Wait(); + EXPECT_TRUE(swapout_ack_filter->has_received_message()); + EXPECT_TRUE(watcher.did_exit_normally()); +} + +class TestWCBeforeUnloadDelegate : public JavaScriptDialogManager, + public WebContentsDelegate { + public: + explicit TestWCBeforeUnloadDelegate(WebContentsImpl* web_contents) + : web_contents_(web_contents) { + web_contents_->SetDelegate(this); + } + + ~TestWCBeforeUnloadDelegate() override { + if (!callback_.is_null()) + std::move(callback_).Run(true, base::string16()); + + web_contents_->SetDelegate(nullptr); + web_contents_->SetJavaScriptDialogManagerForTesting(nullptr); + } + + void Wait() { + run_loop_->Run(); + run_loop_ = std::make_unique<base::RunLoop>(); + } + + // WebContentsDelegate + + JavaScriptDialogManager* GetJavaScriptDialogManager( + WebContents* source) override { + return this; + } + + // JavaScriptDialogManager + + void RunJavaScriptDialog(WebContents* web_contents, + RenderFrameHost* render_frame_host, + JavaScriptDialogType dialog_type, + const base::string16& message_text, + const base::string16& default_prompt_text, + DialogClosedCallback callback, + bool* did_suppress_message) override { + NOTREACHED(); + } + + void RunBeforeUnloadDialog(WebContents* web_contents, + RenderFrameHost* render_frame_host, + bool is_reload, + DialogClosedCallback callback) override { + callback_ = std::move(callback); + run_loop_->Quit(); + } + + bool HandleJavaScriptDialog(WebContents* web_contents, + bool accept, + const base::string16* prompt_override) override { + NOTREACHED(); + return true; + } + + void CancelDialogs(WebContents* web_contents, bool reset_state) override {} + + private: + WebContentsImpl* web_contents_; + + DialogClosedCallback callback_; + + std::unique_ptr<base::RunLoop> run_loop_ = std::make_unique<base::RunLoop>(); + + DISALLOW_COPY_AND_ASSIGN(TestWCBeforeUnloadDelegate); +}; + +// This is a regression test for https://crbug.com/891423 in which tabs showing +// beforeunload dialogs stalled navigation and triggered the "hung process" +// dialog. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + NoCommitTimeoutWithBeforeUnloadDialog) { + WebContentsImpl* web_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + + // Navigate first tab to a.com. + GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), a_url)); + RenderProcessHost* a_process = web_contents->GetMainFrame()->GetProcess(); + + // Open b.com in a second tab. Using a renderer-initiated navigation is + // important to leave a.com and b.com SiteInstances in the same + // BrowsingInstance (so the b.com -> a.com navigation in the next test step + // will reuse the process associated with the first a.com tab). + GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html")); + Shell* new_shell = OpenPopup(web_contents, b_url, "newtab"); + WebContents* new_contents = new_shell->web_contents(); + EXPECT_TRUE(WaitForLoadStop(new_contents)); + RenderProcessHost* b_process = new_contents->GetMainFrame()->GetProcess(); + EXPECT_NE(a_process, b_process); + + // Disable the beforeunload hang monitor (otherwise there will be a race + // between the beforeunload dialog and the beforeunload hang timer) and give + // the page a gesture to allow dialogs. + web_contents->GetMainFrame()->DisableBeforeUnloadHangMonitorForTesting(); + web_contents->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests( + base::string16()); + + // Hang the first contents in a beforeunload dialog. + TestWCBeforeUnloadDelegate test_delegate(web_contents); + EXPECT_TRUE( + ExecJs(web_contents, "window.onbeforeunload=function(e){ return 'x' }")); + EXPECT_TRUE(ExecJs(web_contents, + "setTimeout(function() { window.location.reload() }, 0)")); + test_delegate.Wait(); + + // Attempt to navigate the second tab to a.com. This will attempt to reuse + // the hung process. + base::TimeDelta kTimeout = base::TimeDelta::FromMilliseconds(100); + NavigationHandleImpl::SetCommitTimeoutForTesting(kTimeout); + GURL hung_url(embedded_test_server()->GetURL("a.com", "/title3.html")); + UnresponsiveRendererObserver unresponsive_renderer_observer(new_contents); + EXPECT_TRUE( + ExecJs(new_contents, JsReplace("window.location = $1", hung_url))); + + // Verify that we will not be notified about the unresponsive renderer. + // Before changes in https://crrev.com/c/1089797, the test would get notified + // and therefore |hung_process| would be non-null. + RenderProcessHost* hung_process = + unresponsive_renderer_observer.Wait(kTimeout * 10); + EXPECT_FALSE(hung_process); + + // Reset the timeout. + NavigationHandleImpl::SetCommitTimeoutForTesting(base::TimeDelta()); +} + +// Test that unload handlers in iframes are run, even when the removed subtree +// is complicated with nested iframes in different processes. +// A1 A1 +// / \ / \ +// B1 D --- Navigate ---> E D +// / \ +// C1 C2 +// | | +// B2 A2 +// | +// C3 +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, UnloadHandlerSubframes) { + GURL main_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b(c(b),c(a(c))),d)")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + + // Add a unload handler to every frames. It notifies the browser using the + // DomAutomationController it has been executed. + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + UnloadPrint(root, "A1"); + UnloadPrint(root->child_at(0), "B1"); + UnloadPrint(root->child_at(0)->child_at(0), "C1"); + UnloadPrint(root->child_at(0)->child_at(1), "C2"); + UnloadPrint(root->child_at(0)->child_at(0)->child_at(0), "B2"); + UnloadPrint(root->child_at(0)->child_at(1)->child_at(0), "A2"); + UnloadPrint(root->child_at(0)->child_at(1)->child_at(0)->child_at(0), "C3"); + DOMMessageQueue dom_message_queue( + WebContents::FromRenderFrameHost(web_contents()->GetMainFrame())); + + // Disable the swap out timer on B1. + root->child_at(0)->current_frame_host()->DisableSwapOutTimerForTesting(); + + // Process B and C are expected to shutdown once every unload handler has + // run. + RenderProcessHostWatcher shutdown_B( + root->child_at(0)->current_frame_host()->GetProcess(), + RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + RenderProcessHostWatcher shutdown_C( + root->child_at(0)->child_at(0)->current_frame_host()->GetProcess(), + RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + + // Navigate B to E. + GURL e_url(embedded_test_server()->GetURL("e.com", "/title1.html")); + NavigateFrameToURL(root->child_at(0), e_url); + + // Collect unload handler messages. + std::string message; + std::vector<std::string> messages; + for (int i = 0; i < 6; ++i) { + EXPECT_TRUE(dom_message_queue.WaitForMessage(&message)); + base::TrimString(message, "\"", &message); + messages.push_back(message); + } + EXPECT_FALSE(dom_message_queue.PopMessage(&message)); + + // Check every frame in the replaced subtree has executed its unload handler. + EXPECT_THAT(messages, + WhenSorted(ElementsAre("A2", "B1", "B2", "C1", "C2", "C3"))); + + // In every renderer process, check ancestors have executed their unload + // handler before their children. This is a slightly less restrictive + // condition than the specification which requires it to be global instead of + // per process. + // https://html.spec.whatwg.org/multipage/browsing-the-web.html#unloading-documents + // + // In process B: + auto B1 = std::find(messages.begin(), messages.end(), "B1"); + auto B2 = std::find(messages.begin(), messages.end(), "B2"); + EXPECT_LT(B1, B2); + + // In process C: + auto C2 = std::find(messages.begin(), messages.end(), "C2"); + auto C3 = std::find(messages.begin(), messages.end(), "C3"); + EXPECT_LT(C2, C3); + + // Make sure the processes are deleted at some point. + shutdown_B.Wait(); + shutdown_C.Wait(); +} + +// Check that unload handlers in iframe don't prevents the main frame to be +// deleted after a timeout. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, SlowUnloadHandlerInIframe) { + GURL initial_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b)")); + GURL next_url(embedded_test_server()->GetURL("c.com", "/title1.html")); + + // 1) Navigate on a page with an iframe. + EXPECT_TRUE(NavigateToURL(shell(), initial_url)); + + // 2) Act as if there was an infinite unload handler in B. + auto filter = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_Detach::ID); + RenderFrameHost* rfh_b = + web_contents()->GetFrameTree()->root()->child_at(0)->current_frame_host(); + rfh_b->GetProcess()->AddFilter(filter.get()); + + // 3) Navigate and check the old frame is deleted after some time. + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + RenderFrameDeletedObserver deleted_observer(root->current_frame_host()); + EXPECT_TRUE(NavigateToURL(shell(), next_url)); + deleted_observer.WaitUntilDeleted(); +} + +// Navigate from A(B(A(B)) to C. Check the unload handler are executed, executed +// in the right order and the processes for A and B are removed. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, Unload_ABAB) { + GURL initial_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b(a(b)))")); + GURL next_url(embedded_test_server()->GetURL("c.com", "/title1.html")); + + // 1) Navigate on a page with an iframe. + EXPECT_TRUE(NavigateToURL(shell(), initial_url)); + + // 2) Add unload handler on every frame. + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + UnloadPrint(root, "A1"); + UnloadPrint(root->child_at(0), "B1"); + UnloadPrint(root->child_at(0)->child_at(0), "A2"); + UnloadPrint(root->child_at(0)->child_at(0)->child_at(0), "B2"); + root->current_frame_host()->DisableSwapOutTimerForTesting(); + + DOMMessageQueue dom_message_queue( + WebContents::FromRenderFrameHost(web_contents()->GetMainFrame())); + RenderProcessHostWatcher shutdown_A( + root->current_frame_host()->GetProcess(), + RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + RenderProcessHostWatcher shutdown_B( + root->child_at(0)->current_frame_host()->GetProcess(), + RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + + // 3) Navigate cross process. + EXPECT_TRUE(NavigateToURL(shell(), next_url)); + + // 4) Wait for unload handler messages and check they are sent in order. + std::vector<std::string> messages; + std::string message; + for (int i = 0; i < 4; ++i) { + EXPECT_TRUE(dom_message_queue.WaitForMessage(&message)); + base::TrimString(message, "\"", &message); + messages.push_back(message); + } + EXPECT_FALSE(dom_message_queue.PopMessage(&message)); + + EXPECT_THAT(messages, WhenSorted(ElementsAre("A1", "A2", "B1", "B2"))); + auto A1 = std::find(messages.begin(), messages.end(), "A1"); + auto A2 = std::find(messages.begin(), messages.end(), "A2"); + auto B1 = std::find(messages.begin(), messages.end(), "B1"); + auto B2 = std::find(messages.begin(), messages.end(), "B2"); + EXPECT_LT(A1, A2); + EXPECT_LT(B1, B2); + + // Make sure the processes are deleted at some point. + shutdown_A.Wait(); + shutdown_B.Wait(); +} + +// Start with A(B(C)), navigate C to D and then B to E. By emulating a slow +// unload handler in B,C and D, the end result is C is in pending deletion in B +// and B is in pending deletion in A. +// (1) (2) (3) +//| | | | +//| A | A | A | +//| | | | | \ | +//| B | B | B E | +//| | | \ | \ | +//| C | C D | C D | +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, UnloadNestedPendingDeletion) { + std::string onunload_script = "window.onunload = function(){}"; + GURL url_abc(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b(c))")); + GURL url_d(embedded_test_server()->GetURL("d.com", "/title1.html")); + GURL url_e(embedded_test_server()->GetURL("e.com", "/title1.html")); + + // 1) Navigate to a page with an iframe. + EXPECT_TRUE(NavigateToURL(shell(), url_abc)); + RenderFrameHostImpl* rfh_a = web_contents()->GetMainFrame(); + RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host(); + RenderFrameHostImpl* rfh_c = rfh_b->child_at(0)->current_frame_host(); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_a->unload_state_); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_b->unload_state_); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_c->unload_state_); + + // Act as if there was a slow unload handler on rfh_b and rfh_c. + // The navigating frames are waiting for FrameHostMsg_SwapoutACK. + auto swapout_ack_filter_b = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID); + auto swapout_ack_filter_c = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID); + rfh_b->GetProcess()->AddFilter(swapout_ack_filter_b.get()); + rfh_c->GetProcess()->AddFilter(swapout_ack_filter_c.get()); + EXPECT_TRUE(ExecuteScript(rfh_b->frame_tree_node(), onunload_script)); + EXPECT_TRUE(ExecuteScript(rfh_c->frame_tree_node(), onunload_script)); + rfh_b->DisableSwapOutTimerForTesting(); + rfh_c->DisableSwapOutTimerForTesting(); + + RenderFrameDeletedObserver delete_b(rfh_b), delete_c(rfh_c); + + // 2) Navigate rfh_c to D. + NavigateFrameToURL(rfh_c->frame_tree_node(), url_d); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_a->unload_state_); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_b->unload_state_); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, rfh_c->unload_state_); + RenderFrameHostImpl* rfh_d = rfh_b->child_at(0)->current_frame_host(); + + RenderFrameDeletedObserver delete_d(rfh_d); + + // Act as if there was a slow unload handler on rfh_d. + // The non navigating frames are waiting for FrameHostMsg_Detach. + auto detach_filter = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_Detach::ID); + rfh_d->GetProcess()->AddFilter(detach_filter.get()); + EXPECT_TRUE(ExecuteScript(rfh_d->frame_tree_node(), onunload_script)); + + // 3) Navigate rfh_b to E. + NavigateFrameToURL(rfh_b->frame_tree_node(), url_e); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_a->unload_state_); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, rfh_b->unload_state_); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, rfh_c->unload_state_); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, rfh_d->unload_state_); + + // rfh_d completes its unload event. It deletes the frame, including rfh_c. + EXPECT_FALSE(delete_c.deleted()); + EXPECT_FALSE(delete_d.deleted()); + rfh_d->OnDetach(); + EXPECT_TRUE(delete_c.deleted()); + EXPECT_TRUE(delete_d.deleted()); + + // rfh_b completes its unload event. + EXPECT_FALSE(delete_b.deleted()); + rfh_b->OnSwapOutACK(); + EXPECT_TRUE(delete_b.deleted()); +} + +// A set of nested frames A1(B1(A2)) are pending deletion because of a +// navigation. This tests what happens if only A2 has an unload handler. +// If B1 receives FrameHostMsg_OnDetach before A2, it should not destroy itself +// and its children, but rather wait for A2. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, PartialUnloadHandler) { + GURL url_aba(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b(a))")); + GURL url_c(embedded_test_server()->GetURL("c.com", "/title1.html")); + + // 1) Navigate to A1(B1(A2)) + EXPECT_TRUE(NavigateToURL(shell(), url_aba)); + + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + RenderFrameHostImpl* a1 = root->current_frame_host(); + RenderFrameHostImpl* b1 = a1->child_at(0)->current_frame_host(); + RenderFrameHostImpl* a2 = b1->child_at(0)->current_frame_host(); + RenderFrameDeletedObserver delete_a1(a1); + RenderFrameDeletedObserver delete_a2(a2); + RenderFrameDeletedObserver delete_b1(b1); + + // Disable Detach and Swapout ACK. They will be called manually. + auto swapout_ack_filter = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID); + auto detach_filter_a = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_Detach::ID); + auto detach_filter_b = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_Detach::ID); + a1->GetProcess()->AddFilter(swapout_ack_filter.get()); + a1->GetProcess()->AddFilter(detach_filter_a.get()); + b1->GetProcess()->AddFilter(detach_filter_b.get()); + + a1->DisableSwapOutTimerForTesting(); + + // Add unload handler on A2, but not on the other frames. + UnloadPrint(a2->frame_tree_node(), "A2"); + + DOMMessageQueue dom_message_queue( + WebContents::FromRenderFrameHost(web_contents()->GetMainFrame())); + + // 2) Navigate cross process. + EXPECT_TRUE(NavigateToURL(shell(), url_c)); + + // Check that unload handlers are executed. + std::string message, message_unused; + EXPECT_TRUE(dom_message_queue.WaitForMessage(&message)); + EXPECT_FALSE(dom_message_queue.PopMessage(&message_unused)); + EXPECT_EQ("\"A2\"", message); + + // No RenderFrameHost are deleted so far. + EXPECT_FALSE(delete_a1.deleted()); + EXPECT_FALSE(delete_b1.deleted()); + EXPECT_FALSE(delete_a2.deleted()); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, a1->unload_state_); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::Completed, b1->unload_state_); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, a2->unload_state_); + + // 3) B1 receives confirmation it has been deleted. This has no effect, + // because it is still waiting on A2 to be deleted. + b1->OnDetach(); + EXPECT_FALSE(delete_a1.deleted()); + EXPECT_FALSE(delete_b1.deleted()); + EXPECT_FALSE(delete_a2.deleted()); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, a1->unload_state_); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::Completed, b1->unload_state_); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, a2->unload_state_); + + // 4) A2 received confirmation that it has been deleted and destroy B1 and A2. + a2->OnDetach(); + EXPECT_FALSE(delete_a1.deleted()); + EXPECT_TRUE(delete_b1.deleted()); + EXPECT_TRUE(delete_a2.deleted()); + EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, a1->unload_state_); + + // 5) A1 receives SwapOutACK and deletes itself. + a1->OnSwapOutACK(); + EXPECT_TRUE(delete_a1.deleted()); +} + +// Test RenderFrameHostImpl::PendingDeletionCheckCompletedOnSubtree. +// +// After a navigation commit, some children with no unload handler may be +// eligible for immediate deletion. Several configurations are tested: +// +// Before navigation commit +// +// 0 | N : No unload handler +// ‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑ | [N] : Unload handler +// | | | | | | | | +// [1] 2 [3] 5 7 9 12 | +// | | | / \ / \ | +// 4 [6] 8 10 11 13 [14] | +// +// After navigation commit (expected) +// +// 0 | N : No unload handler +// --------------------- | [N] : Unload handler +// | | | | | +// [1] [3] 5 12 | +// | \ | +// [6] [14] | +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + PendingDeletionCheckCompletedOnSubtree) { + GURL url_1(embedded_test_server()->GetURL( + "a.com", + "/cross_site_iframe_factory.html?a(a,a,a(a),a(a),a(a),a(a,a),a(a,a))")); + GURL url_2(embedded_test_server()->GetURL("b.com", "/title1.html")); + + // 1) Navigate to 0(1,2,3(4),5(6),7(8),9(10,11),12(13,14)); + EXPECT_TRUE(NavigateToURL(shell(), url_1)); + + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + RenderFrameHostImpl* rfh_0 = root->current_frame_host(); + RenderFrameHostImpl* rfh_1 = rfh_0->child_at(0)->current_frame_host(); + RenderFrameHostImpl* rfh_2 = rfh_0->child_at(1)->current_frame_host(); + RenderFrameHostImpl* rfh_3 = rfh_0->child_at(2)->current_frame_host(); + RenderFrameHostImpl* rfh_4 = rfh_3->child_at(0)->current_frame_host(); + RenderFrameHostImpl* rfh_5 = rfh_0->child_at(3)->current_frame_host(); + RenderFrameHostImpl* rfh_6 = rfh_5->child_at(0)->current_frame_host(); + RenderFrameHostImpl* rfh_7 = rfh_0->child_at(4)->current_frame_host(); + RenderFrameHostImpl* rfh_8 = rfh_7->child_at(0)->current_frame_host(); + RenderFrameHostImpl* rfh_9 = rfh_0->child_at(5)->current_frame_host(); + RenderFrameHostImpl* rfh_10 = rfh_9->child_at(0)->current_frame_host(); + RenderFrameHostImpl* rfh_11 = rfh_9->child_at(1)->current_frame_host(); + RenderFrameHostImpl* rfh_12 = rfh_0->child_at(6)->current_frame_host(); + RenderFrameHostImpl* rfh_13 = rfh_12->child_at(0)->current_frame_host(); + RenderFrameHostImpl* rfh_14 = rfh_12->child_at(1)->current_frame_host(); + + RenderFrameDeletedObserver delete_a0(rfh_0), delete_a1(rfh_1), + delete_a2(rfh_2), delete_a3(rfh_3), delete_a4(rfh_4), delete_a5(rfh_5), + delete_a6(rfh_6), delete_a7(rfh_7), delete_a8(rfh_8), delete_a9(rfh_9), + delete_a10(rfh_10), delete_a11(rfh_11), delete_a12(rfh_12), + delete_a13(rfh_13), delete_a14(rfh_14); + + // Add the unload handlers. + UnloadPrint(rfh_1->frame_tree_node(), ""); + UnloadPrint(rfh_3->frame_tree_node(), ""); + UnloadPrint(rfh_6->frame_tree_node(), ""); + UnloadPrint(rfh_14->frame_tree_node(), ""); + + // Disable Detach and Swapout ACK. + auto swapout_ack_filter = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID); + auto detach_filter = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_Detach::ID); + rfh_0->GetProcess()->AddFilter(swapout_ack_filter.get()); + rfh_0->GetProcess()->AddFilter(detach_filter.get()); + rfh_0->DisableSwapOutTimerForTesting(); + + // 2) Navigate cross process and check the tree. See diagram above. + EXPECT_TRUE(NavigateToURL(shell(), url_2)); + + EXPECT_FALSE(delete_a0.deleted()); + EXPECT_FALSE(delete_a1.deleted()); + EXPECT_TRUE(delete_a2.deleted()); + EXPECT_FALSE(delete_a3.deleted()); + EXPECT_TRUE(delete_a4.deleted()); + EXPECT_FALSE(delete_a5.deleted()); + EXPECT_FALSE(delete_a6.deleted()); + EXPECT_TRUE(delete_a7.deleted()); + EXPECT_TRUE(delete_a8.deleted()); + EXPECT_TRUE(delete_a9.deleted()); + EXPECT_TRUE(delete_a10.deleted()); + EXPECT_TRUE(delete_a11.deleted()); + EXPECT_FALSE(delete_a12.deleted()); + EXPECT_TRUE(delete_a13.deleted()); + EXPECT_FALSE(delete_a14.deleted()); +} + +// When an iframe is detached, check that unload handlers execute in all of its +// child frames. Start from A(B(C)) and delete B from A. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + DetachedIframeUnloadHandlerABC) { + GURL initial_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b(c))")); + + // 1) Navigate to a(b(c)) + EXPECT_TRUE(NavigateToURL(shell(), initial_url)); + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + RenderFrameHostImpl* rfh_a = root->current_frame_host(); + RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host(); + RenderFrameHostImpl* rfh_c = rfh_b->child_at(0)->current_frame_host(); + + // 2) Add unload handlers on B and C. + UnloadPrint(rfh_b->frame_tree_node(), "B"); + UnloadPrint(rfh_c->frame_tree_node(), "C"); + + DOMMessageQueue dom_message_queue(web_contents()); + RenderProcessHostWatcher shutdown_B( + rfh_b->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + RenderProcessHostWatcher shutdown_C( + rfh_c->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + + // 3) Detach B from A. + ExecuteScriptAsync(root, "document.querySelector('iframe').remove();"); + + // 4) Wait for unload handler. + std::vector<std::string> messages(2); + EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[0])); + EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[1])); + std::string unused; + EXPECT_FALSE(dom_message_queue.PopMessage(&unused)); + + std::sort(messages.begin(), messages.end()); + EXPECT_EQ("\"B\"", messages[0]); + EXPECT_EQ("\"C\"", messages[1]); + + // Make sure the processes are deleted at some point. + shutdown_B.Wait(); + shutdown_C.Wait(); +} + +// When an iframe is detached, check that unload handlers execute in all of its +// child frames. Start from A(B1(C(B2))) and delete B1 from A. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + DetachedIframeUnloadHandlerABCB) { + GURL initial_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b(c(b)))")); + + // 1) Navigate to a(b(c(b))) + EXPECT_TRUE(NavigateToURL(shell(), initial_url)); + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + RenderFrameHostImpl* rfh_a = root->current_frame_host(); + RenderFrameHostImpl* rfh_b1 = rfh_a->child_at(0)->current_frame_host(); + RenderFrameHostImpl* rfh_c = rfh_b1->child_at(0)->current_frame_host(); + RenderFrameHostImpl* rfh_b2 = rfh_c->child_at(0)->current_frame_host(); + + // 2) Add unload handlers on B1, B2 and C. + UnloadPrint(rfh_b1->frame_tree_node(), "B1"); + UnloadPrint(rfh_b2->frame_tree_node(), "B2"); + UnloadPrint(rfh_c->frame_tree_node(), "C"); + + DOMMessageQueue dom_message_queue(web_contents()); + RenderProcessHostWatcher shutdown_B( + rfh_b1->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + RenderProcessHostWatcher shutdown_C( + rfh_c->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + + // 3) Detach B from A. + ExecuteScriptAsync(root, "document.querySelector('iframe').remove();"); + + // 4) Wait for unload handler. + std::vector<std::string> messages(3); + EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[0])); + EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[1])); + EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[2])); + std::string unused; + EXPECT_FALSE(dom_message_queue.PopMessage(&unused)); + + std::sort(messages.begin(), messages.end()); + EXPECT_EQ("\"B1\"", messages[0]); + EXPECT_EQ("\"B2\"", messages[1]); + EXPECT_EQ("\"C\"", messages[2]); + + // Make sure the processes are deleted at some point. + shutdown_B.Wait(); + shutdown_C.Wait(); +} + +// When an iframe is detached, check that unload handlers execute in all of its +// child frames. Start from A1(A2(B)), delete A2 from itself. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + DetachedIframeUnloadHandlerAAB) { + GURL initial_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(a(b))")); + + // 1) Navigate to a(a(b)). + EXPECT_TRUE(NavigateToURL(shell(), initial_url)); + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + RenderFrameHostImpl* rfh_a1 = root->current_frame_host(); + RenderFrameHostImpl* rfh_a2 = rfh_a1->child_at(0)->current_frame_host(); + RenderFrameHostImpl* rfh_b = rfh_a2->child_at(0)->current_frame_host(); + + // 2) Add unload handlers on A2 ad B. + UnloadPrint(rfh_a2->frame_tree_node(), "A2"); + UnloadPrint(rfh_b->frame_tree_node(), "B"); + + DOMMessageQueue dom_message_queue(web_contents()); + RenderProcessHostWatcher shutdown_B( + rfh_b->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + + // 3) A2 detaches itself. + ExecuteScriptAsync(rfh_a2->frame_tree_node(), + "parent.document.querySelector('iframe').remove();"); + + // 4) Wait for unload handler. + std::vector<std::string> messages(2); + EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[0])); + EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[1])); + std::string unused; + EXPECT_FALSE(dom_message_queue.PopMessage(&unused)); + + std::sort(messages.begin(), messages.end()); + EXPECT_EQ("\"A2\"", messages[0]); + EXPECT_EQ("\"B\"", messages[1]); + + // Make sure the process is deleted at some point. + shutdown_B.Wait(); +} + +// Tests that running layout from an unload handler inside teardown of the +// RenderWidget (inside WidgetMsg_Close) can succeed. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + RendererInitiatedWindowCloseWithUnload) { + GURL main_url(embedded_test_server()->GetURL("a.com", "/empty.html")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + + // We will window.open() another URL on the same domain so they share a + // renderer. This window has an unload handler that forces layout to occur. + // Then we (in a new stack) close that window causing that layout. If all + // goes well the window closes. If it goes poorly, the renderer may crash. + // + // This path is special because the unload results from window.close() which + // avoids the user-initiated close path through ViewMsg_ClosePage. In that + // path the unload handlers are run early, before the actual teardown of + // the closing RenderWidget. + GURL open_url = embedded_test_server()->GetURL( + "a.com", "/unload_handler_force_layout.html"); + + // Listen for messages from the window that the test opens, and convert them + // into the document title, which we can wait on in the main test window. + EXPECT_TRUE( + ExecuteScript(root, + "window.addEventListener('message', function(event) {\n" + " document.title = event.data;\n" + "});")); + + // This performs window.open() and waits for the title of the original + // document to change to signal that the unload handler has been registered. + { + base::string16 title_when_loaded = base::UTF8ToUTF16("loaded"); + TitleWatcher title_watcher(shell()->web_contents(), title_when_loaded); + EXPECT_TRUE( + ExecuteScript(root, JsReplace("var w = window.open($1)", open_url))); + EXPECT_EQ(title_watcher.WaitAndGetTitle(), title_when_loaded); + } + + // The closes the window and waits for the title of the original document to + // change again to signal that the unload handler has run. + { + base::string16 title_when_done = base::UTF8ToUTF16("unloaded"); + TitleWatcher title_watcher(shell()->web_contents(), title_when_done); + EXPECT_TRUE(ExecuteScript(root, "w.close()")); + EXPECT_EQ(title_watcher.WaitAndGetTitle(), title_when_done); + } +} + +} // namespace content
diff --git a/content/browser/speech/OWNERS b/content/browser/speech/OWNERS index cfcf5d6..0e69b3f 100644 --- a/content/browser/speech/OWNERS +++ b/content/browser/speech/OWNERS
@@ -1,4 +1,10 @@ +# Speech recognition olka@chromium.org maxmorin@chromium.org +# Text-to-speech +per-file *tts_*=dmazzoni@chromium.org +per-file *tts_*=dtseng@chromium.org +per-file *tts_*=katie@chromium.org + # COMPONENT: Blink>Speech
diff --git a/content/browser/startup_helper.cc b/content/browser/startup_helper.cc index 7f13b4c..9d979d5 100644 --- a/content/browser/startup_helper.cc +++ b/content/browser/startup_helper.cc
@@ -24,32 +24,20 @@ // Mobile config, for iOS see ios/web/app/web_main_loop.cc. return std::make_unique<base::TaskScheduler::InitParams>( base::SchedulerWorkerPoolParams( - base::RecommendedMaxNumberOfThreadsInPool(2, 8, 0.1, 0), + base::RecommendedMaxNumberOfThreadsInPool(4, 8, 0.2, 0), base::TimeDelta::FromSeconds(30)), base::SchedulerWorkerPoolParams( - base::RecommendedMaxNumberOfThreadsInPool(2, 8, 0.1, 0), - base::TimeDelta::FromSeconds(30)), - base::SchedulerWorkerPoolParams( - base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.3, 0), - base::TimeDelta::FromSeconds(30)), - base::SchedulerWorkerPoolParams( - base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.3, 0), - base::TimeDelta::FromSeconds(60))); + base::RecommendedMaxNumberOfThreadsInPool(6, 8, 0.6, 0), + base::TimeDelta::FromSeconds(30))); #else // Desktop config. return std::make_unique<base::TaskScheduler::InitParams>( base::SchedulerWorkerPoolParams( - base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.1, 0), + base::RecommendedMaxNumberOfThreadsInPool(6, 8, 0.2, 0), base::TimeDelta::FromSeconds(30)), base::SchedulerWorkerPoolParams( - base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.1, 0), - base::TimeDelta::FromSeconds(40)), - base::SchedulerWorkerPoolParams( - base::RecommendedMaxNumberOfThreadsInPool(8, 32, 0.3, 0), - base::TimeDelta::FromSeconds(30)), - base::SchedulerWorkerPoolParams( - base::RecommendedMaxNumberOfThreadsInPool(8, 32, 0.3, 0), - base::TimeDelta::FromSeconds(60)) + base::RecommendedMaxNumberOfThreadsInPool(16, 32, 0.6, 0), + base::TimeDelta::FromSeconds(30)) #if defined(OS_WIN) , base::TaskScheduler::InitParams::SharedWorkerPoolEnvironment::COM_MTA
diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc index 25c05c1..5e1c913 100644 --- a/content/browser/utility_process_host.cc +++ b/content/browser/utility_process_host.cc
@@ -376,7 +376,6 @@ switches::kV, switches::kVModule, #if defined(OS_ANDROID) - switches::kEnableReachedCodeProfiler, switches::kOrderfileMemoryOptimization, #endif // These flags are used by the audio service:
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index 7e7cee1..6aca4fb 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/files/file_util.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "base/optional.h" #include "base/path_service.h" @@ -3071,7 +3072,8 @@ // the swapout ack and stayed in pending deletion for a while. Even if the // frame is still present, it must be removed from the list of frame in // fullscreen immediately. - auto filter = base::MakeRefCounted<SwapoutACKMessageFilter>(); + auto filter = base::MakeRefCounted<DropMessageFilter>( + FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID); main_frame->GetProcess()->AddFilter(filter.get()); main_frame->DisableSwapOutTimerForTesting(); EXPECT_TRUE(NavigateToURL(shell(), url_b));
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index 58b809a1a..74e086c0 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -26,7 +26,6 @@ #include "content/browser/webui/web_ui_controller_factory_registry.h" #include "content/common/frame_messages.h" #include "content/common/input/synthetic_web_input_event_builders.h" -#include "content/common/media/media_player_delegate_messages.h" #include "content/common/view_messages.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/global_request_id.h" @@ -35,7 +34,6 @@ #include "content/public/browser/navigation_details.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_source.h" -#include "content/public/browser/overlay_window.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/ssl_host_state_delegate.h" #include "content/public/browser/storage_partition.h" @@ -3242,113 +3240,6 @@ EXPECT_EQ(SK_ColorGREEN, observer.last_theme_color()); } -class PictureInPictureDelegate : public WebContentsDelegate { - public: - PictureInPictureDelegate() = default; - - MOCK_METHOD3(EnterPictureInPicture, - gfx::Size(content::WebContents* web_contents, - const viz::SurfaceId&, - const gfx::Size&)); - - private: - DISALLOW_COPY_AND_ASSIGN(PictureInPictureDelegate); -}; - -class TestOverlayWindow : public OverlayWindow { - public: - TestOverlayWindow() = default; - ~TestOverlayWindow() override{}; - - static std::unique_ptr<OverlayWindow> Create( - PictureInPictureWindowController* controller) { - return std::unique_ptr<OverlayWindow>(new TestOverlayWindow()); - } - - bool IsActive() const override { return false; } - void Close() override {} - void Show() override {} - void Hide() override {} - void SetPictureInPictureCustomControls( - const std::vector<blink::PictureInPictureControlInfo>& controls) - override {} - bool IsVisible() const override { return false; } - bool IsAlwaysOnTop() const override { return false; } - ui::Layer* GetLayer() override { return nullptr; } - gfx::Rect GetBounds() const override { return gfx::Rect(); } - void UpdateVideoSize(const gfx::Size& natural_size) override {} - void SetPlaybackState(PlaybackState playback_state) override {} - void SetAlwaysHidePlayPauseButton(bool is_visible) override {} - void SetSkipAdButtonVisibility(bool is_visible) override {} - ui::Layer* GetWindowBackgroundLayer() override { return nullptr; } - ui::Layer* GetVideoLayer() override { return nullptr; } - gfx::Rect GetVideoBounds() override { return gfx::Rect(); } - - private: - DISALLOW_COPY_AND_ASSIGN(TestOverlayWindow); -}; - -class PictureInPictureTestBrowserClient : public TestContentBrowserClient { - public: - PictureInPictureTestBrowserClient() - : original_browser_client_(SetBrowserClientForTesting(this)) {} - - ~PictureInPictureTestBrowserClient() override { - SetBrowserClientForTesting(original_browser_client_); - } - - std::unique_ptr<OverlayWindow> CreateWindowForPictureInPicture( - PictureInPictureWindowController* controller) override { - return TestOverlayWindow::Create(controller); - } - - private: - ContentBrowserClient* original_browser_client_; -}; - -TEST_F(WebContentsImplTest, EnterPictureInPicture) { - PictureInPictureTestBrowserClient browser_client; - SetBrowserClientForTesting(&browser_client); - - const int kPlayerVideoOnlyId = 30; /* arbitrary and used for tests */ - - PictureInPictureDelegate delegate; - contents()->SetDelegate(&delegate); - - MediaWebContentsObserver* observer = - contents()->media_web_contents_observer(); - TestRenderFrameHost* rfh = main_test_rfh(); - rfh->InitializeRenderFrameIfNeeded(); - - // If Picture-in-Picture was never triggered, the media player id would not be - // set. - EXPECT_FALSE(observer->GetPictureInPictureVideoMediaPlayerId().has_value()); - - viz::SurfaceId surface_id = - viz::SurfaceId(viz::FrameSinkId(1, 1), - viz::LocalSurfaceId( - 11, base::UnguessableToken::Deserialize(0x111111, 0))); - - EXPECT_CALL(delegate, - EnterPictureInPicture(contents(), surface_id, gfx::Size(42, 42))); - - rfh->OnMessageReceived( - MediaPlayerDelegateHostMsg_OnPictureInPictureModeStarted( - rfh->GetRoutingID(), kPlayerVideoOnlyId, surface_id /* surface_id */, - gfx::Size(42, 42) /* natural_size */, 1 /* request_id */, - true /* show_play_pause_button */)); - EXPECT_TRUE(observer->GetPictureInPictureVideoMediaPlayerId().has_value()); - EXPECT_EQ(kPlayerVideoOnlyId, - observer->GetPictureInPictureVideoMediaPlayerId()->delegate_id); - - // Picture-in-Picture media player id should not be reset when the media is - // destroyed (e.g. video stops playing). This allows the Picture-in-Picture - // window to continue to control the media. - rfh->OnMessageReceived(MediaPlayerDelegateHostMsg_OnMediaDestroyed( - rfh->GetRoutingID(), kPlayerVideoOnlyId)); - EXPECT_TRUE(observer->GetPictureInPictureVideoMediaPlayerId().has_value()); -} - TEST_F(WebContentsImplTest, ParseDownloadHeaders) { download::DownloadUrlParameters::RequestHeadersType request_headers = WebContentsImpl::ParseDownloadHeaders("A: 1\r\nB: 2\r\nC: 3\r\n\r\n");
diff --git a/content/browser/webauth/authenticator_impl.cc b/content/browser/webauth/authenticator_impl.cc index 435edbb..eb0d191 100644 --- a/content/browser/webauth/authenticator_impl.cc +++ b/content/browser/webauth/authenticator_impl.cc
@@ -20,7 +20,6 @@ #include "build/build_config.h" #include "content/browser/bad_message.h" #include "content/browser/webauth/authenticator_type_converters.h" -#include "content/public/browser/authenticator_request_client_delegate.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/navigation_handle.h" @@ -886,9 +885,9 @@ // Duplicate registration: the new credential would be created on an // authenticator that already contains one of the credentials in // |exclude_credentials|. - - HandleBlockingError( - blink::mojom::AuthenticatorStatus::CREDENTIAL_EXCLUDED); + SignalFailureToRequestDelegate( + AuthenticatorRequestClientDelegate::InterestingFailureReason:: + kKeyAlreadyRegistered); return; case device::FidoReturnCode::kAuthenticatorResponseInvalid: // The response from the authenticator was corrupted. @@ -1038,8 +1037,9 @@ switch (status_code) { case device::FidoReturnCode::kUserConsentButCredentialNotRecognized: - HandleBlockingError( - blink::mojom::AuthenticatorStatus::CREDENTIAL_NOT_RECOGNIZED); + SignalFailureToRequestDelegate( + AuthenticatorRequestClientDelegate::InterestingFailureReason:: + kKeyNotRegistered); return; case device::FidoReturnCode::kAuthenticatorResponseInvalid: // The response from the authenticator was corrupted. @@ -1078,34 +1078,36 @@ NOTREACHED(); } -// If WebAuthnUi is enabled, this error blocks until after receiving user -// acknowledgement. Otherwise, the error is returned right away. -void AuthenticatorImpl::HandleBlockingError( - blink::mojom::AuthenticatorStatus status) { - AuthenticatorRequestClientDelegate::InterestingFailureReason reason = - AuthenticatorRequestClientDelegate::InterestingFailureReason::kTimeout; - switch (status) { - case blink::mojom::AuthenticatorStatus::CREDENTIAL_EXCLUDED: - reason = AuthenticatorRequestClientDelegate::InterestingFailureReason:: - kKeyAlreadyRegistered; +void AuthenticatorImpl::SignalFailureToRequestDelegate( + AuthenticatorRequestClientDelegate::InterestingFailureReason reason) { + blink::mojom::AuthenticatorStatus status = + blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR; + + switch (reason) { + case AuthenticatorRequestClientDelegate::InterestingFailureReason:: + kKeyAlreadyRegistered: + status = blink::mojom::AuthenticatorStatus::CREDENTIAL_EXCLUDED; break; - case blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR: - reason = AuthenticatorRequestClientDelegate::InterestingFailureReason:: - kTimeout; + case AuthenticatorRequestClientDelegate::InterestingFailureReason:: + kKeyNotRegistered: + status = blink::mojom::AuthenticatorStatus::CREDENTIAL_NOT_RECOGNIZED; break; - case blink::mojom::AuthenticatorStatus::CREDENTIAL_NOT_RECOGNIZED: - reason = AuthenticatorRequestClientDelegate::InterestingFailureReason:: - kKeyNotRegistered; + case AuthenticatorRequestClientDelegate::InterestingFailureReason::kTimeout: + status = blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR; break; - default: - NOTREACHED(); } error_awaiting_user_acknowledgement_ = status; - DCHECK(request_delegate_); - if (!request_delegate_->DoesBlockRequestOnFailure(reason)) { - FailWithErrorAndCleanup(); + + // If WebAuthnUi is enabled, this error blocks until after receiving user + // acknowledgement. Otherwise, the error is returned right away. + if (request_delegate_->DoesBlockRequestOnFailure(reason)) { + // Cancel pending authenticator requests before the error dialog is shown. + request_->CancelActiveAuthenticators(); + return; } + + FailWithErrorAndCleanup(); } // namespace content void AuthenticatorImpl::FailWithErrorAndCleanup() { @@ -1131,7 +1133,8 @@ awaiting_attestation_response_ = false; } - HandleBlockingError(blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR); + SignalFailureToRequestDelegate( + AuthenticatorRequestClientDelegate::InterestingFailureReason::kTimeout); } void AuthenticatorImpl::Cancel() {
diff --git a/content/browser/webauth/authenticator_impl.h b/content/browser/webauth/authenticator_impl.h index 9f9f0071b..6fe474b 100644 --- a/content/browser/webauth/authenticator_impl.h +++ b/content/browser/webauth/authenticator_impl.h
@@ -15,6 +15,7 @@ #include "base/macros.h" #include "base/optional.h" #include "content/common/content_export.h" +#include "content/public/browser/authenticator_request_client_delegate.h" #include "content/public/browser/web_contents_observer.h" #include "crypto/sha2.h" #include "device/fido/authenticator_get_assertion_response.h" @@ -49,7 +50,6 @@ namespace content { -class AuthenticatorRequestClientDelegate; class BrowserContext; class RenderFrameHost; @@ -159,7 +159,8 @@ // Decides whether or not UI is present that needs to block on user // acknowledgement before returning the error, and handles the error // appropriately. - void HandleBlockingError(blink::mojom::AuthenticatorStatus status); + void SignalFailureToRequestDelegate( + AuthenticatorRequestClientDelegate::InterestingFailureReason reason); void InvokeCallbackAndCleanup( MakeCredentialCallback callback,
diff --git a/content/child/assert_matching_enums.cc b/content/child/assert_matching_enums.cc index be579b00..86bf5fa3 100644 --- a/content/child/assert_matching_enums.cc +++ b/content/child/assert_matching_enums.cc
@@ -12,7 +12,6 @@ #include "third_party/blink/public/platform/web_menu_source_type.h" #include "third_party/blink/public/platform/web_text_input_mode.h" #include "third_party/blink/public/platform/web_text_input_type.h" -#include "third_party/blink/public/web/web_frame_serializer_cache_control_policy.h" #include "ui/base/ime/text_input_mode.h" #include "ui/base/ime/text_input_type.h" #include "ui/base/ui_base_types.h"
diff --git a/content/common/DEPS b/content/common/DEPS index 17c74a5..fe0ac51a 100644 --- a/content/common/DEPS +++ b/content/common/DEPS
@@ -65,7 +65,6 @@ "+third_party/blink/public/web/web_device_emulation_params.h", "+third_party/blink/public/web/web_drag_status.h", "+third_party/blink/public/web/web_frame_owner_properties.h", - "+third_party/blink/public/web/web_frame_serializer_cache_control_policy.h", "+third_party/blink/public/web/web_fullscreen_options.h", "+third_party/blink/public/web/web_ime_text_span.h", "+third_party/blink/public/web/web_media_player_action.h",
diff --git a/content/common/download/mhtml_save_status.cc b/content/common/download/mhtml_save_status.cc index e6cea2ab7..2fbf080 100644 --- a/content/common/download/mhtml_save_status.cc +++ b/content/common/download/mhtml_save_status.cc
@@ -20,8 +20,9 @@ return "File writing error"; case MhtmlSaveStatus::FRAME_NO_LONGER_EXISTS: return "Frame no longer exists"; - case MhtmlSaveStatus::FRAME_SERIALIZATION_FORBIDDEN: - return "Main frame serialization forbidden"; + case MhtmlSaveStatus::DEPRECATED_FRAME_SERIALIZATION_FORBIDDEN: + NOTREACHED(); + return ""; case MhtmlSaveStatus::RENDER_PROCESS_EXITED: return "Render process no longer exists"; }
diff --git a/content/common/download/mhtml_save_status.h b/content/common/download/mhtml_save_status.h index 23b6354..cd090e2 100644 --- a/content/common/download/mhtml_save_status.h +++ b/content/common/download/mhtml_save_status.h
@@ -8,6 +8,8 @@ namespace content { // Status result enum for MHTML generation. +// Changes to this enum must be reflected in the respective metrics enum named +// MhtmlGenerationFinalSaveStatus in enums.xml. enum class MhtmlSaveStatus { SUCCESS = 0, @@ -26,9 +28,8 @@ // the browser. FRAME_NO_LONGER_EXISTS, - // The main frame was not allowed to be serialized by either policy or cache - // control. Determined by the renderer. - FRAME_SERIALIZATION_FORBIDDEN, + // No longer used. + DEPRECATED_FRAME_SERIALIZATION_FORBIDDEN, // A render process needed for the serialization of one of the page's frame is // no more. Determined by the browser.
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index c8a145df..a0619cfaa 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -70,7 +70,6 @@ #include "third_party/blink/public/platform/web_scroll_types.h" #include "third_party/blink/public/platform/web_sudden_termination_disabler_type.h" #include "third_party/blink/public/web/web_frame_owner_properties.h" -#include "third_party/blink/public/web/web_frame_serializer_cache_control_policy.h" #include "third_party/blink/public/web/web_fullscreen_options.h" #include "third_party/blink/public/web/web_media_player_action.h" #include "third_party/blink/public/web/web_tree_scope_type.h"
diff --git a/content/common/media/media_player_delegate_messages.h b/content/common/media/media_player_delegate_messages.h index b482679ef..4870d5b2 100644 --- a/content/common/media/media_player_delegate_messages.h +++ b/content/common/media/media_player_delegate_messages.h
@@ -76,23 +76,6 @@ int /* delegate_id, distinguishes instances */, std::string /* control_id */) -IPC_MESSAGE_ROUTED2(MediaPlayerDelegateMsg_OnPictureInPictureWindowResize, - int /* delegate_id, distinguishes instances */, - gfx::Size /* window_size */) - -// ---------------------------------------------------------------------------- -// Messages from the browser to the renderer acknowledging changes happened. -// ---------------------------------------------------------------------------- - -IPC_MESSAGE_ROUTED3(MediaPlayerDelegateMsg_OnPictureInPictureModeStarted_ACK, - int /* delegate id */, - int /* request_id */, - gfx::Size /* window_size */) - -IPC_MESSAGE_ROUTED2(MediaPlayerDelegateMsg_OnPictureInPictureModeEnded_ACK, - int /* delegate id */, - int /* request_id */) - // ---------------------------------------------------------------------------- // Messages from the renderer notifying the browser of playback state changes. // ---------------------------------------------------------------------------- @@ -124,23 +107,6 @@ int /* delegate_id, distinguishes instances */, gfx::Size /* new size of video */) -IPC_MESSAGE_ROUTED5(MediaPlayerDelegateHostMsg_OnPictureInPictureModeStarted, - int /* delegate id */, - viz::SurfaceId /* surface_id */, - gfx::Size /* natural_size */, - int /* request_id */, - bool /* show_play_pause_button */) - -IPC_MESSAGE_ROUTED2(MediaPlayerDelegateHostMsg_OnPictureInPictureModeEnded, - int /* delegate id */, - int /* request_id */) - -IPC_MESSAGE_ROUTED4(MediaPlayerDelegateHostMsg_OnPictureInPictureSurfaceChanged, - int /* delegate id */, - viz::SurfaceId /* surface_id */, - gfx::Size /* natural_size */, - bool /* show_play_pause_button */) - IPC_MESSAGE_ROUTED2( MediaPlayerDelegateHostMsg_OnSetPictureInPictureCustomControls, int /* delegate id */,
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java index b6b5493..aa39ff0d 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java
@@ -73,7 +73,6 @@ mDisplayAndroid = mActivityTestRule.getWebContents().getTopLevelNativeWindow().getDisplay(); mDisplayAndroid.addObserver(mCallbackHelper); - DisplayAndroid.startAccurateListening(); } }); @@ -94,7 +93,6 @@ mDisplayAndroid = null; mActivityTestRule.getActivity().setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); - DisplayAndroid.stopAccurateListening(); } });
diff --git a/content/public/app/content_browser_manifest.cc b/content/public/app/content_browser_manifest.cc index 9b430a1..880f44a 100644 --- a/content/public/app/content_browser_manifest.cc +++ b/content/public/app/content_browser_manifest.cc
@@ -227,6 +227,7 @@ "blink.mojom.MediaSessionService", "blink.mojom.NotificationService", "blink.mojom.PermissionService", + "blink.mojom.PictureInPictureService", "blink.mojom.Portal", "blink.mojom.PrefetchURLLoaderService", "blink.mojom.PresentationService",
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h index 26a0504..37693ee 100644 --- a/content/public/common/common_param_traits_macros.h +++ b/content/public/common/common_param_traits_macros.h
@@ -26,7 +26,6 @@ #include "third_party/blink/public/platform/web_rect.h" #include "third_party/blink/public/platform/web_security_style.h" #include "third_party/blink/public/platform/web_url_request.h" -#include "third_party/blink/public/web/web_frame_serializer_cache_control_policy.h" #include "third_party/blink/public/web/window_features.mojom.h" #include "ui/accessibility/ax_event.h" #include "ui/accessibility/ax_node_data.h" @@ -49,8 +48,6 @@ ui::PageTransition::PAGE_TRANSITION_LAST_CORE)) IPC_ENUM_TRAITS_MAX_VALUE(content::ConsoleMessageLevel, content::CONSOLE_MESSAGE_LEVEL_LAST) -IPC_ENUM_TRAITS_MAX_VALUE(blink::WebFrameSerializerCacheControlPolicy, - blink::WebFrameSerializerCacheControlPolicy::kLast) IPC_ENUM_TRAITS_MAX_VALUE(network::mojom::ReferrerPolicy, network::mojom::ReferrerPolicy::kMaxValue) IPC_ENUM_TRAITS_MAX_VALUE(blink::WebHistoryScrollRestorationType,
diff --git a/content/public/common/mhtml_generation_params.h b/content/public/common/mhtml_generation_params.h index c602f32..d1fe446 100644 --- a/content/public/common/mhtml_generation_params.h +++ b/content/public/common/mhtml_generation_params.h
@@ -7,7 +7,6 @@ #include "base/files/file_path.h" #include "content/common/content_export.h" -#include "third_party/blink/public/web/web_frame_serializer_cache_control_policy.h" namespace content {
diff --git a/content/public/renderer/media_stream_renderer_factory.h b/content/public/renderer/media_stream_renderer_factory.h index 898e388..1edc14ec 100644 --- a/content/public/renderer/media_stream_renderer_factory.h +++ b/content/public/renderer/media_stream_renderer_factory.h
@@ -36,7 +36,8 @@ const blink::WebMediaStream& web_stream, const base::Closure& error_cb, const MediaStreamVideoRenderer::RepaintCB& repaint_cb, - const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) = 0; + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner) = 0; virtual scoped_refptr<MediaStreamAudioRenderer> GetAudioRenderer( const blink::WebMediaStream& web_stream,
diff --git a/content/public/renderer/media_stream_video_sink.cc b/content/public/renderer/media_stream_video_sink.cc index 57351e45..d66ee53 100644 --- a/content/public/renderer/media_stream_video_sink.cc +++ b/content/public/renderer/media_stream_video_sink.cc
@@ -35,4 +35,13 @@ connected_track_.Reset(); } +void MediaStreamVideoSink::OnFrameDropped( + media::VideoCaptureFrameDropReason reason) { + MediaStreamVideoTrack* const video_track = + MediaStreamVideoTrack::GetVideoTrack(connected_track_); + if (!video_track) + return; + video_track->OnFrameDropped(reason); +} + } // namespace content
diff --git a/content/public/renderer/media_stream_video_sink.h b/content/public/renderer/media_stream_video_sink.h index b7a5f2c4..e84df90 100644 --- a/content/public/renderer/media_stream_video_sink.h +++ b/content/public/renderer/media_stream_video_sink.h
@@ -25,6 +25,9 @@ // http://dev.w3.org/2011/webrtc/editor/getusermedia.html // All methods calls will be done from the main render thread. class CONTENT_EXPORT MediaStreamVideoSink : public blink::WebMediaStreamSink { + public: + void OnFrameDropped(media::VideoCaptureFrameDropReason reason); + protected: MediaStreamVideoSink(); ~MediaStreamVideoSink() override;
diff --git a/content/public/test/navigation_simulator.h b/content/public/test/navigation_simulator.h index 06899619..124e687 100644 --- a/content/public/test/navigation_simulator.h +++ b/content/public/test/navigation_simulator.h
@@ -202,6 +202,8 @@ scoped_refptr<net::HttpResponseHeaders> response_headers) = 0; // Simulates the navigation failing with the error code |error_code|. + // IMPORTANT NOTE: This is simulating a network connection error and implies + // we do not get a response. Error codes like 204 are not properly managed. virtual void Fail(int error_code) = 0; // Simulates the commit of an error page following a navigation failure.
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 9704049..14f9f2e2 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -982,10 +982,7 @@ } if (is_chromecast) { - defines += [ - "IS_CHROMECAST", - "MEDIA_EVENT_LOG_UTILITY=LOG(INFO)", - ] + defines += [ "IS_CHROMECAST" ] } }
diff --git a/content/renderer/compositor/layer_tree_view.cc b/content/renderer/compositor/layer_tree_view.cc index 319ff2f..d55fa923 100644 --- a/content/renderer/compositor/layer_tree_view.cc +++ b/content/renderer/compositor/layer_tree_view.cc
@@ -304,14 +304,6 @@ return frame_sink_id_; } -void LayerTreeView::SetRootLayer(scoped_refptr<cc::Layer> layer) { - layer_tree_host_->SetRootLayer(std::move(layer)); -} - -void LayerTreeView::ClearRootLayer() { - layer_tree_host_->SetRootLayer(nullptr); -} - void LayerTreeView::SetNonBlinkManagedRootLayer( scoped_refptr<cc::Layer> layer) { layer_tree_host_->SetNonBlinkManagedRootLayer(std::move(layer));
diff --git a/content/renderer/compositor/layer_tree_view.h b/content/renderer/compositor/layer_tree_view.h index 19eb62b..fbadffa 100644 --- a/content/renderer/compositor/layer_tree_view.h +++ b/content/renderer/compositor/layer_tree_view.h
@@ -130,9 +130,7 @@ // blink::WebLayerTreeView implementation. viz::FrameSinkId GetFrameSinkId() override; - void SetRootLayer(scoped_refptr<cc::Layer> layer) override; void SetNonBlinkManagedRootLayer(scoped_refptr<cc::Layer> layer); - void ClearRootLayer() override; cc::AnimationHost* CompositorAnimationHost() override; gfx::Size GetViewportSize() const override; void SetBackgroundColor(SkColor color) override;
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc index a4b143c..2d52883 100644 --- a/content/renderer/media/media_factory.cc +++ b/content/renderer/media/media_factory.cc
@@ -579,8 +579,9 @@ std::make_unique<RenderMediaLog>( url::Origin(security_origin).GetURL(), render_frame_->GetTaskRunner(blink::TaskType::kInternalMedia)), - CreateMediaStreamRendererFactory(), render_thread->GetIOTaskRunner(), - video_frame_compositor_task_runner, + CreateMediaStreamRendererFactory(), + render_frame_->GetTaskRunner(blink::TaskType::kInternalMedia), + render_thread->GetIOTaskRunner(), video_frame_compositor_task_runner, render_thread->GetMediaThreadTaskRunner(), render_thread->GetWorkerTaskRunner(), render_thread->GetGpuFactories(), sink_id,
diff --git a/content/renderer/media/render_media_log.cc b/content/renderer/media/render_media_log.cc index fb9f92622..51f4f58a 100644 --- a/content/renderer/media/render_media_log.cc +++ b/content/renderer/media/render_media_log.cc
@@ -16,10 +16,7 @@ #include "content/public/common/content_client.h" #include "content/public/renderer/content_renderer_client.h" #include "content/public/renderer/render_thread.h" - -#ifndef MEDIA_EVENT_LOG_UTILITY -#define MEDIA_EVENT_LOG_UTILITY DVLOG(1) -#endif +#include "media/base/logging_override_if_enabled.h" namespace { @@ -30,8 +27,8 @@ LOG(ERROR) << "MediaEvent: " << media::MediaLog::MediaEventToLogString(*event); } else if (event->type != media::MediaLogEvent::PROPERTY_CHANGE) { - MEDIA_EVENT_LOG_UTILITY << "MediaEvent: " - << media::MediaLog::MediaEventToLogString(*event); + DVLOG(1) << "MediaEvent: " + << media::MediaLog::MediaEventToLogString(*event); } }
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.cc b/content/renderer/media/renderer_webmediaplayer_delegate.cc index f6dbb40..d7d9255c 100644 --- a/content/renderer/media/renderer_webmediaplayer_delegate.cc +++ b/content/renderer/media/renderer_webmediaplayer_delegate.cc
@@ -120,30 +120,6 @@ delegate_id, muted)); } -void RendererWebMediaPlayerDelegate::DidPictureInPictureModeStart( - int delegate_id, - const viz::SurfaceId& surface_id, - const gfx::Size& natural_size, - blink::WebMediaPlayer::PipWindowOpenedCallback callback, - bool show_play_pause_button) { - int request_id = next_picture_in_picture_callback_id_++; - enter_picture_in_picture_callback_map_.insert( - std::make_pair(request_id, std::move(callback))); - Send(new MediaPlayerDelegateHostMsg_OnPictureInPictureModeStarted( - routing_id(), delegate_id, surface_id, natural_size, request_id, - show_play_pause_button)); -} - -void RendererWebMediaPlayerDelegate::DidPictureInPictureModeEnd( - int delegate_id, - base::OnceClosure callback) { - int request_id = next_picture_in_picture_callback_id_++; - exit_picture_in_picture_callback_map_.insert( - std::make_pair(request_id, std::move(callback))); - Send(new MediaPlayerDelegateHostMsg_OnPictureInPictureModeEnded( - routing_id(), delegate_id, request_id)); -} - void RendererWebMediaPlayerDelegate::DidSetPictureInPictureCustomControls( int delegate_id, const std::vector<blink::PictureInPictureControlInfo>& controls) { @@ -151,24 +127,6 @@ routing_id(), delegate_id, controls)); } -void RendererWebMediaPlayerDelegate::DidPictureInPictureSurfaceChange( - int delegate_id, - const viz::SurfaceId& surface_id, - const gfx::Size& natural_size, - bool show_play_pause_button) { - Send(new MediaPlayerDelegateHostMsg_OnPictureInPictureSurfaceChanged( - routing_id(), delegate_id, surface_id, natural_size, - show_play_pause_button)); -} - -void RendererWebMediaPlayerDelegate:: - RegisterPictureInPictureWindowResizeCallback( - int player_id, - blink::WebMediaPlayer::PipWindowResizedCallback callback) { - picture_in_picture_window_resize_observer_ = - std::make_pair(player_id, std::move(callback)); -} - void RendererWebMediaPlayerDelegate::DidPause(int player_id) { DVLOG(2) << __func__ << "(" << player_id << ")"; DCHECK(id_map_.Lookup(player_id)); @@ -291,13 +249,6 @@ OnPictureInPictureModeEnded) IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_ClickPictureInPictureControl, OnPictureInPictureControlClicked) - IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_OnPictureInPictureModeEnded_ACK, - OnPictureInPictureModeEndedAck) - IPC_MESSAGE_HANDLER( - MediaPlayerDelegateMsg_OnPictureInPictureModeStarted_ACK, - OnPictureInPictureModeStartedAck) - IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_OnPictureInPictureWindowResize, - OnPictureInPictureWindowResize) IPC_MESSAGE_UNHANDLED(return false) IPC_END_MESSAGE_MAP() return true; @@ -417,39 +368,6 @@ observer->OnPictureInPictureControlClicked(control_id); } -void RendererWebMediaPlayerDelegate::OnPictureInPictureModeEndedAck( - int player_id, - int request_id) { - auto iter = exit_picture_in_picture_callback_map_.find(request_id); - DCHECK(iter != exit_picture_in_picture_callback_map_.end()); - - std::move(iter->second).Run(); - exit_picture_in_picture_callback_map_.erase(iter); -} - -void RendererWebMediaPlayerDelegate::OnPictureInPictureModeStartedAck( - int player_id, - int request_id, - const gfx::Size& window_size) { - auto iter = enter_picture_in_picture_callback_map_.find(request_id); - DCHECK(iter != enter_picture_in_picture_callback_map_.end()); - - std::move(iter->second).Run(blink::WebSize(window_size)); - enter_picture_in_picture_callback_map_.erase(iter); -} - -void RendererWebMediaPlayerDelegate::OnPictureInPictureWindowResize( - int player_id, - const gfx::Size& window_size) { - if (!picture_in_picture_window_resize_observer_ || - picture_in_picture_window_resize_observer_->first != player_id) { - return; - } - - picture_in_picture_window_resize_observer_->second.Run( - blink::WebSize(window_size)); -} - void RendererWebMediaPlayerDelegate::ScheduleUpdateTask() { if (!pending_update_task_) { base::ThreadTaskRunnerHandle::Get()->PostTask(
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.h b/content/renderer/media/renderer_webmediaplayer_delegate.h index ad78d316..1f7242c3 100644 --- a/content/renderer/media/renderer_webmediaplayer_delegate.h +++ b/content/renderer/media/renderer_webmediaplayer_delegate.h
@@ -65,23 +65,9 @@ blink::WebFullscreenVideoStatus fullscreen_video_status) override; void DidPlayerSizeChange(int delegate_id, const gfx::Size& size) override; void DidPlayerMutedStatusChange(int delegate_id, bool muted) override; - void DidPictureInPictureModeStart( - int delegate_id, - const viz::SurfaceId&, - const gfx::Size&, - blink::WebMediaPlayer::PipWindowOpenedCallback, - bool show_play_pause_button) override; - void DidPictureInPictureModeEnd(int delegate_id, base::OnceClosure) override; void DidSetPictureInPictureCustomControls( int delegate_id, const std::vector<blink::PictureInPictureControlInfo>& controls) override; - void DidPictureInPictureSurfaceChange(int delegate_id, - const viz::SurfaceId&, - const gfx::Size&, - bool show_play_pause_button) override; - void RegisterPictureInPictureWindowResizeCallback( - int player_id, - blink::WebMediaPlayer::PipWindowResizedCallback) override; // content::RenderFrameObserver overrides. void WasHidden() override; @@ -114,11 +100,6 @@ void OnPictureInPictureModeEnded(int player_id); void OnPictureInPictureControlClicked(int player_id, const std::string& control_id); - void OnPictureInPictureModeEndedAck(int player_id, int request_id); - void OnPictureInPictureModeStartedAck(int player_id, - int request_id, - const gfx::Size&); - void OnPictureInPictureWindowResize(int player_id, const gfx::Size&); // Schedules UpdateTask() to run soon. void ScheduleUpdateTask(); @@ -185,35 +166,6 @@ // when the idle cleanup timer should be fired more aggressively. bool is_jelly_bean_; - // Map associating a callback with a request sent to the browser process. The - // index is used as a unique request id that is passed to the browser process - // and will then ACK with the same id which will be used to run the right - // callback. - using ExitPictureInPictureCallbackMap = - base::flat_map<int, base::OnceClosure>; - ExitPictureInPictureCallbackMap exit_picture_in_picture_callback_map_; - - // Map associating a callback with a request sent to the browser process. The - // index is used as a unique request id that is passed to the browser process - // and will then ACK with the same id which will be used to run the right - // callback. - using EnterPictureInPictureCallbackMap = - base::flat_map<int, blink::WebMediaPlayer::PipWindowOpenedCallback>; - EnterPictureInPictureCallbackMap enter_picture_in_picture_callback_map_; - - // Counter that is used to use unique request id associated with - // picture-in-picture callbacks. It is incremented every time it is used. - int next_picture_in_picture_callback_id_ = 0; - - // Associating a player id and a Picture-in-Picture window resize callback. - // It holds the callback alive and guarantees that the notification sent from - // the browser proccess matches the player currently in Picture-in-Picture in - // the renderer. - using PictureInPictureWindowResizeObserver = - std::pair<int, blink::WebMediaPlayer::PipWindowResizedCallback>; - base::Optional<PictureInPictureWindowResizeObserver> - picture_in_picture_window_resize_observer_; - DISALLOW_COPY_AND_ASSIGN(RendererWebMediaPlayerDelegate); };
diff --git a/content/renderer/media/stream/media_stream_renderer_factory_impl.cc b/content/renderer/media/stream/media_stream_renderer_factory_impl.cc index 784cbf7..81bf90f 100644 --- a/content/renderer/media/stream/media_stream_renderer_factory_impl.cc +++ b/content/renderer/media/stream/media_stream_renderer_factory_impl.cc
@@ -4,6 +4,8 @@ #include "content/renderer/media/stream/media_stream_renderer_factory_impl.h" +#include <utility> + #include "base/strings/utf_string_conversions.h" #include "content/renderer/media/stream/media_stream_video_renderer_sink.h" #include "content/renderer/media/stream/media_stream_video_track.h" @@ -53,7 +55,8 @@ const blink::WebMediaStream& web_stream, const base::Closure& error_cb, const MediaStreamVideoRenderer::RepaintCB& repaint_cb, - const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) { + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner) { DCHECK(!web_stream.IsNull()); DVLOG(1) << "MediaStreamRendererFactoryImpl::GetVideoRenderer stream:" @@ -67,7 +70,8 @@ } return new MediaStreamVideoRendererSink(video_tracks[0], error_cb, repaint_cb, - io_task_runner); + std::move(io_task_runner), + std::move(main_render_task_runner)); } scoped_refptr<MediaStreamAudioRenderer>
diff --git a/content/renderer/media/stream/media_stream_renderer_factory_impl.h b/content/renderer/media/stream/media_stream_renderer_factory_impl.h index 8233c30..5c6513f 100644 --- a/content/renderer/media/stream/media_stream_renderer_factory_impl.h +++ b/content/renderer/media/stream/media_stream_renderer_factory_impl.h
@@ -21,7 +21,8 @@ const blink::WebMediaStream& web_stream, const base::Closure& error_cb, const MediaStreamVideoRenderer::RepaintCB& repaint_cb, - const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner) override; scoped_refptr<MediaStreamAudioRenderer> GetAudioRenderer(
diff --git a/content/renderer/media/stream/media_stream_video_capturer_source.cc b/content/renderer/media/stream/media_stream_video_capturer_source.cc index 9f680bf7..a3717a6 100644 --- a/content/renderer/media/stream/media_stream_video_capturer_source.cc +++ b/content/renderer/media/stream/media_stream_video_capturer_source.cc
@@ -47,6 +47,7 @@ void MaybeSuspend() override; void Resume() override; void StopCapture() override; + void OnFrameDropped(media::VideoCaptureFrameDropReason reason) override; void OnLog(const std::string& message) override; private: @@ -131,6 +132,12 @@ base::ResetAndReturn(&stop_capture_cb_).Run(); } +void LocalVideoCapturerSource::OnFrameDropped( + media::VideoCaptureFrameDropReason reason) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + manager_->OnFrameDropped(session_id_, reason); +} + void LocalVideoCapturerSource::OnLog(const std::string& message) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); manager_->OnLog(session_id_, message); @@ -217,6 +224,12 @@ source_->RequestRefreshFrame(); } +void MediaStreamVideoCapturerSource::OnFrameDropped( + media::VideoCaptureFrameDropReason reason) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + source_->OnFrameDropped(reason); +} + void MediaStreamVideoCapturerSource::OnLog(const std::string& message) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); source_->OnLog(message);
diff --git a/content/renderer/media/stream/media_stream_video_capturer_source.h b/content/renderer/media/stream/media_stream_video_capturer_source.h index 6ae378a..00b28faa 100644 --- a/content/renderer/media/stream/media_stream_video_capturer_source.h +++ b/content/renderer/media/stream/media_stream_video_capturer_source.h
@@ -58,6 +58,7 @@ // MediaStreamVideoSource overrides. void RequestRefreshFrame() override; + void OnFrameDropped(media::VideoCaptureFrameDropReason reason) override; void OnLog(const std::string& message) override; void OnHasConsumers(bool has_consumers) override; void OnCapturingLinkSecured(bool is_secure) override;
diff --git a/content/renderer/media/stream/media_stream_video_renderer_sink.cc b/content/renderer/media/stream/media_stream_video_renderer_sink.cc index aa3f094be..d736d57 100644 --- a/content/renderer/media/stream/media_stream_video_renderer_sink.cc +++ b/content/renderer/media/stream/media_stream_video_renderer_sink.cc
@@ -4,6 +4,8 @@ #include "content/renderer/media/stream/media_stream_video_renderer_sink.h" +#include <utility> + #include "base/bind.h" #include "base/feature_list.h" #include "base/memory/weak_ptr.h" @@ -29,10 +31,17 @@ // should be destructed on the IO thread. class MediaStreamVideoRendererSink::FrameDeliverer { public: - FrameDeliverer(const RepaintCB& repaint_cb) - : repaint_cb_(repaint_cb), + FrameDeliverer( + const RepaintCB& repaint_cb, + base::RepeatingCallback<void(media::VideoCaptureFrameDropReason)> + frame_dropped_cb, + scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner) + : main_render_task_runner_(std::move(main_render_task_runner)), + repaint_cb_(repaint_cb), + frame_dropped_cb_(std::move(frame_dropped_cb)), state_(STOPPED), - frame_size_(kMinFrameSize, kMinFrameSize) { + frame_size_(kMinFrameSize, kMinFrameSize), + emit_frame_drop_events_(true) { DETACH_FROM_THREAD(io_thread_checker_); } @@ -51,8 +60,17 @@ TRACE_EVENT_SCOPE_THREAD, "timestamp", frame->timestamp().InMilliseconds()); - if (state_ != STARTED) + if (state_ != STARTED) { + if (emit_frame_drop_events_) { + emit_frame_drop_events_ = false; + main_render_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(frame_dropped_cb_, + media::VideoCaptureFrameDropReason:: + kRendererSinkFrameDelivererIsNotStarted)); + } return; + } frame_size_ = frame->natural_size(); repaint_cb_.Run(frame); @@ -79,27 +97,36 @@ void Start() { DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); DCHECK_EQ(state_, STOPPED); - state_ = STARTED; + SetState(STARTED); } void Resume() { DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); if (state_ == PAUSED) - state_ = STARTED; + SetState(STARTED); } void Pause() { DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); if (state_ == STARTED) - state_ = PAUSED; + SetState(PAUSED); } private: + void SetState(State target_state) { + state_ = target_state; + emit_frame_drop_events_ = true; + } + friend class MediaStreamVideoRendererSink; + const scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner_; const RepaintCB repaint_cb_; + const base::RepeatingCallback<void(media::VideoCaptureFrameDropReason)> + frame_dropped_cb_; State state_; gfx::Size frame_size_; + bool emit_frame_drop_events_; // Used for DCHECKs to ensure method calls are executed on the correct thread. THREAD_CHECKER(io_thread_checker_); @@ -111,19 +138,27 @@ const blink::WebMediaStreamTrack& video_track, const base::Closure& error_cb, const RepaintCB& repaint_cb, - const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner) : error_cb_(error_cb), repaint_cb_(repaint_cb), video_track_(video_track), - io_task_runner_(io_task_runner) {} + io_task_runner_(std::move(io_task_runner)), + main_render_task_runner_(std::move(main_render_task_runner)), + weak_factory_(this) {} -MediaStreamVideoRendererSink::~MediaStreamVideoRendererSink() {} +MediaStreamVideoRendererSink::~MediaStreamVideoRendererSink() { + DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); +} void MediaStreamVideoRendererSink::Start() { DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); - frame_deliverer_.reset( - new MediaStreamVideoRendererSink::FrameDeliverer(repaint_cb_)); + frame_deliverer_.reset(new MediaStreamVideoRendererSink::FrameDeliverer( + repaint_cb_, + base::BindRepeating(&MediaStreamVideoSink::OnFrameDropped, + weak_factory_.GetWeakPtr()), + main_render_task_runner_)); io_task_runner_->PostTask( FROM_HERE, base::BindOnce(&FrameDeliverer::Start, base::Unretained(frame_deliverer_.get())));
diff --git a/content/renderer/media/stream/media_stream_video_renderer_sink.h b/content/renderer/media/stream/media_stream_video_renderer_sink.h index 8e3df03d..ef9a87d 100644 --- a/content/renderer/media/stream/media_stream_video_renderer_sink.h +++ b/content/renderer/media/stream/media_stream_video_renderer_sink.h
@@ -7,6 +7,7 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" #include "content/common/content_export.h" #include "content/public/renderer/media_stream_video_renderer.h" @@ -41,7 +42,8 @@ const blink::WebMediaStreamTrack& video_track, const base::Closure& error_cb, const MediaStreamVideoRenderer::RepaintCB& repaint_cb, - const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner); + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner); // MediaStreamVideoRenderer implementation. Called on the main thread. void Start() override; @@ -77,9 +79,12 @@ std::unique_ptr<FrameDeliverer> frame_deliverer_; const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; + const scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner_; THREAD_CHECKER(main_thread_checker_); + base::WeakPtrFactory<MediaStreamVideoRendererSink> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(MediaStreamVideoRendererSink); };
diff --git a/content/renderer/media/stream/media_stream_video_renderer_sink_unittest.cc b/content/renderer/media/stream/media_stream_video_renderer_sink_unittest.cc index b0be719..8f2586a 100644 --- a/content/renderer/media/stream/media_stream_video_renderer_sink_unittest.cc +++ b/content/renderer/media/stream/media_stream_video_renderer_sink_unittest.cc
@@ -19,6 +19,7 @@ #include "media/base/video_frame.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/web/web_heap.h" @@ -56,7 +57,8 @@ base::Unretained(this)), base::Bind(&MediaStreamVideoRendererSinkTest::RepaintCallback, base::Unretained(this)), - child_process_->io_task_runner()); + child_process_->io_task_runner(), + blink::scheduler::GetSingleThreadTaskRunnerForTesting()); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(IsInStoppedState()); @@ -168,7 +170,8 @@ base::Bind(&MediaStreamVideoRendererSinkTransparencyTest:: VerifyTransparentFrame, base::Unretained(this)), - child_process_->io_task_runner()); + child_process_->io_task_runner(), + blink::scheduler::GetSingleThreadTaskRunnerForTesting()); } void VerifyTransparentFrame(scoped_refptr<media::VideoFrame> frame) {
diff --git a/content/renderer/media/stream/media_stream_video_source.cc b/content/renderer/media/stream/media_stream_video_source.cc index d0e38bc5..61f305b8 100644 --- a/content/renderer/media/stream/media_stream_video_source.cc +++ b/content/renderer/media/stream/media_stream_video_source.cc
@@ -36,10 +36,12 @@ } MediaStreamVideoSource::MediaStreamVideoSource() - : state_(NEW), - track_adapter_( - new VideoTrackAdapter(ChildProcess::current()->io_task_runner())), - weak_factory_(this) {} + : state_(NEW), weak_factory_(this) { + track_adapter_ = base::MakeRefCounted<VideoTrackAdapter>( + ChildProcess::current()->io_task_runner(), + base::BindRepeating(&MediaStreamVideoSource::OnFrameDropped, + weak_factory_.GetWeakPtr())); +} MediaStreamVideoSource::~MediaStreamVideoSource() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/content/renderer/media/stream/media_stream_video_source.h b/content/renderer/media/stream/media_stream_video_source.h index 4d7a98f..4ebb5fd 100644 --- a/content/renderer/media/stream/media_stream_video_source.h +++ b/content/renderer/media/stream/media_stream_video_source.h
@@ -126,6 +126,10 @@ // Request underlying source to capture a new frame. virtual void RequestRefreshFrame() {} + // Optionally overridden by subclasses to implement handling frame drop + // events. + virtual void OnFrameDropped(media::VideoCaptureFrameDropReason reason) {} + // Optionally overridden by subclasses to implement handling log messages. virtual void OnLog(const std::string& message) {} @@ -302,7 +306,7 @@ RestartCallback restart_callback_; // |track_adapter_| delivers video frames to the tracks on the IO-thread. - const scoped_refptr<VideoTrackAdapter> track_adapter_; + scoped_refptr<VideoTrackAdapter> track_adapter_; // Tracks that currently are connected to this source. std::vector<MediaStreamVideoTrack*> tracks_;
diff --git a/content/renderer/media/stream/media_stream_video_track.cc b/content/renderer/media/stream/media_stream_video_track.cc index e65bbb6..36920859 100644 --- a/content/renderer/media/stream/media_stream_video_track.cc +++ b/content/renderer/media/stream/media_stream_video_track.cc
@@ -17,6 +17,7 @@ #include "content/renderer/media/stream/media_stream_constraints_util_video_device.h" #include "media/base/bind_to_current_loop.h" #include "media/capture/video_capture_types.h" +#include "third_party/blink/public/web/web_local_frame.h" namespace content { @@ -43,8 +44,11 @@ public: using VideoSinkId = MediaStreamVideoSink*; - FrameDeliverer(scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - bool enabled); + FrameDeliverer( + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + base::RepeatingCallback<void(media::VideoCaptureFrameDropReason)> + frame_dropped_cb, + bool enabled); void SetEnabled(bool enabled); @@ -74,6 +78,7 @@ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner); void SetEnabledOnIO(bool enabled); + // Returns a black frame where the size and time stamp is set to the same as // as in |reference_frame|. scoped_refptr<media::VideoFrame> GetBlackFrame( @@ -83,9 +88,15 @@ // Render Thread. THREAD_CHECKER(main_render_thread_checker_); const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; + // Can be null in testing. + scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner_; + + base::RepeatingCallback<void(media::VideoCaptureFrameDropReason)> + frame_dropped_cb_; bool enabled_; scoped_refptr<media::VideoFrame> black_frame_; + bool emit_frame_drop_events_; using VideoIdCallbackPair = std::pair<VideoSinkId, blink::VideoCaptureDeliverFrameCB>; @@ -96,9 +107,21 @@ MediaStreamVideoTrack::FrameDeliverer::FrameDeliverer( scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + base::RepeatingCallback<void(media::VideoCaptureFrameDropReason)> + frame_dropped_cb, bool enabled) - : io_task_runner_(io_task_runner), enabled_(enabled) { + : io_task_runner_(std::move(io_task_runner)), + frame_dropped_cb_(std::move(frame_dropped_cb)), + enabled_(enabled), + emit_frame_drop_events_(true) { DCHECK(io_task_runner_.get()); + + blink::WebLocalFrame* web_frame = + blink::WebLocalFrame::FrameForCurrentContext(); + if (web_frame) { + main_render_task_runner_ = + web_frame->GetTaskRunner(blink::TaskType::kInternalMedia); + } } MediaStreamVideoTrack::FrameDeliverer::~FrameDeliverer() { @@ -155,7 +178,10 @@ void MediaStreamVideoTrack::FrameDeliverer::SetEnabledOnIO(bool enabled) { DCHECK(io_task_runner_->BelongsToCurrentThread()); - enabled_ = enabled; + if (enabled != enabled_) { + enabled_ = enabled; + emit_frame_drop_events_ = true; + } if (enabled_) black_frame_ = nullptr; } @@ -164,6 +190,15 @@ const scoped_refptr<media::VideoFrame>& frame, base::TimeTicks estimated_capture_time) { DCHECK(io_task_runner_->BelongsToCurrentThread()); + if (!enabled_ && main_render_task_runner_ && emit_frame_drop_events_) { + emit_frame_drop_events_ = false; + main_render_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + frame_dropped_cb_, + media::VideoCaptureFrameDropReason:: + kVideoTrackFrameDelivererNotEnabledReplacingWithBlackFrame)); + } const scoped_refptr<media::VideoFrame>& video_frame = enabled_ ? frame : GetBlackFrame(frame); for (const auto& entry : callbacks_) @@ -259,14 +294,17 @@ const MediaStreamVideoSource::ConstraintsCallback& callback, bool enabled) : blink::WebPlatformMediaStreamTrack(true), - frame_deliverer_( - new MediaStreamVideoTrack::FrameDeliverer(source->io_task_runner(), - enabled)), adapter_settings_(std::make_unique<VideoTrackAdapterSettings>( VideoTrackAdapterSettings())), is_screencast_(false), source_(source->GetWeakPtr()), weak_factory_(this) { + frame_deliverer_ = + base::MakeRefCounted<MediaStreamVideoTrack::FrameDeliverer>( + source->io_task_runner(), + base::BindRepeating(&MediaStreamVideoTrack::OnFrameDropped, + weak_factory_.GetWeakPtr()), + enabled); source->AddTrack( this, VideoTrackAdapterSettings(), base::Bind(&MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO, @@ -289,9 +327,6 @@ const MediaStreamVideoSource::ConstraintsCallback& callback, bool enabled) : blink::WebPlatformMediaStreamTrack(true), - frame_deliverer_( - new MediaStreamVideoTrack::FrameDeliverer(source->io_task_runner(), - enabled)), adapter_settings_( std::make_unique<VideoTrackAdapterSettings>(adapter_settings)), noise_reduction_(noise_reduction), @@ -299,6 +334,12 @@ min_frame_rate_(min_frame_rate), source_(source->GetWeakPtr()), weak_factory_(this) { + frame_deliverer_ = + base::MakeRefCounted<MediaStreamVideoTrack::FrameDeliverer>( + source->io_task_runner(), + base::BindRepeating(&MediaStreamVideoTrack::OnFrameDropped, + weak_factory_.GetWeakPtr()), + enabled); source->AddTrack( this, adapter_settings, base::Bind(&MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO, @@ -446,4 +487,12 @@ return computed_source_format_; } +void MediaStreamVideoTrack::OnFrameDropped( + media::VideoCaptureFrameDropReason reason) { + DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_); + if (!source_) + return; + source_->OnFrameDropped(reason); +} + } // namespace content
diff --git a/content/renderer/media/stream/media_stream_video_track.h b/content/renderer/media/stream/media_stream_video_track.h index f3b8eb4..f79c09a 100644 --- a/content/renderer/media/stream/media_stream_video_track.h +++ b/content/renderer/media/stream/media_stream_video_track.h
@@ -131,6 +131,8 @@ MediaStreamVideoSource* source() const { return source_.get(); } + void OnFrameDropped(media::VideoCaptureFrameDropReason reason); + private: // MediaStreamVideoSink is a friend to allow it to call AddSink() and // RemoveSink(). @@ -161,7 +163,7 @@ // |FrameDeliverer| is an internal helper object used for delivering video // frames on the IO-thread using callbacks to all registered tracks. class FrameDeliverer; - const scoped_refptr<FrameDeliverer> frame_deliverer_; + scoped_refptr<FrameDeliverer> frame_deliverer_; // TODO(guidou): Make this field a regular field instead of a unique_ptr. std::unique_ptr<VideoTrackAdapterSettings> adapter_settings_;
diff --git a/content/renderer/media/stream/video_track_adapter.cc b/content/renderer/media/stream/video_track_adapter.cc index 22d2295..0280575c 100644 --- a/content/renderer/media/stream/video_track_adapter.cc +++ b/content/renderer/media/stream/video_track_adapter.cc
@@ -130,7 +130,9 @@ // will be done. VideoFrameResolutionAdapter( scoped_refptr<base::SingleThreadTaskRunner> render_message_loop, - const VideoTrackAdapterSettings& settings); + const VideoTrackAdapterSettings& settings, + base::RepeatingCallback<void(media::VideoCaptureFrameDropReason)> + frame_dropped_cb); // Add |frame_callback| to receive video frames on the IO-thread and // |settings_callback| to set track settings on the main thread. @@ -170,9 +172,11 @@ const base::TimeTicks& estimated_capture_time); // Returns |true| if the input frame rate is higher that the requested max - // frame rate and |frame| should be dropped. + // frame rate and |frame| should be dropped. If it returns true, |reason| is + // assigned to indicate the particular reason for the decision. bool MaybeDropFrame(const scoped_refptr<media::VideoFrame>& frame, - float source_frame_rate); + float source_frame_rate, + media::VideoCaptureFrameDropReason* reason); // Updates track settings if either frame width, height or frame rate have // changed since last update. @@ -184,6 +188,9 @@ // or frame rate have changed since last update. void MaybeUpdateTracksFormat(const scoped_refptr<media::VideoFrame>& frame); + void PostFrameDroppedToMainTaskRunner( + media::VideoCaptureFrameDropReason reason); + // Bound to the IO-thread. THREAD_CHECKER(io_thread_checker_); @@ -191,6 +198,9 @@ // registered in AddCallbacks. const scoped_refptr<base::SingleThreadTaskRunner> renderer_task_runner_; + base::RepeatingCallback<void(media::VideoCaptureFrameDropReason)> + frame_dropped_cb_; + VideoTrackAdapterSettings settings_; double frame_rate_; base::TimeDelta last_time_stamp_; @@ -206,8 +216,11 @@ VideoTrackAdapter::VideoFrameResolutionAdapter::VideoFrameResolutionAdapter( scoped_refptr<base::SingleThreadTaskRunner> render_message_loop, - const VideoTrackAdapterSettings& settings) + const VideoTrackAdapterSettings& settings, + base::RepeatingCallback<void(media::VideoCaptureFrameDropReason)> + frame_dropped_cb) : renderer_task_runner_(render_message_loop), + frame_dropped_cb_(std::move(frame_dropped_cb)), settings_(settings), frame_rate_(MediaStreamVideoSource::kDefaultFrameRate), last_time_stamp_(base::TimeDelta::Max()), @@ -276,6 +289,8 @@ if (!frame) { DLOG(ERROR) << "Incoming frame is not valid."; + PostFrameDroppedToMainTaskRunner( + media::VideoCaptureFrameDropReason::kResolutionAdapterFrameIsNotValid); return; } @@ -289,8 +304,11 @@ frame_rate = MediaStreamVideoSource::kUnknownFrameRate; } - if (MaybeDropFrame(frame, frame_rate)) + auto frame_drop_reason = media::VideoCaptureFrameDropReason::kNone; + if (MaybeDropFrame(frame, frame_rate, &frame_drop_reason)) { + PostFrameDroppedToMainTaskRunner(frame_drop_reason); return; + } // TODO(perkj): Allow cropping / scaling of textures once // https://crbug/362521 is fixed. @@ -313,8 +331,12 @@ video_frame = media::VideoFrame::WrapVideoFrame( frame, frame->format(), region_in_frame, desired_size); - if (!video_frame) + if (!video_frame) { + PostFrameDroppedToMainTaskRunner( + media::VideoCaptureFrameDropReason:: + kResolutionAdapterWrappingFrameForCroppingFailed); return; + } video_frame->AddDestructionObserver( base::BindOnce(&TrackReleaseOriginalFrame, frame)); @@ -342,6 +364,10 @@ const scoped_refptr<media::VideoFrame>& frame, const base::TimeTicks& estimated_capture_time) { DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); + if (callbacks_.empty()) { + PostFrameDroppedToMainTaskRunner( + media::VideoCaptureFrameDropReason::kResolutionAdapterHasNoCallbacks); + } for (const auto& callback : callbacks_) { MaybeUpdateTrackSettings(callback.second.settings_callback, frame); callback.second.frame_callback.Run(frame, estimated_capture_time); @@ -350,7 +376,8 @@ bool VideoTrackAdapter::VideoFrameResolutionAdapter::MaybeDropFrame( const scoped_refptr<media::VideoFrame>& frame, - float source_frame_rate) { + float source_frame_rate, + media::VideoCaptureFrameDropReason* reason) { DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); // Do not drop frames if max frame rate hasn't been specified or the source @@ -384,6 +411,8 @@ // actual camera. DVLOG(3) << "Drop frame since delta time since previous frame is " << delta_ms << "ms."; + *reason = media::VideoCaptureFrameDropReason:: + kResolutionAdapterTimestampTooCloseToPrevious; return true; } last_time_stamp_ = frame->timestamp(); @@ -404,6 +433,8 @@ return false; } DVLOG(3) << "Drop frame. Input frame_rate_ " << frame_rate_ << "."; + *reason = media::VideoCaptureFrameDropReason:: + kResolutionAdapterFrameRateIsHigherThanRequested; return true; } @@ -441,6 +472,13 @@ } } +void VideoTrackAdapter::VideoFrameResolutionAdapter:: + PostFrameDroppedToMainTaskRunner( + media::VideoCaptureFrameDropReason reason) { + renderer_task_runner_->PostTask(FROM_HERE, + base::BindOnce(frame_dropped_cb_, reason)); +} + VideoTrackAdapterSettings::VideoTrackAdapterSettings() : VideoTrackAdapterSettings(base::nullopt, 0.0, @@ -485,9 +523,12 @@ } VideoTrackAdapter::VideoTrackAdapter( - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + base::RepeatingCallback<void(media::VideoCaptureFrameDropReason)> + frame_dropped_cb) : io_task_runner_(io_task_runner), renderer_task_runner_(base::ThreadTaskRunnerHandle::Get()), + frame_dropped_cb_(std::move(frame_dropped_cb)), monitoring_frame_rate_(false), muted_state_(false), frame_counter_(0), @@ -529,7 +570,8 @@ } } if (!adapter.get()) { - adapter = new VideoFrameResolutionAdapter(renderer_task_runner_, settings); + adapter = new VideoFrameResolutionAdapter(renderer_task_runner_, settings, + frame_dropped_cb_); adapters_.push_back(adapter); } @@ -727,6 +769,13 @@ frame->natural_size().height() == source_frame_size_->width()) { is_device_rotated = true; } + if (adapters_.empty()) { + renderer_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(frame_dropped_cb_, + media::VideoCaptureFrameDropReason:: + kVideoTrackAdapterHasNoResolutionAdapters)); + } for (const auto& adapter : adapters_) adapter->DeliverFrame(frame, estimated_capture_time, is_device_rotated); }
diff --git a/content/renderer/media/stream/video_track_adapter.h b/content/renderer/media/stream/video_track_adapter.h index 4ed082d..4280f1b 100644 --- a/content/renderer/media/stream/video_track_adapter.h +++ b/content/renderer/media/stream/video_track_adapter.h
@@ -81,8 +81,10 @@ public: using OnMutedCallback = base::Callback<void(bool mute_state)>; - explicit VideoTrackAdapter( - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner); + VideoTrackAdapter( + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + base::RepeatingCallback<void(media::VideoCaptureFrameDropReason)> + frame_dropped_cb); // Register |track| to receive video frames in |frame_callback| with // a resolution within the boundaries of the arguments, and settings @@ -161,6 +163,9 @@ // VideoCaptureDeliverFrameCB is released on the main render thread. const scoped_refptr<base::SingleThreadTaskRunner> renderer_task_runner_; + const base::RepeatingCallback<void(media::VideoCaptureFrameDropReason)> + frame_dropped_cb_; + // VideoFrameResolutionAdapter is an inner class that lives on the IO-thread. // It does the resolution adaptation and delivers frames to all registered // tracks.
diff --git a/content/renderer/media/stream/webmediaplayer_ms.cc b/content/renderer/media/stream/webmediaplayer_ms.cc index 0c73be8..3b11c6d 100644 --- a/content/renderer/media/stream/webmediaplayer_ms.cc +++ b/content/renderer/media/stream/webmediaplayer_ms.cc
@@ -231,6 +231,7 @@ media::WebMediaPlayerDelegate* delegate, std::unique_ptr<media::MediaLog> media_log, std::unique_ptr<MediaStreamRendererFactory> factory, + scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner, scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, @@ -251,10 +252,11 @@ video_rotation_(media::VIDEO_ROTATION_0), media_log_(std::move(media_log)), renderer_factory_(std::move(factory)), - io_task_runner_(io_task_runner), - compositor_task_runner_(compositor_task_runner), - media_task_runner_(media_task_runner), - worker_task_runner_(worker_task_runner), + main_render_task_runner_(std::move(main_render_task_runner)), + io_task_runner_(std::move(io_task_runner)), + compositor_task_runner_(std::move(compositor_task_runner)), + media_task_runner_(std::move(media_task_runner)), + worker_task_runner_(std::move(worker_task_runner)), gpu_factories_(gpu_factories), initial_audio_output_device_id_(sink_id.Utf8()), volume_(1.0), @@ -339,7 +341,8 @@ web_stream_, media::BindToCurrentLoop( base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr())), - frame_deliverer_->GetRepaintCallback(), io_task_runner_); + frame_deliverer_->GetRepaintCallback(), io_task_runner_, + main_render_task_runner_); RenderFrame* const frame = RenderFrame::FromWebFrame(frame_); @@ -422,11 +425,8 @@ // disabled. // The viz::SurfaceId may be updated when the video begins playback or when // the size of the video changes. - if (client_ && IsInPictureInPicture() && !client_->IsInAutoPIP()) { - delegate_->DidPictureInPictureSurfaceChange( - delegate_id_, surface_id, NaturalSize(), - false /* show_play_pause_button */); - } + if (client_) + client_->OnPictureInPictureStateChange(); } void WebMediaPlayerMS::TrackAdded(const blink::WebMediaStreamTrack& track) { @@ -457,6 +457,16 @@ audio_renderer_->Stop(); } +int WebMediaPlayerMS::GetDelegateId() { + return delegate_id_; +} + +base::Optional<viz::SurfaceId> WebMediaPlayerMS::GetSurfaceId() { + if (bridge_) + return bridge_->GetSurfaceId(); + return base::nullopt; +} + void WebMediaPlayerMS::Reload() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (web_stream_.IsNull()) @@ -493,7 +503,8 @@ web_stream_, media::BindToCurrentLoop( base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr())), - frame_deliverer_->GetRepaintCallback(), io_task_runner_); + frame_deliverer_->GetRepaintCallback(), io_task_runner_, + main_render_task_runner_); DCHECK(video_frame_provider_); video_frame_provider_->Start(); break; @@ -636,30 +647,17 @@ delegate_->DidPlayerMutedStatusChange(delegate_id_, volume == 0.0); } -void WebMediaPlayerMS::EnterPictureInPicture( - blink::WebMediaPlayer::PipWindowOpenedCallback callback) { +void WebMediaPlayerMS::EnterPictureInPicture() { if (!bridge_) ActivateSurfaceLayerForVideo(); DCHECK(bridge_); - - const viz::SurfaceId& surface_id = bridge_->GetSurfaceId(); - DCHECK(surface_id.is_valid()); - - // Notifies the browser process that the player should now be in - // Picture-in-Picture mode. - delegate_->DidPictureInPictureModeStart(delegate_id_, surface_id, - NaturalSize(), std::move(callback), - false /* show_play_pause_button */); + DCHECK(bridge_->GetSurfaceId().is_valid()); } -void WebMediaPlayerMS::ExitPictureInPicture( - blink::WebMediaPlayer::PipWindowClosedCallback callback) { - // Notifies the browser process that Picture-in-Picture has ended. It will - // clear out the states and close the window. - delegate_->DidPictureInPictureModeEnd(delegate_id_, std::move(callback)); - +void WebMediaPlayerMS::ExitPictureInPicture() { // Internal cleanups. + // TODO(mlamouri): remove the need for this. OnPictureInPictureModeEnded(); } @@ -668,14 +666,6 @@ delegate_->DidSetPictureInPictureCustomControls(delegate_id_, controls); } -void WebMediaPlayerMS::RegisterPictureInPictureWindowResizeCallback( - blink::WebMediaPlayer::PipWindowResizedCallback callback) { - DCHECK(IsInPictureInPicture() && !client_->IsInAutoPIP()); - - delegate_->RegisterPictureInPictureWindowResizeCallback(delegate_id_, - std::move(callback)); -} - void WebMediaPlayerMS::SetSinkId( const blink::WebString& sink_id, std::unique_ptr<blink::WebSetSinkIdCallbacks> web_callback) {
diff --git a/content/renderer/media/stream/webmediaplayer_ms.h b/content/renderer/media/stream/webmediaplayer_ms.h index 6769ce3..3fcc581 100644 --- a/content/renderer/media/stream/webmediaplayer_ms.h +++ b/content/renderer/media/stream/webmediaplayer_ms.h
@@ -86,7 +86,8 @@ media::WebMediaPlayerDelegate* delegate, std::unique_ptr<media::MediaLog> media_log, std::unique_ptr<MediaStreamRendererFactory> factory, - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_, + scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner, scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, scoped_refptr<base::TaskRunner> worker_task_runner, @@ -115,14 +116,10 @@ void Seek(double seconds) override; void SetRate(double rate) override; void SetVolume(double volume) override; - void EnterPictureInPicture( - blink::WebMediaPlayer::PipWindowOpenedCallback callback) override; - void ExitPictureInPicture( - blink::WebMediaPlayer::PipWindowClosedCallback callback) override; + void EnterPictureInPicture() override; + void ExitPictureInPicture() override; void SetPictureInPictureCustomControls( const std::vector<blink::PictureInPictureControlInfo>&) override; - void RegisterPictureInPictureWindowResizeCallback( - blink::WebMediaPlayer::PipWindowResizedCallback) override; void SetSinkId( const blink::WebString& sink_id, std::unique_ptr<blink::WebSetSinkIdCallbacks> web_callback) override; @@ -239,6 +236,8 @@ void TrackAdded(const blink::WebMediaStreamTrack& track) override; void TrackRemoved(const blink::WebMediaStreamTrack& track) override; void ActiveStateChanged(bool is_active) override; + int GetDelegateId() override; + base::Optional<viz::SurfaceId> GetSurfaceId() override; void OnDisplayTypeChanged(WebMediaPlayer::DisplayType) override; @@ -318,6 +317,7 @@ std::unique_ptr<MediaStreamRendererFactory> renderer_factory_; + const scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner_; const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; const scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
diff --git a/content/renderer/media/stream/webmediaplayer_ms_unittest.cc b/content/renderer/media/stream/webmediaplayer_ms_unittest.cc index ba82ff2..c649211 100644 --- a/content/renderer/media/stream/webmediaplayer_ms_unittest.cc +++ b/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
@@ -113,21 +113,9 @@ EXPECT_EQ(delegate_id_, delegate_id); } - MOCK_METHOD5(DidPictureInPictureModeStart, - void(int, - const viz::SurfaceId&, - const gfx::Size&, - blink::WebMediaPlayer::PipWindowOpenedCallback, - bool)); - MOCK_METHOD2(DidPictureInPictureModeEnd, - void(int, blink::WebMediaPlayer::PipWindowClosedCallback)); MOCK_METHOD2(DidSetPictureInPictureCustomControls, void(int, const std::vector<blink::PictureInPictureControlInfo>&)); - MOCK_METHOD4(DidPictureInPictureSurfaceChange, - void(int, const viz::SurfaceId&, const gfx::Size&, bool)); - MOCK_METHOD2(RegisterPictureInPictureWindowResizeCallback, - void(int, blink::WebMediaPlayer::PipWindowResizedCallback)); void DidPause(int delegate_id) override { EXPECT_EQ(delegate_id_, delegate_id); @@ -454,7 +442,8 @@ const blink::WebMediaStream& web_stream, const base::Closure& error_cb, const MediaStreamVideoRenderer::RepaintCB& repaint_cb, - const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner) override; MockMediaStreamVideoRenderer* provider() { @@ -491,7 +480,8 @@ const blink::WebMediaStream& web_stream, const base::Closure& error_cb, const MediaStreamVideoRenderer::RepaintCB& repaint_cb, - const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) { + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner) { if (!support_video_renderer_) return nullptr; @@ -616,6 +606,7 @@ void StopRendering() override; void DidReceiveFrame() override; bool IsDrivingFrameUpdates() const override { return true; } + void OnPictureInPictureStateChange() override {} // For test use void SetBackgroundRendering(bool background_rendering) { @@ -690,6 +681,7 @@ blink::scheduler::GetSingleThreadTaskRunnerForTesting(), blink::scheduler::GetSingleThreadTaskRunnerForTesting(), blink::scheduler::GetSingleThreadTaskRunnerForTesting(), + blink::scheduler::GetSingleThreadTaskRunnerForTesting(), gpu_factories_.get(), blink::WebString(), base::BindOnce(&WebMediaPlayerMSTest::CreateMockSurfaceLayerBridge, base::Unretained(this)), @@ -1404,68 +1396,9 @@ } #endif -// Tests delegate methods are called when Picture-in-Picture is triggered. -TEST_P(WebMediaPlayerMSTest, PictureInPictureTriggerCallback) { - InitializeWebMediaPlayerMS(); - - // It works only a surface layer is used instead of a video layer. - if (!enable_surface_layer_for_video_) { - EXPECT_CALL(*this, DoSetCcLayer(false)); - return; - } - - MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true); - - int tokens[] = {0, 33, 66, 100, 133, 166, 200, 233, 266, 300, - 333, 366, 400, 433, 466, 500, 533, 566, 600}; - std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int)); - provider->QueueFrames(timestamps); - - EXPECT_CALL(*submitter_ptr_, StartRendering()); - EXPECT_CALL(*this, DisplayType()).Times(2); - EXPECT_CALL(*this, DoReadyStateChanged( - blink::WebMediaPlayer::kReadyStateHaveMetadata)); - EXPECT_CALL(*this, DoReadyStateChanged( - blink::WebMediaPlayer::kReadyStateHaveEnoughData)); - EXPECT_CALL(*this, - CheckSizeChanged(gfx::Size(kStandardWidth, kStandardHeight))); - message_loop_controller_.RunAndWaitForStatus( - media::PipelineStatus::PIPELINE_OK); - testing::Mock::VerifyAndClearExpectations(this); - - EXPECT_CALL(*this, DisplayType()) - .WillRepeatedly( - Return(blink::WebMediaPlayer::DisplayType::kPictureInPicture)); - - const gfx::Size natural_size = player_->NaturalSize(); - EXPECT_CALL(delegate_, DidPictureInPictureSurfaceChange( - delegate_.delegate_id(), - surface_layer_bridge_ptr_->GetSurfaceId(), - natural_size, false)) - .Times(2); - - player_->OnSurfaceIdUpdated(surface_layer_bridge_ptr_->GetSurfaceId()); - - EXPECT_CALL(delegate_, DidPictureInPictureModeStart( - delegate_.delegate_id(), - surface_layer_bridge_ptr_->GetSurfaceId(), - natural_size, _, false)); - - player_->EnterPictureInPicture(base::DoNothing()); - player_->OnSurfaceIdUpdated(surface_layer_bridge_ptr_->GetSurfaceId()); - - // Updating SurfaceId should NOT exit Picture-in-Picture. - EXPECT_CALL(delegate_, DidPictureInPictureModeEnd(delegate_.delegate_id(), _)) - .Times(0); - - testing::Mock::VerifyAndClearExpectations(this); - EXPECT_CALL(*this, DoSetCcLayer(false)); - EXPECT_CALL(*submitter_ptr_, StopUsingProvider()); -} - -INSTANTIATE_TEST_SUITE_P(, - WebMediaPlayerMSTest, - ::testing::Combine(::testing::Bool(), - ::testing::Bool(), - ::testing::Bool())); +INSTANTIATE_TEST_CASE_P(, + WebMediaPlayerMSTest, + ::testing::Combine(::testing::Bool(), + ::testing::Bool(), + ::testing::Bool())); } // namespace content
diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc index f85d5ed..0379d1d 100644 --- a/content/renderer/media/video_capture_impl.cc +++ b/content/renderer/media/video_capture_impl.cc
@@ -262,6 +262,11 @@ weak_factory_.GetWeakPtr(), callback)); } +void VideoCaptureImpl::OnFrameDropped( + media::VideoCaptureFrameDropReason reason) { + GetVideoCaptureHost()->OnFrameDropped(device_id_, reason); +} + void VideoCaptureImpl::OnLog(const std::string& message) { GetVideoCaptureHost()->OnLog(device_id_, message); } @@ -338,6 +343,8 @@ bool consume_buffer = state_ == blink::VIDEO_CAPTURE_STATE_STARTED; if (!consume_buffer) { + OnFrameDropped( + media::VideoCaptureFrameDropReason::kVideoCaptureImplNotInStartedState); GetVideoCaptureHost()->ReleaseBuffer(device_id_, buffer_id, -1.0); return; } @@ -433,6 +440,8 @@ break; } if (!frame) { + OnFrameDropped(media::VideoCaptureFrameDropReason:: + kVideoCaptureImplFailedToWrapDataAsMediaVideoFrame); GetVideoCaptureHost()->ReleaseBuffer(device_id_, buffer_id, -1.0); return; }
diff --git a/content/renderer/media/video_capture_impl.h b/content/renderer/media/video_capture_impl.h index fbef75ba..751e4505 100644 --- a/content/renderer/media/video_capture_impl.h +++ b/content/renderer/media/video_capture_impl.h
@@ -64,6 +64,7 @@ void GetDeviceFormatsInUse( const blink::VideoCaptureDeviceFormatsCB& callback); + void OnFrameDropped(media::VideoCaptureFrameDropReason reason); void OnLog(const std::string& message); media::VideoCaptureSessionId session_id() const { return session_id_; }
diff --git a/content/renderer/media/video_capture_impl_manager.cc b/content/renderer/media/video_capture_impl_manager.cc index 3edbc14..6494661 100644 --- a/content/renderer/media/video_capture_impl_manager.cc +++ b/content/renderer/media/video_capture_impl_manager.cc
@@ -270,6 +270,19 @@ } } +void VideoCaptureImplManager::OnFrameDropped( + media::VideoCaptureSessionId id, + media::VideoCaptureFrameDropReason reason) { + DCHECK(render_main_task_runner_->BelongsToCurrentThread()); + const auto it = std::find_if( + devices_.begin(), devices_.end(), + [id](const DeviceEntry& entry) { return entry.session_id == id; }); + DCHECK(it != devices_.end()); + ChildProcess::current()->io_task_runner()->PostTask( + FROM_HERE, base::BindOnce(&VideoCaptureImpl::OnFrameDropped, + base::Unretained(it->impl.get()), reason)); +} + void VideoCaptureImplManager::OnLog(media::VideoCaptureSessionId id, const std::string& message) { DCHECK(render_main_task_runner_->BelongsToCurrentThread());
diff --git a/content/renderer/media/video_capture_impl_manager.h b/content/renderer/media/video_capture_impl_manager.h index 68d57dd0..a587f109 100644 --- a/content/renderer/media/video_capture_impl_manager.h +++ b/content/renderer/media/video_capture_impl_manager.h
@@ -104,6 +104,8 @@ bool suspend); void OnLog(media::VideoCaptureSessionId id, const std::string& message); + void OnFrameDropped(media::VideoCaptureSessionId id, + media::VideoCaptureFrameDropReason reason); virtual std::unique_ptr<VideoCaptureImpl> CreateVideoCaptureImplForTesting( media::VideoCaptureSessionId session_id) const;
diff --git a/content/renderer/media/video_capture_impl_manager_unittest.cc b/content/renderer/media/video_capture_impl_manager_unittest.cc index 964b929..f7aec1ca 100644 --- a/content/renderer/media/video_capture_impl_manager_unittest.cc +++ b/content/renderer/media/video_capture_impl_manager_unittest.cc
@@ -96,6 +96,8 @@ NOTREACHED(); } + MOCK_METHOD2(OnFrameDropped, + void(int32_t, media::VideoCaptureFrameDropReason)); MOCK_METHOD2(OnLog, void(int32_t, const std::string&)); PauseResumeCallback* const pause_callback_;
diff --git a/content/renderer/media/video_capture_impl_unittest.cc b/content/renderer/media/video_capture_impl_unittest.cc index 1468b24f..90ed82e 100644 --- a/content/renderer/media/video_capture_impl_unittest.cc +++ b/content/renderer/media/video_capture_impl_unittest.cc
@@ -70,6 +70,8 @@ void(int32_t, int32_t, GetDeviceSupportedFormatsCallback&)); MOCK_METHOD3(GetDeviceFormatsInUseMock, void(int32_t, int32_t, GetDeviceFormatsInUseCallback&)); + MOCK_METHOD2(OnFrameDropped, + void(int32_t, media::VideoCaptureFrameDropReason)); MOCK_METHOD2(OnLog, void(int32_t, const std::string&)); void GetDeviceSupportedFormats(
diff --git a/content/renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc b/content/renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc index 18325df..510dff25 100644 --- a/content/renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc +++ b/content/renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc
@@ -50,12 +50,10 @@ void Seek(double seconds) override {} void SetRate(double) override {} void SetVolume(double) override {} - void EnterPictureInPicture(PipWindowOpenedCallback) override {} - void ExitPictureInPicture(PipWindowClosedCallback) override {} + void EnterPictureInPicture() override {} + void ExitPictureInPicture() override {} void SetPictureInPictureCustomControls( const std::vector<blink::PictureInPictureControlInfo>&) override {} - void RegisterPictureInPictureWindowResizeCallback( - PipWindowResizedCallback) override {} blink::WebTimeRanges Buffered() const override { return blink::WebTimeRanges(); }
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index a7fbf37..5d1e5433 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -199,7 +199,6 @@ #include "third_party/blink/public/web/web_element_collection.h" #include "third_party/blink/public/web/web_frame_owner_properties.h" #include "third_party/blink/public/web/web_frame_serializer.h" -#include "third_party/blink/public/web/web_frame_serializer_cache_control_policy.h" #include "third_party/blink/public/web/web_frame_widget.h" #include "third_party/blink/public/web/web_input_method_controller.h" #include "third_party/blink/public/web/web_local_frame.h" @@ -6416,10 +6415,7 @@ // the main frame is skipped, then the whole archive is bad. mhtml_contents.emplace_back(WebFrameSerializer::GenerateMHTMLHeader( mhtml_boundary, GetWebFrame(), &delegate)); - if (mhtml_contents.back().IsEmpty()) - save_status = MhtmlSaveStatus::FRAME_SERIALIZATION_FORBIDDEN; - else - has_some_data = true; + has_some_data = true; } // Generate MHTML parts. Note that if this is not the main frame, then even
diff --git a/content/renderer/render_process_impl.cc b/content/renderer/render_process_impl.cc index 2a63b828..f71fc7c 100644 --- a/content/renderer/render_process_impl.cc +++ b/content/renderer/render_process_impl.cc
@@ -64,24 +64,18 @@ std::unique_ptr<base::TaskScheduler::InitParams> GetDefaultTaskSchedulerInitParams() { - constexpr int kMaxNumThreadsInBackgroundPool = 1; - constexpr int kMaxNumThreadsInBackgroundBlockingPool = 1; - constexpr int kMaxNumThreadsInForegroundPoolLowerBound = 2; - constexpr int kMaxNumThreadsInForegroundBlockingPool = 1; + constexpr int kMaxNumThreadsInBackgroundPool = 2; + constexpr int kMaxNumThreadsInForegroundPoolLowerBound = 3; constexpr auto kSuggestedReclaimTime = base::TimeDelta::FromSeconds(30); return std::make_unique<base::TaskScheduler::InitParams>( base::SchedulerWorkerPoolParams(kMaxNumThreadsInBackgroundPool, kSuggestedReclaimTime), - base::SchedulerWorkerPoolParams(kMaxNumThreadsInBackgroundBlockingPool, - kSuggestedReclaimTime), base::SchedulerWorkerPoolParams( std::max( kMaxNumThreadsInForegroundPoolLowerBound, content::GetMinThreadsInRendererTaskSchedulerForegroundPool()), - kSuggestedReclaimTime), - base::SchedulerWorkerPoolParams(kMaxNumThreadsInForegroundBlockingPool, - kSuggestedReclaimTime)); + kSuggestedReclaimTime)); } #if defined(DCHECK_IS_CONFIGURABLE)
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 90d4c53..f086864 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -1133,6 +1133,10 @@ delegate()->DidCompletePageScaleAnimationForWidget(); } +void RenderWidget::SetRootLayer(scoped_refptr<cc::Layer> layer) { + layer_tree_view_->layer_tree_host()->SetRootLayer(std::move(layer)); +} + void RenderWidget::ScheduleAnimation() { // This call is not needed in single thread mode for tests without a // scheduler, but they need to override the WebWidgetClient and replace this
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 9b96c79..888a92f 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -346,6 +346,7 @@ const gfx::Rect& window_screen_rect) override; // blink::WebWidgetClient + void SetRootLayer(scoped_refptr<cc::Layer> layer) override; void ScheduleAnimation() override; void SetShowFPSCounter(bool show) override; void SetShowPaintRects(bool) override;
diff --git a/content/renderer/render_widget_fullscreen_pepper.cc b/content/renderer/render_widget_fullscreen_pepper.cc index 99cc4ea..6d59773 100644 --- a/content/renderer/render_widget_fullscreen_pepper.cc +++ b/content/renderer/render_widget_fullscreen_pepper.cc
@@ -340,8 +340,7 @@ void RenderWidgetFullscreenPepper::SetLayer(cc::Layer* layer) { layer_ = layer; if (!layer_) { - if (layer_tree_view()) - layer_tree_view()->ClearRootLayer(); + RenderWidget::SetRootLayer(nullptr); return; } UpdateLayerBounds();
diff --git a/content/shell/renderer/web_test/test_media_stream_renderer_factory.cc b/content/shell/renderer/web_test/test_media_stream_renderer_factory.cc index d7905c1..a4f1019 100644 --- a/content/shell/renderer/web_test/test_media_stream_renderer_factory.cc +++ b/content/shell/renderer/web_test/test_media_stream_renderer_factory.cc
@@ -4,6 +4,9 @@ #include "content/shell/renderer/web_test/test_media_stream_renderer_factory.h" +#include <utility> + +#include "base/single_thread_task_runner.h" #include "content/shell/renderer/web_test/test_media_stream_video_renderer.h" #include "media/media_buildflags.h" #include "third_party/blink/public/platform/web_media_stream.h" @@ -36,12 +39,14 @@ const blink::WebMediaStream& web_stream, const base::Closure& error_cb, const MediaStreamVideoRenderer::RepaintCB& repaint_cb, - const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) { + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner) { if (!IsMockMediaStreamWithVideo(web_stream)) return nullptr; return new TestMediaStreamVideoRenderer( - io_task_runner, gfx::Size(kVideoCaptureWidth, kVideoCaptureHeight), + std::move(io_task_runner), + gfx::Size(kVideoCaptureWidth, kVideoCaptureHeight), base::TimeDelta::FromMilliseconds(kVideoCaptureFrameDurationMs), error_cb, repaint_cb); }
diff --git a/content/shell/renderer/web_test/test_media_stream_renderer_factory.h b/content/shell/renderer/web_test/test_media_stream_renderer_factory.h index 2a54228..2c13265 100644 --- a/content/shell/renderer/web_test/test_media_stream_renderer_factory.h +++ b/content/shell/renderer/web_test/test_media_stream_renderer_factory.h
@@ -24,7 +24,8 @@ const blink::WebMediaStream& web_stream, const base::Closure& error_cb, const MediaStreamVideoRenderer::RepaintCB& repaint_cb, - const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner) override; scoped_refptr<MediaStreamAudioRenderer> GetAudioRenderer(
diff --git a/content/shell/test_runner/web_view_test_proxy.cc b/content/shell/test_runner/web_view_test_proxy.cc index c11b977..c474b37 100644 --- a/content/shell/test_runner/web_view_test_proxy.cc +++ b/content/shell/test_runner/web_view_test_proxy.cc
@@ -29,6 +29,9 @@ widget_test_client_(widget_test_client), render_widget_(render_widget) {} +void ProxyWebWidgetClient::SetRootLayer(scoped_refptr<cc::Layer> layer) { + base_class_widget_client_->SetRootLayer(std::move(layer)); +} void ProxyWebWidgetClient::ScheduleAnimation() { // When using threaded compositing, have the RenderWidget schedule a request // for a frame, as we use the compositor's scheduler. Otherwise the testing
diff --git a/content/shell/test_runner/web_view_test_proxy.h b/content/shell/test_runner/web_view_test_proxy.h index 8d6e9e0..dd64afa 100644 --- a/content/shell/test_runner/web_view_test_proxy.h +++ b/content/shell/test_runner/web_view_test_proxy.h
@@ -59,6 +59,7 @@ content::RenderWidget* render_widget); // blink::WebWidgetClient implementation. + void SetRootLayer(scoped_refptr<cc::Layer>) override; void ScheduleAnimation() override; void IntrinsicSizingInfoChanged( const blink::WebIntrinsicSizingInfo&) override;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index f4f11e1..391d776b 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -884,6 +884,7 @@ "../browser/site_per_process_browsertest.h", "../browser/site_per_process_hit_test_browsertest.cc", "../browser/site_per_process_mac_browsertest.mm", + "../browser/site_per_process_unload_browsertest.cc", "../browser/snapshot_browsertest.cc", "../browser/storage_partition_impl_browsertest.cc", "../browser/tracing/background_tracing_manager_browsertest.cc", @@ -1542,6 +1543,7 @@ "../browser/payments/payment_app_content_unittest_base.h", "../browser/payments/payment_app_provider_impl_unittest.cc", "../browser/payments/payment_manager_unittest.cc", + "../browser/picture_in_picture/picture_in_picture_service_impl_unittest.cc", "../browser/plugin_list_unittest.cc", "../browser/presentation/presentation_service_impl_unittest.cc", "../browser/renderer_host/clipboard_host_impl_unittest.cc",
diff --git a/content/test/content_browser_test_utils_internal.cc b/content/test/content_browser_test_utils_internal.cc index 8869f33..3abc7f9 100644 --- a/content/test/content_browser_test_utils_internal.cc +++ b/content/test/content_browser_test_utils_internal.cc
@@ -14,6 +14,7 @@ #include "base/bind.h" #include "base/containers/stack.h" +#include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "base/task/post_task.h" #include "base/test/test_timeouts.h" @@ -432,13 +433,49 @@ message_loop_runner_->Quit(); } -SwapoutACKMessageFilter::SwapoutACKMessageFilter() - : BrowserMessageFilter(FrameMsgStart) {} +DropMessageFilter::DropMessageFilter(uint32_t message_class, + uint32_t drop_message_id) + : BrowserMessageFilter(message_class), drop_message_id_(drop_message_id) {} -SwapoutACKMessageFilter::~SwapoutACKMessageFilter() {} +DropMessageFilter::~DropMessageFilter() = default; -bool SwapoutACKMessageFilter::OnMessageReceived(const IPC::Message& message) { - return message.type() == FrameHostMsg_SwapOut_ACK::ID; +bool DropMessageFilter::OnMessageReceived(const IPC::Message& message) { + return message.type() == drop_message_id_; +} + +ObserveMessageFilter::ObserveMessageFilter(uint32_t message_class, + uint32_t watch_message_id) + : BrowserMessageFilter(message_class), + watch_message_id_(watch_message_id) {} + +ObserveMessageFilter::~ObserveMessageFilter() = default; + +bool ObserveMessageFilter::OnMessageReceived(const IPC::Message& message) { + if (message.type() == watch_message_id_) + received_ = true; + return false; +} + +UnresponsiveRendererObserver::UnresponsiveRendererObserver( + WebContents* web_contents) + : WebContentsObserver(web_contents) {} + +UnresponsiveRendererObserver::~UnresponsiveRendererObserver() = default; + +RenderProcessHost* UnresponsiveRendererObserver::Wait(base::TimeDelta timeout) { + if (!captured_render_process_host_) { + base::OneShotTimer timer; + timer.Start(FROM_HERE, timeout, run_loop_.QuitClosure()); + run_loop_.Run(); + timer.Stop(); + } + return captured_render_process_host_; +} + +void UnresponsiveRendererObserver::OnRendererUnresponsive( + RenderProcessHost* render_process_host) { + captured_render_process_host_ = render_process_host; + run_loop_.Quit(); } } // namespace content
diff --git a/content/test/content_browser_test_utils_internal.h b/content/test/content_browser_test_utils_internal.h index 8c6cee8..ae946e9 100644 --- a/content/test/content_browser_test_utils_internal.h +++ b/content/test/content_browser_test_utils_internal.h
@@ -231,18 +231,61 @@ DISALLOW_COPY_AND_ASSIGN(ShowWidgetMessageFilter); }; -// A BrowserMessageFilter that drops SwapOut ACK messages. -class SwapoutACKMessageFilter : public BrowserMessageFilter { +// A BrowserMessageFilter that drops a blacklisted message. +class DropMessageFilter : public BrowserMessageFilter { public: - SwapoutACKMessageFilter(); + DropMessageFilter(uint32_t message_class, uint32_t drop_message_id); protected: - ~SwapoutACKMessageFilter() override; + ~DropMessageFilter() override; private: // BrowserMessageFilter: bool OnMessageReceived(const IPC::Message& message) override; - DISALLOW_COPY_AND_ASSIGN(SwapoutACKMessageFilter); + + const uint32_t drop_message_id_; + + DISALLOW_COPY_AND_ASSIGN(DropMessageFilter); +}; + +// A BrowserMessageFilter that observes a message without handling it, and +// reports when it was seen. +class ObserveMessageFilter : public BrowserMessageFilter { + public: + ObserveMessageFilter(uint32_t message_class, uint32_t watch_message_id); + + bool has_received_message() { return received_; } + + protected: + ~ObserveMessageFilter() override; + + private: + // BrowserMessageFilter: + bool OnMessageReceived(const IPC::Message& message) override; + + const uint32_t watch_message_id_; + bool received_ = false; + + DISALLOW_COPY_AND_ASSIGN(ObserveMessageFilter); +}; + +// This observer waits until WebContentsObserver::OnRendererUnresponsive +// notification. +class UnresponsiveRendererObserver : public WebContentsObserver { + public: + explicit UnresponsiveRendererObserver(WebContents* web_contents); + ~UnresponsiveRendererObserver() override; + + RenderProcessHost* Wait(base::TimeDelta timeout = base::TimeDelta::Max()); + + private: + // WebContentsObserver: + void OnRendererUnresponsive(RenderProcessHost* render_process_host) override; + + RenderProcessHost* captured_render_process_host_ = nullptr; + base::RunLoop run_loop_; + + DISALLOW_COPY_AND_ASSIGN(UnresponsiveRendererObserver); }; } // namespace content
diff --git a/content/test/data/unload_handler_force_layout.html b/content/test/data/unload_handler_force_layout.html new file mode 100644 index 0000000..77d515e --- /dev/null +++ b/content/test/data/unload_handler_force_layout.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<body> + <div id="tall" style="height: 1000em"> + This page will force a layout on unload + </div> +</body> +<script> +window.addEventListener('unload', function(event) { + // Shrink the page. + document.getElementById('tall').style.height = '999em'; + // Move the scroll position. + window.scroll(0, 100); + // Read the scroll position - this forces layout. + console.log(window.scrollY); + // Notify the opening window so tests can wait for this to run. + window.opener.postMessage('unloaded', '*'); +}); +// Notify the opening window that the page loaded, so tests can wait for it. +window.opener.postMessage('loaded', '*'); +</script> +</html>
diff --git a/content/test/navigation_simulator_impl.cc b/content/test/navigation_simulator_impl.cc index 7820c64..1b0022c 100644 --- a/content/test/navigation_simulator_impl.cc +++ b/content/test/navigation_simulator_impl.cc
@@ -392,9 +392,8 @@ } void NavigationSimulatorImpl::Start() { - CHECK(state_ == INITIALIZATION) + CHECK(state_ == INITIALIZATION || state_ == WAITING_BEFORE_UNLOAD) << "NavigationSimulatorImpl::Start should only be called once."; - state_ = STARTED; if (browser_initiated_) { if (!SimulateBrowserInitiatedStart()) @@ -403,6 +402,7 @@ if (!SimulateRendererInitiatedStart()) return; } + state_ = STARTED; CHECK(handle_); if (IsRendererDebugURL(navigation_url_)) @@ -865,6 +865,34 @@ return request_id_; } +void NavigationSimulatorImpl::BrowserInitiatedStartAndWaitBeforeUnload() { + if (reload_type_ != ReloadType::NONE) { + web_contents_->GetController().Reload(reload_type_, + false /*check_for_repost */); + } else if (session_history_offset_) { + web_contents_->GetController().GoToOffset(session_history_offset_); + } else { + if (load_url_params_) { + web_contents_->GetController().LoadURLWithParams(*load_url_params_); + load_url_params_ = nullptr; + } else { + web_contents_->GetController().LoadURL(navigation_url_, referrer_, + transition_, std::string()); + } + } + + frame_tree_node_ = GetFrameTreeNodeForPendingEntry(web_contents_); + CHECK(frame_tree_node_); + render_frame_host_ = + static_cast<TestRenderFrameHost*>(frame_tree_node_->current_frame_host()); + + // The navigation url might have been rewritten by the NavigationController. + // Update it. + navigation_url_ = web_contents_->GetController().GetPendingEntry()->GetURL(); + + state_ = WAITING_BEFORE_UNLOAD; +} + void NavigationSimulatorImpl::DidStartNavigation( NavigationHandle* navigation_handle) { // Check if this navigation is the one we're simulating. @@ -923,29 +951,8 @@ } bool NavigationSimulatorImpl::SimulateBrowserInitiatedStart() { - if (reload_type_ != ReloadType::NONE) { - web_contents_->GetController().Reload(reload_type_, - false /*check_for_repost */); - } else if (session_history_offset_) { - web_contents_->GetController().GoToOffset(session_history_offset_); - } else { - if (load_url_params_) { - web_contents_->GetController().LoadURLWithParams(*load_url_params_); - load_url_params_ = nullptr; - } else { - web_contents_->GetController().LoadURL(navigation_url_, referrer_, - transition_, std::string()); - } - } - - frame_tree_node_ = GetFrameTreeNodeForPendingEntry(web_contents_); - CHECK(frame_tree_node_); - render_frame_host_ = - static_cast<TestRenderFrameHost*>(frame_tree_node_->current_frame_host()); - - // The navigation url might have been rewritten by the NavigationController. - // Update it. - navigation_url_ = web_contents_->GetController().GetPendingEntry()->GetURL(); + if (state_ == INITIALIZATION) + BrowserInitiatedStartAndWaitBeforeUnload(); // Simulate the BeforeUnload ACK if needed. NavigationRequest* request = frame_tree_node_->navigation_request();
diff --git a/content/test/navigation_simulator_impl.h b/content/test/navigation_simulator_impl.h index 7d2ebfd..e01d209 100644 --- a/content/test/navigation_simulator_impl.h +++ b/content/test/navigation_simulator_impl.h
@@ -92,6 +92,12 @@ // Additional utilites usable only inside content/. + // This will do the very beginning of a navigation but stop before the + // beforeunload event response. Will leave the Simulator in a + // WAITING_BEFORE_UNLOAD state. We do not wait for beforeunload event when + // starting renderer-side, use solely for browser initiated navigations. + void BrowserInitiatedStartAndWaitBeforeUnload(); + // Set LoadURLParams and make browser initiated navigations use // LoadURLWithParams instead of LoadURL. void SetLoadURLParams(NavigationController::LoadURLParams* load_url_params); @@ -180,6 +186,7 @@ enum State { INITIALIZATION, + WAITING_BEFORE_UNLOAD, STARTED, READY_TO_COMMIT, FAILED,
diff --git a/device/fido/OWNERS b/device/fido/OWNERS index 2079630c..3ded3306 100644 --- a/device/fido/OWNERS +++ b/device/fido/OWNERS
@@ -5,15 +5,19 @@ # TouchID, Windows Hello. martinkr@google.com -martinkr@chromium.org # prefer @google.com +# (Secondary email; prefer google.com address.) +martinkr@chromium.org # Attestation and legacy U2F implementation. agl@chromium.org # Emeriti; for occasional reviews -engedy@chromium.org # esp. view & frame lifetimes -jdoerrie@chromium.org # Bluetooth -hongjunchoi@chromium.org # CTAP2 implementation +# esp. view & frame lifetimes +engedy@chromium.org +# Bluetooth +jdoerrie@chromium.org +# CTAP2 implementation +hongjunchoi@chromium.org # TEAM: identity-dev@chromium.org # COMPONENT: Blink>WebAuthentication
diff --git a/device/fido/ctap_make_credential_request.h b/device/fido/ctap_make_credential_request.h index 80500544..12b72d5 100644 --- a/device/fido/ctap_make_credential_request.h +++ b/device/fido/ctap_make_credential_request.h
@@ -81,6 +81,7 @@ const base::Optional<std::vector<uint8_t>>& pin_auth() const { return pin_auth_; } + const base::Optional<uint8_t>& pin_protocol() const { return pin_protocol_; } void set_is_u2f_only(bool is_u2f_only) { is_u2f_only_ = is_u2f_only; } bool is_u2f_only() { return is_u2f_only_; }
diff --git a/device/fido/fido_constants.h b/device/fido/fido_constants.h index 02cc5b4..85cfa30 100644 --- a/device/fido/fido_constants.h +++ b/device/fido/fido_constants.h
@@ -105,7 +105,7 @@ kCtap2ErrUserActionPending = 0x23, kCtap2ErrOperationPending = 0x24, kCtap2ErrNoOperations = 0x25, - kCtap2ErrUnsupportedAlgorithms = 0x26, + kCtap2ErrUnsupportedAlgorithm = 0x26, kCtap2ErrOperationDenied = 0x27, kCtap2ErrKeyStoreFull = 0x28, kCtap2ErrNotBusy = 0x29, @@ -156,7 +156,7 @@ CtapDeviceResponseCode::kCtap2ErrUserActionPending, CtapDeviceResponseCode::kCtap2ErrOperationPending, CtapDeviceResponseCode::kCtap2ErrNoOperations, - CtapDeviceResponseCode::kCtap2ErrUnsupportedAlgorithms, + CtapDeviceResponseCode::kCtap2ErrUnsupportedAlgorithm, CtapDeviceResponseCode::kCtap2ErrOperationDenied, CtapDeviceResponseCode::kCtap2ErrKeyStoreFull, CtapDeviceResponseCode::kCtap2ErrNotBusy,
diff --git a/device/fido/fido_task.cc b/device/fido/fido_task.cc index 80ba6505..f0f44bb 100644 --- a/device/fido/fido_task.cc +++ b/device/fido/fido_task.cc
@@ -24,9 +24,6 @@ FidoTask::~FidoTask() = default; void FidoTask::CancelTask() { - if (device()->supported_protocol() != ProtocolVersion::kCtap) - return; - device()->Cancel(); }
diff --git a/device/fido/hid/fido_hid_device.cc b/device/fido/hid/fido_hid_device.cc index 80ad4ae..143dc29 100644 --- a/device/fido/hid/fido_hid_device.cc +++ b/device/fido/hid/fido_hid_device.cc
@@ -48,10 +48,15 @@ if (state_ != State::kBusy && state_ != State::kReady) return; - // Delete any remaining pending requests on this Channel ID. + state_ = State::kReady; pending_transactions_ = {}; + timeout_callback_.Cancel(); + WriteMessage( - FidoHidMessage::Create(channel_id_, FidoHidDeviceCommand::kCancel, + FidoHidMessage::Create(channel_id_, + supported_protocol() == ProtocolVersion::kCtap + ? FidoHidDeviceCommand::kCancel + : FidoHidDeviceCommand::kInit, output_report_size_, std::vector<uint8_t>()), false /* response_expected */, base::DoNothing()); }
diff --git a/device/fido/mac/make_credential_operation.mm b/device/fido/mac/make_credential_operation.mm index 8c81fc5..be3d8e5 100644 --- a/device/fido/mac/make_credential_operation.mm +++ b/device/fido/mac/make_credential_operation.mm
@@ -64,7 +64,7 @@ if (!std::any_of(key_params.begin(), key_params.end(), is_es256)) { DVLOG(1) << "No supported algorithm found."; std::move(callback()) - .Run(CtapDeviceResponseCode::kCtap2ErrUnsupportedAlgorithms, + .Run(CtapDeviceResponseCode::kCtap2ErrUnsupportedAlgorithm, base::nullopt); return; }
diff --git a/device/fido/virtual_ctap2_device.cc b/device/fido/virtual_ctap2_device.cc index d1fe3d50..6b5354dd 100644 --- a/device/fido/virtual_ctap2_device.cc +++ b/device/fido/virtual_ctap2_device.cc
@@ -50,18 +50,6 @@ data.value_or(std::vector<uint8_t>{})))); } -bool AreMakeCredentialOptionsValid(const AuthenticatorSupportedOptions& options, - const CtapMakeCredentialRequest& request) { - if (request.resident_key_required() && !options.supports_resident_key) - return false; - - return request.user_verification() != - UserVerificationRequirement::kRequired || - options.user_verification_availability == - AuthenticatorSupportedOptions::UserVerificationAvailability:: - kSupportedAndConfigured; -} - bool AreGetAssertionOptionsValid(const AuthenticatorSupportedOptions& options, const CtapGetAssertionRequest& request) { if (request.user_presence_required() && !options.user_presence_required) @@ -275,29 +263,104 @@ CtapMakeCredentialRequest::ClientDataHash client_data_hash = std::get<1>(*request_and_hash); - if (!AreMakeCredentialOptionsValid(device_info_.options(), request) || - !AreMakeCredentialParamsValid(request)) { - DLOG(ERROR) << "Virtual CTAP2 device does not support options required by " - "the request."; - return CtapDeviceResponseCode::kCtap2ErrOther; + const AuthenticatorSupportedOptions& options = device_info_.options(); + + // The following quotes are from the CTAP2 spec: + + // 1. "If authenticator supports clientPin and platform sends a zero length + // pinAuth, wait for user touch and then return either CTAP2_ERR_PIN_NOT_SET + // if pin is not set or CTAP2_ERR_PIN_INVALID if pin has been set." + const bool supports_pin = + options.client_pin_availability != + AuthenticatorSupportedOptions::ClientPinAvailability::kNotSupported; + if (supports_pin && request.pin_auth() && request.pin_auth()->empty()) { + if (mutable_state()->simulate_press_callback) { + mutable_state()->simulate_press_callback.Run(); + } + switch (device_info_.options().client_pin_availability) { + case AuthenticatorSupportedOptions::ClientPinAvailability:: + kSupportedAndPinSet: + return CtapDeviceResponseCode::kCtap2ErrPinInvalid; + case AuthenticatorSupportedOptions::ClientPinAvailability:: + kSupportedButPinNotSet: + return CtapDeviceResponseCode::kCtap2ErrPinNotSet; + case AuthenticatorSupportedOptions::ClientPinAvailability::kNotSupported: + NOTREACHED(); + } } - // Client pin is not supported. - if (request.pin_auth()) { - DLOG(ERROR) << "Virtual CTAP2 device does not support client pin."; + // 2. "If authenticator supports clientPin and pinAuth parameter is present + // and the pinProtocol is not supported, return CTAP2_ERR_PIN_AUTH_INVALID + // error." + if (supports_pin && request.pin_auth() && + (!request.pin_protocol() || *request.pin_protocol() != 1)) { return CtapDeviceResponseCode::kCtap2ErrPinInvalid; } - // Check for already registered credentials. + // 3. "If authenticator is not protected by some form of user verification and + // platform has set "uv" or pinAuth to get the user verification, return + // CTAP2_ERR_INVALID_OPTION." + const bool can_do_uv = + options.user_verification_availability == + AuthenticatorSupportedOptions::UserVerificationAvailability:: + kSupportedAndConfigured || + options.client_pin_availability == + AuthenticatorSupportedOptions::ClientPinAvailability:: + kSupportedAndPinSet; + if (!can_do_uv && + (request.user_verification() == UserVerificationRequirement::kRequired || + request.pin_auth())) { + return CtapDeviceResponseCode::kCtap2ErrInvalidOption; + } + + // Step 4. + bool uv = false; + if (can_do_uv) { + if (request.user_verification() == UserVerificationRequirement::kRequired) { + // Internal UV is assumed to always succeed. + if (mutable_state()->simulate_press_callback) { + mutable_state()->simulate_press_callback.Run(); + } + uv = true; + } + + if (request.pin_auth()) { + DCHECK(request.pin_protocol() && *request.pin_protocol() == 1); + // The pin_auth argument is assumed to be correct. + uv = true; + } + + if (!uv) { + return CtapDeviceResponseCode::kCtap2ErrPinAuthInvalid; + } + } + + // 6. Check for already registered credentials. const auto rp_id_hash = fido_parsing_utils::CreateSHA256Hash(request.rp().rp_id()); if (request.exclude_list()) { for (const auto& excluded_credential : *request.exclude_list()) { - if (FindRegistrationData(excluded_credential.id(), rp_id_hash)) + if (FindRegistrationData(excluded_credential.id(), rp_id_hash)) { + if (mutable_state()->simulate_press_callback) { + mutable_state()->simulate_press_callback.Run(); + } return CtapDeviceResponseCode::kCtap2ErrCredentialExcluded; + } } } + // Step 7. + if (!AreMakeCredentialParamsValid(request)) { + DLOG(ERROR) << "Virtual CTAP2 device does not support options required by " + "the request."; + return CtapDeviceResponseCode::kCtap2ErrUnsupportedAlgorithm; + } + + // Step 8. + if (request.resident_key_required() && !options.supports_resident_key) { + return CtapDeviceResponseCode::kCtap2ErrUnsupportedOption; + } + // Create key to register. // Note: Non-deterministic, you need to mock this out if you rely on // deterministic behavior. @@ -331,7 +394,7 @@ } auto authenticator_data = ConstructAuthenticatorData( - rp_id_hash, 01ul, std::move(attested_credential_data), + rp_id_hash, uv, 01ul, std::move(attested_credential_data), std::move(extensions)); auto sign_buffer = ConstructSignatureBuffer(authenticator_data, client_data_hash); @@ -409,7 +472,8 @@ found_data->counter++; auto authenticator_data = ConstructAuthenticatorData( - rp_id_hash, found_data->counter, base::nullopt, base::nullopt); + rp_id_hash, false /* user verified */, found_data->counter, base::nullopt, + base::nullopt); auto signature_buffer = ConstructSignatureBuffer(authenticator_data, client_data_hash); @@ -432,14 +496,16 @@ AuthenticatorData VirtualCtap2Device::ConstructAuthenticatorData( base::span<const uint8_t, kRpIdHashLength> rp_id_hash, + bool user_verified, uint32_t current_signature_count, base::Optional<AttestedCredentialData> attested_credential_data, base::Optional<cbor::Value> extensions) { uint8_t flag = base::strict_cast<uint8_t>(AuthenticatorData::Flag::kTestOfUserPresence); - std::array<uint8_t, kSignCounterLength> signature_counter; - - // Constructing AuthenticatorData for registration operation. + if (user_verified) { + flag |= base::strict_cast<uint8_t>( + AuthenticatorData::Flag::kTestOfUserVerification); + } if (attested_credential_data) flag |= base::strict_cast<uint8_t>(AuthenticatorData::Flag::kAttestation); if (extensions) { @@ -447,6 +513,7 @@ AuthenticatorData::Flag::kExtensionDataIncluded); } + std::array<uint8_t, kSignCounterLength> signature_counter; signature_counter[0] = (current_signature_count >> 24) & 0xff; signature_counter[1] = (current_signature_count >> 16) & 0xff; signature_counter[2] = (current_signature_count >> 8) & 0xff;
diff --git a/device/fido/virtual_ctap2_device.h b/device/fido/virtual_ctap2_device.h index fab7d8d..9925fb5 100644 --- a/device/fido/virtual_ctap2_device.h +++ b/device/fido/virtual_ctap2_device.h
@@ -53,6 +53,7 @@ AuthenticatorData ConstructAuthenticatorData( base::span<const uint8_t, kRpIdHashLength> rp_id_hash, + bool user_verified, uint32_t current_signature_count, base::Optional<AttestedCredentialData> attested_credential_data, base::Optional<cbor::Value> extensions);
diff --git a/device/fido/win/type_conversions.cc b/device/fido/win/type_conversions.cc index 20b94a76..299ed74 100644 --- a/device/fido/win/type_conversions.cc +++ b/device/fido/win/type_conversions.cc
@@ -216,7 +216,7 @@ {L"ConstraintError", CtapDeviceResponseCode::kCtap2ErrUnsupportedOption}, {L"NotSupportedError", - CtapDeviceResponseCode::kCtap2ErrUnsupportedAlgorithms}, + CtapDeviceResponseCode::kCtap2ErrUnsupportedAlgorithm}, {L"NotAllowedError", CtapDeviceResponseCode::kCtap2ErrOperationDenied}, {L"UnknownError", CtapDeviceResponseCode::kCtap2ErrOther},
diff --git a/docs/mojo_ipc_conversion.md b/docs/mojo_ipc_conversion.md index 2a4c81d..877af54 100644 --- a/docs/mojo_ipc_conversion.md +++ b/docs/mojo_ipc_conversion.md
@@ -348,7 +348,126 @@ treated as technical debt. *** -## Typemaps For Content and Blink Types +## Blink-Specific Advice + +### Variants +Let's assume we have a mojom file such as this: + +``` cpp +module example.mojom; + +interface Foo { + SendData(string param1, array<int32> param2); +}; +``` + +The following GN snippet will generate two concrete targets: `example` and +`example_blink`: + +``` +mojom("example") { + sources = [ "example.mojom" ] +} +``` + +The target `example` will generate Chromium-style C++ bindings using STL types: + +``` cpp +// example.mojom.h +namespace example { +namespace mojom { + +class Example { + virtual void SendArray(const std::string& param1, const std::vector<int32_t>& param2) = 0; +} + +} // namespace mojom +} // namespace example +``` + +The target `example_blink` will generate Blink-style C++ bindings using WTF types: + +``` cpp +// example.mojom-blink.h +namespace example { +namespace mojom { +namespace blink { + +class Example { + virtual void SendArray(const WTF::String& param1, const WTF::Vector<int32_t>& param2) = 0; +} + +} // namespace blink +} // namespace mojom +} // namespace example +``` + +Thanks to these separate sets of bindings no work is necessary to convert types +between Blink-style code and Chromium-style code. It is handled automatically +during message serialization and deserialization. + +For more information about variants, see +[this section](/mojo/public/cpp/bindings/README.md#Variants) of the C++ bindings +documentation. + +### Binding callbacks + +Mojo methods that return a value take an instance of `base::OnceCallback`. +Use `WTF::Bind()` and an appropriate wrapper function depending on the type of +object and the callback. + +For garbage-collected (Oilpan) classes owning the `InterfacePtr`, it is recommended +to use `WrapPersistent(this)` for response callbacks and `WrapWeakPersistent(this)` +for connection error handlers: + +``` cpp +// src/third_party/blink/renderer/modules/vr/vr_controller.h +service_.set_connection_error_handler( + WTF::Bind(&VRController::Dispose, WrapWeakPersistent(this))); +service_->RequestDevice( + WTF::Bind(&VRController::OnRequestDeviceReturned, WrapPersistent(this))); +``` + +Non-garbage-collected objects can use `WTF::Unretained(this)` for both response +and error handler callbacks when the `InterfacePtr` is owned by the object bound +to the callback or the object is guaranteed to outlive the Mojo connection for +another reason. Otherwise a weak pointer should be used. However, it is not a +common pattern since using Oilpan is recommended for all Blink code. + +### Implementing Mojo interfaces in Blink + +Only a `mojo::Binding` or `mojo::BindingSet` should be used when implementing a +Mojo interface in an Oilpan-managed object. The object must then have a pre-finalizer +to close any open pipes when the object is about to be swept as lazy sweeping +means that it may be invalid long before the destructor is called. This requires +setup in both the object header and implementation. + +``` cpp +// MyObject.h +class MyObject : public GarbageCollected, + public example::mojom::blink::Example { + USING_PRE_FINALIZER(MyObject, Dispose); + + public: + MyObject(); + void Dispose(); + + // Implementation of example::mojom::blink::Example. + + private: + mojo::Binding<example::mojom::blink::Example> m_binding{this}; +}; + +// MyObject.cpp +void MyObject::Dispose() { + m_binding.Close(); +} +``` + +For more information about Blink's Garbage Collector, see +[Blink GC API Reference](/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md). + +### Typemaps For Content and Blink Types Using typemapping for messages that go between Blink and content browser code can sometimes be tricky due to things like dependency cycles or confusion over
diff --git a/extensions/browser/api/declarative_net_request/ruleset_manager.cc b/extensions/browser/api/declarative_net_request/ruleset_manager.cc index d8f7c91..4b607e9 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_manager.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_manager.cc
@@ -459,11 +459,10 @@ bool RulesetManager::ExtensionRulesetData::operator<( const ExtensionRulesetData& other) const { - // Sort based on descending installation time, using extension id to break + // Sort based on *descending* installation time, using extension id to break // ties. - return (extension_install_time != other.extension_install_time) - ? (extension_install_time > other.extension_install_time) - : (extension_id < other.extension_id); + return std::tie(extension_install_time, extension_id) > + std::tie(other.extension_install_time, other.extension_id); } bool RulesetManager::ShouldEvaluateRequest(
diff --git a/extensions/browser/process_map.cc b/extensions/browser/process_map.cc index 18ada297..1928d3d5 100644 --- a/extensions/browser/process_map.cc +++ b/extensions/browser/process_map.cc
@@ -16,16 +16,7 @@ // Item struct ProcessMap::Item { - Item() : process_id(0), site_instance_id(0) { - } - - // Purposely implicit constructor needed on older gcc's. See: - // http://codereview.chromium.org/8769022/ - explicit Item(const ProcessMap::Item& other) - : extension_id(other.extension_id), - process_id(other.process_id), - site_instance_id(other.site_instance_id) { - } + Item() {} Item(const std::string& extension_id, int process_id, int site_instance_id) @@ -37,6 +28,9 @@ ~Item() { } + Item(ProcessMap::Item&&) = default; + Item& operator=(ProcessMap::Item&&) = default; + bool operator<(const ProcessMap::Item& other) const { return std::tie(extension_id, process_id, site_instance_id) < std::tie(other.extension_id, other.process_id, @@ -44,8 +38,11 @@ } std::string extension_id; - int process_id; - int site_instance_id; + int process_id = 0; + int site_instance_id = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(Item); };
diff --git a/extensions/browser/warning_set.cc b/extensions/browser/warning_set.cc index 30bbb7d..9b7a956 100644 --- a/extensions/browser/warning_set.cc +++ b/extensions/browser/warning_set.cc
@@ -6,6 +6,8 @@ #include <stddef.h> +#include <tuple> + #include "base/files/file_path.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" @@ -126,6 +128,11 @@ {} /*message_parameters*/); } +bool Warning::operator<(const Warning& other) const { + return std::tie(extension_id_, type_) < + std::tie(other.extension_id_, other.type_); +} + std::string Warning::GetLocalizedMessage(const ExtensionSet* extensions) const { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -166,10 +173,4 @@ } } -bool operator<(const Warning& a, const Warning& b) { - if (a.extension_id() != b.extension_id()) - return a.extension_id() < b.extension_id(); - return a.warning_type() < b.warning_type(); -} - } // namespace extensions
diff --git a/extensions/browser/warning_set.h b/extensions/browser/warning_set.h index f54cf21..a7de984a 100644 --- a/extensions/browser/warning_set.h +++ b/extensions/browser/warning_set.h
@@ -63,6 +63,11 @@ static Warning CreateRulesetFailedToLoadWarning( const ExtensionId& extension_id); + // Compare Warnings based on the tuple of (extension_id, type). + // The message associated with Warnings is purely informational + // and does not contribute to distinguishing extensions. + bool operator<(const Warning& other) const; + // Returns the specific warning type. WarningType warning_type() const { return type_; } @@ -90,11 +95,6 @@ std::vector<std::string> message_parameters_; }; -// Compare Warnings based on the tuple of (extension_id, type). -// The message associated with Warnings is purely informational -// and does not contribute to distinguishing extensions. -bool operator<(const Warning& a, const Warning& b); - typedef std::set<Warning> WarningSet; } // namespace extensions
diff --git a/extensions/common/host_id.cc b/extensions/common/host_id.cc index e7d474fe..afc0b28 100644 --- a/extensions/common/host_id.cc +++ b/extensions/common/host_id.cc
@@ -4,6 +4,8 @@ #include "extensions/common/host_id.h" +#include <tuple> + HostID::HostID() : type_(HostType::EXTENSIONS) { } @@ -21,13 +23,9 @@ } bool HostID::operator<(const HostID& host_id) const { - if (type_ != host_id.type()) - return type_ < host_id.type(); - else if (id_ != host_id.id()) - return id_ < host_id.id(); - return false; + return std::tie(type_, id_) < std::tie(host_id.type_, host_id.id_); } bool HostID::operator==(const HostID& host_id) const { - return type_ == host_id.type() && id_ == host_id.id(); + return type_ == host_id.type_ && id_ == host_id.id_; }
diff --git a/fuchsia/BUILD.gn b/fuchsia/BUILD.gn index 09d45205..8944eddd 100644 --- a/fuchsia/BUILD.gn +++ b/fuchsia/BUILD.gn
@@ -5,11 +5,7 @@ assert(is_fuchsia) import("//build/config/fuchsia/fidl_library.gni") -import("//build/config/fuchsia/rules.gni") import("//build/util/process_version.gni") -import("//mojo/public/tools/bindings/mojom.gni") -import("//testing/test.gni") -import("//tools/grit/repack.gni") config("webrunner_implementation") { defines = [ "WEBRUNNER_IMPLEMENTATION" ] @@ -27,236 +23,6 @@ ] } -source_set("test_support") { - testonly = true - sources = [ - # TODO(kmarshall): Move common/test/* to test/. - "common/test/test_common.cc", - "common/test/test_common.h", - "test/fake_context.cc", - "test/fake_context.h", - "test/promise.h", - ] - deps = [ - ":mem_buffer_common", - ":web_fidl", - "//base", - "//base/test:test_config", - "//content/test:test_support", - ] - public_deps = [ - ":web_fidl", - "//skia/public/interfaces", - ] -} - -fuchsia_package("service_pkg") { - binary = ":service_exe" - package_name_override = "chromium" - sandbox_policy = "service/sandbox_policy" - excluded_files = [ - "lib/libswiftshader_libEGL.so", - "lib/libswiftshader_libGLESv2.so", - ] -} - -executable("service_exe") { - deps = [ - ":service_lib", - ":web_fidl", - "//base", - "//content/public/app:both", - "//services/service_manager/embedder:embedder_switches", - ] - sources = [ - "service/web_content_service_main.cc", - ] -} - -fuchsia_package_runner("service_runner") { - package = ":service_pkg" - package_name_override = "chromium" - install_only = true -} - -mojom("mojom") { - sources = [ - "common/on_load_script_injector.mojom", - ] - - public_deps = [ - "//mojo/public/mojom/base", - ] -} - -component("service_lib") { - deps = [ - ":mem_buffer_common", - ":mojom", - ":service_pak", - "//base", - "//components/version_info", - "//content/public/app:both", - "//content/public/browser", - "//content/public/child", - "//content/public/common", - "//content/public/renderer", - "//mojo/public/cpp/bindings", - "//services/network/public/cpp", - "//services/service_manager/sandbox", - "//skia/public/interfaces", - "//third_party/blink/public/common", - "//ui/aura", - "//ui/base/ime", - "//ui/display", - "//ui/ozone", - "//ui/platform_window", - "//ui/wm", - "//ui/wm/public", - ] - - data_deps = [ - ":service_pak", - ] - data = [ - "$root_out_dir/webrunner.pak", - ] - public_deps = [ - ":web_fidl", - ] - configs += [ ":webrunner_implementation" ] - - sources = [ - "browser/context_impl.cc", - "browser/context_impl.h", - "browser/frame_impl.cc", - "browser/frame_impl.h", - "browser/message_port_impl.cc", - "browser/message_port_impl.h", - "browser/webrunner_browser_context.cc", - "browser/webrunner_browser_context.h", - "browser/webrunner_browser_main.cc", - "browser/webrunner_browser_main.h", - "browser/webrunner_browser_main_parts.cc", - "browser/webrunner_browser_main_parts.h", - "browser/webrunner_content_browser_client.cc", - "browser/webrunner_content_browser_client.h", - "browser/webrunner_net_log.cc", - "browser/webrunner_net_log.h", - "browser/webrunner_screen.cc", - "browser/webrunner_screen.h", - "browser/webrunner_url_request_context_getter.cc", - "browser/webrunner_url_request_context_getter.h", - "common/webrunner_content_client.cc", - "common/webrunner_content_client.h", - "renderer/on_load_script_injector.cc", - "renderer/on_load_script_injector.h", - "renderer/webrunner_content_renderer_client.cc", - "renderer/webrunner_content_renderer_client.h", - "service/common.cc", - "service/common.h", - "service/context_provider_impl.cc", - "service/context_provider_impl.h", - "service/context_provider_main.cc", - "service/context_provider_main.h", - "service/webrunner_main_delegate.cc", - "service/webrunner_main_delegate.h", - ] -} - -repack("service_pak") { - sources = [ - "$root_gen_dir/components/components_resources.pak", - "$root_gen_dir/components/strings/components_strings_en-US.pak", - "$root_gen_dir/content/app/resources/content_resources_100_percent.pak", - "$root_gen_dir/content/app/strings/content_strings_en-US.pak", - "$root_gen_dir/content/browser/tracing/tracing_resources.pak", - "$root_gen_dir/content/content_resources.pak", - "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak", - "$root_gen_dir/net/net_resources.pak", - "$root_gen_dir/third_party/blink/public/resources/blink_resources.pak", - "$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak", - "$root_gen_dir/ui/resources/ui_resources_100_percent.pak", - "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak", - "$root_gen_dir/ui/strings/ui_strings_en-US.pak", - ] - - deps = [ - "//components/resources:components_resources", - "//components/strings", - "//content:resources", - "//content/app/resources", - "//content/app/strings", - "//content/browser/tracing:resources", - "//mojo/public/js:resources", - "//net:net_resources", - "//third_party/blink/public:resources", - "//third_party/blink/public:scaled_resources_100_percent", - "//ui/resources", - "//ui/strings", - ] - - output = "$root_out_dir/webrunner.pak" -} - -source_set("browsertest_common") { - testonly = true - sources = [ - "common/test/webrunner_browser_test.cc", - "common/test/webrunner_browser_test.h", - "common/test/webrunner_test_launcher.cc", - ] - deps = [ - ":service_lib", - ":web_fidl", - "//content/public/browser", - "//content/test:test_support", - "//net:test_support", - "//testing/gtest", - "//ui/ozone", - ] -} - -test("webrunner_browsertests") { - sources = [ - "browser/context_impl_browsertest.cc", - "browser/frame_impl_browsertest.cc", - ] - defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] - data = [ - "browser/test/data", - ] - deps = [ - ":browsertest_common", - ":mem_buffer_common", - ":service_lib", - ":test_support", - ":test_support", - ":web_fidl", - "//base/test:test_support", - "//content/public/browser", - "//net:test_support", - "//testing/gmock", - "//testing/gtest", - "//ui/ozone", - ] -} - -test("webrunner_unittests") { - sources = [ - "service/context_provider_impl_unittest.cc", - ] - deps = [ - ":service_lib", - ":test_support", - ":web_fidl", - "//base/test:run_all_unittests", - "//base/test:test_support", - "//testing/gmock", - "//testing/gtest", - ] -} - fidl_library("web_fidl") { library_name = "web" namespace = "chromium" @@ -338,7 +104,7 @@ # Puts copies of files at the top level of the CIPD archive's structure. copy("restaged_packages") { sources = [ - "$root_gen_dir/fuchsia/chromium/chromium.far", + "$root_gen_dir/fuchsia/engine/chromium/chromium.far", "$root_gen_dir/fuchsia/http/http/http.far", "$root_gen_dir/fuchsia/runners/cast_runner/cast_runner.far", "$root_gen_dir/fuchsia/runners/web_runner/web_runner.far", @@ -347,7 +113,7 @@ "$_artifact_root/{{source_file_part}}", ] deps = [ - ":service_pkg", + "//fuchsia/engine:web_engine", "//fuchsia/http:http_pkg", "//fuchsia/runners:cast_runner_pkg", "//fuchsia/runners:web_runner_pkg", @@ -368,10 +134,11 @@ group("gn_all") { testonly = true deps = [ - ":service_exe", - ":webrunner_browsertests", - ":webrunner_unittests", + "engine:web_engine", + "engine:web_engine_browsertests", + "engine:web_engine_unittests", "http:http_service_tests", + "modular:modular_unittests", "runners:cast_runner", "runners:cast_runner_browsertests", "runners:cast_runner_integration_tests",
diff --git a/fuchsia/engine/BUILD.gn b/fuchsia/engine/BUILD.gn new file mode 100644 index 0000000..f56205d --- /dev/null +++ b/fuchsia/engine/BUILD.gn
@@ -0,0 +1,235 @@ +# Copyright 2019 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_fuchsia) + +import("//build/config/fuchsia/rules.gni") +import("//mojo/public/tools/bindings/mojom.gni") +import("//testing/test.gni") +import("//tools/grit/repack.gni") + +source_set("test_support") { + testonly = true + sources = [ + "test/fake_context.cc", + "test/fake_context.h", + "test/promise.h", + "test/test_common.cc", + "test/test_common.h", + ] + deps = [ + "//base", + "//base/test:test_config", + "//content/test:test_support", + "//fuchsia:mem_buffer_common", + ] + public_deps = [ + "//fuchsia:web_fidl", + "//skia/public/interfaces", + ] +} + +mojom("mojom") { + sources = [ + "on_load_script_injector.mojom", + ] + public_deps = [ + "//mojo/public/mojom/base", + ] + visibility = [ ":*" ] +} + +repack("web_engine_pak") { + sources = [ + "$root_gen_dir/components/components_resources.pak", + "$root_gen_dir/components/strings/components_strings_en-US.pak", + "$root_gen_dir/content/app/resources/content_resources_100_percent.pak", + "$root_gen_dir/content/app/strings/content_strings_en-US.pak", + "$root_gen_dir/content/browser/tracing/tracing_resources.pak", + "$root_gen_dir/content/content_resources.pak", + "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak", + "$root_gen_dir/net/net_resources.pak", + "$root_gen_dir/third_party/blink/public/resources/blink_resources.pak", + "$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak", + "$root_gen_dir/ui/resources/ui_resources_100_percent.pak", + "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak", + "$root_gen_dir/ui/strings/ui_strings_en-US.pak", + ] + + deps = [ + "//components/resources:components_resources", + "//components/strings", + "//content:resources", + "//content/app/resources", + "//content/app/strings", + "//content/browser/tracing:resources", + "//mojo/public/js:resources", + "//net:net_resources", + "//third_party/blink/public:resources", + "//third_party/blink/public:scaled_resources_100_percent", + "//ui/resources", + "//ui/strings", + ] + + output = "$root_out_dir/webrunner.pak" + visibility = [ ":*" ] +} + +component("web_engine_core") { + deps = [ + ":mojom", + ":web_engine_pak", + "//base", + "//components/version_info", + "//content/public/app:both", + "//content/public/browser", + "//content/public/child", + "//content/public/common", + "//content/public/renderer", + "//fuchsia:mem_buffer_common", + "//mojo/public/cpp/bindings", + "//services/network/public/cpp", + "//services/service_manager/sandbox", + "//skia/public/interfaces", + "//third_party/blink/public/common", + "//ui/aura", + "//ui/base/ime", + "//ui/display", + "//ui/ozone", + "//ui/platform_window", + "//ui/wm", + "//ui/wm/public", + ] + data_deps = [ + ":web_engine_pak", + ] + data = [ + "$root_out_dir/webrunner.pak", + ] + public_deps = [ + "//fuchsia:web_fidl", + ] + configs += [ "//fuchsia:webrunner_implementation" ] + sources = [ + "browser/context_impl.cc", + "browser/context_impl.h", + "browser/frame_impl.cc", + "browser/frame_impl.h", + "browser/message_port_impl.cc", + "browser/message_port_impl.h", + "browser/webrunner_browser_context.cc", + "browser/webrunner_browser_context.h", + "browser/webrunner_browser_main.cc", + "browser/webrunner_browser_main.h", + "browser/webrunner_browser_main_parts.cc", + "browser/webrunner_browser_main_parts.h", + "browser/webrunner_content_browser_client.cc", + "browser/webrunner_content_browser_client.h", + "browser/webrunner_net_log.cc", + "browser/webrunner_net_log.h", + "browser/webrunner_screen.cc", + "browser/webrunner_screen.h", + "browser/webrunner_url_request_context_getter.cc", + "browser/webrunner_url_request_context_getter.h", + "common.cc", + "common.h", + "context_provider_impl.cc", + "context_provider_impl.h", + "context_provider_main.cc", + "context_provider_main.h", + "renderer/on_load_script_injector.cc", + "renderer/on_load_script_injector.h", + "renderer/webrunner_content_renderer_client.cc", + "renderer/webrunner_content_renderer_client.h", + "webrunner_content_client.cc", + "webrunner_content_client.h", + "webrunner_main_delegate.cc", + "webrunner_main_delegate.h", + ] + visibility = [ ":*" ] +} + +executable("web_engine_exe") { + deps = [ + ":web_engine_core", + "//base", + "//content/public/app:both", + "//services/service_manager/embedder:embedder_switches", + ] + sources = [ + "webrunner_main.cc", + ] + visibility = [ ":*" ] +} + +fuchsia_package("web_engine") { + binary = ":web_engine_exe" + package_name_override = "chromium" + sandbox_policy = "sandbox_policy" + excluded_files = [ + "lib/libswiftshader_libEGL.so", + "lib/libswiftshader_libGLESv2.so", + ] +} + +fuchsia_package_runner("web_engine_runner") { + package = ":web_engine" + package_name_override = "chromium" + install_only = true +} + +source_set("browsertest_core") { + testonly = true + sources = [ + "test/webrunner_browser_test.cc", + "test/webrunner_browser_test.h", + "test/webrunner_test_launcher.cc", + ] + deps = [ + ":web_engine_core", + "//content/public/browser", + "//content/test:test_support", + "//fuchsia:web_fidl", + "//net:test_support", + "//testing/gtest", + "//ui/ozone", + ] +} + +test("web_engine_browsertests") { + sources = [ + "browser/context_impl_browsertest.cc", + "browser/frame_impl_browsertest.cc", + ] + defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] + data = [ + "test/data", + ] + deps = [ + ":browsertest_core", + ":test_support", + ":web_engine_core", + "//base/test:test_support", + "//content/public/browser", + "//fuchsia:mem_buffer_common", + "//net:test_support", + "//testing/gmock", + "//testing/gtest", + "//ui/ozone", + ] +} + +test("web_engine_unittests") { + sources = [ + "context_provider_impl_unittest.cc", + ] + deps = [ + ":test_support", + ":web_engine_core", + "//base/test:run_all_unittests", + "//base/test:test_support", + "//testing/gmock", + "//testing/gtest", + ] +}
diff --git a/fuchsia/service/DEPS b/fuchsia/engine/DEPS similarity index 100% rename from fuchsia/service/DEPS rename to fuchsia/engine/DEPS
diff --git a/fuchsia/common/OWNERS b/fuchsia/engine/OWNERS similarity index 100% rename from fuchsia/common/OWNERS rename to fuchsia/engine/OWNERS
diff --git a/fuchsia/browser/DEPS b/fuchsia/engine/browser/DEPS similarity index 100% rename from fuchsia/browser/DEPS rename to fuchsia/engine/browser/DEPS
diff --git a/fuchsia/browser/context_impl.cc b/fuchsia/engine/browser/context_impl.cc similarity index 93% rename from fuchsia/browser/context_impl.cc rename to fuchsia/engine/browser/context_impl.cc index d1f471ad..2d9c52d3 100644 --- a/fuchsia/browser/context_impl.cc +++ b/fuchsia/engine/browser/context_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/browser/context_impl.h" +#include "fuchsia/engine/browser/context_impl.h" #include <lib/zx/object.h> #include <memory> @@ -10,9 +10,7 @@ #include "base/fuchsia/fuchsia_logging.h" #include "content/public/browser/web_contents.h" -#include "fuchsia/browser/frame_impl.h" - -namespace webrunner { +#include "fuchsia/engine/browser/frame_impl.h" ContextImpl::ContextImpl(content::BrowserContext* browser_context) : browser_context_(browser_context) {} @@ -61,5 +59,3 @@ return nullptr; } - -} // namespace webrunner
diff --git a/fuchsia/browser/context_impl.h b/fuchsia/engine/browser/context_impl.h similarity index 91% rename from fuchsia/browser/context_impl.h rename to fuchsia/engine/browser/context_impl.h index cfa95da..dfa9f16 100644 --- a/fuchsia/browser/context_impl.h +++ b/fuchsia/engine/browser/context_impl.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 FUCHSIA_BROWSER_CONTEXT_IMPL_H_ -#define FUCHSIA_BROWSER_CONTEXT_IMPL_H_ +#ifndef FUCHSIA_ENGINE_BROWSER_CONTEXT_IMPL_H_ +#define FUCHSIA_ENGINE_BROWSER_CONTEXT_IMPL_H_ #include <lib/fidl/cpp/binding_set.h> #include <memory> @@ -18,8 +18,6 @@ class BrowserContext; } // namespace content -namespace webrunner { - class FrameImpl; // Implementation of Context from //fuchsia/fidl/context.fidl. @@ -64,6 +62,4 @@ DISALLOW_COPY_AND_ASSIGN(ContextImpl); }; -} // namespace webrunner - -#endif // FUCHSIA_BROWSER_CONTEXT_IMPL_H_ +#endif // FUCHSIA_ENGINE_BROWSER_CONTEXT_IMPL_H_
diff --git a/fuchsia/browser/context_impl_browsertest.cc b/fuchsia/engine/browser/context_impl_browsertest.cc similarity index 94% rename from fuchsia/browser/context_impl_browsertest.cc rename to fuchsia/engine/browser/context_impl_browsertest.cc index 62e683279..45ba94bfc 100644 --- a/fuchsia/browser/context_impl_browsertest.cc +++ b/fuchsia/engine/browser/context_impl_browsertest.cc
@@ -12,9 +12,9 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" -#include "fuchsia/common/test/test_common.h" -#include "fuchsia/common/test/webrunner_browser_test.h" -#include "fuchsia/service/common.h" +#include "fuchsia/engine/common.h" +#include "fuchsia/engine/test/test_common.h" +#include "fuchsia/engine/test/webrunner_browser_test.h" #include "net/cookies/cookie_store.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" @@ -22,8 +22,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "url/url_constants.h" -namespace webrunner { - using testing::_; using testing::Field; using testing::InvokeWithoutArgs; @@ -34,7 +32,7 @@ // Defines a suite of tests that exercise browser-level configuration and // functionality. -class ContextImplTest : public WebRunnerBrowserTest { +class ContextImplTest : public cr_fuchsia::test::WebRunnerBrowserTest { public: ContextImplTest() = default; ~ContextImplTest() = default; @@ -48,7 +46,8 @@ // Synchronously gets a list of cookies for this BrowserContext. net::CookieList GetCookies(); - testing::StrictMock<MockNavigationObserver> navigation_observer_; + testing::StrictMock<cr_fuchsia::test::MockNavigationObserver> + navigation_observer_; private: DISALLOW_COPY_AND_ASSIGN(ContextImplTest); @@ -186,5 +185,3 @@ } EXPECT_TRUE(found); } - -} // namespace webrunner
diff --git a/fuchsia/browser/frame_impl.cc b/fuchsia/engine/browser/frame_impl.cc similarity index 97% rename from fuchsia/browser/frame_impl.cc rename to fuchsia/engine/browser/frame_impl.cc index 2bbc7765..a9d00701 100644 --- a/fuchsia/browser/frame_impl.cc +++ b/fuchsia/engine/browser/frame_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/browser/frame_impl.h" +#include "fuchsia/engine/browser/frame_impl.h" #include <zircon/syscalls.h> @@ -19,9 +19,9 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/renderer_preferences_util.h" #include "content/public/common/was_activated_option.h" -#include "fuchsia/browser/context_impl.h" -#include "fuchsia/browser/message_port_impl.h" #include "fuchsia/common/mem_buffer_util.h" +#include "fuchsia/engine/browser/context_impl.h" +#include "fuchsia/engine/browser/message_port_impl.h" #include "mojo/public/cpp/system/platform_handle.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "ui/aura/layout_manager.h" @@ -32,8 +32,6 @@ #include "ui/wm/core/base_focus_rules.h" #include "url/gurl.h" -namespace webrunner { - namespace { // Layout manager that allows only one child window and stretches it to fill the @@ -316,7 +314,7 @@ origins_strings.push_back(origin); base::string16 script_utf16; - if (!ReadUTF8FromVMOAsUTF16(script, &script_utf16)) { + if (!webrunner::ReadUTF8FromVMOAsUTF16(script, &script_utf16)) { callback(false); return; } @@ -334,7 +332,8 @@ // used directly by renderers without string format conversions. // Create a read-only VMO from |script|. - fuchsia::mem::Buffer script_buffer = MemBufferFromString16(script_utf16); + fuchsia::mem::Buffer script_buffer = + webrunner::MemBufferFromString16(script_utf16); if (!script_buffer.vmo) { LOG(WARNING) << "Couldn't read script contents from VMO."; callback(false); @@ -371,7 +370,7 @@ target_origin_utf16 = base::UTF8ToUTF16(target_origin); base::string16 data_utf16; - if (!ReadUTF8FromVMOAsUTF16(message.data, &data_utf16)) { + if (!webrunner::ReadUTF8FromVMOAsUTF16(message.data, &data_utf16)) { DLOG(WARNING) << "PostMessage() rejected non-UTF8 |message.data|."; callback(false); return; @@ -598,5 +597,3 @@ return true; } - -} // namespace webrunner
diff --git a/fuchsia/browser/frame_impl.h b/fuchsia/engine/browser/frame_impl.h similarity index 96% rename from fuchsia/browser/frame_impl.h rename to fuchsia/engine/browser/frame_impl.h index 0181622..30bbd349 100644 --- a/fuchsia/browser/frame_impl.h +++ b/fuchsia/engine/browser/frame_impl.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 FUCHSIA_BROWSER_FRAME_IMPL_H_ -#define FUCHSIA_BROWSER_FRAME_IMPL_H_ +#ifndef FUCHSIA_ENGINE_BROWSER_FRAME_IMPL_H_ +#define FUCHSIA_ENGINE_BROWSER_FRAME_IMPL_H_ #include <lib/fidl/cpp/binding_set.h> #include <lib/zx/channel.h> @@ -17,7 +17,7 @@ #include "base/memory/platform_shared_memory_region.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" -#include "fuchsia/common/on_load_script_injector.mojom.h" +#include "fuchsia/engine/on_load_script_injector.mojom.h" #include "fuchsia/fidl/chromium/web/cpp/fidl.h" #include "ui/aura/window_tree_host.h" #include "ui/wm/core/focus_controller.h" @@ -31,8 +31,6 @@ class WebContents; } // namespace content -namespace webrunner { - class ContextImpl; // Implementation of Frame from //fuchsia/fidl/frame.fidl. @@ -160,6 +158,4 @@ DISALLOW_COPY_AND_ASSIGN(FrameImpl); }; -} // namespace webrunner - -#endif // FUCHSIA_BROWSER_FRAME_IMPL_H_ +#endif // FUCHSIA_ENGINE_BROWSER_FRAME_IMPL_H_
diff --git a/fuchsia/browser/frame_impl_browsertest.cc b/fuchsia/engine/browser/frame_impl_browsertest.cc similarity index 83% rename from fuchsia/browser/frame_impl_browsertest.cc rename to fuchsia/engine/browser/frame_impl_browsertest.cc index f1d2753..b7c3279b9 100644 --- a/fuchsia/browser/frame_impl_browsertest.cc +++ b/fuchsia/engine/browser/frame_impl_browsertest.cc
@@ -11,12 +11,12 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" -#include "fuchsia/browser/frame_impl.h" #include "fuchsia/common/mem_buffer_util.h" -#include "fuchsia/common/test/test_common.h" -#include "fuchsia/common/test/webrunner_browser_test.h" -#include "fuchsia/service/common.h" -#include "fuchsia/test/promise.h" +#include "fuchsia/engine/browser/frame_impl.h" +#include "fuchsia/engine/common.h" +#include "fuchsia/engine/test/promise.h" +#include "fuchsia/engine/test/test_common.h" +#include "fuchsia/engine/test/webrunner_browser_test.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/url_request/url_request_context.h" @@ -24,8 +24,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "url/url_constants.h" -namespace webrunner { - using testing::_; using testing::AllOf; using testing::Field; @@ -43,7 +41,7 @@ const char kPage2Title[] = "title 2"; const char kDataUrl[] = "data:text/html;base64,PGI+SGVsbG8sIHdvcmxkLi4uPC9iPg=="; -const char kTestServerRoot[] = FILE_PATH_LITERAL("fuchsia/browser/test/data"); +const char kTestServerRoot[] = FILE_PATH_LITERAL("fuchsia/engine/test/data"); MATCHER(IsSet, "Checks if an optional field is set.") { return !arg.is_null(); @@ -51,7 +49,7 @@ // Defines a suite of tests that exercise Frame-level functionality, such as // navigation commands and page events. -class FrameImplTest : public WebRunnerBrowserTest { +class FrameImplTest : public cr_fuchsia::test::WebRunnerBrowserTest { public: FrameImplTest() : run_timeout_(TestTimeouts::action_timeout()) { set_test_server_root(base::FilePath(kTestServerRoot)); @@ -85,7 +83,8 @@ navigation_observer_.Acknowledge(); } - testing::StrictMock<MockNavigationObserver> navigation_observer_; + testing::StrictMock<cr_fuchsia::test::MockNavigationObserver> + navigation_observer_; private: const base::RunLoop::ScopedRunTimeoutForTest run_timeout_; @@ -400,7 +399,8 @@ frame->ExecuteJavaScript( std::move(origins), - MemBufferFromString("window.location.href = \"" + title2.spec() + "\";"), + webrunner::MemBufferFromString("window.location.href = \"" + + title2.spec() + "\";"), chromium::web::ExecuteMode::IMMEDIATE_ONCE, [](bool success) { EXPECT_TRUE(success); }); @@ -420,10 +420,11 @@ std::vector<std::string> origins = {url.GetOrigin().spec()}; - frame->ExecuteJavaScript(std::move(origins), - MemBufferFromString("stashed_title = 'hello';"), - chromium::web::ExecuteMode::ON_PAGE_LOAD, - [](bool success) { EXPECT_TRUE(success); }); + frame->ExecuteJavaScript( + std::move(origins), + webrunner::MemBufferFromString("stashed_title = 'hello';"), + chromium::web::ExecuteMode::ON_PAGE_LOAD, + [](bool success) { EXPECT_TRUE(success); }); chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); @@ -437,10 +438,11 @@ std::vector<std::string> origins = {url.GetOrigin().spec()}; - frame->ExecuteJavaScript(std::move(origins), - MemBufferFromString("stashed_title = 'hello';"), - chromium::web::ExecuteMode::ON_PAGE_LOAD, - [](bool success) { EXPECT_TRUE(success); }); + frame->ExecuteJavaScript( + std::move(origins), + webrunner::MemBufferFromString("stashed_title = 'hello';"), + chromium::web::ExecuteMode::ON_PAGE_LOAD, + [](bool success) { EXPECT_TRUE(success); }); chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); @@ -454,10 +456,11 @@ std::vector<std::string> origins = {"http://example.com"}; - frame->ExecuteJavaScript(std::move(origins), - MemBufferFromString("stashed_title = 'hello';"), - chromium::web::ExecuteMode::ON_PAGE_LOAD, - [](bool success) { EXPECT_TRUE(success); }); + frame->ExecuteJavaScript( + std::move(origins), + webrunner::MemBufferFromString("stashed_title = 'hello';"), + chromium::web::ExecuteMode::ON_PAGE_LOAD, + [](bool success) { EXPECT_TRUE(success); }); chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); @@ -475,10 +478,11 @@ std::vector<std::string> origins = {"*"}; - frame->ExecuteJavaScript(std::move(origins), - MemBufferFromString("stashed_title = 'hello';"), - chromium::web::ExecuteMode::ON_PAGE_LOAD, - [](bool success) { EXPECT_TRUE(success); }); + frame->ExecuteJavaScript( + std::move(origins), + webrunner::MemBufferFromString("stashed_title = 'hello';"), + chromium::web::ExecuteMode::ON_PAGE_LOAD, + [](bool success) { EXPECT_TRUE(success); }); // Test script injection for the origin 127.0.0.1. chromium::web::NavigationControllerPtr controller; @@ -502,14 +506,15 @@ chromium::web::FramePtr frame = CreateFrame(); std::vector<std::string> origins = {url.GetOrigin().spec()}; - frame->ExecuteJavaScript(origins, - MemBufferFromString("stashed_title = 'hello';"), - chromium::web::ExecuteMode::ON_PAGE_LOAD, - [](bool success) { EXPECT_TRUE(success); }); - frame->ExecuteJavaScript(std::move(origins), - MemBufferFromString("stashed_title += ' there';"), - chromium::web::ExecuteMode::ON_PAGE_LOAD, - [](bool success) { EXPECT_TRUE(success); }); + frame->ExecuteJavaScript( + origins, webrunner::MemBufferFromString("stashed_title = 'hello';"), + chromium::web::ExecuteMode::ON_PAGE_LOAD, + [](bool success) { EXPECT_TRUE(success); }); + frame->ExecuteJavaScript( + std::move(origins), + webrunner::MemBufferFromString("stashed_title += ' there';"), + chromium::web::ExecuteMode::ON_PAGE_LOAD, + [](bool success) { EXPECT_TRUE(success); }); chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); @@ -524,19 +529,20 @@ std::vector<std::string> origins = {url.GetOrigin().spec()}; - frame->ExecuteJavaScript(origins, - MemBufferFromString("stashed_title = 'hello';"), - chromium::web::ExecuteMode::ON_PAGE_LOAD, - [](bool success) { EXPECT_TRUE(success); }); + frame->ExecuteJavaScript( + origins, webrunner::MemBufferFromString("stashed_title = 'hello';"), + chromium::web::ExecuteMode::ON_PAGE_LOAD, + [](bool success) { EXPECT_TRUE(success); }); chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); CheckLoadUrl(url.spec(), "hello", nullptr, controller.get()); - frame->ExecuteJavaScript(std::move(origins), - MemBufferFromString("stashed_title += ' there';"), - chromium::web::ExecuteMode::ON_PAGE_LOAD, - [](bool success) { EXPECT_TRUE(success); }); + frame->ExecuteJavaScript( + std::move(origins), + webrunner::MemBufferFromString("stashed_title += ' there';"), + chromium::web::ExecuteMode::ON_PAGE_LOAD, + [](bool success) { EXPECT_TRUE(success); }); // Navigate away to clean the slate. CheckLoadUrl(url::kAboutBlankURL, url::kAboutBlankURL, nullptr, @@ -560,12 +566,12 @@ // 0xFE is an illegal UTF-8 byte; it should cause UTF-8 conversion to fail. std::vector<std::string> origins = {url.host()}; - frame->ExecuteJavaScript(std::move(origins), MemBufferFromString("true;\xfe"), - chromium::web::ExecuteMode::IMMEDIATE_ONCE, - [&run_loop](bool success) { - EXPECT_FALSE(success); - run_loop.Quit(); - }); + frame->ExecuteJavaScript( + std::move(origins), webrunner::MemBufferFromString("true;\xfe"), + chromium::web::ExecuteMode::IMMEDIATE_ONCE, [&run_loop](bool success) { + EXPECT_FALSE(success); + run_loop.Quit(); + }); run_loop.Run(); } @@ -734,10 +740,11 @@ controller.get()); chromium::web::WebMessage message; - message.data = MemBufferFromString(kPage1Path); - Promise<bool> post_result; - frame->PostMessage(std::move(message), post_message_url.GetOrigin().spec(), - ConvertToFitFunction(post_result.GetReceiveCallback())); + message.data = webrunner::MemBufferFromString(kPage1Path); + cr_fuchsia::test::Promise<bool> post_result; + frame->PostMessage( + std::move(message), post_message_url.GetOrigin().spec(), + cr_fuchsia::test::ConvertToFitFunction(post_result.GetReceiveCallback())); base::RunLoop run_loop; EXPECT_CALL(navigation_observer_, MockableOnNavigationStateChanged( @@ -767,30 +774,36 @@ msg.outgoing_transfer = std::make_unique<chromium::web::OutgoingTransferable>(); msg.outgoing_transfer->set_message_port(message_port.NewRequest()); - msg.data = MemBufferFromString("hi"); - Promise<bool> post_result; + msg.data = webrunner::MemBufferFromString("hi"); + cr_fuchsia::test::Promise<bool> post_result; frame->PostMessage(std::move(msg), post_message_url.GetOrigin().spec(), - ConvertToFitFunction(post_result.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction( + post_result.GetReceiveCallback())); base::RunLoop run_loop; - Promise<chromium::web::WebMessage> receiver(run_loop.QuitClosure()); + cr_fuchsia::test::Promise<chromium::web::WebMessage> receiver( + run_loop.QuitClosure()); message_port->ReceiveMessage( - ConvertToFitFunction(receiver.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction(receiver.GetReceiveCallback())); run_loop.Run(); - EXPECT_EQ("got_port", StringFromMemBufferOrDie(receiver->data)); + EXPECT_EQ("got_port", + cr_fuchsia::test::StringFromMemBufferOrDie(receiver->data)); } { - msg.data = MemBufferFromString("ping"); - Promise<bool> post_result; - message_port->PostMessage( - std::move(msg), ConvertToFitFunction(post_result.GetReceiveCallback())); + msg.data = webrunner::MemBufferFromString("ping"); + cr_fuchsia::test::Promise<bool> post_result; + message_port->PostMessage(std::move(msg), + cr_fuchsia::test::ConvertToFitFunction( + post_result.GetReceiveCallback())); base::RunLoop run_loop; - Promise<chromium::web::WebMessage> receiver(run_loop.QuitClosure()); + cr_fuchsia::test::Promise<chromium::web::WebMessage> receiver( + run_loop.QuitClosure()); message_port->ReceiveMessage( - ConvertToFitFunction(receiver.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction(receiver.GetReceiveCallback())); run_loop.Run(); - EXPECT_EQ("ack ping", StringFromMemBufferOrDie(receiver->data)); + EXPECT_EQ("ack ping", + cr_fuchsia::test::StringFromMemBufferOrDie(receiver->data)); EXPECT_TRUE(*post_result); } } @@ -814,17 +827,20 @@ msg.outgoing_transfer = std::make_unique<chromium::web::OutgoingTransferable>(); msg.outgoing_transfer->set_message_port(message_port.NewRequest()); - msg.data = MemBufferFromString("hi"); - Promise<bool> post_result; + msg.data = webrunner::MemBufferFromString("hi"); + cr_fuchsia::test::Promise<bool> post_result; frame->PostMessage(std::move(msg), post_message_url.GetOrigin().spec(), - ConvertToFitFunction(post_result.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction( + post_result.GetReceiveCallback())); base::RunLoop run_loop; - Promise<chromium::web::WebMessage> receiver(run_loop.QuitClosure()); + cr_fuchsia::test::Promise<chromium::web::WebMessage> receiver( + run_loop.QuitClosure()); message_port->ReceiveMessage( - ConvertToFitFunction(receiver.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction(receiver.GetReceiveCallback())); run_loop.Run(); - EXPECT_EQ("got_port", StringFromMemBufferOrDie(receiver->data)); + EXPECT_EQ("got_port", + cr_fuchsia::test::StringFromMemBufferOrDie(receiver->data)); EXPECT_TRUE(*post_result); } @@ -860,17 +876,20 @@ msg.outgoing_transfer = std::make_unique<chromium::web::OutgoingTransferable>(); msg.outgoing_transfer->set_message_port(message_port.NewRequest()); - msg.data = MemBufferFromString("hi"); - Promise<bool> post_result; + msg.data = webrunner::MemBufferFromString("hi"); + cr_fuchsia::test::Promise<bool> post_result; frame->PostMessage(std::move(msg), "*", - ConvertToFitFunction(post_result.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction( + post_result.GetReceiveCallback())); base::RunLoop run_loop; - Promise<chromium::web::WebMessage> receiver(run_loop.QuitClosure()); + cr_fuchsia::test::Promise<chromium::web::WebMessage> receiver( + run_loop.QuitClosure()); message_port->ReceiveMessage( - ConvertToFitFunction(receiver.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction(receiver.GetReceiveCallback())); run_loop.Run(); - EXPECT_EQ("got_port", StringFromMemBufferOrDie(receiver->data)); + EXPECT_EQ("got_port", + cr_fuchsia::test::StringFromMemBufferOrDie(receiver->data)); incoming_message_port = receiver->incoming_transfer->message_port().Bind(); EXPECT_TRUE(*post_result); } @@ -879,10 +898,11 @@ // the MessagePortImpl buffer. for (int i = 0; i < 3; ++i) { base::RunLoop run_loop; - Promise<bool> post_result(run_loop.QuitClosure()); - msg.data = MemBufferFromString("ping"); - incoming_message_port->PostMessage( - std::move(msg), ConvertToFitFunction(post_result.GetReceiveCallback())); + cr_fuchsia::test::Promise<bool> post_result(run_loop.QuitClosure()); + msg.data = webrunner::MemBufferFromString("ping"); + incoming_message_port->PostMessage(std::move(msg), + cr_fuchsia::test::ConvertToFitFunction( + post_result.GetReceiveCallback())); run_loop.Run(); EXPECT_TRUE(*post_result); } @@ -895,30 +915,35 @@ msg.outgoing_transfer = std::make_unique<chromium::web::OutgoingTransferable>(); msg.outgoing_transfer->set_message_port(ack_message_port.NewRequest()); - msg.data = MemBufferFromString("hi"); + msg.data = webrunner::MemBufferFromString("hi"); // Quit the runloop only after we've received a WebMessage AND a PostMessage // result. - Promise<bool> post_result; + cr_fuchsia::test::Promise<bool> post_result; frame->PostMessage(std::move(msg), "*", - ConvertToFitFunction(post_result.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction( + post_result.GetReceiveCallback())); base::RunLoop run_loop; - Promise<chromium::web::WebMessage> receiver(run_loop.QuitClosure()); + cr_fuchsia::test::Promise<chromium::web::WebMessage> receiver( + run_loop.QuitClosure()); ack_message_port->ReceiveMessage( - ConvertToFitFunction(receiver.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction(receiver.GetReceiveCallback())); run_loop.Run(); - EXPECT_EQ("got_port", StringFromMemBufferOrDie(receiver->data)); + EXPECT_EQ("got_port", + cr_fuchsia::test::StringFromMemBufferOrDie(receiver->data)); EXPECT_TRUE(*post_result); } // Pull the three 'ack ping's from the buffer. for (int i = 0; i < 3; ++i) { base::RunLoop run_loop; - Promise<chromium::web::WebMessage> receiver(run_loop.QuitClosure()); + cr_fuchsia::test::Promise<chromium::web::WebMessage> receiver( + run_loop.QuitClosure()); incoming_message_port->ReceiveMessage( - ConvertToFitFunction(receiver.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction(receiver.GetReceiveCallback())); run_loop.Run(); - EXPECT_EQ("ack ping", StringFromMemBufferOrDie(receiver->data)); + EXPECT_EQ("ack ping", + cr_fuchsia::test::StringFromMemBufferOrDie(receiver->data)); } } @@ -942,14 +967,15 @@ msg.outgoing_transfer = std::make_unique<chromium::web::OutgoingTransferable>(); msg.outgoing_transfer->set_message_port(unused_message_port.NewRequest()); - msg.data = MemBufferFromString("bad origin, bad!"); - Promise<bool> unused_post_result; - frame->PostMessage( - std::move(msg), "https://example.com", - ConvertToFitFunction(unused_post_result.GetReceiveCallback())); - Promise<chromium::web::WebMessage> unused_message_read; + msg.data = webrunner::MemBufferFromString("bad origin, bad!"); + cr_fuchsia::test::Promise<bool> unused_post_result; + frame->PostMessage(std::move(msg), "https://example.com", + cr_fuchsia::test::ConvertToFitFunction( + unused_post_result.GetReceiveCallback())); + cr_fuchsia::test::Promise<chromium::web::WebMessage> unused_message_read; bad_origin_incoming_message_port->ReceiveMessage( - ConvertToFitFunction(unused_message_read.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction( + unused_message_read.GetReceiveCallback())); // PostMessage() with a valid origin should succeed. // Verify it by looking for an ack message on the MessagePort we passed in. @@ -961,16 +987,19 @@ msg.outgoing_transfer = std::make_unique<chromium::web::OutgoingTransferable>(); msg.outgoing_transfer->set_message_port(message_port.NewRequest()); - msg.data = MemBufferFromString("good origin"); - Promise<bool> post_result; - frame->PostMessage(std::move(msg), "*", - ConvertToFitFunction(post_result.GetReceiveCallback())); + msg.data = webrunner::MemBufferFromString("good origin"); + cr_fuchsia::test::Promise<bool> post_result; + frame->PostMessage( + std::move(msg), "*", + cr_fuchsia::test::ConvertToFitFunction(post_result.GetReceiveCallback())); base::RunLoop run_loop; - Promise<chromium::web::WebMessage> receiver(run_loop.QuitClosure()); + cr_fuchsia::test::Promise<chromium::web::WebMessage> receiver( + run_loop.QuitClosure()); message_port->ReceiveMessage( - ConvertToFitFunction(receiver.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction(receiver.GetReceiveCallback())); run_loop.Run(); - EXPECT_EQ("got_port", StringFromMemBufferOrDie(receiver->data)); + EXPECT_EQ("got_port", + cr_fuchsia::test::StringFromMemBufferOrDie(receiver->data)); incoming_message_port = receiver->incoming_transfer->message_port().Bind(); EXPECT_TRUE(*post_result); @@ -1090,5 +1119,3 @@ EXPECT_THAT(iter->second.headers, testing::Contains(testing::Key("X-2ExtraHeaders"))); } - -} // namespace webrunner
diff --git a/fuchsia/browser/message_port_impl.cc b/fuchsia/engine/browser/message_port_impl.cc similarity index 97% rename from fuchsia/browser/message_port_impl.cc rename to fuchsia/engine/browser/message_port_impl.cc index f7728e3..838299c 100644 --- a/fuchsia/browser/message_port_impl.cc +++ b/fuchsia/engine/browser/message_port_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/browser/message_port_impl.h" +#include "fuchsia/engine/browser/message_port_impl.h" #include <stdint.h> @@ -23,7 +23,6 @@ #include "third_party/blink/public/common/messaging/transferable_message_struct_traits.h" #include "third_party/blink/public/mojom/messaging/transferable_message.mojom.h" -namespace webrunner { namespace { // Converts a message posted to a JS MessagePort to a WebMessage. @@ -84,7 +83,7 @@ // Returns a null mojo::Message if |message| was invalid. mojo::Message FromFidlMessage(chromium::web::WebMessage message) { base::string16 data_utf16; - if (!ReadUTF8FromVMOAsUTF16(message.data, &data_utf16)) + if (!webrunner::ReadUTF8FromVMOAsUTF16(message.data, &data_utf16)) return mojo::Message(); // TODO(crbug.com/893236): support >1 transferable when fidlc cycle detection @@ -187,5 +186,3 @@ MessagePortImpl* created_port = new MessagePortImpl(std::move(port)); return created_port->binding_.NewBinding(); } - -} // namespace webrunner
diff --git a/fuchsia/browser/message_port_impl.h b/fuchsia/engine/browser/message_port_impl.h similarity index 92% rename from fuchsia/browser/message_port_impl.h rename to fuchsia/engine/browser/message_port_impl.h index 835d9fc..8ec47a6 100644 --- a/fuchsia/browser/message_port_impl.h +++ b/fuchsia/engine/browser/message_port_impl.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 FUCHSIA_BROWSER_MESSAGE_PORT_IMPL_H_ -#define FUCHSIA_BROWSER_MESSAGE_PORT_IMPL_H_ +#ifndef FUCHSIA_ENGINE_BROWSER_MESSAGE_PORT_IMPL_H_ +#define FUCHSIA_ENGINE_BROWSER_MESSAGE_PORT_IMPL_H_ #include <lib/fidl/cpp/binding.h> #include <deque> @@ -16,8 +16,6 @@ #include "mojo/public/cpp/bindings/message.h" #include "mojo/public/cpp/system/message_pipe.h" -namespace webrunner { - // Defines the implementation of a MessagePort which routes messages from // FIDL clients to web content, or vice versa. Every MessagePortImpl has a FIDL // port and a Mojo port. @@ -70,6 +68,4 @@ DISALLOW_COPY_AND_ASSIGN(MessagePortImpl); }; -} // namespace webrunner - -#endif // FUCHSIA_BROWSER_MESSAGE_PORT_IMPL_H_ +#endif // FUCHSIA_ENGINE_BROWSER_MESSAGE_PORT_IMPL_H_
diff --git a/fuchsia/browser/webrunner_browser_context.cc b/fuchsia/engine/browser/webrunner_browser_context.cc similarity index 94% rename from fuchsia/browser/webrunner_browser_context.cc rename to fuchsia/engine/browser/webrunner_browser_context.cc index 93775d2..3fae9fd 100644 --- a/fuchsia/browser/webrunner_browser_context.cc +++ b/fuchsia/engine/browser/webrunner_browser_context.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/browser/webrunner_browser_context.h" +#include "fuchsia/engine/browser/webrunner_browser_context.h" #include <memory> #include <utility> @@ -16,14 +16,12 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/resource_context.h" -#include "fuchsia/browser/webrunner_net_log.h" -#include "fuchsia/browser/webrunner_url_request_context_getter.h" -#include "fuchsia/service/common.h" +#include "fuchsia/engine/browser/webrunner_net_log.h" +#include "fuchsia/engine/browser/webrunner_url_request_context_getter.h" +#include "fuchsia/engine/common.h" #include "net/url_request/url_request_context.h" #include "services/network/public/cpp/network_switches.h" -namespace webrunner { - class WebRunnerBrowserContext::ResourceContext : public content::ResourceContext { public: @@ -173,5 +171,3 @@ bool in_memory) { return nullptr; } - -} // namespace webrunner
diff --git a/fuchsia/browser/webrunner_browser_context.h b/fuchsia/engine/browser/webrunner_browser_context.h similarity index 92% rename from fuchsia/browser/webrunner_browser_context.h rename to fuchsia/engine/browser/webrunner_browser_context.h index d1be10e..e865dd93 100644 --- a/fuchsia/browser/webrunner_browser_context.h +++ b/fuchsia/engine/browser/webrunner_browser_context.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 FUCHSIA_BROWSER_WEBRUNNER_BROWSER_CONTEXT_H_ -#define FUCHSIA_BROWSER_WEBRUNNER_BROWSER_CONTEXT_H_ +#ifndef FUCHSIA_ENGINE_BROWSER_WEBRUNNER_BROWSER_CONTEXT_H_ +#define FUCHSIA_ENGINE_BROWSER_WEBRUNNER_BROWSER_CONTEXT_H_ #include <memory> @@ -11,8 +11,6 @@ #include "base/macros.h" #include "content/public/browser/browser_context.h" -namespace webrunner { - class WebRunnerNetLog; class WebRunnerURLRequestContextGetter; @@ -68,6 +66,4 @@ DISALLOW_COPY_AND_ASSIGN(WebRunnerBrowserContext); }; -} // namespace webrunner - -#endif // FUCHSIA_BROWSER_WEBRUNNER_BROWSER_CONTEXT_H_ +#endif // FUCHSIA_ENGINE_BROWSER_WEBRUNNER_BROWSER_CONTEXT_H_
diff --git a/fuchsia/browser/webrunner_browser_main.cc b/fuchsia/engine/browser/webrunner_browser_main.cc similarity index 86% rename from fuchsia/browser/webrunner_browser_main.cc rename to fuchsia/engine/browser/webrunner_browser_main.cc index aaca77df..ed2cd63b 100644 --- a/fuchsia/browser/webrunner_browser_main.cc +++ b/fuchsia/engine/browser/webrunner_browser_main.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/browser/webrunner_browser_main.h" +#include "fuchsia/engine/browser/webrunner_browser_main.h" #include <memory> @@ -10,8 +10,6 @@ #include "build/build_config.h" #include "content/public/browser/browser_main_runner.h" -namespace webrunner { - int WebRunnerBrowserMain(const content::MainFunctionParams& parameters) { std::unique_ptr<content::BrowserMainRunner> main_runner = content::BrowserMainRunner::Create(); @@ -25,5 +23,3 @@ return exit_code; } - -} // namespace webrunner
diff --git a/fuchsia/browser/webrunner_browser_main.h b/fuchsia/engine/browser/webrunner_browser_main.h similarity index 62% rename from fuchsia/browser/webrunner_browser_main.h rename to fuchsia/engine/browser/webrunner_browser_main.h index 50a0858..fa8db4f 100644 --- a/fuchsia/browser/webrunner_browser_main.h +++ b/fuchsia/engine/browser/webrunner_browser_main.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 FUCHSIA_BROWSER_WEBRUNNER_BROWSER_MAIN_H_ -#define FUCHSIA_BROWSER_WEBRUNNER_BROWSER_MAIN_H_ +#ifndef FUCHSIA_ENGINE_BROWSER_WEBRUNNER_BROWSER_MAIN_H_ +#define FUCHSIA_ENGINE_BROWSER_WEBRUNNER_BROWSER_MAIN_H_ #include <memory> @@ -11,8 +11,6 @@ struct MainFunctionParams; } // namespace content -namespace webrunner { int WebRunnerBrowserMain(const content::MainFunctionParams& parameters); -} // namespace webrunner -#endif // FUCHSIA_BROWSER_WEBRUNNER_BROWSER_MAIN_H_ +#endif // FUCHSIA_ENGINE_BROWSER_WEBRUNNER_BROWSER_MAIN_H_
diff --git a/fuchsia/browser/webrunner_browser_main_parts.cc b/fuchsia/engine/browser/webrunner_browser_main_parts.cc similarity index 90% rename from fuchsia/browser/webrunner_browser_main_parts.cc rename to fuchsia/engine/browser/webrunner_browser_main_parts.cc index c069b2f..f77d44e 100644 --- a/fuchsia/browser/webrunner_browser_main_parts.cc +++ b/fuchsia/engine/browser/webrunner_browser_main_parts.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/browser/webrunner_browser_main_parts.h" +#include "fuchsia/engine/browser/webrunner_browser_main_parts.h" #include <utility> @@ -11,15 +11,13 @@ #include "base/fuchsia/fuchsia_logging.h" #include "base/logging.h" #include "content/public/browser/render_frame_host.h" -#include "fuchsia/browser/context_impl.h" -#include "fuchsia/browser/webrunner_browser_context.h" -#include "fuchsia/browser/webrunner_screen.h" -#include "fuchsia/service/common.h" +#include "fuchsia/engine/browser/context_impl.h" +#include "fuchsia/engine/browser/webrunner_browser_context.h" +#include "fuchsia/engine/browser/webrunner_screen.h" +#include "fuchsia/engine/common.h" #include "ui/aura/screen_ozone.h" #include "ui/ozone/public/ozone_platform.h" -namespace webrunner { - WebRunnerBrowserMainParts::WebRunnerBrowserMainParts( zx::channel context_channel) : context_channel_(std::move(context_channel)) {} @@ -83,5 +81,3 @@ browser_context_.reset(); screen_.reset(); } - -} // namespace webrunner
diff --git a/fuchsia/browser/webrunner_browser_main_parts.h b/fuchsia/engine/browser/webrunner_browser_main_parts.h similarity index 82% rename from fuchsia/browser/webrunner_browser_main_parts.h rename to fuchsia/engine/browser/webrunner_browser_main_parts.h index 7c25109..a1684c262 100644 --- a/fuchsia/browser/webrunner_browser_main_parts.h +++ b/fuchsia/engine/browser/webrunner_browser_main_parts.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 FUCHSIA_BROWSER_WEBRUNNER_BROWSER_MAIN_PARTS_H_ -#define FUCHSIA_BROWSER_WEBRUNNER_BROWSER_MAIN_PARTS_H_ +#ifndef FUCHSIA_ENGINE_BROWSER_WEBRUNNER_BROWSER_MAIN_PARTS_H_ +#define FUCHSIA_ENGINE_BROWSER_WEBRUNNER_BROWSER_MAIN_PARTS_H_ #include <lib/fidl/cpp/binding.h> #include <memory> @@ -11,15 +11,13 @@ #include "base/macros.h" #include "base/optional.h" #include "content/public/browser/browser_main_parts.h" -#include "fuchsia/browser/context_impl.h" +#include "fuchsia/engine/browser/context_impl.h" #include "fuchsia/fidl/chromium/web/cpp/fidl.h" namespace display { class Screen; } -namespace webrunner { - class WebRunnerBrowserContext; class WebRunnerBrowserMainParts : public content::BrowserMainParts { @@ -47,6 +45,4 @@ DISALLOW_COPY_AND_ASSIGN(WebRunnerBrowserMainParts); }; -} // namespace webrunner - -#endif // FUCHSIA_BROWSER_WEBRUNNER_BROWSER_MAIN_PARTS_H_ +#endif // FUCHSIA_ENGINE_BROWSER_WEBRUNNER_BROWSER_MAIN_PARTS_H_
diff --git a/fuchsia/browser/webrunner_content_browser_client.cc b/fuchsia/engine/browser/webrunner_content_browser_client.cc similarity index 84% rename from fuchsia/browser/webrunner_content_browser_client.cc rename to fuchsia/engine/browser/webrunner_content_browser_client.cc index d7cb950b..db00a1c 100644 --- a/fuchsia/browser/webrunner_content_browser_client.cc +++ b/fuchsia/engine/browser/webrunner_content_browser_client.cc
@@ -2,15 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/browser/webrunner_content_browser_client.h" +#include "fuchsia/engine/browser/webrunner_content_browser_client.h" #include <utility> #include "components/version_info/version_info.h" #include "content/public/common/user_agent.h" -#include "fuchsia/browser/webrunner_browser_main_parts.h" - -namespace webrunner { +#include "fuchsia/engine/browser/webrunner_browser_main_parts.h" WebRunnerContentBrowserClient::WebRunnerContentBrowserClient( zx::channel context_channel) @@ -30,5 +28,3 @@ return content::BuildUserAgentFromProduct( version_info::GetProductNameAndVersionForUserAgent()); } - -} // namespace webrunner
diff --git a/fuchsia/browser/webrunner_content_browser_client.h b/fuchsia/engine/browser/webrunner_content_browser_client.h similarity index 80% rename from fuchsia/browser/webrunner_content_browser_client.h rename to fuchsia/engine/browser/webrunner_content_browser_client.h index 84a1ddd..9760134 100644 --- a/fuchsia/browser/webrunner_content_browser_client.h +++ b/fuchsia/engine/browser/webrunner_content_browser_client.h
@@ -2,16 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_BROWSER_WEBRUNNER_CONTENT_BROWSER_CLIENT_H_ -#define FUCHSIA_BROWSER_WEBRUNNER_CONTENT_BROWSER_CLIENT_H_ +#ifndef FUCHSIA_ENGINE_BROWSER_WEBRUNNER_CONTENT_BROWSER_CLIENT_H_ +#define FUCHSIA_ENGINE_BROWSER_WEBRUNNER_CONTENT_BROWSER_CLIENT_H_ #include <lib/zx/channel.h> #include "base/macros.h" #include "content/public/browser/content_browser_client.h" -namespace webrunner { - class WebRunnerBrowserMainParts; class WebRunnerContentBrowserClient : public content::ContentBrowserClient { @@ -33,6 +31,4 @@ DISALLOW_COPY_AND_ASSIGN(WebRunnerContentBrowserClient); }; -} // namespace webrunner - -#endif // FUCHSIA_BROWSER_WEBRUNNER_CONTENT_BROWSER_CLIENT_H_ +#endif // FUCHSIA_ENGINE_BROWSER_WEBRUNNER_CONTENT_BROWSER_CLIENT_H_
diff --git a/fuchsia/browser/webrunner_net_log.cc b/fuchsia/engine/browser/webrunner_net_log.cc similarity index 93% rename from fuchsia/browser/webrunner_net_log.cc rename to fuchsia/engine/browser/webrunner_net_log.cc index ba60913..de9c5ff 100644 --- a/fuchsia/browser/webrunner_net_log.cc +++ b/fuchsia/engine/browser/webrunner_net_log.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/browser/webrunner_net_log.h" +#include "fuchsia/engine/browser/webrunner_net_log.h" #include <string> #include <utility> @@ -15,8 +15,6 @@ #include "net/log/file_net_log_observer.h" #include "net/log/net_log_util.h" -namespace webrunner { - namespace { std::unique_ptr<base::DictionaryValue> GetWebRunnerConstants() { @@ -50,5 +48,3 @@ if (file_net_log_observer_) file_net_log_observer_->StopObserving(nullptr, base::OnceClosure()); } - -} // namespace webrunner
diff --git a/fuchsia/browser/webrunner_net_log.h b/fuchsia/engine/browser/webrunner_net_log.h similarity index 76% rename from fuchsia/browser/webrunner_net_log.h rename to fuchsia/engine/browser/webrunner_net_log.h index 00d736e..997af52 100644 --- a/fuchsia/browser/webrunner_net_log.h +++ b/fuchsia/engine/browser/webrunner_net_log.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 FUCHSIA_BROWSER_WEBRUNNER_NET_LOG_H_ -#define FUCHSIA_BROWSER_WEBRUNNER_NET_LOG_H_ +#ifndef FUCHSIA_ENGINE_BROWSER_WEBRUNNER_NET_LOG_H_ +#define FUCHSIA_ENGINE_BROWSER_WEBRUNNER_NET_LOG_H_ #include <memory> @@ -18,8 +18,6 @@ class FileNetLogObserver; } // namespace net -namespace webrunner { - class WebRunnerNetLog : public net::NetLog { public: explicit WebRunnerNetLog(const base::FilePath& log_path); @@ -31,6 +29,4 @@ DISALLOW_COPY_AND_ASSIGN(WebRunnerNetLog); }; -} // namespace webrunner - -#endif // FUCHSIA_BROWSER_WEBRUNNER_NET_LOG_H_ +#endif // FUCHSIA_ENGINE_BROWSER_WEBRUNNER_NET_LOG_H_
diff --git a/fuchsia/browser/webrunner_screen.cc b/fuchsia/engine/browser/webrunner_screen.cc similarity index 81% rename from fuchsia/browser/webrunner_screen.cc rename to fuchsia/engine/browser/webrunner_screen.cc index 18fe947..98ff226 100644 --- a/fuchsia/browser/webrunner_screen.cc +++ b/fuchsia/engine/browser/webrunner_screen.cc
@@ -2,12 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/browser/webrunner_screen.h" +#include "fuchsia/engine/browser/webrunner_screen.h" #include "ui/display/display.h" -namespace webrunner { - WebRunnerScreen::WebRunnerScreen() { const int64_t kDefaultDisplayId = 1; display::Display display(kDefaultDisplayId); @@ -15,5 +13,3 @@ } WebRunnerScreen::~WebRunnerScreen() = default; - -} // namespace webrunner
diff --git a/fuchsia/browser/webrunner_screen.h b/fuchsia/engine/browser/webrunner_screen.h similarity index 72% rename from fuchsia/browser/webrunner_screen.h rename to fuchsia/engine/browser/webrunner_screen.h index f44dd9e..baa27d7 100644 --- a/fuchsia/browser/webrunner_screen.h +++ b/fuchsia/engine/browser/webrunner_screen.h
@@ -2,15 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_BROWSER_WEBRUNNER_SCREEN_H_ -#define FUCHSIA_BROWSER_WEBRUNNER_SCREEN_H_ +#ifndef FUCHSIA_ENGINE_BROWSER_WEBRUNNER_SCREEN_H_ +#define FUCHSIA_ENGINE_BROWSER_WEBRUNNER_SCREEN_H_ #include "base/macros.h" #include "ui/display/screen_base.h" -namespace webrunner { - // display::Screen implementation for WebRunner on Fuchsia. class DISPLAY_EXPORT WebRunnerScreen : public display::ScreenBase { public: @@ -21,6 +19,4 @@ DISALLOW_COPY_AND_ASSIGN(WebRunnerScreen); }; -} // namespace webrunner - -#endif // FUCHSIA_BROWSER_WEBRUNNER_SCREEN_H_ +#endif // FUCHSIA_ENGINE_BROWSER_WEBRUNNER_SCREEN_H_
diff --git a/fuchsia/browser/webrunner_url_request_context_getter.cc b/fuchsia/engine/browser/webrunner_url_request_context_getter.cc similarity index 95% rename from fuchsia/browser/webrunner_url_request_context_getter.cc rename to fuchsia/engine/browser/webrunner_url_request_context_getter.cc index 32d2b2d..6347a5e 100644 --- a/fuchsia/browser/webrunner_url_request_context_getter.cc +++ b/fuchsia/engine/browser/webrunner_url_request_context_getter.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/browser/webrunner_url_request_context_getter.h" +#include "fuchsia/engine/browser/webrunner_url_request_context_getter.h" #include <utility> @@ -14,8 +14,6 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_builder.h" -namespace webrunner { - WebRunnerURLRequestContextGetter::WebRunnerURLRequestContextGetter( scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, net::NetLog* net_log, @@ -73,5 +71,3 @@ WebRunnerURLRequestContextGetter::GetNetworkTaskRunner() const { return network_task_runner_; } - -} // namespace webrunner
diff --git a/fuchsia/browser/webrunner_url_request_context_getter.h b/fuchsia/engine/browser/webrunner_url_request_context_getter.h similarity index 86% rename from fuchsia/browser/webrunner_url_request_context_getter.h rename to fuchsia/engine/browser/webrunner_url_request_context_getter.h index d89ec0b..0969560 100644 --- a/fuchsia/browser/webrunner_url_request_context_getter.h +++ b/fuchsia/engine/browser/webrunner_url_request_context_getter.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 FUCHSIA_BROWSER_WEBRUNNER_URL_REQUEST_CONTEXT_GETTER_H_ -#define FUCHSIA_BROWSER_WEBRUNNER_URL_REQUEST_CONTEXT_GETTER_H_ +#ifndef FUCHSIA_ENGINE_BROWSER_WEBRUNNER_URL_REQUEST_CONTEXT_GETTER_H_ +#define FUCHSIA_ENGINE_BROWSER_WEBRUNNER_URL_REQUEST_CONTEXT_GETTER_H_ #include <memory> @@ -20,8 +20,6 @@ class ProxyConfigService; } // namespace net -namespace webrunner { - class WebRunnerURLRequestContextGetter : public net::URLRequestContextGetter { public: WebRunnerURLRequestContextGetter( @@ -52,6 +50,4 @@ DISALLOW_COPY_AND_ASSIGN(WebRunnerURLRequestContextGetter); }; -} // namespace webrunner - -#endif // FUCHSIA_BROWSER_WEBRUNNER_URL_REQUEST_CONTEXT_GETTER_H_ +#endif // FUCHSIA_ENGINE_BROWSER_WEBRUNNER_URL_REQUEST_CONTEXT_GETTER_H_
diff --git a/fuchsia/service/common.cc b/fuchsia/engine/common.cc similarity index 71% rename from fuchsia/service/common.cc rename to fuchsia/engine/common.cc index cdccace..2c43db2b 100644 --- a/fuchsia/service/common.cc +++ b/fuchsia/engine/common.cc
@@ -2,10 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/service/common.h" - -namespace webrunner { +#include "fuchsia/engine/common.h" constexpr char kIncognitoSwitch[] = "incognito"; - -} // namespace webrunner
diff --git a/fuchsia/service/common.h b/fuchsia/engine/common.h similarity index 81% rename from fuchsia/service/common.h rename to fuchsia/engine/common.h index e48ec86..9903ce48 100644 --- a/fuchsia/service/common.h +++ b/fuchsia/engine/common.h
@@ -2,15 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_SERVICE_COMMON_H_ -#define FUCHSIA_SERVICE_COMMON_H_ +#ifndef FUCHSIA_ENGINE_COMMON_H_ +#define FUCHSIA_ENGINE_COMMON_H_ #include <zircon/processargs.h> #include "fuchsia/common/fuchsia_export.h" -namespace webrunner { - // Switch passed to content process when running in incognito mode, i.e. when // there is no kWebContextDataPath. FUCHSIA_EXPORT extern const char kIncognitoSwitch[]; @@ -22,6 +20,4 @@ // Context process. constexpr uint32_t kContextRequestHandleId = PA_HND(PA_USER0, 0); -} // namespace webrunner - -#endif // FUCHSIA_SERVICE_COMMON_H_ +#endif // FUCHSIA_ENGINE_COMMON_H_
diff --git a/fuchsia/service/context_provider_impl.cc b/fuchsia/engine/context_provider_impl.cc similarity index 96% rename from fuchsia/service/context_provider_impl.cc rename to fuchsia/engine/context_provider_impl.cc index 3183327..2e0ba2a 100644 --- a/fuchsia/service/context_provider_impl.cc +++ b/fuchsia/engine/context_provider_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/service/context_provider_impl.h" +#include "fuchsia/engine/context_provider_impl.h" #include <fuchsia/sys/cpp/fidl.h> #include <lib/async/default.h> @@ -25,10 +25,9 @@ #include "base/logging.h" #include "base/path_service.h" #include "base/process/launch.h" -#include "fuchsia/service/common.h" +#include "fuchsia/engine/common.h" #include "services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.h" -namespace webrunner { namespace { // Relaunches the current executable as a Context process. @@ -137,5 +136,3 @@ fidl::InterfaceRequest<chromium::web::ContextProvider> request) { bindings_.AddBinding(this, std::move(request)); } - -} // namespace webrunner
diff --git a/fuchsia/service/context_provider_impl.h b/fuchsia/engine/context_provider_impl.h similarity index 91% rename from fuchsia/service/context_provider_impl.h rename to fuchsia/engine/context_provider_impl.h index 84239c8..878d510 100644 --- a/fuchsia/service/context_provider_impl.h +++ b/fuchsia/engine/context_provider_impl.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 FUCHSIA_SERVICE_CONTEXT_PROVIDER_IMPL_H_ -#define FUCHSIA_SERVICE_CONTEXT_PROVIDER_IMPL_H_ +#ifndef FUCHSIA_ENGINE_CONTEXT_PROVIDER_IMPL_H_ +#define FUCHSIA_ENGINE_CONTEXT_PROVIDER_IMPL_H_ #include <lib/fidl/cpp/binding_set.h> #include <memory> @@ -19,8 +19,6 @@ class Process; } // namespace base -namespace webrunner { - class FUCHSIA_EXPORT ContextProviderImpl : public chromium::web::ContextProvider { public: @@ -66,6 +64,4 @@ DISALLOW_COPY_AND_ASSIGN(ContextProviderImpl); }; -} // namespace webrunner - -#endif // FUCHSIA_SERVICE_CONTEXT_PROVIDER_IMPL_H_ +#endif // FUCHSIA_ENGINE_CONTEXT_PROVIDER_IMPL_H_
diff --git a/fuchsia/service/context_provider_impl_unittest.cc b/fuchsia/engine/context_provider_impl_unittest.cc similarity index 97% rename from fuchsia/service/context_provider_impl_unittest.cc rename to fuchsia/engine/context_provider_impl_unittest.cc index f548786..4401415 100644 --- a/fuchsia/service/context_provider_impl_unittest.cc +++ b/fuchsia/engine/context_provider_impl_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/service/context_provider_impl.h" +#include "fuchsia/engine/context_provider_impl.h" #include <lib/fdio/util.h> #include <lib/fidl/cpp/binding.h> @@ -31,13 +31,12 @@ #include "base/path_service.h" #include "base/test/multiprocess_test.h" #include "base/test/test_timeouts.h" +#include "fuchsia/engine/common.h" +#include "fuchsia/engine/test/fake_context.h" #include "fuchsia/fidl/chromium/web/cpp/fidl_test_base.h" -#include "fuchsia/service/common.h" -#include "fuchsia/test/fake_context.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/multiprocess_func_list.h" -namespace webrunner { namespace { constexpr char kTestDataFileIn[] = "DataFileIn"; @@ -60,7 +59,7 @@ zx::channel context_handle(zx_take_startup_handle(kContextRequestHandleId)); CHECK(context_handle); - FakeContext context; + cr_fuchsia::test::FakeContext context; fidl::Binding<chromium::web::Context> context_binding( &context, fidl::InterfaceRequest<chromium::web::Context>( std::move(context_handle))); @@ -68,9 +67,9 @@ // When a Frame's NavigationEventObserver is bound, immediately broadcast a // navigation event to its listeners. context.set_on_create_frame_callback( - base::BindRepeating([](FakeFrame* frame) { + base::BindRepeating([](cr_fuchsia::test::FakeFrame* frame) { frame->set_on_set_observer_callback(base::BindOnce( - [](FakeFrame* frame) { + [](cr_fuchsia::test::FakeFrame* frame) { chromium::web::NavigationEvent event; event.url = kUrl; event.title = kTitle; @@ -320,5 +319,3 @@ base::GetDefaultJob(), zx::duration(TestTimeouts::action_timeout().InNanoseconds()))); } - -} // namespace webrunner
diff --git a/fuchsia/service/context_provider_main.cc b/fuchsia/engine/context_provider_main.cc similarity index 83% rename from fuchsia/service/context_provider_main.cc rename to fuchsia/engine/context_provider_main.cc index dfa1749..fa417b6 100644 --- a/fuchsia/service/context_provider_main.cc +++ b/fuchsia/engine/context_provider_main.cc
@@ -2,16 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/service/context_provider_main.h" +#include "fuchsia/engine/context_provider_main.h" #include "base/fuchsia/scoped_service_binding.h" #include "base/fuchsia/service_directory.h" #include "base/logging.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" -#include "fuchsia/service/context_provider_impl.h" - -namespace webrunner { +#include "fuchsia/engine/context_provider_impl.h" int ContextProviderMain() { base::MessageLoopForUI message_loop; @@ -26,5 +24,3 @@ return 0; } - -} // namespace webrunner
diff --git a/fuchsia/service/context_provider_main.h b/fuchsia/engine/context_provider_main.h similarity index 68% rename from fuchsia/service/context_provider_main.h rename to fuchsia/engine/context_provider_main.h index 4ae7b8c..ec1ec64 100644 --- a/fuchsia/service/context_provider_main.h +++ b/fuchsia/engine/context_provider_main.h
@@ -2,18 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_SERVICE_CONTEXT_PROVIDER_MAIN_H_ -#define FUCHSIA_SERVICE_CONTEXT_PROVIDER_MAIN_H_ +#ifndef FUCHSIA_ENGINE_CONTEXT_PROVIDER_MAIN_H_ +#define FUCHSIA_ENGINE_CONTEXT_PROVIDER_MAIN_H_ #include "fuchsia/common/fuchsia_export.h" -namespace webrunner { - // Main function for the process that implements web::ContextProvider interface. // Called by WebRunnerMainDelegate when the process is started without --type // argument. FUCHSIA_EXPORT int ContextProviderMain(); -} // namespace webrunner - -#endif // FUCHSIA_SERVICE_CONTEXT_PROVIDER_MAIN_H_ \ No newline at end of file +#endif // FUCHSIA_ENGINE_CONTEXT_PROVIDER_MAIN_H_ \ No newline at end of file
diff --git a/fuchsia/common/on_load_script_injector.mojom b/fuchsia/engine/on_load_script_injector.mojom similarity index 94% rename from fuchsia/common/on_load_script_injector.mojom rename to fuchsia/engine/on_load_script_injector.mojom index 47ec9f13..a641eff 100644 --- a/fuchsia/common/on_load_script_injector.mojom +++ b/fuchsia/engine/on_load_script_injector.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -module webrunner.mojom; +module mojom; // Interface associated with RenderFrames for managing on-load JavaScript // injection tasks the frame. Does not enforce script injection policies,
diff --git a/fuchsia/renderer/DEPS b/fuchsia/engine/renderer/DEPS similarity index 100% rename from fuchsia/renderer/DEPS rename to fuchsia/engine/renderer/DEPS
diff --git a/fuchsia/renderer/on_load_script_injector.cc b/fuchsia/engine/renderer/on_load_script_injector.cc similarity index 94% rename from fuchsia/renderer/on_load_script_injector.cc rename to fuchsia/engine/renderer/on_load_script_injector.cc index 1256331..1c9e166 100644 --- a/fuchsia/renderer/on_load_script_injector.cc +++ b/fuchsia/engine/renderer/on_load_script_injector.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/renderer/on_load_script_injector.h" +#include "fuchsia/engine/renderer/on_load_script_injector.h" #include <lib/zx/vmo.h> #include <utility> @@ -14,8 +14,6 @@ #include "content/public/renderer/render_frame.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" -namespace webrunner { - OnLoadScriptInjector::OnLoadScriptInjector(content::RenderFrame* frame) : RenderFrameObserver(frame), weak_ptr_factory_(this) { render_frame()->GetAssociatedInterfaceRegistry()->AddInterface( @@ -63,5 +61,3 @@ void OnLoadScriptInjector::OnDestruct() { delete this; } - -} // namespace webrunner
diff --git a/fuchsia/renderer/on_load_script_injector.h b/fuchsia/engine/renderer/on_load_script_injector.h similarity index 84% rename from fuchsia/renderer/on_load_script_injector.h rename to fuchsia/engine/renderer/on_load_script_injector.h index f814a2b..9435ad92 100644 --- a/fuchsia/renderer/on_load_script_injector.h +++ b/fuchsia/engine/renderer/on_load_script_injector.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 FUCHSIA_RENDERER_ON_LOAD_SCRIPT_INJECTOR_H_ -#define FUCHSIA_RENDERER_ON_LOAD_SCRIPT_INJECTOR_H_ +#ifndef FUCHSIA_ENGINE_RENDERER_ON_LOAD_SCRIPT_INJECTOR_H_ +#define FUCHSIA_ENGINE_RENDERER_ON_LOAD_SCRIPT_INJECTOR_H_ #include <lib/zx/vmo.h> #include <vector> @@ -12,11 +12,9 @@ #include "base/memory/shared_memory_handle.h" #include "base/memory/weak_ptr.h" #include "content/public/renderer/render_frame_observer.h" -#include "fuchsia/common/on_load_script_injector.mojom.h" +#include "fuchsia/engine/on_load_script_injector.mojom.h" #include "mojo/public/cpp/bindings/associated_binding_set.h" -namespace webrunner { - // Injects one or more scripts into a RenderFrame at the earliest possible time // during the page load process. class OnLoadScriptInjector : public content::RenderFrameObserver, @@ -45,6 +43,4 @@ DISALLOW_COPY_AND_ASSIGN(OnLoadScriptInjector); }; -} // namespace webrunner - -#endif // FUCHSIA_RENDERER_ON_LOAD_SCRIPT_INJECTOR_H_ +#endif // FUCHSIA_ENGINE_RENDERER_ON_LOAD_SCRIPT_INJECTOR_H_
diff --git a/fuchsia/renderer/webrunner_content_renderer_client.cc b/fuchsia/engine/renderer/webrunner_content_renderer_client.cc similarity index 82% rename from fuchsia/renderer/webrunner_content_renderer_client.cc rename to fuchsia/engine/renderer/webrunner_content_renderer_client.cc index cd05d13..36ae235 100644 --- a/fuchsia/renderer/webrunner_content_renderer_client.cc +++ b/fuchsia/engine/renderer/webrunner_content_renderer_client.cc
@@ -2,16 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/renderer/webrunner_content_renderer_client.h" +#include "fuchsia/engine/renderer/webrunner_content_renderer_client.h" #include "base/macros.h" #include "content/public/renderer/render_frame.h" -#include "fuchsia/renderer/on_load_script_injector.h" +#include "fuchsia/engine/renderer/on_load_script_injector.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" -namespace webrunner { - WebRunnerContentRendererClient::WebRunnerContentRendererClient() = default; WebRunnerContentRendererClient::~WebRunnerContentRendererClient() = default; @@ -22,5 +20,3 @@ // The objects' lifetimes are bound to the RenderFrame's lifetime. new OnLoadScriptInjector(render_frame); } - -} // namespace webrunner
diff --git a/fuchsia/renderer/webrunner_content_renderer_client.h b/fuchsia/engine/renderer/webrunner_content_renderer_client.h similarity index 72% rename from fuchsia/renderer/webrunner_content_renderer_client.h rename to fuchsia/engine/renderer/webrunner_content_renderer_client.h index fdadb5e..89ce455 100644 --- a/fuchsia/renderer/webrunner_content_renderer_client.h +++ b/fuchsia/engine/renderer/webrunner_content_renderer_client.h
@@ -2,14 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_RENDERER_WEBRUNNER_CONTENT_RENDERER_CLIENT_H_ -#define FUCHSIA_RENDERER_WEBRUNNER_CONTENT_RENDERER_CLIENT_H_ +#ifndef FUCHSIA_ENGINE_RENDERER_WEBRUNNER_CONTENT_RENDERER_CLIENT_H_ +#define FUCHSIA_ENGINE_RENDERER_WEBRUNNER_CONTENT_RENDERER_CLIENT_H_ #include "base/macros.h" #include "content/public/renderer/content_renderer_client.h" -namespace webrunner { - class WebRunnerContentRendererClient : public content::ContentRendererClient { public: WebRunnerContentRendererClient(); @@ -22,6 +20,4 @@ DISALLOW_COPY_AND_ASSIGN(WebRunnerContentRendererClient); }; -} // namespace webrunner - -#endif // FUCHSIA_RENDERER_WEBRUNNER_CONTENT_RENDERER_CLIENT_H_ +#endif // FUCHSIA_ENGINE_RENDERER_WEBRUNNER_CONTENT_RENDERER_CLIENT_H_
diff --git a/fuchsia/service/sandbox_policy b/fuchsia/engine/sandbox_policy similarity index 100% rename from fuchsia/service/sandbox_policy rename to fuchsia/engine/sandbox_policy
diff --git a/fuchsia/common/DEPS b/fuchsia/engine/test/DEPS similarity index 73% rename from fuchsia/common/DEPS rename to fuchsia/engine/test/DEPS index 5fed384..9f118d56 100644 --- a/fuchsia/common/DEPS +++ b/fuchsia/engine/test/DEPS
@@ -1,8 +1,6 @@ include_rules = [ - "+components/version_info", "+content/public/browser", "+content/public/common", "+content/public/test", - "+ui/base", "+ui/ozone/public", ]
diff --git a/fuchsia/browser/test/data/dynamic_title.html b/fuchsia/engine/test/data/dynamic_title.html similarity index 100% rename from fuchsia/browser/test/data/dynamic_title.html rename to fuchsia/engine/test/data/dynamic_title.html
diff --git a/fuchsia/browser/test/data/message_port.html b/fuchsia/engine/test/data/message_port.html similarity index 100% rename from fuchsia/browser/test/data/message_port.html rename to fuchsia/engine/test/data/message_port.html
diff --git a/fuchsia/browser/test/data/title1.html b/fuchsia/engine/test/data/title1.html similarity index 100% rename from fuchsia/browser/test/data/title1.html rename to fuchsia/engine/test/data/title1.html
diff --git a/fuchsia/browser/test/data/title2.html b/fuchsia/engine/test/data/title2.html similarity index 100% rename from fuchsia/browser/test/data/title2.html rename to fuchsia/engine/test/data/title2.html
diff --git a/fuchsia/browser/test/data/window_post_message.html b/fuchsia/engine/test/data/window_post_message.html similarity index 100% rename from fuchsia/browser/test/data/window_post_message.html rename to fuchsia/engine/test/data/window_post_message.html
diff --git a/fuchsia/test/fake_context.cc b/fuchsia/engine/test/fake_context.cc similarity index 92% rename from fuchsia/test/fake_context.cc rename to fuchsia/engine/test/fake_context.cc index c9a72dc..5a02ba0 100644 --- a/fuchsia/test/fake_context.cc +++ b/fuchsia/engine/test/fake_context.cc
@@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/test/fake_context.h" +#include "fuchsia/engine/test/fake_context.h" #include "base/fuchsia/fuchsia_logging.h" #include "base/logging.h" -namespace webrunner { +namespace cr_fuchsia { +namespace test { FakeFrame::FakeFrame(fidl::InterfaceRequest<chromium::web::Frame> request) : binding_(this, std::move(request)) { @@ -54,4 +55,5 @@ NOTREACHED() << name; } -} // namespace webrunner +} // namespace test +} // namespace cr_fuchsia
diff --git a/fuchsia/test/fake_context.h b/fuchsia/engine/test/fake_context.h similarity index 92% rename from fuchsia/test/fake_context.h rename to fuchsia/engine/test/fake_context.h index d0505e9..7c3956c 100644 --- a/fuchsia/test/fake_context.h +++ b/fuchsia/engine/test/fake_context.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 FUCHSIA_TEST_FAKE_CONTEXT_H_ -#define FUCHSIA_TEST_FAKE_CONTEXT_H_ +#ifndef FUCHSIA_ENGINE_TEST_FAKE_CONTEXT_H_ +#define FUCHSIA_ENGINE_TEST_FAKE_CONTEXT_H_ #include <lib/fidl/cpp/binding.h> #include <lib/fidl/cpp/binding_set.h> @@ -15,7 +15,8 @@ #include "fuchsia/fidl/chromium/web/cpp/fidl.h" #include "fuchsia/fidl/chromium/web/cpp/fidl_test_base.h" -namespace webrunner { +namespace cr_fuchsia { +namespace test { // A fake Frame implementation that manages its own lifetime. class FakeFrame : public chromium::web::testing::Frame_TestBase { @@ -85,6 +86,7 @@ DISALLOW_COPY_AND_ASSIGN(FakeContext); }; -} // namespace webrunner +} // namespace test +} // namespace cr_fuchsia -#endif // FUCHSIA_TEST_FAKE_CONTEXT_H_ +#endif // FUCHSIA_ENGINE_TEST_FAKE_CONTEXT_H_
diff --git a/fuchsia/test/promise.h b/fuchsia/engine/test/promise.h similarity index 89% rename from fuchsia/test/promise.h rename to fuchsia/engine/test/promise.h index e56ff58a..06c3e92 100644 --- a/fuchsia/test/promise.h +++ b/fuchsia/engine/test/promise.h
@@ -2,14 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_TEST_PROMISE_H_ -#define FUCHSIA_TEST_PROMISE_H_ +#ifndef FUCHSIA_ENGINE_TEST_PROMISE_H_ +#define FUCHSIA_ENGINE_TEST_PROMISE_H_ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/optional.h" -namespace webrunner { +namespace cr_fuchsia { +namespace test { // Stores an asynchronously generated value for later retrieval, optionally // invoking a callback on value receipt for controlling test flow. @@ -65,6 +66,7 @@ }; } -} // namespace webrunner +} // namespace test +} // namespace cr_fuchsia -#endif // FUCHSIA_TEST_PROMISE_H_ +#endif // FUCHSIA_ENGINE_TEST_PROMISE_H_
diff --git a/fuchsia/common/test/test_common.cc b/fuchsia/engine/test/test_common.cc similarity index 84% rename from fuchsia/common/test/test_common.cc rename to fuchsia/engine/test/test_common.cc index 94e23ff..799425a 100644 --- a/fuchsia/common/test/test_common.cc +++ b/fuchsia/engine/test/test_common.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/common/test/test_common.h" +#include "fuchsia/engine/test/test_common.h" #include <string> #include <utility> @@ -11,7 +11,8 @@ #include "base/run_loop.h" #include "fuchsia/common/mem_buffer_util.h" -namespace webrunner { +namespace cr_fuchsia { +namespace test { MockNavigationObserver::MockNavigationObserver() = default; @@ -34,8 +35,9 @@ std::string StringFromMemBufferOrDie(const fuchsia::mem::Buffer& buffer) { std::string output; - CHECK(StringFromMemBuffer(buffer, &output)); + CHECK(webrunner::StringFromMemBuffer(buffer, &output)); return output; } -} // namespace webrunner +} // namespace test +} // namespace cr_fuchsia
diff --git a/fuchsia/common/test/test_common.h b/fuchsia/engine/test/test_common.h similarity index 88% rename from fuchsia/common/test/test_common.h rename to fuchsia/engine/test/test_common.h index 594695d..c367bb6 100644 --- a/fuchsia/common/test/test_common.h +++ b/fuchsia/engine/test/test_common.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 FUCHSIA_COMMON_TEST_TEST_COMMON_H_ -#define FUCHSIA_COMMON_TEST_TEST_COMMON_H_ +#ifndef FUCHSIA_ENGINE_TEST_TEST_COMMON_H_ +#define FUCHSIA_ENGINE_TEST_TEST_COMMON_H_ #include <string> #include <utility> @@ -12,7 +12,8 @@ #include "fuchsia/fidl/chromium/web/cpp/fidl.h" #include "testing/gmock/include/gmock/gmock.h" -namespace webrunner { +namespace cr_fuchsia { +namespace test { // Defines mock methods used by tests to observe NavigationStateChangeEvents // and lower-level WebContentsObserver events. @@ -51,6 +52,7 @@ // Reads the contents of |buffer| in a std::string. std::string StringFromMemBufferOrDie(const fuchsia::mem::Buffer& buffer); -} // namespace webrunner +} // namespace test +} // namespace cr_fuchsia -#endif // FUCHSIA_COMMON_TEST_TEST_COMMON_H_ +#endif // FUCHSIA_ENGINE_TEST_TEST_COMMON_H_
diff --git a/fuchsia/common/test/webrunner_browser_test.cc b/fuchsia/engine/test/webrunner_browser_test.cc similarity index 83% rename from fuchsia/common/test/webrunner_browser_test.cc rename to fuchsia/engine/test/webrunner_browser_test.cc index 308c525..bce5a62 100644 --- a/fuchsia/common/test/webrunner_browser_test.cc +++ b/fuchsia/engine/test/webrunner_browser_test.cc
@@ -2,20 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/common/test/webrunner_browser_test.h" +#include "fuchsia/engine/test/webrunner_browser_test.h" #include "base/fuchsia/fuchsia_logging.h" -#include "fuchsia/browser/webrunner_browser_context.h" -#include "fuchsia/browser/webrunner_browser_main_parts.h" -#include "fuchsia/browser/webrunner_content_browser_client.h" -#include "fuchsia/service/webrunner_main_delegate.h" +#include "fuchsia/engine/browser/webrunner_browser_context.h" +#include "fuchsia/engine/browser/webrunner_browser_main_parts.h" +#include "fuchsia/engine/browser/webrunner_content_browser_client.h" +#include "fuchsia/engine/webrunner_main_delegate.h" #include "net/test/embedded_test_server/default_handlers.h" -namespace webrunner { +namespace cr_fuchsia { +namespace test { + namespace { - zx_handle_t g_context_channel = ZX_HANDLE_INVALID; - } // namespace WebRunnerBrowserTest::WebRunnerBrowserTest() = default; @@ -74,4 +74,5 @@ ->context(); } -} // namespace webrunner +} // namespace test +} // namespace cr_fuchsia
diff --git a/fuchsia/common/test/webrunner_browser_test.h b/fuchsia/engine/test/webrunner_browser_test.h similarity index 86% rename from fuchsia/common/test/webrunner_browser_test.h rename to fuchsia/engine/test/webrunner_browser_test.h index 6a7c22b..d58e42a7 100644 --- a/fuchsia/common/test/webrunner_browser_test.h +++ b/fuchsia/engine/test/webrunner_browser_test.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 FUCHSIA_COMMON_TEST_WEBRUNNER_BROWSER_TEST_H_ -#define FUCHSIA_COMMON_TEST_WEBRUNNER_BROWSER_TEST_H_ +#ifndef FUCHSIA_ENGINE_TEST_WEBRUNNER_BROWSER_TEST_H_ +#define FUCHSIA_ENGINE_TEST_WEBRUNNER_BROWSER_TEST_H_ #include <lib/fidl/cpp/binding_set.h> #include <memory> @@ -12,10 +12,11 @@ #include "base/macros.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_base.h" -#include "fuchsia/browser/context_impl.h" +#include "fuchsia/engine/browser/context_impl.h" #include "fuchsia/fidl/chromium/web/cpp/fidl.h" -namespace webrunner { +namespace cr_fuchsia { +namespace test { // Base test class used for testing the WebRunner Context FIDL service in // integration. @@ -62,6 +63,7 @@ DISALLOW_COPY_AND_ASSIGN(WebRunnerBrowserTest); }; -} // namespace webrunner +} // namespace test +} // namespace cr_fuchsia -#endif // FUCHSIA_COMMON_TEST_FUCHSIA_BROWSER_TEST_H_ +#endif // FUCHSIA_ENGINE_TEST_WEBRUNNER_BROWSER_TEST_H_
diff --git a/fuchsia/common/test/webrunner_test_launcher.cc b/fuchsia/engine/test/webrunner_test_launcher.cc similarity index 85% rename from fuchsia/common/test/webrunner_test_launcher.cc rename to fuchsia/engine/test/webrunner_test_launcher.cc index ec8ba31f..bc72cdc 100644 --- a/fuchsia/common/test/webrunner_test_launcher.cc +++ b/fuchsia/engine/test/webrunner_test_launcher.cc
@@ -9,13 +9,15 @@ #include "base/test/test_suite.h" #include "content/public/common/content_switches.h" #include "content/public/test/test_launcher.h" -#include "fuchsia/common/test/webrunner_browser_test.h" +#include "fuchsia/engine/common.h" +#include "fuchsia/engine/test/webrunner_browser_test.h" +#include "fuchsia/engine/webrunner_main_delegate.h" #include "fuchsia/fidl/chromium/web/cpp/fidl.h" -#include "fuchsia/service/common.h" -#include "fuchsia/service/webrunner_main_delegate.h" #include "ui/ozone/public/ozone_switches.h" -namespace webrunner { +namespace cr_fuchsia { +namespace test { + namespace { class WebRunnerTestLauncherDelegate : public content::TestLauncherDelegate { @@ -47,7 +49,7 @@ ZX_CHECK(result == ZX_OK, result) << "zx::channel::create"; WebRunnerBrowserTest::SetContextClientChannel(std::move(client_channel)); - return new webrunner::WebRunnerMainDelegate(std::move(server_channel)); + return new WebRunnerMainDelegate(std::move(server_channel)); } private: @@ -57,7 +59,9 @@ }; } // namespace -} // namespace webrunner + +} // namespace test +} // namespace cr_fuchsia int main(int argc, char** argv) { base::CommandLine::Init(argc, argv); @@ -69,6 +73,6 @@ if (parallel_jobs > 1U) { parallel_jobs /= 2U; } - webrunner::WebRunnerTestLauncherDelegate launcher_delegate; + cr_fuchsia::test::WebRunnerTestLauncherDelegate launcher_delegate; return LaunchTests(&launcher_delegate, parallel_jobs, argc, argv); }
diff --git a/fuchsia/common/webrunner_content_client.cc b/fuchsia/engine/webrunner_content_client.cc similarity index 91% rename from fuchsia/common/webrunner_content_client.cc rename to fuchsia/engine/webrunner_content_client.cc index f27320e6..6d2d961d 100644 --- a/fuchsia/common/webrunner_content_client.cc +++ b/fuchsia/engine/webrunner_content_client.cc
@@ -2,13 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/common/webrunner_content_client.h" - +#include "fuchsia/engine/webrunner_content_client.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" -namespace webrunner { - WebRunnerContentClient::WebRunnerContentClient() = default; WebRunnerContentClient::~WebRunnerContentClient() = default; @@ -39,5 +36,3 @@ NOTIMPLEMENTED_LOG_ONCE(); return nullptr; } - -} // namespace webrunner
diff --git a/fuchsia/common/webrunner_content_client.h b/fuchsia/engine/webrunner_content_client.h similarity index 80% rename from fuchsia/common/webrunner_content_client.h rename to fuchsia/engine/webrunner_content_client.h index 26e36a8..780c226 100644 --- a/fuchsia/common/webrunner_content_client.h +++ b/fuchsia/engine/webrunner_content_client.h
@@ -2,14 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_COMMON_WEBRUNNER_CONTENT_CLIENT_H_ -#define FUCHSIA_COMMON_WEBRUNNER_CONTENT_CLIENT_H_ +#ifndef FUCHSIA_ENGINE_WEBRUNNER_CONTENT_CLIENT_H_ +#define FUCHSIA_ENGINE_WEBRUNNER_CONTENT_CLIENT_H_ #include "base/macros.h" #include "content/public/common/content_client.h" -namespace webrunner { - class WebRunnerContentClient : public content::ContentClient { public: WebRunnerContentClient(); @@ -28,6 +26,4 @@ DISALLOW_COPY_AND_ASSIGN(WebRunnerContentClient); }; -} // namespace webrunner - -#endif // FUCHSIA_COMMON_WEBRUNNER_CONTENT_CLIENT_H_ +#endif // FUCHSIA_ENGINE_WEBRUNNER_CONTENT_CLIENT_H_
diff --git a/fuchsia/service/web_content_service_main.cc b/fuchsia/engine/webrunner_main.cc similarity index 77% rename from fuchsia/service/web_content_service_main.cc rename to fuchsia/engine/webrunner_main.cc index 6fb4d72..c439750 100644 --- a/fuchsia/service/web_content_service_main.cc +++ b/fuchsia/engine/webrunner_main.cc
@@ -6,9 +6,9 @@ #include "base/command_line.h" #include "content/public/app/content_main.h" -#include "fuchsia/service/common.h" -#include "fuchsia/service/context_provider_main.h" -#include "fuchsia/service/webrunner_main_delegate.h" +#include "fuchsia/engine/common.h" +#include "fuchsia/engine/context_provider_main.h" +#include "fuchsia/engine/webrunner_main_delegate.h" #include "services/service_manager/embedder/switches.h" int main(int argc, const char** argv) { @@ -23,17 +23,16 @@ // zx_take_startup_handle() is called only when process_type is empty (i.e. // for Browser and ContextProvider processes). Renderer and other child // processes may use the same handle id for other handles. - context_channel.reset( - zx_take_startup_handle(webrunner::kContextRequestHandleId)); + context_channel.reset(zx_take_startup_handle(kContextRequestHandleId)); // If |process_type| is empty then this may be a Browser process, or the // main ContextProvider process. Browser processes will have a // |context_channel| set if (!context_channel) - return webrunner::ContextProviderMain(); + return ContextProviderMain(); } - webrunner::WebRunnerMainDelegate delegate(std::move(context_channel)); + WebRunnerMainDelegate delegate(std::move(context_channel)); content::ContentMainParams params(&delegate); // Repeated base::CommandLine::Init() is ignored, so it's safe to pass null
diff --git a/fuchsia/service/webrunner_main_delegate.cc b/fuchsia/engine/webrunner_main_delegate.cc similarity index 88% rename from fuchsia/service/webrunner_main_delegate.cc rename to fuchsia/engine/webrunner_main_delegate.cc index 3617114..ed0664a9 100644 --- a/fuchsia/service/webrunner_main_delegate.cc +++ b/fuchsia/engine/webrunner_main_delegate.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/service/webrunner_main_delegate.h" +#include "fuchsia/engine/webrunner_main_delegate.h" #include <utility> @@ -10,14 +10,13 @@ #include "base/command_line.h" #include "base/path_service.h" #include "content/public/common/content_switches.h" -#include "fuchsia/browser/webrunner_browser_main.h" -#include "fuchsia/browser/webrunner_content_browser_client.h" -#include "fuchsia/common/webrunner_content_client.h" -#include "fuchsia/renderer/webrunner_content_renderer_client.h" -#include "fuchsia/service/common.h" +#include "fuchsia/engine/browser/webrunner_browser_main.h" +#include "fuchsia/engine/browser/webrunner_content_browser_client.h" +#include "fuchsia/engine/common.h" +#include "fuchsia/engine/renderer/webrunner_content_renderer_client.h" +#include "fuchsia/engine/webrunner_content_client.h" #include "ui/base/resource/resource_bundle.h" -namespace webrunner { namespace { WebRunnerMainDelegate* g_current_webrunner_main_delegate = nullptr; @@ -97,5 +96,3 @@ renderer_client_ = std::make_unique<WebRunnerContentRendererClient>(); return renderer_client_.get(); } - -} // namespace webrunner
diff --git a/fuchsia/service/webrunner_main_delegate.h b/fuchsia/engine/webrunner_main_delegate.h similarity index 87% rename from fuchsia/service/webrunner_main_delegate.h rename to fuchsia/engine/webrunner_main_delegate.h index c430930c..5479aa74 100644 --- a/fuchsia/service/webrunner_main_delegate.h +++ b/fuchsia/engine/webrunner_main_delegate.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_SERVICE_WEBRUNNER_MAIN_DELEGATE_H_ -#define FUCHSIA_SERVICE_WEBRUNNER_MAIN_DELEGATE_H_ +#ifndef FUCHSIA_ENGINE_WEBRUNNER_MAIN_DELEGATE_H_ +#define FUCHSIA_ENGINE_WEBRUNNER_MAIN_DELEGATE_H_ #include <lib/zx/channel.h> #include <memory> @@ -17,8 +17,6 @@ class ContentClient; } // namespace content -namespace webrunner { - class WebRunnerContentBrowserClient; class WebRunnerContentRendererClient; @@ -53,6 +51,4 @@ DISALLOW_COPY_AND_ASSIGN(WebRunnerMainDelegate); }; -} // namespace webrunner - -#endif // FUCHSIA_SERVICE_WEBRUNNER_MAIN_DELEGATE_H_ +#endif // FUCHSIA_ENGINE_WEBRUNNER_MAIN_DELEGATE_H_
diff --git a/fuchsia/modular/BUILD.gn b/fuchsia/modular/BUILD.gn new file mode 100644 index 0000000..f7d6cd6 --- /dev/null +++ b/fuchsia/modular/BUILD.gn
@@ -0,0 +1,36 @@ +# Copyright 2019 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_fuchsia) + +import("//build/config/fuchsia/fidl_library.gni") +import("//build/config/fuchsia/rules.gni") +import("//testing/test.gni") + +source_set("modular") { + sources = [ + "agent_impl.cc", + "agent_impl.h", + ] + deps = [ + "//base", + ] + public_deps = [ + "//third_party/fuchsia-sdk/sdk:modular", + ] +} + +test("modular_unittests") { + sources = [ + "agent_impl_unittests.cc", + ] + deps = [ + ":modular", + "//base", + "//base:testfidl", + "//base/test:run_all_unittests", + "//fuchsia/engine:test_support", + "//testing/gtest", + ] +}
diff --git a/fuchsia/modular/agent_impl.cc b/fuchsia/modular/agent_impl.cc new file mode 100644 index 0000000..1a958d6 --- /dev/null +++ b/fuchsia/modular/agent_impl.cc
@@ -0,0 +1,83 @@ +// Copyright 2019 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 "fuchsia/modular/agent_impl.h" + +#include "base/bind.h" + +namespace modular { + +AgentImpl::ComponentStateBase::~ComponentStateBase() = default; + +AgentImpl::ComponentStateBase::ComponentStateBase( + base::StringPiece component_id) + : component_id_(component_id) { + fidl::InterfaceHandle<::fuchsia::io::Directory> directory; + service_directory_.Initialize(directory.NewRequest()); + service_provider_ = std::make_unique<base::fuchsia::ServiceProviderImpl>( + std::move(directory)); + + // Tear down this instance when the client disconnects from the directory. + service_provider_->SetOnLastClientDisconnectedClosure(base::BindOnce( + &ComponentStateBase::OnComponentDisconnected, base::Unretained(this))); +} + +void AgentImpl::ComponentStateBase::OnComponentDisconnected() { + DCHECK(agent_impl_); + agent_impl_->DeleteComponentState(component_id_); + // Do not touch |this|, since it is already gone. +} + +AgentImpl::AgentImpl( + base::fuchsia::ServiceDirectory* service_directory, + CreateComponentStateCallback create_component_state_callback) + : create_component_state_callback_( + std::move(create_component_state_callback)), + agent_binding_(service_directory, this) { + agent_binding_.SetOnLastClientCallback(base::BindOnce( + &AgentImpl::MaybeRunOnLastClientCallback, base::Unretained(this))); +} + +AgentImpl::~AgentImpl() { + DCHECK(active_components_.empty()); +} + +void AgentImpl::Connect( + std::string requester_url, + fidl::InterfaceRequest<::fuchsia::sys::ServiceProvider> services) { + auto it = active_components_.find(requester_url); + if (it == active_components_.end()) { + std::unique_ptr<ComponentStateBase> component_state = + create_component_state_callback_.Run(requester_url); + if (!component_state) + return; + + auto result = + active_components_.emplace(requester_url, std::move(component_state)); + it = result.first; + CHECK(result.second); + it->second->agent_impl_ = this; + } + it->second->service_provider_->AddBinding(std::move(services)); +} + +void AgentImpl::RunTask(std::string task_id, RunTaskCallback callback) { + NOTIMPLEMENTED(); +} + +void AgentImpl::DeleteComponentState(base::StringPiece component_id) { + size_t removed_components = active_components_.erase(component_id); + DCHECK_EQ(removed_components, 1u); + MaybeRunOnLastClientCallback(); +} + +void AgentImpl::MaybeRunOnLastClientCallback() { + if (!on_last_client_callback_) + return; + if (!active_components_.empty() || agent_binding_.has_clients()) + return; + std::move(on_last_client_callback_).Run(); +} + +} // namespace modular
diff --git a/fuchsia/modular/agent_impl.h b/fuchsia/modular/agent_impl.h new file mode 100644 index 0000000..07013b5 --- /dev/null +++ b/fuchsia/modular/agent_impl.h
@@ -0,0 +1,129 @@ +// Copyright 2019 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 FUCHSIA_MODULAR_AGENT_IMPL_H_ +#define FUCHSIA_MODULAR_AGENT_IMPL_H_ + +#include <fuchsia/modular/cpp/fidl.h> +#include <lib/fidl/cpp/binding_set.h> +#include <lib/zx/channel.h> +#include <memory> +#include <string> +#include <utility> + +#include "base/containers/flat_map.h" +#include "base/fuchsia/scoped_service_binding.h" +#include "base/fuchsia/service_directory.h" +#include "base/fuchsia/service_provider_impl.h" +#include "base/macros.h" +#include "base/strings/string_piece.h" + +namespace modular { + +// AgentImpl allows the set of services published to each component to be +// configured via a caller-supplied factory function for per-component state. +// Specializations of the ComponentStateBase returned by the factory function +// can extend it to publish specific services, and to manage per-component +// service state as desired. +class AgentImpl : public ::fuchsia::modular::Agent { + public: + // Common base for per-component services and state. The base provides a + // service directory into which specializations publish their services, to + // have them made available to the client. Different specializations of the + // ComponentStateBase can be created to suit different components. + // + // For example, to publish separate instances of Service1 to each component, + // while having all components share a single instance of Service2: + // + // MyComponentState : public ComponentStateBase { + // public: + // MyComponentState(..) : ComponentStateBase(..) + // : binding1_(service_directory(), &service1_), + // binding2_(service_directory(), shared_service2_) {} + // private: + // Service1 service1_; + // ScopedServiceBinding<Service1> binding1_; + // Service2* shared_service2_; // e.g. Owned by the AgentImpl's embedder. + // ScopedServiceBinding<Service2> binding2_; + // }; + class ComponentStateBase { + public: + virtual ~ComponentStateBase(); + + protected: + ComponentStateBase(base::StringPiece component_id); + + // Returns the identity of the component served by this instance. + const base::StringPiece component_id() const { return component_id_; } + + // Returns the directory into which the ComponentState implementation should + // publish the services that the component may use. + base::fuchsia::ServiceDirectory* service_directory() { + return &service_directory_; + } + + private: + friend class AgentImpl; + + void OnComponentDisconnected(); + + const std::string component_id_; + AgentImpl* agent_impl_ = nullptr; + base::fuchsia::ServiceDirectory service_directory_; + std::unique_ptr<base::fuchsia::ServiceProviderImpl> service_provider_; + + DISALLOW_COPY_AND_ASSIGN(ComponentStateBase); + }; + + // Creates a component state instance providing the services to which the + // specified |component_id| should have access. Return nullptr to reject the + // connection request. + using CreateComponentStateCallback = + base::RepeatingCallback<std::unique_ptr<ComponentStateBase>( + base::StringPiece component_id)>; + + // Binds the Agent service in the supplied |service_directory|, and invokes + // |create_component_state_callback| on each Connect() call, for the caller to + // create per-component data structures and services. + AgentImpl(base::fuchsia::ServiceDirectory* service_directory, + CreateComponentStateCallback create_component_state_callback); + ~AgentImpl() override; + + // Configures a Closure that will be run when no component instances, nor + // connections to the Agent interface, remain. + void set_on_last_client_callback(base::OnceClosure on_last_client_callback) { + on_last_client_callback_ = std::move(on_last_client_callback); + } + + // fuchsia::modular::Agent implementation. + void Connect(std::string requester_url, + fidl::InterfaceRequest<::fuchsia::sys::ServiceProvider> services) + override; + void RunTask(std::string task_id, RunTaskCallback callback) override; + + private: + friend class ComponentStateBase; + + void DeleteComponentState(base::StringPiece component_id); + void MaybeRunOnLastClientCallback(); + + // Returns a ComponentStateBase instance for a given component-Id. + const CreateComponentStateCallback create_component_state_callback_; + + // Binds this Agent implementation into the |service_directory|. + base::fuchsia::ScopedServiceBinding<::fuchsia::modular::Agent> agent_binding_; + + // Owns the ComponentState instances for each connected component. + base::flat_map<std::string, std::unique_ptr<ComponentStateBase>> + active_components_; + + // Run when no active components, nor Agent clients, remain. + base::OnceClosure on_last_client_callback_; + + DISALLOW_COPY_AND_ASSIGN(AgentImpl); +}; + +} // namespace modular + +#endif // FUCHSIA_MODULAR_AGENT_IMPL_H_
diff --git a/fuchsia/modular/agent_impl_unittests.cc b/fuchsia/modular/agent_impl_unittests.cc new file mode 100644 index 0000000..3c227469 --- /dev/null +++ b/fuchsia/modular/agent_impl_unittests.cc
@@ -0,0 +1,287 @@ +// Copyright 2019 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 "fuchsia/modular/agent_impl.h" + +#include "base/fuchsia/fuchsia_logging.h" +#include "base/fuchsia/service_directory.h" +#include "base/fuchsia/service_directory_client.h" +#include "base/fuchsia/testfidl/cpp/fidl.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "fuchsia/engine/test/promise.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace modular { + +namespace { + +const char kNoServicesComponentId[] = "no-services"; +const char kAccumulatorComponentId1[] = "accumulator1"; +const char kAccumulatorComponentId2[] = "accumulator2"; + +class EmptyComponentState : public AgentImpl::ComponentStateBase { + public: + EmptyComponentState(base::StringPiece component) + : ComponentStateBase(component) {} +}; + +class AccumulatingTestInterfaceImpl + : public base::fuchsia::testfidl::TestInterface { + public: + AccumulatingTestInterfaceImpl() = default; + + // TestInterface implementation: + void Add(int32_t a, int32_t b, AddCallback callback) override { + accumulated_ += a + b; + callback(accumulated_); + } + + private: + int32_t accumulated_ = 0; + + DISALLOW_COPY_AND_ASSIGN(AccumulatingTestInterfaceImpl); +}; + +class AccumulatorComponentState : public AgentImpl::ComponentStateBase { + public: + AccumulatorComponentState(base::StringPiece component) + : ComponentStateBase(component), + service_binding_(service_directory(), &service_) {} + + private: + AccumulatingTestInterfaceImpl service_; + base::fuchsia::ScopedServiceBinding<base::fuchsia::testfidl::TestInterface> + service_binding_; +}; + +class AgentImplTest : public ::testing::Test { + public: + AgentImplTest() { + fidl::InterfaceHandle<::fuchsia::io::Directory> directory; + services_ = std::make_unique<base::fuchsia::ServiceDirectory>( + directory.NewRequest()); + services_client_ = std::make_unique<base::fuchsia::ServiceDirectoryClient>( + std::move(directory)); + } + + fuchsia::modular::AgentPtr CreateAgentAndConnect() { + DCHECK(!agent_impl_); + agent_impl_ = std::make_unique<AgentImpl>( + services_.get(), base::BindRepeating(&AgentImplTest::OnComponentConnect, + base::Unretained(this))); + fuchsia::modular::AgentPtr agent; + services_client_->ConnectToService(agent.NewRequest()); + return agent; + } + + protected: + std::unique_ptr<AgentImpl::ComponentStateBase> OnComponentConnect( + base::StringPiece component_id) { + if (component_id == kNoServicesComponentId) { + return std::make_unique<EmptyComponentState>(component_id); + } else if (component_id == kAccumulatorComponentId1 || + component_id == kAccumulatorComponentId2) { + return std::make_unique<AccumulatorComponentState>(component_id); + } + return nullptr; + } + + base::MessageLoopForIO message_loop_; + std::unique_ptr<base::fuchsia::ServiceDirectory> services_; + std::unique_ptr<base::fuchsia::ServiceDirectoryClient> services_client_; + + std::unique_ptr<AgentImpl> agent_impl_; + + DISALLOW_COPY_AND_ASSIGN(AgentImplTest); +}; + +void SetBoolToTrue(bool* bool_value) { + *bool_value = true; +} + +} // namespace + +// Verify that the Agent can publish and unpublish itself. +TEST_F(AgentImplTest, PublishAndUnpublish) { + cr_fuchsia::test::Promise<zx_status_t> client_disconnect_status1; + fuchsia::modular::AgentPtr agent = CreateAgentAndConnect(); + agent.set_error_handler(cr_fuchsia::test::ConvertToFitFunction( + client_disconnect_status1.GetReceiveCallback())); + + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(client_disconnect_status1.has_value()); + + // Teardown the Agent. + agent_impl_.reset(); + + // Verify that the client got disconnected on teardown. + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(*client_disconnect_status1, ZX_ERR_PEER_CLOSED); + + // Verify that the Agent service is no longer available. + cr_fuchsia::test::Promise<zx_status_t> client_disconnect_status2; + services_client_->ConnectToService(agent.NewRequest()); + agent.set_error_handler(cr_fuchsia::test::ConvertToFitFunction( + client_disconnect_status2.GetReceiveCallback())); + + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(*client_disconnect_status2, ZX_ERR_PEER_CLOSED); +} + +// Verify that the on-last-client callback is not invoked if the Agent channel +// is closed, until the last component is gone. +TEST_F(AgentImplTest, OnLastClientCallbackAfterComponentOutlivesAgent) { + fuchsia::modular::AgentPtr agent = CreateAgentAndConnect(); + + // Register an on-last-client callback. + bool on_last_client_called = false; + agent_impl_->set_on_last_client_callback( + base::BindOnce(&SetBoolToTrue, base::Unretained(&on_last_client_called))); + + // Connect a component to the Agent. + fuchsia::sys::ServiceProviderPtr component_services; + agent->Connect(kNoServicesComponentId, component_services.NewRequest()); + + // Disconnect from the Agent API. + agent.Unbind(); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(on_last_client_called); + + // Disconnect the component. + component_services.Unbind(); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(on_last_client_called); +} + +// Verify that the on-last-client callback is not invoked when the last +// component disconnects, until the Agent channel is also closed. +TEST_F(AgentImplTest, OnLastClientCallbackAfterAgentOutlivesComponent) { + fuchsia::modular::AgentPtr agent = CreateAgentAndConnect(); + + // Register an on-last-client callback. + bool on_last_client_called = false; + agent_impl_->set_on_last_client_callback( + base::BindOnce(&SetBoolToTrue, base::Unretained(&on_last_client_called))); + + // Connect a component to the Agent. + fuchsia::sys::ServiceProviderPtr component_services; + agent->Connect(kNoServicesComponentId, component_services.NewRequest()); + + // Disconnect the component. + component_services.Unbind(); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(on_last_client_called); + + // Disconnect from the Agent API. + agent.Unbind(); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(on_last_client_called); +} + +// Verify that multiple connection attempts with the different component Ids +// to the same service get different instances. +TEST_F(AgentImplTest, DifferentComponentIdSameService) { + fuchsia::modular::AgentPtr agent = CreateAgentAndConnect(); + + // Connect to the Agent twice using the same component Id. + fuchsia::sys::ServiceProviderPtr component_services1; + agent->Connect(kAccumulatorComponentId1, component_services1.NewRequest()); + fuchsia::sys::ServiceProviderPtr component_services2; + agent->Connect(kAccumulatorComponentId2, component_services2.NewRequest()); + + // Request the TestInterface from each of the service directories. + base::fuchsia::testfidl::TestInterfacePtr test_interface1; + component_services1->ConnectToService( + base::fuchsia::testfidl::TestInterface::Name_, + test_interface1.NewRequest().TakeChannel()); + base::fuchsia::testfidl::TestInterfacePtr test_interface2; + component_services2->ConnectToService( + base::fuchsia::testfidl::TestInterface::Name_, + test_interface1.NewRequest().TakeChannel()); + + // Both TestInterface pointers should remain valid until we are done. + test_interface1.set_error_handler( + [](zx_status_t status) { ZX_LOG(FATAL, status); }); + test_interface2.set_error_handler( + [](zx_status_t status) { ZX_LOG(FATAL, status); }); + + // Call Add() via one TestInterface and verify accumulator had been at zero. + { + base::RunLoop loop; + test_interface1->Add(1, 2, + [quit_loop = loop.QuitClosure()](int32_t result) { + EXPECT_EQ(result, 3); + quit_loop.Run(); + }); + } + + // Call Add() via the second TestInterface, and verify that first Add() call's + // effects aren't visible. + { + base::RunLoop loop; + test_interface2->Add(3, 4, + [quit_loop = loop.QuitClosure()](int32_t result) { + EXPECT_EQ(result, 7); + quit_loop.Run(); + }); + } + + test_interface1.set_error_handler(nullptr); + test_interface2.set_error_handler(nullptr); +} + +// Verify that multiple connection attempts with the same component Id connect +// it to the same service instances. +TEST_F(AgentImplTest, SameComponentIdSameService) { + fuchsia::modular::AgentPtr agent = CreateAgentAndConnect(); + + // Connect to the Agent twice using the same component Id. + fuchsia::sys::ServiceProviderPtr component_services1; + agent->Connect(kAccumulatorComponentId1, component_services1.NewRequest()); + fuchsia::sys::ServiceProviderPtr component_services2; + agent->Connect(kAccumulatorComponentId1, component_services2.NewRequest()); + + // Request the TestInterface from each of the service directories. + base::fuchsia::testfidl::TestInterfacePtr test_interface1; + component_services1->ConnectToService( + base::fuchsia::testfidl::TestInterface::Name_, + test_interface1.NewRequest().TakeChannel()); + base::fuchsia::testfidl::TestInterfacePtr test_interface2; + component_services2->ConnectToService( + base::fuchsia::testfidl::TestInterface::Name_, + test_interface1.NewRequest().TakeChannel()); + + // Both TestInterface pointers should remain valid until we are done. + test_interface1.set_error_handler( + [](zx_status_t status) { ZX_LOG(FATAL, status); }); + test_interface2.set_error_handler( + [](zx_status_t status) { ZX_LOG(FATAL, status); }); + + // Call Add() via one TestInterface and verify accumulator had been at zero. + { + base::RunLoop loop; + test_interface1->Add(1, 2, + [quit_loop = loop.QuitClosure()](int32_t result) { + EXPECT_EQ(result, 3); + quit_loop.Run(); + }); + } + + // Call Add() via the other TestInterface, and verify that the result of the + // previous Add() was already in the accumulator. + { + base::RunLoop loop; + test_interface2->Add(3, 4, + [quit_loop = loop.QuitClosure()](int32_t result) { + EXPECT_EQ(result, 10); + quit_loop.Run(); + }); + } + + test_interface1.set_error_handler(nullptr); + test_interface2.set_error_handler(nullptr); +} + +} // namespace modular
diff --git a/fuchsia/runners/BUILD.gn b/fuchsia/runners/BUILD.gn index 14ff0a2a..4ff1698c 100644 --- a/fuchsia/runners/BUILD.gn +++ b/fuchsia/runners/BUILD.gn
@@ -80,7 +80,7 @@ package_name_override = "cast_runner" install_only = true package_deps = [ [ - "//fuchsia:service_pkg", + "//fuchsia/engine:web_engine", "chromium", ] ] } @@ -114,12 +114,12 @@ ":cast_runner_test_core", "//base/test:run_all_unittests", "//base/test:test_support", - "//fuchsia:test_support", + "//fuchsia/engine:test_support", "//net:test_support", "//testing/gtest", ] package_deps = [ [ - "//fuchsia:service_pkg", + "//fuchsia/engine:web_engine", "chromium", ] ] } @@ -137,9 +137,9 @@ ":cast_runner_core", "//base/test:test_support", "//content/public/browser", - "//fuchsia:browsertest_common", "//fuchsia:mem_buffer_common", - "//fuchsia:test_support", + "//fuchsia/engine:browsertest_core", + "//fuchsia/engine:test_support", "//testing/gmock", "//testing/gtest", "//ui/ozone", @@ -168,7 +168,7 @@ package_name_override = "web_runner" install_only = true package_deps = [ [ - "//fuchsia:service_pkg", + "//fuchsia/engine:web_engine", "chromium", ] ] } @@ -181,14 +181,14 @@ "//base", "//base/test:run_all_unittests", "//base/test:test_support", - "//fuchsia:test_support", + "//fuchsia/engine:test_support", "//net:test_support", "//testing/gtest", "//third_party/fuchsia-sdk/sdk:sys", ] package_deps = [ [ - "//fuchsia:service_pkg", + "//fuchsia/engine:web_engine", "chromium", ], [
diff --git a/fuchsia/runners/cast/cast_channel_bindings_browsertest.cc b/fuchsia/runners/cast/cast_channel_bindings_browsertest.cc index 330e3edc..ba272dd 100644 --- a/fuchsia/runners/cast/cast_channel_bindings_browsertest.cc +++ b/fuchsia/runners/cast/cast_channel_bindings_browsertest.cc
@@ -13,10 +13,10 @@ #include "base/test/test_timeouts.h" #include "base/threading/thread_restrictions.h" #include "fuchsia/common/mem_buffer_util.h" -#include "fuchsia/common/test/test_common.h" -#include "fuchsia/common/test/webrunner_browser_test.h" +#include "fuchsia/engine/test/promise.h" +#include "fuchsia/engine/test/test_common.h" +#include "fuchsia/engine/test/webrunner_browser_test.h" #include "fuchsia/runners/cast/cast_channel_bindings.h" -#include "fuchsia/test/promise.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/url_constants.h" @@ -30,7 +30,7 @@ ADD_FAILURE(); } -class CastChannelBindingsTest : public webrunner::WebRunnerBrowserTest, +class CastChannelBindingsTest : public cr_fuchsia::test::WebRunnerBrowserTest, public chromium::web::NavigationEventObserver, public chromium::cast::CastChannel { public: @@ -43,7 +43,7 @@ protected: void SetUpOnMainThread() override { - webrunner::WebRunnerBrowserTest::SetUpOnMainThread(); + cr_fuchsia::test::WebRunnerBrowserTest::SetUpOnMainThread(); base::ScopedAllowBlockingForTesting allow_blocking; frame_ = WebRunnerBrowserTest::CreateFrame(this); connector_ = std::make_unique<NamedMessagePortConnector>(); @@ -92,12 +92,12 @@ std::string ReadStringFromChannel() { base::RunLoop run_loop; - webrunner::Promise<chromium::web::WebMessage> message( + cr_fuchsia::test::Promise<chromium::web::WebMessage> message( run_loop.QuitClosure()); connected_channel_->ReceiveMessage( - webrunner::ConvertToFitFunction(message.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction(message.GetReceiveCallback())); run_loop.Run(); - return webrunner::StringFromMemBufferOrDie(message->data); + return cr_fuchsia::test::StringFromMemBufferOrDie(message->data); } void CheckLoadUrl(const std::string& url, @@ -190,10 +190,10 @@ message.data = webrunner::MemBufferFromString("hello"); base::RunLoop run_loop; - webrunner::Promise<bool> post_result(run_loop.QuitClosure()); - connected_channel_->PostMessage( - std::move(message), - webrunner::ConvertToFitFunction(post_result.GetReceiveCallback())); + cr_fuchsia::test::Promise<bool> post_result(run_loop.QuitClosure()); + connected_channel_->PostMessage(std::move(message), + cr_fuchsia::test::ConvertToFitFunction( + post_result.GetReceiveCallback())); run_loop.Run(); EXPECT_EQ(true, *post_result); }
diff --git a/fuchsia/runners/cast/cast_runner_integration_test.cc b/fuchsia/runners/cast/cast_runner_integration_test.cc index db21715..ebb27f9 100644 --- a/fuchsia/runners/cast/cast_runner_integration_test.cc +++ b/fuchsia/runners/cast/cast_runner_integration_test.cc
@@ -11,14 +11,14 @@ #include "base/message_loop/message_loop.h" #include "base/strings/stringprintf.h" #include "base/test/test_timeouts.h" -#include "fuchsia/common/test/test_common.h" +#include "fuchsia/engine/test/promise.h" +#include "fuchsia/engine/test/test_common.h" #include "fuchsia/fidl/chromium/web/cpp/fidl.h" #include "fuchsia/runners/cast/cast_runner.h" #include "fuchsia/runners/cast/fake_application_config_manager.h" #include "fuchsia/runners/cast/test_common.h" #include "fuchsia/runners/common/web_component.h" #include "fuchsia/runners/common/web_content_runner.h" -#include "fuchsia/test/promise.h" #include "net/test/embedded_test_server/default_handlers.h" #include "testing/gtest/include/gtest/gtest.h" @@ -157,7 +157,8 @@ chromium::web::NavigationControllerPtr nav_controller; { base::RunLoop run_loop; - webrunner::Promise<WebComponent*> web_component(run_loop.QuitClosure()); + cr_fuchsia::test::Promise<WebComponent*> web_component( + run_loop.QuitClosure()); cast_runner_->GetWebComponentForTest(web_component.GetReceiveCallback()); run_loop.Run(); ASSERT_NE(*web_component, nullptr); @@ -169,10 +170,10 @@ // Ensure the NavigationEntry has the expected URL. { base::RunLoop run_loop; - webrunner::Promise<std::unique_ptr<chromium::web::NavigationEntry>> + cr_fuchsia::test::Promise<std::unique_ptr<chromium::web::NavigationEntry>> nav_entry(run_loop.QuitClosure()); nav_controller->GetVisibleEntry( - webrunner::ConvertToFitFunction(nav_entry.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction(nav_entry.GetReceiveCallback())); run_loop.Run(); EXPECT_EQ(nav_entry->get()->url, test_server_.GetURL(kBlankAppPath).spec()); } @@ -196,7 +197,8 @@ // Ensure no WebComponent was created. base::RunLoop run_loop; - webrunner::Promise<WebComponent*> web_component(run_loop.QuitClosure()); + cr_fuchsia::test::Promise<WebComponent*> web_component( + run_loop.QuitClosure()); cast_runner_->GetWebComponentForTest(web_component.GetReceiveCallback()); run_loop.Run(); EXPECT_EQ(*web_component, nullptr); @@ -220,7 +222,8 @@ chromium::web::NavigationControllerPtr nav_controller; { base::RunLoop run_loop; - webrunner::Promise<WebComponent*> web_component(run_loop.QuitClosure()); + cr_fuchsia::test::Promise<WebComponent*> web_component( + run_loop.QuitClosure()); cast_runner_->GetWebComponentForTest(web_component.GetReceiveCallback()); run_loop.Run(); ASSERT_NE(*web_component, nullptr); @@ -232,10 +235,10 @@ // Ensure the NavigationEntry has the expected URL. { base::RunLoop run_loop; - webrunner::Promise<std::unique_ptr<chromium::web::NavigationEntry>> + cr_fuchsia::test::Promise<std::unique_ptr<chromium::web::NavigationEntry>> nav_entry(run_loop.QuitClosure()); nav_controller->GetVisibleEntry( - webrunner::ConvertToFitFunction(nav_entry.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction(nav_entry.GetReceiveCallback())); run_loop.Run(); EXPECT_EQ(nav_entry->get()->url, test_server_.GetURL(kCastChannelAppPath).spec()); @@ -246,13 +249,14 @@ auto expected_list = {"this", "is", "a", "test"}; for (const std::string& expected : expected_list) { base::RunLoop run_loop; - webrunner::Promise<chromium::web::WebMessage> message( + cr_fuchsia::test::Promise<chromium::web::WebMessage> message( run_loop.QuitClosure()); connected_channel_->ReceiveMessage( - webrunner::ConvertToFitFunction(message.GetReceiveCallback())); + cr_fuchsia::test::ConvertToFitFunction(message.GetReceiveCallback())); run_loop.Run(); - EXPECT_EQ(webrunner::StringFromMemBufferOrDie(message->data), expected); + EXPECT_EQ(cr_fuchsia::test::StringFromMemBufferOrDie(message->data), + expected); } component_controller_ptr.Unbind();
diff --git a/fuchsia/runners/cast/named_message_port_connector_browsertest.cc b/fuchsia/runners/cast/named_message_port_connector_browsertest.cc index b5739cee6..a3c8ba8 100644 --- a/fuchsia/runners/cast/named_message_port_connector_browsertest.cc +++ b/fuchsia/runners/cast/named_message_port_connector_browsertest.cc
@@ -11,10 +11,10 @@ #include "base/path_service.h" #include "base/test/test_timeouts.h" #include "fuchsia/common/mem_buffer_util.h" -#include "fuchsia/common/test/test_common.h" -#include "fuchsia/common/test/webrunner_browser_test.h" +#include "fuchsia/engine/test/promise.h" +#include "fuchsia/engine/test/test_common.h" +#include "fuchsia/engine/test/webrunner_browser_test.h" #include "fuchsia/runners/cast/named_message_port_connector.h" -#include "fuchsia/test/promise.h" #include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,7 +25,7 @@ using NavigationDetails = chromium::web::NavigationEvent; class NamedMessagePortConnectorTest - : public webrunner::WebRunnerBrowserTest, + : public cr_fuchsia::test::WebRunnerBrowserTest, public chromium::web::NavigationEventObserver { public: NamedMessagePortConnectorTest() @@ -37,7 +37,7 @@ protected: void SetUpOnMainThread() override { - webrunner::WebRunnerBrowserTest::SetUpOnMainThread(); + cr_fuchsia::test::WebRunnerBrowserTest::SetUpOnMainThread(); frame_ = WebRunnerBrowserTest::CreateFrame(this); } @@ -77,13 +77,13 @@ frame_->GetNavigationController(controller.NewRequest()); base::RunLoop receive_port_run_loop; - webrunner::Promise<chromium::web::MessagePortPtr> message_port( + cr_fuchsia::test::Promise<chromium::web::MessagePortPtr> message_port( receive_port_run_loop.QuitClosure()); connector_.Register( "hello", - base::BindRepeating( - &webrunner::Promise<chromium::web::MessagePortPtr>::ReceiveValue, - base::Unretained(&message_port)), + base::BindRepeating(&cr_fuchsia::test::Promise< + chromium::web::MessagePortPtr>::ReceiveValue, + base::Unretained(&message_port)), frame_.get()); CheckLoadUrl(test_url.spec(), controller.get()); @@ -91,29 +91,29 @@ chromium::web::WebMessage msg; msg.data = webrunner::MemBufferFromString("ping"); - webrunner::Promise<bool> post_result; + cr_fuchsia::test::Promise<bool> post_result; (*message_port) - ->PostMessage(std::move(msg), webrunner::ConvertToFitFunction( + ->PostMessage(std::move(msg), cr_fuchsia::test::ConvertToFitFunction( post_result.GetReceiveCallback())); std::vector<std::string> test_messages = {"early 1", "early 2", "ack ping"}; for (std::string expected_msg : test_messages) { base::RunLoop run_loop; - webrunner::Promise<chromium::web::WebMessage> message_receiver( + cr_fuchsia::test::Promise<chromium::web::WebMessage> message_receiver( run_loop.QuitClosure()); (*message_port) - ->ReceiveMessage(webrunner::ConvertToFitFunction( + ->ReceiveMessage(cr_fuchsia::test::ConvertToFitFunction( message_receiver.GetReceiveCallback())); run_loop.Run(); - EXPECT_EQ(webrunner::StringFromMemBufferOrDie(message_receiver->data), - expected_msg); + EXPECT_EQ( + cr_fuchsia::test::StringFromMemBufferOrDie(message_receiver->data), + expected_msg); } // Ensure that the MessagePort is dropped when navigating away. { base::RunLoop run_loop; - (*message_port).set_error_handler([&run_loop](zx_status_t status) { - EXPECT_EQ(status, ZX_ERR_PEER_CLOSED); + (*message_port).set_error_handler([&run_loop](zx_status_t) { run_loop.Quit(); }); controller->LoadUrl("about:blank", nullptr);
diff --git a/google_apis/google_api_keys.cc b/google_apis/google_api_keys.cc index 643926f..d05b9ef 100644 --- a/google_apis/google_api_keys.cc +++ b/google_apis/google_api_keys.cc
@@ -73,10 +73,6 @@ #define GOOGLE_API_KEY_PHYSICAL_WEB_TEST DUMMY_API_TOKEN #endif -#if !defined(GOOGLE_API_KEY_REMOTING_FTL) -#define GOOGLE_API_KEY_REMOTING_FTL DUMMY_API_TOKEN -#endif - // These are used as shortcuts for developers and users providing // OAuth credentials via preprocessor defines or environment // variables. If set, they will be used to replace any of the client @@ -115,11 +111,6 @@ api_key_non_stable_ = api_key_; #endif - api_key_remoting_ftl_ = - CalculateKeyValue(GOOGLE_API_KEY_REMOTING_FTL, - STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_REMOTING_FTL), - NULL, std::string(), environment.get(), command_line); - std::string default_client_id = CalculateKeyValue(GOOGLE_DEFAULT_CLIENT_ID, STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_ID), @@ -207,7 +198,6 @@ void set_api_key(const std::string& api_key) { api_key_ = api_key; } #endif std::string api_key_non_stable() const { return api_key_non_stable_; } - std::string api_key_remoting_ftl() const { return api_key_remoting_ftl_; } std::string GetClientID(OAuth2Client client) const { DCHECK_LT(client, CLIENT_NUM_ITEMS); @@ -303,7 +293,6 @@ std::string api_key_; std::string api_key_non_stable_; - std::string api_key_remoting_ftl_; std::string client_ids_[CLIENT_NUM_ITEMS]; std::string client_secrets_[CLIENT_NUM_ITEMS]; }; @@ -323,10 +312,6 @@ return g_api_key_cache.Get().api_key_non_stable(); } -std::string GetFtlAPIKey() { - return g_api_key_cache.Get().api_key_remoting_ftl(); -} - #if defined(OS_IOS) void SetAPIKey(const std::string& api_key) { g_api_key_cache.Get().set_api_key(api_key);
diff --git a/google_apis/google_api_keys.h b/google_apis/google_api_keys.h index 6f13643d..d4979fe9 100644 --- a/google_apis/google_api_keys.h +++ b/google_apis/google_api_keys.h
@@ -73,10 +73,6 @@ // Non-stable channels may have a different Google API key. std::string GetNonStableAPIKey(); -// Retrieves the Chrome Remote Desktop FTL API key to be used during the -// signaling process. -std::string GetRemotingFtlAPIKey(); - #if defined(OS_IOS) // Sets the API key. This should be called as early as possible before this // API key is even accessed.
diff --git a/gpu/ipc/service/direct_composition_surface_win.cc b/gpu/ipc/service/direct_composition_surface_win.cc index 2ef9df0..2f1bd42 100644 --- a/gpu/ipc/service/direct_composition_surface_win.cc +++ b/gpu/ipc/service/direct_composition_surface_win.cc
@@ -1121,7 +1121,9 @@ if (image_dxgi && use_decode_swap_chain) { D3D11_TEXTURE2D_DESC texture_desc = {}; image_dxgi->texture()->GetDesc(&texture_desc); + bool is_decoder_texture = texture_desc.BindFlags & D3D11_BIND_DECODER; + // Decode swap chains do not support shared resources. // TODO(sunnyps): Find a workaround for when the decoder moves to its own // thread and D3D device. See https://crbug.com/911847 @@ -1129,7 +1131,17 @@ texture_desc.MiscFlags & (D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED_NTHANDLE); - if (is_decoder_texture && !is_shared_texture) { + + // Downscaled video isn't promoted to hardware overlays. We prefer to blit + // into the smaller size so that it can be promoted to a hardware overlay. + float swap_chain_scale_x = + swap_chain_size.width() * 1.0f / params.content_rect.width(); + float swap_chain_scale_y = + swap_chain_size.height() * 1.0f / params.content_rect.height(); + bool is_downscale = + (swap_chain_scale_x < 1.0f) || (swap_chain_scale_y < 1.0f); + + if (is_decoder_texture && !is_shared_texture && !is_downscale) { if (PresentToDecodeSwapChain(image_dxgi, params.content_rect, swap_chain_size, needs_commit)) { return true;
diff --git a/headless/BUILD.gn b/headless/BUILD.gn index e27f6a5..d3fcfea 100644 --- a/headless/BUILD.gn +++ b/headless/BUILD.gn
@@ -606,18 +606,9 @@ ] deps = [ - "//base", "//components/crash/content/app:chrome_crashpad_handler", ] - if (is_component_build) { - sources += [ "$root_out_dir/libbase.dylib" ] - if (use_custom_libcxx) { - sources += [ "$root_out_dir/libc++.dylib" ] - deps += [ "//buildtools/third_party/libc++:libc++" ] - } - } - outputs = [ "$root_out_dir/Helpers/{{source_file_part}}", ]
diff --git a/ios/chrome/app/DEPS b/ios/chrome/app/DEPS index a16b778f..8c2ddbfb 100644 --- a/ios/chrome/app/DEPS +++ b/ios/chrome/app/DEPS
@@ -16,6 +16,7 @@ "+components/payments/core", "+components/prefs", "+components/reading_list/core", + "+components/search_engines", "+components/suggestions", "+components/sync/driver", "+components/task_scheduler_util",
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index c3534dc..2677ba3f8 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -35,6 +35,7 @@ #include "components/payments/core/features.h" #include "components/prefs/ios/pref_observer_bridge.h" #include "components/prefs/pref_change_registrar.h" +#include "components/search_engines/template_url_service.h" #include "components/url_formatter/url_formatter.h" #include "components/web_resource/web_resource_pref_names.h" #import "ios/chrome/app/application_delegate/app_state.h" @@ -427,6 +428,8 @@ - (void)showTabSwitcher; // Starts a voice search on the current BVC. - (void)startVoiceSearchInCurrentBVC; +// Loads the query from startup parameters in the current BVC. +- (void)loadStartupQueryInCurrentBVC; // Dismisses |signinInteractionCoordinator|. - (void)dismissSigninInteractionCoordinator; // Called when the last incognito tab was closed. @@ -1765,6 +1768,26 @@ [self.currentBVC startVoiceSearch]; } +- (void)loadStartupQueryInCurrentBVC { + NSString* query = self.startupParameters.textQuery; + + TemplateURLService* templateURLService = + ios::TemplateURLServiceFactory::GetForBrowserState(_mainBrowserState); + const TemplateURL* defaultURL = + templateURLService->GetDefaultSearchProvider(); + DCHECK(!defaultURL->url().empty()); + DCHECK( + defaultURL->url_ref().IsValid(templateURLService->search_terms_data())); + base::string16 queryString = base::SysNSStringToUTF16(query); + TemplateURLRef::SearchTermsArgs search_args(queryString); + + GURL result(defaultURL->url_ref().ReplaceSearchTerms( + search_args, templateURLService->search_terms_data())); + web::NavigationManager::WebLoadParams params(result); + params.transition_type = ui::PAGE_TRANSITION_TYPED; + [self.currentBVC.dispatcher loadURLWithParams:ChromeLoadParams(params)]; +} + #pragma mark - Preferences Management - (void)onPreferenceChanged:(const std::string&)preferenceName { @@ -2248,6 +2271,10 @@ return ^{ [self.currentBVC.dispatcher focusOmnibox]; }; + case SEARCH_TEXT: + return ^{ + [self loadStartupQueryInCurrentBVC]; + }; default: return nil; } @@ -2266,6 +2293,7 @@ ProceduralBlock startupCompletion = [self completionBlockForTriggeringAction:[_startupParameters postOpeningAction]]; + // Commands are only allowed on NTP. DCHECK(IsURLNtp(url) || !startupCompletion);
diff --git a/ios/chrome/app/startup/BUILD.gn b/ios/chrome/app/startup/BUILD.gn index d7c7e3b..e85121be 100644 --- a/ios/chrome/app/startup/BUILD.gn +++ b/ios/chrome/app/startup/BUILD.gn
@@ -53,6 +53,7 @@ ":startup_basic", "//base", "//components/ntp_snippets", + "//components/search_engines:search_engines", "//ios/chrome/browser", "//ios/chrome/browser/browser_state", "//ios/chrome/browser/first_run",
diff --git a/ios/chrome/app/startup/chrome_app_startup_parameters.h b/ios/chrome/app/startup/chrome_app_startup_parameters.h index ac70aec..e066086 100644 --- a/ios/chrome/app/startup/chrome_app_startup_parameters.h +++ b/ios/chrome/app/startup/chrome_app_startup_parameters.h
@@ -100,7 +100,7 @@ @interface ChromeAppStartupParameters (Testing) + (instancetype)newAppStartupParametersForCommand:(NSString*)command - withExternalURL:(NSString*)externalURL + withExternalText:(NSString*)externalText withIndex:(NSNumber*)index withURL:(NSURL*)url fromSourceApplication:(NSString*)appId
diff --git a/ios/chrome/app/startup/chrome_app_startup_parameters.mm b/ios/chrome/app/startup/chrome_app_startup_parameters.mm index dfce669..9c131af7 100644 --- a/ios/chrome/app/startup/chrome_app_startup_parameters.mm +++ b/ios/chrome/app/startup/chrome_app_startup_parameters.mm
@@ -204,10 +204,10 @@ id commandTime = base::mac::ObjCCast<NSDate>( [commandDictionary objectForKey:commandTimePreference]); - NSString* commandURLPreference = - base::SysUTF8ToNSString(app_group::kChromeAppGroupCommandURLPreference); - NSString* externalURL = base::mac::ObjCCast<NSString>( - [commandDictionary objectForKey:commandURLPreference]); + NSString* commandTextPreference = + base::SysUTF8ToNSString(app_group::kChromeAppGroupCommandTextPreference); + NSString* externalText = base::mac::ObjCCast<NSString>( + [commandDictionary objectForKey:commandTextPreference]); NSString* commandIndexPreference = base::SysUTF8ToNSString(app_group::kChromeAppGroupCommandIndexPreference); @@ -226,16 +226,15 @@ return nil; return [ChromeAppStartupParameters newAppStartupParametersForCommand:command - withExternalURL:externalURL + withExternalText:externalText withIndex:index withURL:url - fromSourceApplication:appId fromSecureSourceApplication:commandCaller]; } + (instancetype)newAppStartupParametersForCommand:(NSString*)command - withExternalURL:(NSString*)externalURL + withExternalText:(NSString*)externalText withIndex:(NSNumber*)index withURL:(NSURL*)url fromSourceApplication:(NSString*)appId @@ -279,9 +278,9 @@ if ([command isEqualToString:base::SysUTF8ToNSString( app_group::kChromeAppGroupOpenURLCommand)]) { - if (!externalURL || ![externalURL isKindOfClass:[NSString class]]) + if (!externalText || ![externalText isKindOfClass:[NSString class]]) return nil; - GURL externalGURL(base::SysNSStringToUTF8(externalURL)); + GURL externalGURL(base::SysNSStringToUTF8(externalText)); if (!externalGURL.is_valid() || !externalGURL.SchemeIsHTTPOrHTTPS()) return nil; params = @@ -294,6 +293,25 @@ if ([command isEqualToString:base::SysUTF8ToNSString( + app_group::kChromeAppGroupSearchTextCommand)]) { + if (!externalText) { + return nil; + } + + params = [[ChromeAppStartupParameters alloc] + initWithExternalURL:GURL(kChromeUINewTabURL) + declaredSourceApp:appId + secureSourceApp:secureSourceApp + completeURL:url]; + + params.textQuery = externalText; + params.postOpeningAction = SEARCH_TEXT; + + action = ACTION_NEW_SEARCH; + } + + if ([command + isEqualToString:base::SysUTF8ToNSString( app_group::kChromeAppGroupQRScannerCommand)]) { params = [[ChromeAppStartupParameters alloc] initWithExternalURL:GURL(kChromeUINewTabURL)
diff --git a/ios/chrome/app/startup/chrome_app_startup_parameters_unittest.mm b/ios/chrome/app/startup/chrome_app_startup_parameters_unittest.mm index 939c2f27..a034336 100644 --- a/ios/chrome/app/startup/chrome_app_startup_parameters_unittest.mm +++ b/ios/chrome/app/startup/chrome_app_startup_parameters_unittest.mm
@@ -153,7 +153,7 @@ TEST_F(AppStartupParametersTest, ParseURLWithAppGroupVoiceSearch) { ChromeAppStartupParameters* params = [ChromeAppStartupParameters newAppStartupParametersForCommand:@"voicesearch" - withExternalURL:nil + withExternalText:nil withIndex:0 withURL:nil fromSourceApplication:nil @@ -169,7 +169,7 @@ TEST_F(AppStartupParametersTest, ParseURLWithAppGroupQRCode) { ChromeAppStartupParameters* params = [ChromeAppStartupParameters newAppStartupParametersForCommand:@"qrscanner" - withExternalURL:nil + withExternalText:nil withIndex:0 withURL:nil fromSourceApplication:nil @@ -185,7 +185,7 @@ TEST_F(AppStartupParametersTest, ParseURLWithAppGroupFocusOmbnibox) { ChromeAppStartupParameters* params = [ChromeAppStartupParameters newAppStartupParametersForCommand:@"focusomnibox" - withExternalURL:nil + withExternalText:nil withIndex:0 withURL:nil fromSourceApplication:nil @@ -201,7 +201,7 @@ TEST_F(AppStartupParametersTest, ParseURLWithAppGroupNewTab) { ChromeAppStartupParameters* params = [ChromeAppStartupParameters newAppStartupParametersForCommand:@"newtab" - withExternalURL:nil + withExternalText:nil withIndex:0 withURL:nil fromSourceApplication:nil @@ -216,7 +216,7 @@ TEST_F(AppStartupParametersTest, ParseURLWithAppGroupOpenURL) { ChromeAppStartupParameters* params = [ChromeAppStartupParameters newAppStartupParametersForCommand:@"openurl" - withExternalURL:@"http://foo/bar" + withExternalText:@"http://foo/bar" withIndex:0 withURL:nil @@ -229,7 +229,7 @@ TEST_F(AppStartupParametersTest, ParseURLWithAppGroupGarbage) { ChromeAppStartupParameters* params = [ChromeAppStartupParameters newAppStartupParametersForCommand:@"garbage" - withExternalURL:nil + withExternalText:nil withIndex:0 withURL:nil fromSourceApplication:nil
diff --git a/ios/chrome/browser/app_startup_parameters.h b/ios/chrome/browser/app_startup_parameters.h index efd4a325..4269314 100644 --- a/ios/chrome/browser/app_startup_parameters.h +++ b/ios/chrome/browser/app_startup_parameters.h
@@ -16,6 +16,7 @@ START_QR_CODE_SCANNER, FOCUS_OMNIBOX, NTP_TAB_OPENING_POST_OPENING_ACTION_COUNT, + SEARCH_TEXT, }; class GURL; @@ -48,6 +49,8 @@ NTPTabOpeningPostOpeningAction postOpeningAction; // Boolean to track if a Payment Request response is requested at startup. @property(nonatomic, readwrite, assign) BOOL completePaymentRequest; +// Text query that should be executed on startup. +@property(nonatomic, readwrite, copy) NSString* textQuery; - (instancetype)init NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/app_startup_parameters.mm b/ios/chrome/browser/app_startup_parameters.mm index 55d34a8..d73b504 100644 --- a/ios/chrome/browser/app_startup_parameters.mm +++ b/ios/chrome/browser/app_startup_parameters.mm
@@ -24,6 +24,7 @@ @synthesize postOpeningAction = _postOpeningAction; @synthesize launchInIncognito = _launchInIncognito; @synthesize completePaymentRequest = _completePaymentRequest; +@synthesize textQuery = _textQuery; - (const GURL&)externalURL { return _externalURL; @@ -88,6 +89,9 @@ case FOCUS_OMNIBOX: [description appendString:@", should focus omnibox"]; break; + case SEARCH_TEXT: + [description appendString:@", should search for text"]; + break; default: break; }
diff --git a/ios/chrome/browser/ui/translate/BUILD.gn b/ios/chrome/browser/ui/translate/BUILD.gn index ad3499c5..019104f 100644 --- a/ios/chrome/browser/ui/translate/BUILD.gn +++ b/ios/chrome/browser/ui/translate/BUILD.gn
@@ -66,6 +66,7 @@ "//ios/chrome/browser/ui/translate/resources:translate_icon", "//ios/chrome/browser/ui/translate/resources:translate_options", "//ios/chrome/browser/ui/util", + "//ios/chrome/common:common_extension", "//ios/chrome/common/ui_util", "//ios/third_party/material_components_ios", "//ui/base",
diff --git a/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm b/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm index 61e3a00..c608a39 100644 --- a/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm +++ b/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm
@@ -9,10 +9,9 @@ #import "ios/chrome/browser/ui/translate/translate_infobar_language_tab_strip_view.h" #import "ios/chrome/browser/ui/translate/translate_infobar_language_tab_view_delegate.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" +#import "ios/chrome/common/highlight_button.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h" #import "ios/third_party/material_components_ios/src/components/ActivityIndicator/src/MaterialActivityIndicator.h" -#import "ios/third_party/material_components_ios/src/components/Buttons/src/MaterialButtons.h" -#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -29,12 +28,6 @@ // Duration to wait before changing visibility of subviews after they are added. const CGFloat kUpdateSubviewsDelay = 0.1; -// Duration of the animation to make the activity indicator visible. -const NSTimeInterval kActivityIndicatorVisbilityAnimationDuration = 0.4; - -// Title color of the action buttons in RGB. -const int kButtonTitleColor = 0x4285f4; - // Padding for contents of the button. const CGFloat kButtonPadding = 12; @@ -43,7 +36,7 @@ @interface TranslateInfobarLanguageTabView () // Button subview providing the tappable area. -@property(nonatomic, weak) MDCFlatButton* button; +@property(nonatomic, weak) UIButton* button; // Activity indicator replacing the button when in loading state. @property(nonatomic, weak) MDCActivityIndicator* activityIndicator; @@ -100,21 +93,16 @@ ]]; AddSameCenterConstraints(self, self.activityIndicator); - MDCFlatButton* button = [[MDCFlatButton alloc] init]; + UIButton* button = [[HighlightButton alloc] init]; self.button = button; self.button.translatesAutoresizingMaskIntoConstraints = NO; - [self.button setUnderlyingColorHint:[UIColor blackColor]]; self.button.contentEdgeInsets = UIEdgeInsetsMake( kButtonPadding, kButtonPadding, kButtonPadding, kButtonPadding); - self.button.titleLabel.adjustsFontSizeToFitWidth = YES; - self.button.titleLabel.minimumScaleFactor = 0.6f; [self.button setTitle:self.title forState:UIControlStateNormal]; - self.button.uppercaseTitle = NO; - [self.button - setTitleFont:[UIFont preferredFontForTextStyle:UIFontTextStyleHeadline] - forState:UIControlStateNormal]; + self.button.titleLabel.font = + [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; + self.button.titleLabel.adjustsFontForContentSizeCategory = YES; [self.button setTitleColor:[self titleColor] forState:UIControlStateNormal]; - self.button.inkColor = [[MDCPalette greyPalette] tint300]; [self.button addTarget:self action:@selector(buttonWasTapped) forControlEvents:UIControlEventTouchUpInside]; @@ -127,16 +115,11 @@ - (void)updateSubviewsForState:(TranslateInfobarLanguageTabViewState)state { if (state == TranslateInfobarLanguageTabViewStateLoading) { [self.activityIndicator startAnimating]; - // Animate showing the activity indicator and hiding the button. Otherwise - // the ripple effect on the button won't be seen. - [UIView animateWithDuration:kActivityIndicatorVisbilityAnimationDuration - animations:^{ - self.activityIndicator.alpha = 1.0; - self.button.alpha = 0.0; - }]; + self.activityIndicator.hidden = NO; + self.button.hidden = YES; } else { - self.button.alpha = 1.0; - self.activityIndicator.alpha = 0.0; + self.button.hidden = NO; + self.activityIndicator.hidden = YES; [self.activityIndicator stopAnimating]; [self.button setTitleColor:[self titleColor] forState:UIControlStateNormal]; @@ -146,7 +129,7 @@ // Returns the button's title color depending on the state. - (UIColor*)titleColor { return self.state == TranslateInfobarLanguageTabViewStateSelected - ? UIColorFromRGB(kButtonTitleColor) + ? [[MDCPalette cr_bluePalette] tint500] : [[MDCPalette greyPalette] tint600]; }
diff --git a/ios/chrome/browser/unified_consent/BUILD.gn b/ios/chrome/browser/unified_consent/BUILD.gn index 37f1254..c5af4b14 100644 --- a/ios/chrome/browser/unified_consent/BUILD.gn +++ b/ios/chrome/browser/unified_consent/BUILD.gn
@@ -5,8 +5,6 @@ source_set("unified_consent") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ - "unified_consent_service_client_impl.cc", - "unified_consent_service_client_impl.h", "unified_consent_service_factory.cc", "unified_consent_service_factory.h", ]
diff --git a/ios/chrome/browser/unified_consent/unified_consent_service_client_impl.cc b/ios/chrome/browser/unified_consent/unified_consent_service_client_impl.cc deleted file mode 100644 index 0f976c28..0000000 --- a/ios/chrome/browser/unified_consent/unified_consent_service_client_impl.cc +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ios/chrome/browser/unified_consent/unified_consent_service_client_impl.h" - -UnifiedConsentServiceClientImpl::ServiceState -UnifiedConsentServiceClientImpl::GetServiceState(Service service) { - switch (service) { - case Service::kSafeBrowsingExtendedReporting: - case Service::kSpellCheck: - case Service::kContextualSearch: - return ServiceState::kNotSupported; - } - NOTREACHED(); -} - -void UnifiedConsentServiceClientImpl::SetServiceEnabled(Service service, - bool enabled) { - if (GetServiceState(service) == ServiceState::kNotSupported) - return; - - NOTREACHED(); -}
diff --git a/ios/chrome/browser/unified_consent/unified_consent_service_client_impl.h b/ios/chrome/browser/unified_consent/unified_consent_service_client_impl.h deleted file mode 100644 index f92c010..0000000 --- a/ios/chrome/browser/unified_consent/unified_consent_service_client_impl.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UNIFIED_CONSENT_UNIFIED_CONSENT_SERVICE_CLIENT_IMPL_H_ -#define IOS_CHROME_BROWSER_UNIFIED_CONSENT_UNIFIED_CONSENT_SERVICE_CLIENT_IMPL_H_ - -#include "base/macros.h" -#include "components/unified_consent/unified_consent_service_client.h" - -// iOS implementation for UnifiedConsentServiceClient. -class UnifiedConsentServiceClientImpl - : public unified_consent::UnifiedConsentServiceClient { - public: - UnifiedConsentServiceClientImpl() = default; - ~UnifiedConsentServiceClientImpl() override = default; - - // unified_consent::UnifiedConsentServiceClient overrides: - ServiceState GetServiceState(Service service) override; - void SetServiceEnabled(Service service, bool enabled) override; - - DISALLOW_COPY_AND_ASSIGN(UnifiedConsentServiceClientImpl); -}; - -#endif // IOS_CHROME_BROWSER_UNIFIED_CONSENT_UNIFIED_CONSENT_SERVICE_CLIENT_IMPL_H_
diff --git a/ios/chrome/browser/unified_consent/unified_consent_service_factory.cc b/ios/chrome/browser/unified_consent/unified_consent_service_factory.cc index 26aa859..be31447 100644 --- a/ios/chrome/browser/unified_consent/unified_consent_service_factory.cc +++ b/ios/chrome/browser/unified_consent/unified_consent_service_factory.cc
@@ -13,7 +13,6 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" #include "ios/chrome/browser/sync/profile_sync_service_factory.h" -#include "ios/chrome/browser/unified_consent/unified_consent_service_client_impl.h" UnifiedConsentServiceFactory::UnifiedConsentServiceFactory() : BrowserStateKeyedServiceFactory( @@ -53,8 +52,6 @@ ios::ChromeBrowserState* browser_state = ios::ChromeBrowserState::FromBrowserState(context); PrefService* user_pref_service = browser_state->GetPrefs(); - std::unique_ptr<unified_consent::UnifiedConsentServiceClient> service_client = - std::make_unique<UnifiedConsentServiceClientImpl>(); identity::IdentityManager* identity_manager = IdentityManagerFactory::GetForBrowserState(browser_state); @@ -62,16 +59,14 @@ ProfileSyncServiceFactory::GetForBrowserState(browser_state); // Record settings for pre- and post-UnifiedConsent users. - unified_consent::metrics::RecordSettingsHistogram(service_client.get(), - user_pref_service); + unified_consent::metrics::RecordSettingsHistogram(user_pref_service); if (!unified_consent::IsUnifiedConsentFeatureEnabled()) { - unified_consent::UnifiedConsentService::RollbackIfNeeded( - user_pref_service, sync_service, service_client.get()); + unified_consent::UnifiedConsentService::RollbackIfNeeded(user_pref_service, + sync_service); return nullptr; } return std::make_unique<unified_consent::UnifiedConsentService>( - std::move(service_client), user_pref_service, identity_manager, - sync_service); + user_pref_service, identity_manager, sync_service); }
diff --git a/ios/chrome/common/app_group/app_group_constants.h b/ios/chrome/common/app_group/app_group_constants.h index 2bf4cc4..09e2afe 100644 --- a/ios/chrome/common/app_group/app_group_constants.h +++ b/ios/chrome/common/app_group/app_group_constants.h
@@ -45,6 +45,9 @@ // The command to open a URL. Parameter must contain the URL. extern const char kChromeAppGroupOpenURLCommand[]; +// The command to search some text. Parameter must contain the text. +extern const char kChromeAppGroupSearchTextCommand[]; + // The command to trigger a voice search. extern const char kChromeAppGroupVoiceSearchCommand[]; @@ -64,9 +67,9 @@ // |kChromeAppGroupCommandAppPreference| issued the command. extern const char kChromeAppGroupCommandTimePreference[]; -// The key in kChromeAppGroupCommandPreference containing the URL to open for if -// the command requires one. -extern const char kChromeAppGroupCommandURLPreference[]; +// The key in kChromeAppGroupCommandPreference containing the text use for the +// command if it requires one. This could be a URL, a string, etc. +extern const char kChromeAppGroupCommandTextPreference[]; // The key in kChromeAppGroupCommandPreference containing the index to open for // if the command requires one.
diff --git a/ios/chrome/common/app_group/app_group_constants.mm b/ios/chrome/common/app_group/app_group_constants.mm index 676179e7..7868c32 100644 --- a/ios/chrome/common/app_group/app_group_constants.mm +++ b/ios/chrome/common/app_group/app_group_constants.mm
@@ -23,10 +23,11 @@ const char kChromeAppGroupCommandTimePreference[] = "CommandTime"; const char kChromeAppGroupCommandAppPreference[] = "SourceApp"; const char kChromeAppGroupCommandCommandPreference[] = "Command"; -const char kChromeAppGroupCommandURLPreference[] = "URL"; +const char kChromeAppGroupCommandTextPreference[] = "Text"; const char kChromeAppGroupCommandIndexPreference[] = "Index"; const char kChromeAppGroupOpenURLCommand[] = "openurl"; +const char kChromeAppGroupSearchTextCommand[] = "searchtext"; const char kChromeAppGroupVoiceSearchCommand[] = "voicesearch"; const char kChromeAppGroupNewTabCommand[] = "newtab"; const char kChromeAppGroupFocusOmniboxCommand[] = "focusomnibox";
diff --git a/ios/chrome/content_widget_extension/content_widget_view_controller.mm b/ios/chrome/content_widget_extension/content_widget_view_controller.mm index 09b89ad..15cd316 100644 --- a/ios/chrome/content_widget_extension/content_widget_view_controller.mm +++ b/ios/chrome/content_widget_extension/content_widget_view_controller.mm
@@ -174,8 +174,8 @@ base::SysUTF8ToNSString(app_group::kChromeAppGroupCommandAppPreference); NSString* commandPrefKey = base::SysUTF8ToNSString( app_group::kChromeAppGroupCommandCommandPreference); - NSString* URLPrefKey = - base::SysUTF8ToNSString(app_group::kChromeAppGroupCommandURLPreference); + NSString* textPrefKey = + base::SysUTF8ToNSString(app_group::kChromeAppGroupCommandTextPreference); NSString* indexKey = base::SysUTF8ToNSString(app_group::kChromeAppGroupCommandIndexPreference); @@ -184,7 +184,7 @@ appPrefKey : app_group::kOpenCommandSourceContentExtension, commandPrefKey : base::SysUTF8ToNSString(app_group::kChromeAppGroupOpenURLCommand), - URLPrefKey : URL.absoluteString, + textPrefKey : URL.absoluteString, indexKey : [NSNumber numberWithInt:[self.sites objectForKey:URL].position] };
diff --git a/ios/chrome/search_widget_extension/BUILD.gn b/ios/chrome/search_widget_extension/BUILD.gn index f29eaa8..946289ae 100644 --- a/ios/chrome/search_widget_extension/BUILD.gn +++ b/ios/chrome/search_widget_extension/BUILD.gn
@@ -8,8 +8,8 @@ import("//build/mac/tweak_info_plist.gni") import("//ios/build/chrome_build.gni") import("//ios/build/config.gni") -import("//tools/grit/repack.gni") import("//ios/chrome/tools/strings/generate_localizable_strings.gni") +import("//tools/grit/repack.gni") tweak_info_plist("tweak_info_plist") { info_plist = "Info.plist" @@ -46,8 +46,8 @@ source_set("search_widget") { sources = [ - "copied_url_view.h", - "copied_url_view.mm", + "copied_content_view.h", + "copied_content_view.mm", "search_action_view.h", "search_action_view.mm", "search_widget_view.h",
diff --git a/ios/chrome/search_widget_extension/copied_url_view.h b/ios/chrome/search_widget_extension/copied_content_view.h similarity index 64% rename from ios/chrome/search_widget_extension/copied_url_view.h rename to ios/chrome/search_widget_extension/copied_content_view.h index c26c325..01255ac 100644 --- a/ios/chrome/search_widget_extension/copied_url_view.h +++ b/ios/chrome/search_widget_extension/copied_content_view.h
@@ -2,22 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_SEARCH_WIDGET_EXTENSION_COPIED_URL_VIEW_H_ -#define IOS_CHROME_SEARCH_WIDGET_EXTENSION_COPIED_URL_VIEW_H_ +#ifndef IOS_CHROME_SEARCH_WIDGET_EXTENSION_COPIED_CONTENT_VIEW_H_ +#define IOS_CHROME_SEARCH_WIDGET_EXTENSION_COPIED_CONTENT_VIEW_H_ #import <UIKit/UIKit.h> #import "ios/chrome/common/highlight_button.h" +typedef NS_ENUM(NSInteger, CopiedContentType) { + CopiedContentTypeNone, + CopiedContentTypeURL, + CopiedContentTypeString, +}; + // View to show and allow opening of the copied URL. Shows a button with the // |copiedURLString| if it has been set. When tapped, |actionSelector| in // |target| is called. If no |copiedURLString| was set, the button is replaced // by a hairline separation and placeholder text. -@interface CopiedURLView : HighlightButton - -// The copied URL string to be displayed. nil is a valid value to indicate -// there is no copied URL to display. -@property(nonatomic, copy) NSString* copiedURLString; +@interface CopiedContentView : HighlightButton // Designated initializer, creates the copiedURLView with a |target| to open the // URL. @@ -27,6 +29,9 @@ - (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; - (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; +- (void)setCopiedContentType:(CopiedContentType)type + copiedText:(NSString*)copiedText; + @end -#endif // IOS_CHROME_SEARCH_WIDGET_EXTENSION_COPIED_URL_VIEW_H_ +#endif // IOS_CHROME_SEARCH_WIDGET_EXTENSION_COPIED_CONTENT_VIEW_H_
diff --git a/ios/chrome/search_widget_extension/copied_content_view.mm b/ios/chrome/search_widget_extension/copied_content_view.mm new file mode 100644 index 0000000..db5b381 --- /dev/null +++ b/ios/chrome/search_widget_extension/copied_content_view.mm
@@ -0,0 +1,197 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/search_widget_extension/copied_content_view.h" + +#import <NotificationCenter/NotificationCenter.h> + +#include "base/logging.h" +#import "ios/chrome/search_widget_extension/ui_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { + +const CGFloat kURLButtonMargin = 10; + +} // namespace + +@interface CopiedContentView () + +// The type of the copied content +@property(nonatomic) CopiedContentType type; +// The copied text to be displayed if the type supports showing the string. +@property(nonatomic, copy) NSString* copiedText; +// The copied URL label containing the URL or a placeholder text. +@property(nonatomic, strong) UILabel* copiedContentLabel; +// The copied URL title label containing the title of the copied URL button. +@property(nonatomic, strong) UILabel* openCopiedContentTitleLabel; +// The hairline view potentially shown at the top of the copied URL view. +@property(nonatomic, strong) UIView* hairlineView; +// The button-shaped background view shown when there is a copied URL to open. +@property(nonatomic, strong) UIView* copiedButtonView; + +// Updates the view to show the currently set |type| and |copiedText|. +- (void)updateUI; + +@end + +@implementation CopiedContentView + +@synthesize copiedContentLabel = _copiedContentLabel; +@synthesize copiedText = _copiedText; +@synthesize openCopiedContentTitleLabel = _openCopiedContentTitleLabel; +@synthesize hairlineView = _hairlineView; +@synthesize copiedButtonView = _copiedButtonView; + +- (instancetype)initWithActionTarget:(id)target + actionSelector:(SEL)actionSelector { + DCHECK(target); + self = [super initWithFrame:CGRectZero]; + if (self) { + self.translatesAutoresizingMaskIntoConstraints = NO; + + [self addTarget:target + action:actionSelector + forControlEvents:UIControlEventTouchUpInside]; + + UIVibrancyEffect* primaryEffect = + [UIVibrancyEffect widgetPrimaryVibrancyEffect]; + UIVibrancyEffect* secondaryEffect = + [UIVibrancyEffect widgetSecondaryVibrancyEffect]; + + UIVisualEffectView* primaryEffectView = + [[UIVisualEffectView alloc] initWithEffect:primaryEffect]; + UIVisualEffectView* secondaryEffectView = + [[UIVisualEffectView alloc] initWithEffect:secondaryEffect]; + for (UIVisualEffectView* effectView in + @[ primaryEffectView, secondaryEffectView ]) { + [self addSubview:effectView]; + effectView.translatesAutoresizingMaskIntoConstraints = NO; + [NSLayoutConstraint + activateConstraints:ui_util::CreateSameConstraints(self, effectView)]; + effectView.userInteractionEnabled = NO; + } + + _hairlineView = [[UIView alloc] initWithFrame:CGRectZero]; + _hairlineView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.05]; + _hairlineView.translatesAutoresizingMaskIntoConstraints = NO; + [secondaryEffectView.contentView addSubview:_hairlineView]; + + _copiedButtonView = [[UIView alloc] init]; + _copiedButtonView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.05]; + _copiedButtonView.layer.cornerRadius = 5; + _copiedButtonView.translatesAutoresizingMaskIntoConstraints = NO; + [secondaryEffectView.contentView addSubview:_copiedButtonView]; + + _openCopiedContentTitleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + _openCopiedContentTitleLabel.textAlignment = NSTextAlignmentCenter; + _openCopiedContentTitleLabel.translatesAutoresizingMaskIntoConstraints = NO; + _openCopiedContentTitleLabel.font = + [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; + [primaryEffectView.contentView addSubview:_openCopiedContentTitleLabel]; + + _copiedContentLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + _copiedContentLabel.textAlignment = NSTextAlignmentCenter; + _copiedContentLabel.font = + [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; + _copiedContentLabel.translatesAutoresizingMaskIntoConstraints = NO; + [secondaryEffectView.contentView addSubview:_copiedContentLabel]; + + [NSLayoutConstraint activateConstraints:@[ + [_hairlineView.topAnchor constraintEqualToAnchor:self.topAnchor], + [_hairlineView.leftAnchor constraintEqualToAnchor:self.leftAnchor], + [_hairlineView.rightAnchor constraintEqualToAnchor:self.rightAnchor], + [_hairlineView.heightAnchor constraintEqualToConstant:0.5], + + [_copiedButtonView.leadingAnchor + constraintEqualToAnchor:self.leadingAnchor + constant:ui_util::kContentMargin], + [_copiedButtonView.trailingAnchor + constraintEqualToAnchor:self.trailingAnchor + constant:-ui_util::kContentMargin], + [_copiedButtonView.topAnchor + constraintEqualToAnchor:self.topAnchor + constant:ui_util::kContentMargin], + [_copiedButtonView.bottomAnchor + constraintEqualToAnchor:self.bottomAnchor + constant:-ui_util::kContentMargin], + + [_openCopiedContentTitleLabel.topAnchor + constraintEqualToAnchor:_copiedButtonView.topAnchor + constant:kURLButtonMargin], + [_openCopiedContentTitleLabel.leadingAnchor + constraintEqualToAnchor:_copiedButtonView.leadingAnchor + constant:ui_util::kContentMargin], + [_openCopiedContentTitleLabel.trailingAnchor + constraintEqualToAnchor:_copiedButtonView.trailingAnchor + constant:-ui_util::kContentMargin], + + [_copiedContentLabel.topAnchor + constraintEqualToAnchor:_openCopiedContentTitleLabel.bottomAnchor], + [_copiedContentLabel.bottomAnchor + constraintEqualToAnchor:_copiedButtonView.bottomAnchor + constant:-kURLButtonMargin], + [_copiedContentLabel.leadingAnchor + constraintEqualToAnchor:_openCopiedContentTitleLabel.leadingAnchor], + [_copiedContentLabel.trailingAnchor + constraintEqualToAnchor:_openCopiedContentTitleLabel.trailingAnchor], + ]]; + [self setCopiedContentType:CopiedContentTypeNone copiedText:nil]; + } + return self; +} + +- (void)setCopiedContentType:(CopiedContentType)type + copiedText:(NSString*)copiedText { + self.type = type; + self.copiedText = copiedText; + [self updateUI]; +} + +- (void)updateUI { + BOOL hasContent = self.type != CopiedContentTypeNone; + self.userInteractionEnabled = hasContent; + self.copiedButtonView.hidden = !hasContent; + self.hairlineView.hidden = hasContent; + self.accessibilityTraits = + (hasContent) ? UIAccessibilityTraitLink : UIAccessibilityTraitNone; + self.copiedContentLabel.alpha = (hasContent) ? 1 : 0.5; + self.openCopiedContentTitleLabel.alpha = (hasContent) ? 1 : 0.5; + + NSString* titleText; + NSString* contentText; + switch (self.type) { + case CopiedContentTypeNone: { + titleText = NSLocalizedString(@"IDS_IOS_NO_COPIED_CONTENT_TITLE", nil); + contentText = + NSLocalizedString(@"IDS_IOS_NO_COPIED_CONTENT_MESSAGE", nil); + break; + } + case CopiedContentTypeURL: { + titleText = NSLocalizedString(@"IDS_IOS_OPEN_COPIED_LINK", nil); + contentText = self.copiedText; + break; + } + case CopiedContentTypeString: { + titleText = NSLocalizedString(@"IDS_IOS_OPEN_COPIED_TEXT", nil); + contentText = self.copiedText; + break; + } + } + self.openCopiedContentTitleLabel.text = titleText; + self.copiedContentLabel.text = contentText; + NSMutableArray<NSString*>* accessibilityPieces = + [[NSMutableArray alloc] init]; + [accessibilityPieces addObject:titleText]; + if (contentText) { + [accessibilityPieces addObject:contentText]; + } + self.accessibilityLabel = + [accessibilityPieces componentsJoinedByString:@" - "]; +} + +@end
diff --git a/ios/chrome/search_widget_extension/copied_url_view.mm b/ios/chrome/search_widget_extension/copied_url_view.mm deleted file mode 100644 index 5b7f9ab..0000000 --- a/ios/chrome/search_widget_extension/copied_url_view.mm +++ /dev/null
@@ -1,190 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/search_widget_extension/copied_url_view.h" - -#import <NotificationCenter/NotificationCenter.h> - -#include "base/logging.h" -#import "ios/chrome/search_widget_extension/ui_util.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { - -const CGFloat kURLButtonMargin = 10; - -} // namespace - -@interface CopiedURLView () - -// The copied URL label containing the URL or a placeholder text. -@property(nonatomic, strong) UILabel* copiedURLLabel; -// The copied URL title label containing the title of the copied URL button. -@property(nonatomic, strong) UILabel* openCopiedURLTitleLabel; -// The hairline view potentially shown at the top of the copied URL view. -@property(nonatomic, strong) UIView* hairlineView; -// The button-shaped background view shown when there is a copied URL to open. -@property(nonatomic, strong) UIView* copiedButtonView; - -// Updates the view to show the copied URL in a button. -- (void)updateUICopiedURL; - -// Updates the view to show that there is no copied URL, with no button and a -// hairline at the top of the view. -- (void)updateUINoCopiedURL; - -@end - -@implementation CopiedURLView - -- (void)setCopiedURLString:(NSString*)copiedURL { - _copiedURLString = copiedURL; - if (copiedURL) { - [self updateUICopiedURL]; - } else { - [self updateUINoCopiedURL]; - } -} - -@synthesize copiedURLLabel = _copiedURLLabel; -@synthesize copiedURLString = _copiedURLString; -@synthesize openCopiedURLTitleLabel = _openCopiedURLTitleLabel; -@synthesize hairlineView = _hairlineView; -@synthesize copiedButtonView = _copiedButtonView; - -- (instancetype)initWithActionTarget:(id)target - actionSelector:(SEL)actionSelector { - DCHECK(target); - self = [super initWithFrame:CGRectZero]; - if (self) { - self.translatesAutoresizingMaskIntoConstraints = NO; - - [self addTarget:target - action:actionSelector - forControlEvents:UIControlEventTouchUpInside]; - - UIVibrancyEffect* primaryEffect = - [UIVibrancyEffect widgetPrimaryVibrancyEffect]; - UIVibrancyEffect* secondaryEffect = - [UIVibrancyEffect widgetSecondaryVibrancyEffect]; - - UIVisualEffectView* primaryEffectView = - [[UIVisualEffectView alloc] initWithEffect:primaryEffect]; - UIVisualEffectView* secondaryEffectView = - [[UIVisualEffectView alloc] initWithEffect:secondaryEffect]; - for (UIVisualEffectView* effectView in - @[ primaryEffectView, secondaryEffectView ]) { - [self addSubview:effectView]; - effectView.translatesAutoresizingMaskIntoConstraints = NO; - [NSLayoutConstraint - activateConstraints:ui_util::CreateSameConstraints(self, effectView)]; - effectView.userInteractionEnabled = NO; - } - - _hairlineView = [[UIView alloc] initWithFrame:CGRectZero]; - _hairlineView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.05]; - _hairlineView.translatesAutoresizingMaskIntoConstraints = NO; - [secondaryEffectView.contentView addSubview:_hairlineView]; - - _copiedButtonView = [[UIView alloc] init]; - _copiedButtonView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.05]; - _copiedButtonView.layer.cornerRadius = 5; - _copiedButtonView.translatesAutoresizingMaskIntoConstraints = NO; - [secondaryEffectView.contentView addSubview:_copiedButtonView]; - - _openCopiedURLTitleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - _openCopiedURLTitleLabel.textAlignment = NSTextAlignmentCenter; - _openCopiedURLTitleLabel.translatesAutoresizingMaskIntoConstraints = NO; - _openCopiedURLTitleLabel.font = - [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; - [primaryEffectView.contentView addSubview:_openCopiedURLTitleLabel]; - - _copiedURLLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - _copiedURLLabel.textAlignment = NSTextAlignmentCenter; - _copiedURLLabel.font = - [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; - _copiedURLLabel.translatesAutoresizingMaskIntoConstraints = NO; - [secondaryEffectView.contentView addSubview:_copiedURLLabel]; - - [NSLayoutConstraint activateConstraints:@[ - [_hairlineView.topAnchor constraintEqualToAnchor:self.topAnchor], - [_hairlineView.leftAnchor constraintEqualToAnchor:self.leftAnchor], - [_hairlineView.rightAnchor constraintEqualToAnchor:self.rightAnchor], - [_hairlineView.heightAnchor constraintEqualToConstant:0.5], - - [_copiedButtonView.leadingAnchor - constraintEqualToAnchor:self.leadingAnchor - constant:ui_util::kContentMargin], - [_copiedButtonView.trailingAnchor - constraintEqualToAnchor:self.trailingAnchor - constant:-ui_util::kContentMargin], - [_copiedButtonView.topAnchor - constraintEqualToAnchor:self.topAnchor - constant:ui_util::kContentMargin], - [_copiedButtonView.bottomAnchor - constraintEqualToAnchor:self.bottomAnchor - constant:-ui_util::kContentMargin], - - [_openCopiedURLTitleLabel.topAnchor - constraintEqualToAnchor:_copiedButtonView.topAnchor - constant:kURLButtonMargin], - [_openCopiedURLTitleLabel.leadingAnchor - constraintEqualToAnchor:_copiedButtonView.leadingAnchor - constant:ui_util::kContentMargin], - [_openCopiedURLTitleLabel.trailingAnchor - constraintEqualToAnchor:_copiedButtonView.trailingAnchor - constant:-ui_util::kContentMargin], - - [_copiedURLLabel.topAnchor - constraintEqualToAnchor:_openCopiedURLTitleLabel.bottomAnchor], - [_copiedURLLabel.bottomAnchor - constraintEqualToAnchor:_copiedButtonView.bottomAnchor - constant:-kURLButtonMargin], - [_copiedURLLabel.leadingAnchor - constraintEqualToAnchor:_openCopiedURLTitleLabel.leadingAnchor], - [_copiedURLLabel.trailingAnchor - constraintEqualToAnchor:_openCopiedURLTitleLabel.trailingAnchor], - ]]; - [self updateUINoCopiedURL]; - } - return self; -} - -- (void)updateUICopiedURL { - self.copiedButtonView.hidden = NO; - self.hairlineView.hidden = YES; - self.copiedURLLabel.text = self.copiedURLString; - self.openCopiedURLTitleLabel.alpha = 1; - self.openCopiedURLTitleLabel.text = - NSLocalizedString(@"IDS_IOS_OPEN_COPIED_LINK", nil); - self.copiedURLLabel.alpha = 1; - self.userInteractionEnabled = YES; - self.accessibilityLabel = [NSString - stringWithFormat:@"%@ - %@", - NSLocalizedString(@"IDS_IOS_OPEN_COPIED_LINK", nil), - self.copiedURLString]; - self.accessibilityTraits = UIAccessibilityTraitLink; -} - -- (void)updateUINoCopiedURL { - self.userInteractionEnabled = NO; - self.copiedButtonView.hidden = YES; - self.hairlineView.hidden = NO; - self.copiedURLLabel.text = - NSLocalizedString(@"IDS_IOS_NO_COPIED_LINK_MESSAGE", nil); - self.accessibilityLabel = - NSLocalizedString(@"IDS_IOS_NO_COPIED_LINK_MESSAGE", nil); - self.openCopiedURLTitleLabel.text = - NSLocalizedString(@"IDS_IOS_NO_COPIED_LINK_TITLE", nil); - self.accessibilityLabel = - NSLocalizedString(@"IDS_IOS_NO_COPIED_LINK_TITLE", nil); - self.accessibilityTraits = UIAccessibilityTraitNone; - self.copiedURLLabel.alpha = 0.5; - self.openCopiedURLTitleLabel.alpha = 0.5; -} - -@end
diff --git a/ios/chrome/search_widget_extension/search_widget_extension_localize_strings_config.plist b/ios/chrome/search_widget_extension/search_widget_extension_localize_strings_config.plist index aa477f3..8e4851a 100644 --- a/ios/chrome/search_widget_extension/search_widget_extension_localize_strings_config.plist +++ b/ios/chrome/search_widget_extension/search_widget_extension_localize_strings_config.plist
@@ -18,9 +18,10 @@ <string>IDS_IOS_INCOGNITO_SEARCH</string> <string>IDS_IOS_VOICE_SEARCH</string> <string>IDS_IOS_SCAN_QR_CODE</string> - <string>IDS_IOS_NO_COPIED_LINK_TITLE</string> - <string>IDS_IOS_NO_COPIED_LINK_MESSAGE</string> + <string>IDS_IOS_NO_COPIED_CONTENT_TITLE</string> + <string>IDS_IOS_NO_COPIED_CONTENT_MESSAGE</string> <string>IDS_IOS_OPEN_COPIED_LINK</string> + <string>IDS_IOS_OPEN_COPIED_TEXT</string> </array> </dict> <dict>
diff --git a/ios/chrome/search_widget_extension/search_widget_view.h b/ios/chrome/search_widget_extension/search_widget_view.h index b9382ba..e1b8faf 100644 --- a/ios/chrome/search_widget_extension/search_widget_view.h +++ b/ios/chrome/search_widget_extension/search_widget_view.h
@@ -7,6 +7,8 @@ #import <UIKit/UIKit.h> +typedef NS_ENUM(NSInteger, CopiedContentType); + // Protocol to be implemented by targets for user actions coming from the search // widget view. @protocol SearchWidgetViewActionTarget @@ -20,7 +22,7 @@ // Called when the user taps the QR Code button. - (void)openQRCode:(id)sender; // Called when the user taps the Open Copied URL section. -- (void)openCopiedURL:(id)sender; +- (void)openCopiedContent:(id)sender; @end @@ -42,9 +44,10 @@ // Gets the height of the widget. - (CGFloat)widgetHeight; -// Sets the copied URL string to be displayed. nil is a valid value to indicate -// there is no copied URL to display. -- (void)setCopiedURLString:(NSString*)URL; +// Sets the copied content type. |copiedText| should be provided if the content +// type requires textual data, otherwise it should be nil. +- (void)setCopiedContentType:(CopiedContentType)type + copiedText:(NSString*)copiedText; @end
diff --git a/ios/chrome/search_widget_extension/search_widget_view.mm b/ios/chrome/search_widget_extension/search_widget_view.mm index cf96319..ca8c427 100644 --- a/ios/chrome/search_widget_extension/search_widget_view.mm +++ b/ios/chrome/search_widget_extension/search_widget_view.mm
@@ -4,7 +4,7 @@ #import "ios/chrome/search_widget_extension/search_widget_view.h" #include "base/logging.h" -#import "ios/chrome/search_widget_extension/copied_url_view.h" +#import "ios/chrome/search_widget_extension/copied_content_view.h" #import "ios/chrome/search_widget_extension/search_action_view.h" #import "ios/chrome/search_widget_extension/ui_util.h" @@ -24,7 +24,7 @@ // The actions section. Can be bigger than the content within. @property(nonatomic, strong) UIView* actionsSection; // The copied URL section. Fits its contents. -@property(nonatomic, strong) CopiedURLView* copiedURLSection; +@property(nonatomic, strong) CopiedContentView* copiedURLSection; // The height used in the compact display mode. @property(nonatomic) CGFloat compactHeight; // The target for actions in the view. @@ -79,9 +79,9 @@ _actionsSection.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:_actionsSection]; - _copiedURLSection = - [[CopiedURLView alloc] initWithActionTarget:self.target - actionSelector:@selector(openCopiedURL:)]; + _copiedURLSection = [[CopiedContentView alloc] + initWithActionTarget:self.target + actionSelector:@selector(openCopiedContent:)]; [self addSubview:_copiedURLSection]; _actionsSectionHeightConstraint = [self.actionsSection.heightAnchor @@ -217,8 +217,9 @@ return [self actionContentHeight] + [self copiedURLSectionHeight]; } -- (void)setCopiedURLString:(NSString*)URL { - [self.copiedURLSection setCopiedURLString:URL]; +- (void)setCopiedContentType:(CopiedContentType)type + copiedText:(NSString*)copiedText { + [self.copiedURLSection setCopiedContentType:type copiedText:copiedText]; } @end
diff --git a/ios/chrome/search_widget_extension/search_widget_view_controller.mm b/ios/chrome/search_widget_extension/search_widget_view_controller.mm index 50266f85..3646c314 100644 --- a/ios/chrome/search_widget_extension/search_widget_view_controller.mm +++ b/ios/chrome/search_widget_extension/search_widget_view_controller.mm
@@ -10,7 +10,7 @@ #include "ios/chrome/common/app_group/app_group_constants.h" #include "ios/chrome/common/app_group/app_group_metrics.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h" -#import "ios/chrome/search_widget_extension/copied_url_view.h" +#import "ios/chrome/search_widget_extension/copied_content_view.h" #import "ios/chrome/search_widget_extension/search_widget_view.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -27,7 +27,8 @@ @interface SearchWidgetViewController ()<SearchWidgetViewActionTarget> @property(nonatomic, weak) SearchWidgetView* widgetView; -@property(nonatomic, strong) NSURL* copiedURL; +@property(nonatomic, strong, nullable) NSString* copiedText; +@property(nonatomic) CopiedContentType copiedContentType; @property(nonatomic, strong) ClipboardRecentContentImplIOS* clipboardRecentContent; @@ -36,22 +37,28 @@ - (BOOL)updateWidget; // Opens the main application with the given |command|. - (void)openAppWithCommand:(NSString*)command; -// Opens the main application with the given |command| and |URL|. -- (void)openAppWithCommand:(NSString*)command URL:(NSString*)URL; +// Opens the main application with the given |command| and |text|. +- (void)openAppWithCommand:(NSString*)command text:(NSString*)text; // Returns the dictionary of commands to pass via user defaults to open the main -// application for a given |command| and optional |URL|. -+ (NSDictionary*)dictForCommand:(NSString*)command URL:(NSString*)URL; +// application for a given |command| and optional |text|. ++ (NSDictionary*)dictForCommand:(NSString*)command text:(NSString*)text; // Register a display of the widget in the app_group NSUserDefaults. // Metrics on the widget usage will be sent (if enabled) on the next Chrome // startup. - (void)registerWidgetDisplay; +// Sets the copied content type. |copiedText| should be provided if the content +// type requires textual data, otherwise it should be nil. Also saves the data +// and returns YES if the screen needs updating and NO otherwise. +- (BOOL)setCopiedContentType:(CopiedContentType)type + copiedText:(NSString*)copiedText; @end @implementation SearchWidgetViewController @synthesize widgetView = _widgetView; -@synthesize copiedURL = _copiedURL; +@synthesize copiedText = _copiedText; +@synthesize copiedContentType = _copiedContentType; @synthesize clipboardRecentContent = _clipboardRecentContent; - (instancetype)init { @@ -62,6 +69,7 @@ authorizedSchemes:[NSSet setWithObjects:@"http", @"https", nil] userDefaults:app_group::GetGroupUserDefaults() delegate:nil]; + _copiedContentType = CopiedContentTypeNone; } return self; } @@ -112,14 +120,19 @@ } - (BOOL)updateWidget { - NSURL* url = [_clipboardRecentContent recentURLFromClipboard]; + NSString* copiedText; + CopiedContentType type = CopiedContentTypeNone; - if (![url isEqual:self.copiedURL]) { - self.copiedURL = url; - [self.widgetView setCopiedURLString:self.copiedURL.absoluteString]; - return YES; + if (NSURL* url = [self.clipboardRecentContent recentURLFromClipboard]) { + copiedText = url.absoluteString; + type = CopiedContentTypeURL; + } else if (NSString* text = + [self.clipboardRecentContent recentTextFromClipboard]) { + copiedText = text; + type = CopiedContentTypeString; } - return NO; + + return [self setCopiedContentType:type copiedText:copiedText]; } - (void)viewWillTransitionToSize:(CGSize)size @@ -178,17 +191,29 @@ app_group::kChromeAppGroupQRScannerCommand)]; } -- (void)openCopiedURL:(id)sender { - DCHECK(self.copiedURL); - [self openAppWithCommand:base::SysUTF8ToNSString( - app_group::kChromeAppGroupOpenURLCommand) - URL:self.copiedURL.absoluteString]; +- (void)openCopiedContent:(id)sender { + DCHECK(self.copiedText); + NSString* command; + switch (self.copiedContentType) { + case CopiedContentTypeURL: + command = + base::SysUTF8ToNSString(app_group::kChromeAppGroupOpenURLCommand); + break; + case CopiedContentTypeString: + command = + base::SysUTF8ToNSString(app_group::kChromeAppGroupSearchTextCommand); + break; + case CopiedContentTypeNone: + NOTREACHED(); + return; + } + [self openAppWithCommand:command text:self.copiedText]; } #pragma mark - internal - (void)openAppWithCommand:(NSString*)command { - return [self openAppWithCommand:command URL:nil]; + return [self openAppWithCommand:command text:nil]; } - (void)registerWidgetDisplay { @@ -199,13 +224,13 @@ forKey:app_group::kSearchExtensionDisplayCount]; } -- (void)openAppWithCommand:(NSString*)command URL:(NSString*)URL { +- (void)openAppWithCommand:(NSString*)command text:(NSString*)text { NSUserDefaults* sharedDefaults = app_group::GetGroupUserDefaults(); NSString* defaultsKey = base::SysUTF8ToNSString(app_group::kChromeAppGroupCommandPreference); - [sharedDefaults - setObject:[SearchWidgetViewController dictForCommand:command URL:URL] - forKey:defaultsKey]; + [sharedDefaults setObject:[SearchWidgetViewController dictForCommand:command + text:text] + forKey:defaultsKey]; [sharedDefaults synchronize]; NSString* scheme = base::mac::ObjCCast<NSString>([[NSBundle mainBundle] @@ -224,7 +249,7 @@ [self.extensionContext openURL:openURL completionHandler:nil]; } -+ (NSDictionary*)dictForCommand:(NSString*)command URL:(NSString*)URL { ++ (NSDictionary*)dictForCommand:(NSString*)command text:(NSString*)text { NSString* timePrefKey = base::SysUTF8ToNSString(app_group::kChromeAppGroupCommandTimePreference); NSString* appPrefKey = @@ -232,14 +257,14 @@ NSString* commandPrefKey = base::SysUTF8ToNSString( app_group::kChromeAppGroupCommandCommandPreference); - if (URL) { - NSString* URLPrefKey = - base::SysUTF8ToNSString(app_group::kChromeAppGroupCommandURLPreference); + if (text) { + NSString* textPrefKey = base::SysUTF8ToNSString( + app_group::kChromeAppGroupCommandTextPreference); return @{ timePrefKey : [NSDate date], appPrefKey : app_group::kOpenCommandSourceSearchExtension, commandPrefKey : command, - URLPrefKey : URL, + textPrefKey : text, }; } return @{ @@ -249,4 +274,17 @@ }; } +- (BOOL)setCopiedContentType:(CopiedContentType)type + copiedText:(NSString*)copiedText { + if (self.copiedContentType == type && + [self.copiedText isEqualToString:copiedText]) { + return NO; + } + self.copiedContentType = type; + self.copiedText = copiedText; + [self.widgetView setCopiedContentType:self.copiedContentType + copiedText:self.copiedText]; + return YES; +} + @end
diff --git a/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings.grd b/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings.grd index 501f9888..ada8007 100644 --- a/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings.grd +++ b/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings.grd
@@ -142,14 +142,17 @@ <message name="IDS_IOS_SCAN_QR_CODE" desc="Label in the widget extension for the action to launch the app and open the qr code scanner. [Length: 30em]"> Scan QR Code </message> - <message name="IDS_IOS_NO_COPIED_LINK_TITLE" desc="Label in the widget extension for the title of the copied link section when there is no copied link."> - No Copied Link + <message name="IDS_IOS_NO_COPIED_CONTENT_TITLE" desc="Label in the widget extension for the title of the copied content section when there is no copied content."> + Nothing in clipboard </message> - <message name="IDS_IOS_NO_COPIED_LINK_MESSAGE" desc="Label in the widget extension for the message shown in the copied link section when there is no copied link."> - Links you copy will appear here. + <message name="IDS_IOS_NO_COPIED_CONTENT_MESSAGE" desc="Label in the widget extension for the message shown in the copied link section when there is no copied content."> + Content you copy will appear here. </message> - <message name="IDS_IOS_OPEN_COPIED_LINK" desc="Label in the widget extension for the title of the copied link section when there is a copied link displayed."> - Open Copied Link + <message name="IDS_IOS_OPEN_COPIED_LINK" desc="Label in the widget extension for the title of the copied content section when there is a copied link displayed."> + Visit Link You Copied + </message> + <message name="IDS_IOS_OPEN_COPIED_TEXT" desc="Label in the widget extension for the title of the copied content section when there is copied text displayed."> + Search for Text You Copied </message> </messages> </release>
diff --git a/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings_grd/IDS_IOS_NO_COPIED_CONTENT_MESSAGE.png.sha1 b/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings_grd/IDS_IOS_NO_COPIED_CONTENT_MESSAGE.png.sha1 new file mode 100644 index 0000000..6b597d60 --- /dev/null +++ b/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings_grd/IDS_IOS_NO_COPIED_CONTENT_MESSAGE.png.sha1
@@ -0,0 +1 @@ +d186de0c73a9f82b4394f353c1c88238d8510f2b \ No newline at end of file
diff --git a/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings_grd/IDS_IOS_NO_COPIED_CONTENT_TITLE.png.sha1 b/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings_grd/IDS_IOS_NO_COPIED_CONTENT_TITLE.png.sha1 new file mode 100644 index 0000000..6b597d60 --- /dev/null +++ b/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings_grd/IDS_IOS_NO_COPIED_CONTENT_TITLE.png.sha1
@@ -0,0 +1 @@ +d186de0c73a9f82b4394f353c1c88238d8510f2b \ No newline at end of file
diff --git a/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings_grd/IDS_IOS_OPEN_COPIED_LINK.png.sha1 b/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings_grd/IDS_IOS_OPEN_COPIED_LINK.png.sha1 new file mode 100644 index 0000000..c99268f --- /dev/null +++ b/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings_grd/IDS_IOS_OPEN_COPIED_LINK.png.sha1
@@ -0,0 +1 @@ +9d22924eaaa7c279f2f914469997c5d9354f381f \ No newline at end of file
diff --git a/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings_grd/IDS_IOS_OPEN_COPIED_TEXT.png.sha1 b/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings_grd/IDS_IOS_OPEN_COPIED_TEXT.png.sha1 new file mode 100644 index 0000000..f27d8ca --- /dev/null +++ b/ios/chrome/search_widget_extension/strings/ios_search_widget_extension_strings_grd/IDS_IOS_OPEN_COPIED_TEXT.png.sha1
@@ -0,0 +1 @@ +82cb8be5eac23f717639c4bad7de956f9aa4050a \ No newline at end of file
diff --git a/ios/web/public/global_state/ios_global_state.mm b/ios/web/public/global_state/ios_global_state.mm index 16bed4f9b..2228c72 100644 --- a/ios/web/public/global_state/ios_global_state.mm +++ b/ios/web/public/global_state/ios_global_state.mm
@@ -23,19 +23,29 @@ net::NetworkChangeNotifier* g_network_change_notifer = nullptr; base::TaskScheduler::InitParams GetDefaultTaskSchedulerInitParams() { + constexpr int kMinBackgroundThreads = 4; + constexpr int kMaxBackgroundThreads = 16; + constexpr double kCoreMultiplierBackgroundThreads = 0.2; + constexpr int kOffsetBackgroundThreads = 0; + constexpr int kReclaimTimeBackground = 30; + + constexpr int kMinForegroundThreads = 6; + constexpr int kMaxForegroundThreads = 16; + constexpr double kCoreMultiplierForegroundThreads = 0.6; + constexpr int kOffsetForegroundThreads = 0; + constexpr int kReclaimTimeForeground = 30; + return base::TaskScheduler::InitParams( base::SchedulerWorkerPoolParams( - base::RecommendedMaxNumberOfThreadsInPool(2, 8, 0.1, 0), - base::TimeDelta::FromSeconds(30)), + base::RecommendedMaxNumberOfThreadsInPool( + kMinBackgroundThreads, kMaxBackgroundThreads, + kCoreMultiplierBackgroundThreads, kOffsetBackgroundThreads), + base::TimeDelta::FromSeconds(kReclaimTimeBackground)), base::SchedulerWorkerPoolParams( - base::RecommendedMaxNumberOfThreadsInPool(2, 8, 0.1, 0), - base::TimeDelta::FromSeconds(30)), - base::SchedulerWorkerPoolParams( - base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.3, 0), - base::TimeDelta::FromSeconds(30)), - base::SchedulerWorkerPoolParams( - base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.3, 0), - base::TimeDelta::FromSeconds(60))); + base::RecommendedMaxNumberOfThreadsInPool( + kMinForegroundThreads, kMaxForegroundThreads, + kCoreMultiplierForegroundThreads, kOffsetForegroundThreads), + base::TimeDelta::FromSeconds(kReclaimTimeForeground))); } } // namespace
diff --git a/ios/web/test/test_web_thread_bundle.cc b/ios/web/test/test_web_thread_bundle.cc index 1e12d6b9..326ffd4 100644 --- a/ios/web/test/test_web_thread_bundle.cc +++ b/ios/web/test/test_web_thread_bundle.cc
@@ -87,8 +87,7 @@ std::make_unique<base::internal::TaskSchedulerImpl>( "ScopedTaskEnvironment")); base::TaskScheduler::GetInstance()->Start( - {worker_pool_params, worker_pool_params, worker_pool_params, - worker_pool_params}); + {worker_pool_params, worker_pool_params}); } } // namespace web
diff --git a/media/blink/webmediaplayer_delegate.h b/media/blink/webmediaplayer_delegate.h index af33ac9..c3f9c0d7 100644 --- a/media/blink/webmediaplayer_delegate.h +++ b/media/blink/webmediaplayer_delegate.h
@@ -16,10 +16,6 @@ class Size; } // namespace gfx -namespace viz { -class SurfaceId; -} // namespace viz - namespace media { enum class MediaContentType; @@ -118,38 +114,12 @@ // Notify that the muted status of the media player has changed. virtual void DidPlayerMutedStatusChange(int delegate_id, bool muted) = 0; - // Notify that the source media player has entered Picture-in-Picture mode. - virtual void DidPictureInPictureModeStart( - int delegate_id, - const viz::SurfaceId&, - const gfx::Size&, - blink::WebMediaPlayer::PipWindowOpenedCallback, - bool show_play_pause_button) = 0; - - // Notify that the source media player has exited Picture-in-Picture mode. - virtual void DidPictureInPictureModeEnd(int delegate_id, - base::OnceClosure) = 0; - // Notify that custom controls have been sent to be assigned to the // Picture-in-Picture window. virtual void DidSetPictureInPictureCustomControls( int delegate_id, const std::vector<blink::PictureInPictureControlInfo>&) = 0; - // Notify that the media player in Picture-in-Picture had a change of surface. - virtual void DidPictureInPictureSurfaceChange( - int delegate_id, - const viz::SurfaceId&, - const gfx::Size&, - bool show_play_pause_button) = 0; - - // Registers a callback associated with a player that will be called when - // receiving a notification from the browser process that the - // Picture-in-Picture associated to this player has been resized. - virtual void RegisterPictureInPictureWindowResizeCallback( - int player_id, - blink::WebMediaPlayer::PipWindowResizedCallback) = 0; - // Notify that playback is stopped. This will drop wake locks and remove any // external controls. //
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index d1092da..e903282 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -517,11 +517,8 @@ // disabled. // The viz::SurfaceId may be updated when the video begins playback or when // the size of the video changes. - if (client_ && IsInPictureInPicture() && !client_->IsInAutoPIP()) { - delegate_->DidPictureInPictureSurfaceChange( - delegate_id_, surface_id, pipeline_metadata_.natural_size, - ShouldShowPlayPauseButtonInPictureInPictureWindow()); - } + if (client_) + client_->OnPictureInPictureStateChange(); } bool WebMediaPlayerImpl::SupportsOverlayFullscreenVideo() { @@ -904,30 +901,17 @@ UpdatePlayState(); } -void WebMediaPlayerImpl::EnterPictureInPicture( - blink::WebMediaPlayer::PipWindowOpenedCallback callback) { +void WebMediaPlayerImpl::EnterPictureInPicture() { if (!surface_layer_for_video_enabled_) ActivateSurfaceLayerForVideo(); DCHECK(bridge_); - - const viz::SurfaceId& surface_id = bridge_->GetSurfaceId(); - DCHECK(surface_id.is_valid()); - - // Notifies the browser process that the player should now be in - // Picture-in-Picture mode. - delegate_->DidPictureInPictureModeStart( - delegate_id_, surface_id, pipeline_metadata_.natural_size, - std::move(callback), ShouldShowPlayPauseButtonInPictureInPictureWindow()); + DCHECK(bridge_->GetSurfaceId().is_valid()); } -void WebMediaPlayerImpl::ExitPictureInPicture( - blink::WebMediaPlayer::PipWindowClosedCallback callback) { - // Notifies the browser process that Picture-in-Picture has ended. It will - // clear out the states and close the window. - delegate_->DidPictureInPictureModeEnd(delegate_id_, std::move(callback)); - +void WebMediaPlayerImpl::ExitPictureInPicture() { // Internal cleanups. + // TODO(mlamouri): remove the need for this. OnPictureInPictureModeEnded(); } @@ -936,14 +920,6 @@ delegate_->DidSetPictureInPictureCustomControls(delegate_id_, controls); } -void WebMediaPlayerImpl::RegisterPictureInPictureWindowResizeCallback( - blink::WebMediaPlayer::PipWindowResizedCallback callback) { - DCHECK(IsInPictureInPicture() && !client_->IsInAutoPIP()); - - delegate_->RegisterPictureInPictureWindowResizeCallback(delegate_id_, - std::move(callback)); -} - void WebMediaPlayerImpl::SetSinkId( const blink::WebString& sink_id, std::unique_ptr<blink::WebSetSinkIdCallbacks> web_callback) { @@ -3144,6 +3120,16 @@ return opaque_; } +int WebMediaPlayerImpl::GetDelegateId() { + return delegate_id_; +} + +base::Optional<viz::SurfaceId> WebMediaPlayerImpl::GetSurfaceId() { + if (!surface_layer_for_video_enabled_) + return base::nullopt; + return bridge_->GetSurfaceId(); +} + bool WebMediaPlayerImpl::ShouldPauseVideoWhenHidden() const { if (!is_background_video_playback_enabled_) return true; @@ -3448,11 +3434,6 @@ WebMediaPlayer::DisplayType::kPictureInPicture; } -bool WebMediaPlayerImpl::ShouldShowPlayPauseButtonInPictureInPictureWindow() - const { - return Duration() != std::numeric_limits<double>::infinity(); -} - void WebMediaPlayerImpl::MaybeSetContainerName() { // MSE nor MediaPlayerRenderer provide container information. if (chunk_demuxer_ || using_media_player_renderer_)
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h index 2030aee..7183daa 100644 --- a/media/blink/webmediaplayer_impl.h +++ b/media/blink/webmediaplayer_impl.h
@@ -120,14 +120,10 @@ void Seek(double seconds) override; void SetRate(double rate) override; void SetVolume(double volume) override; - void EnterPictureInPicture( - blink::WebMediaPlayer::PipWindowOpenedCallback callback) override; - void ExitPictureInPicture( - blink::WebMediaPlayer::PipWindowClosedCallback callback) override; + void EnterPictureInPicture() override; + void ExitPictureInPicture() override; void SetPictureInPictureCustomControls( const std::vector<blink::PictureInPictureControlInfo>&) override; - void RegisterPictureInPictureWindowResizeCallback( - blink::WebMediaPlayer::PipWindowResizedCallback callback) override; void SetSinkId( const blink::WebString& sink_id, std::unique_ptr<blink::WebSetSinkIdCallbacks> web_callback) override; @@ -264,10 +260,11 @@ // paused; see UpdatePlayState_ComputePlayState() for the exact details. void ForceStaleStateForTesting(ReadyState target_state) override; bool IsSuspendedForTesting() override; - bool DidLazyLoad() const override; void OnBecameVisible() override; bool IsOpaque() const override; + int GetDelegateId() override; + base::Optional<viz::SurfaceId> GetSurfaceId() override; bool IsBackgroundMediaSuspendEnabled() const { return is_background_suspend_enabled_; @@ -578,11 +575,6 @@ void SendBytesReceivedUpdate(); - // Returns whether the Picture-in-Picture window should contain a play/pause - // button. It will return false if video is "live", in other words if duration - // is equals to Infinity. - bool ShouldShowPlayPauseButtonInPictureInPictureWindow() const; - blink::WebLocalFrame* const frame_; // The playback state last reported to |delegate_|, to avoid setting duplicate
diff --git a/media/blink/webmediaplayer_impl_unittest.cc b/media/blink/webmediaplayer_impl_unittest.cc index ddc23ba..33f932eb 100644 --- a/media/blink/webmediaplayer_impl_unittest.cc +++ b/media/blink/webmediaplayer_impl_unittest.cc
@@ -148,9 +148,9 @@ MOCK_METHOD1(ActivateViewportIntersectionMonitoring, void(bool)); MOCK_METHOD1(MediaRemotingStarted, void(const blink::WebString&)); MOCK_METHOD1(MediaRemotingStopped, void(blink::WebLocalizedString::Name)); - MOCK_METHOD0(PictureInPictureStarted, void()); MOCK_METHOD0(PictureInPictureStopped, void()); MOCK_METHOD1(PictureInPictureControlClicked, void(const blink::WebString&)); + MOCK_METHOD0(OnPictureInPictureStateChange, void()); MOCK_CONST_METHOD0(CouldPlayIfEnoughData, bool()); MOCK_METHOD0(RequestPlay, void()); MOCK_METHOD0(RequestPause, void()); @@ -215,21 +215,9 @@ DCHECK_EQ(player_id_, delegate_id); } - MOCK_METHOD5(DidPictureInPictureModeStart, - void(int, - const viz::SurfaceId&, - const gfx::Size&, - blink::WebMediaPlayer::PipWindowOpenedCallback, - bool)); - MOCK_METHOD2(DidPictureInPictureModeEnd, - void(int, blink::WebMediaPlayer::PipWindowClosedCallback)); MOCK_METHOD2(DidSetPictureInPictureCustomControls, void(int, const std::vector<blink::PictureInPictureControlInfo>&)); - MOCK_METHOD4(DidPictureInPictureSurfaceChange, - void(int, const viz::SurfaceId&, const gfx::Size&, bool)); - MOCK_METHOD2(RegisterPictureInPictureWindowResizeCallback, - void(int, blink::WebMediaPlayer::PipWindowResizedCallback)); void ClearStaleFlag(int player_id) override { DCHECK_EQ(player_id_, player_id); @@ -1566,8 +1554,8 @@ } } -// Tests delegate methods are called when Picture-in-Picture is triggered. -TEST_F(WebMediaPlayerImplTest, PictureInPictureTriggerCallback) { +// Tests that updating the surface id calls OnPictureInPictureStateChange. +TEST_F(WebMediaPlayerImplTest, PictureInPictureStateChange) { base::test::ScopedFeatureList feature_list; feature_list.InitFromCommandLine(kUseSurfaceLayerForVideo.name, ""); @@ -1588,68 +1576,10 @@ EXPECT_CALL(client_, DisplayType()) .WillRepeatedly( Return(blink::WebMediaPlayer::DisplayType::kPictureInPicture)); - EXPECT_CALL(delegate_, - DidPictureInPictureSurfaceChange( - delegate_.player_id(), surface_id_, GetNaturalSize(), true)) - .Times(2); + EXPECT_CALL(client_, OnPictureInPictureStateChange()).Times(1); wmpi_->OnSurfaceIdUpdated(surface_id_); - EXPECT_CALL(delegate_, - DidPictureInPictureModeStart(delegate_.player_id(), surface_id_, - GetNaturalSize(), _, true)); - - wmpi_->EnterPictureInPicture(base::DoNothing()); - wmpi_->OnSurfaceIdUpdated(surface_id_); - - // Updating SurfaceId should NOT exit Picture-in-Picture. - EXPECT_CALL(delegate_, DidPictureInPictureModeEnd(delegate_.player_id(), _)) - .Times(0); - EXPECT_CALL(*surface_layer_bridge_ptr_, ClearObserver()); -} - -// Tests delegate methods are called with the appropriate play/pause button -// state when Picture-in-Picture is triggered and video duration is infinity. -TEST_F(WebMediaPlayerImplTest, - PictureInPictureTriggerWithInfiniteDurationCallback) { - base::test::ScopedFeatureList feature_list; - feature_list.InitFromCommandLine(kUseSurfaceLayerForVideo.name, ""); - - InitializeWebMediaPlayerImpl(); - SetDuration(kInfiniteDuration); - - EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer()); - EXPECT_CALL(*surface_layer_bridge_ptr_, GetSurfaceId()) - .WillRepeatedly(ReturnRef(surface_id_)); - EXPECT_CALL(*surface_layer_bridge_ptr_, GetLocalSurfaceIdAllocationTime()) - .WillRepeatedly(Return(base::TimeTicks())); - EXPECT_CALL(*compositor_, EnableSubmission(_, _, _, _)); - EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false)); - - PipelineMetadata metadata; - metadata.has_video = true; - OnMetadata(metadata); - - EXPECT_CALL(client_, DisplayType()) - .WillRepeatedly( - Return(blink::WebMediaPlayer::DisplayType::kPictureInPicture)); - EXPECT_CALL(delegate_, - DidPictureInPictureSurfaceChange( - delegate_.player_id(), surface_id_, GetNaturalSize(), false)) - .Times(2); - - wmpi_->OnSurfaceIdUpdated(surface_id_); - - EXPECT_CALL(delegate_, - DidPictureInPictureModeStart(delegate_.player_id(), surface_id_, - GetNaturalSize(), _, false)); - - wmpi_->EnterPictureInPicture(base::DoNothing()); - wmpi_->OnSurfaceIdUpdated(surface_id_); - - // Updating SurfaceId should NOT exit Picture-in-Picture. - EXPECT_CALL(delegate_, DidPictureInPictureModeEnd(delegate_.player_id(), _)) - .Times(0); EXPECT_CALL(*surface_layer_bridge_ptr_, ClearObserver()); }
diff --git a/media/capture/mojom/video_capture.mojom b/media/capture/mojom/video_capture.mojom index adb9ec3..e074393c 100644 --- a/media/capture/mojom/video_capture.mojom +++ b/media/capture/mojom/video_capture.mojom
@@ -109,6 +109,10 @@ GetDeviceFormatsInUse(int32 device_id, int32 session_id) => (array<VideoCaptureFormat> formats_in_use); + // Notifies the host about a frame being dropped. + OnFrameDropped(int32 device_id, + media.mojom.VideoCaptureFrameDropReason reason); + // Sends a log message to the VideoCaptureHost. OnLog(int32 device_id, string message); };
diff --git a/media/capture/mojom/video_capture_types.mojom b/media/capture/mojom/video_capture_types.mojom index 8dd3731..89bbfec 100644 --- a/media/capture/mojom/video_capture_types.mojom +++ b/media/capture/mojom/video_capture_types.mojom
@@ -228,7 +228,17 @@ kWinMediaFoundationLockingBufferDelieveredNullptr, kWinMediaFoundationGetBufferByIndexReturnedNull, kBufferPoolMaxBufferCountExceeded, - kBufferPoolBufferAllocationFailed + kBufferPoolBufferAllocationFailed, + kVideoCaptureImplNotInStartedState, + kVideoCaptureImplFailedToWrapDataAsMediaVideoFrame, + kVideoTrackAdapterHasNoResolutionAdapters, + kResolutionAdapterFrameIsNotValid, + kResolutionAdapterWrappingFrameForCroppingFailed, + kResolutionAdapterTimestampTooCloseToPrevious, + kResolutionAdapterFrameRateIsHigherThanRequested, + kResolutionAdapterHasNoCallbacks, + kVideoTrackFrameDelivererNotEnabledReplacingWithBlackFrame, + kRendererSinkFrameDelivererIsNotStarted }; struct VideoCaptureFormat {
diff --git a/media/capture/mojom/video_capture_types_mojom_traits.cc b/media/capture/mojom/video_capture_types_mojom_traits.cc index 1220ecc..b6a0ebf9 100644 --- a/media/capture/mojom/video_capture_types_mojom_traits.cc +++ b/media/capture/mojom/video_capture_types_mojom_traits.cc
@@ -1260,6 +1260,43 @@ case media::VideoCaptureFrameDropReason::kBufferPoolBufferAllocationFailed: return media::mojom::VideoCaptureFrameDropReason:: kBufferPoolBufferAllocationFailed; + case media::VideoCaptureFrameDropReason::kVideoCaptureImplNotInStartedState: + return media::mojom::VideoCaptureFrameDropReason:: + kVideoCaptureImplNotInStartedState; + case media::VideoCaptureFrameDropReason:: + kVideoCaptureImplFailedToWrapDataAsMediaVideoFrame: + return media::mojom::VideoCaptureFrameDropReason:: + kVideoCaptureImplFailedToWrapDataAsMediaVideoFrame; + case media::VideoCaptureFrameDropReason:: + kVideoTrackAdapterHasNoResolutionAdapters: + return media::mojom::VideoCaptureFrameDropReason:: + kVideoTrackAdapterHasNoResolutionAdapters; + case media::VideoCaptureFrameDropReason::kResolutionAdapterFrameIsNotValid: + return media::mojom::VideoCaptureFrameDropReason:: + kResolutionAdapterFrameIsNotValid; + case media::VideoCaptureFrameDropReason:: + kResolutionAdapterWrappingFrameForCroppingFailed: + return media::mojom::VideoCaptureFrameDropReason:: + kResolutionAdapterWrappingFrameForCroppingFailed; + case media::VideoCaptureFrameDropReason:: + kResolutionAdapterTimestampTooCloseToPrevious: + return media::mojom::VideoCaptureFrameDropReason:: + kResolutionAdapterTimestampTooCloseToPrevious; + case media::VideoCaptureFrameDropReason:: + kResolutionAdapterFrameRateIsHigherThanRequested: + return media::mojom::VideoCaptureFrameDropReason:: + kResolutionAdapterFrameRateIsHigherThanRequested; + case media::VideoCaptureFrameDropReason::kResolutionAdapterHasNoCallbacks: + return media::mojom::VideoCaptureFrameDropReason:: + kResolutionAdapterHasNoCallbacks; + case media::VideoCaptureFrameDropReason:: + kVideoTrackFrameDelivererNotEnabledReplacingWithBlackFrame: + return media::mojom::VideoCaptureFrameDropReason:: + kVideoTrackFrameDelivererNotEnabledReplacingWithBlackFrame; + case media::VideoCaptureFrameDropReason:: + kRendererSinkFrameDelivererIsNotStarted: + return media::mojom::VideoCaptureFrameDropReason:: + kRendererSinkFrameDelivererIsNotStarted; } NOTREACHED(); return media::mojom::VideoCaptureFrameDropReason::kNone; @@ -1345,6 +1382,56 @@ *output = media::VideoCaptureFrameDropReason::kBufferPoolBufferAllocationFailed; return true; + case media::mojom::VideoCaptureFrameDropReason:: + kVideoCaptureImplNotInStartedState: + *output = media::VideoCaptureFrameDropReason:: + kVideoCaptureImplNotInStartedState; + return true; + case media::mojom::VideoCaptureFrameDropReason:: + kVideoCaptureImplFailedToWrapDataAsMediaVideoFrame: + *output = media::VideoCaptureFrameDropReason:: + kVideoCaptureImplFailedToWrapDataAsMediaVideoFrame; + return true; + case media::mojom::VideoCaptureFrameDropReason:: + kVideoTrackAdapterHasNoResolutionAdapters: + *output = media::VideoCaptureFrameDropReason:: + kVideoTrackAdapterHasNoResolutionAdapters; + return true; + case media::mojom::VideoCaptureFrameDropReason:: + kResolutionAdapterFrameIsNotValid: + *output = + media::VideoCaptureFrameDropReason::kResolutionAdapterFrameIsNotValid; + return true; + case media::mojom::VideoCaptureFrameDropReason:: + kResolutionAdapterWrappingFrameForCroppingFailed: + *output = media::VideoCaptureFrameDropReason:: + kResolutionAdapterWrappingFrameForCroppingFailed; + return true; + case media::mojom::VideoCaptureFrameDropReason:: + kResolutionAdapterTimestampTooCloseToPrevious: + *output = media::VideoCaptureFrameDropReason:: + kResolutionAdapterTimestampTooCloseToPrevious; + return true; + case media::mojom::VideoCaptureFrameDropReason:: + kResolutionAdapterFrameRateIsHigherThanRequested: + *output = media::VideoCaptureFrameDropReason:: + kResolutionAdapterFrameRateIsHigherThanRequested; + return true; + case media::mojom::VideoCaptureFrameDropReason:: + kResolutionAdapterHasNoCallbacks: + *output = + media::VideoCaptureFrameDropReason::kResolutionAdapterHasNoCallbacks; + return true; + case media::mojom::VideoCaptureFrameDropReason:: + kVideoTrackFrameDelivererNotEnabledReplacingWithBlackFrame: + *output = media::VideoCaptureFrameDropReason:: + kVideoTrackFrameDelivererNotEnabledReplacingWithBlackFrame; + return true; + case media::mojom::VideoCaptureFrameDropReason:: + kRendererSinkFrameDelivererIsNotStarted: + *output = media::VideoCaptureFrameDropReason:: + kRendererSinkFrameDelivererIsNotStarted; + return true; } NOTREACHED(); return false;
diff --git a/media/capture/video_capture_types.h b/media/capture/video_capture_types.h index 107034f..30ad34a 100644 --- a/media/capture/video_capture_types.h +++ b/media/capture/video_capture_types.h
@@ -201,7 +201,17 @@ kWinMediaFoundationGetBufferByIndexReturnedNull = 14, kBufferPoolMaxBufferCountExceeded = 15, kBufferPoolBufferAllocationFailed = 16, - kMaxValue = 16 + kVideoCaptureImplNotInStartedState = 17, + kVideoCaptureImplFailedToWrapDataAsMediaVideoFrame = 18, + kVideoTrackAdapterHasNoResolutionAdapters = 19, + kResolutionAdapterFrameIsNotValid = 20, + kResolutionAdapterWrappingFrameForCroppingFailed = 21, + kResolutionAdapterTimestampTooCloseToPrevious = 22, + kResolutionAdapterFrameRateIsHigherThanRequested = 23, + kResolutionAdapterHasNoCallbacks = 24, + kVideoTrackFrameDelivererNotEnabledReplacingWithBlackFrame = 25, + kRendererSinkFrameDelivererIsNotStarted = 26, + kMaxValue = 26 }; // Assert that the int:frequency mapping is correct.
diff --git a/media/capture/video_capturer_source.h b/media/capture/video_capturer_source.h index 73d32fa..b02a0515 100644 --- a/media/capture/video_capturer_source.h +++ b/media/capture/video_capturer_source.h
@@ -108,6 +108,9 @@ // use refcounted or weak references in |new_frame_callback|. virtual void StopCapture() = 0; + // Indicates to the source that a frame has been dropped. + virtual void OnFrameDropped(media::VideoCaptureFrameDropReason reason) {} + // Sends a log message to the source. virtual void OnLog(const std::string& message) {} };
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl index b7683be..f353ac7 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
@@ -122,11 +122,6 @@ }; template <> -struct DefaultHash<{{enum_name}}> { - using Hash = {{hash_fn_name}}; -}; - -template <> struct HashTraits<{{enum_name}}> : public GenericHashTraits<{{enum_name}}> { static_assert({{empty_value_unused}}, @@ -146,3 +141,17 @@ }; } // namespace WTF {%- endmacro %} + +{%- macro enum_hash_blink_forward(enum) %} +{%- set enum_name = enum|get_qualified_name_for_kind( + flatten_nested_kind=True, include_variant=False) %} +{%- set hash_fn_name = enum|wtf_hash_fn_name_for_enum %} +namespace WTF { +struct {{hash_fn_name}}; + +template <> +struct DefaultHash<{{enum_name}}> { + using Hash = {{hash_fn_name}}; +}; +} // namespace WTF +{%- endmacro %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl index c5b8eec3..be9db6ce 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl
@@ -58,6 +58,20 @@ #include "{{export_header}}" {%- endif %} +{#--- WTF enum hashing #} +{%- from "enum_macros.tmpl" import enum_hash_blink_forward%} +{%- if for_blink %} +{%- if all_enums %} +#include "third_party/blink/renderer/platform/wtf/hash_functions.h" +{%- endif %} + +{%- for enum in all_enums %} +{%- if not enum|is_native_only_kind %} +{{enum_hash_blink_forward(enum)}} +{%- endif %} +{%- endfor %} +{%- endif %} + {{namespace_begin()}} {#- These are non-variant header only. #}
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc index 0609b5a..8904b3f2 100644 --- a/net/quic/quic_stream_factory_test.cc +++ b/net/quic/quic_stream_factory_test.cc
@@ -225,15 +225,13 @@ random_generator_(0), runner_(new TestTaskRunner(&clock_)), version_(version), - client_headers_include_h2_stream_dependency_( - client_headers_include_h2_stream_dependency), client_maker_( version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_), &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT, - client_headers_include_h2_stream_dependency_), + client_headers_include_h2_stream_dependency), server_maker_( version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_), @@ -255,23 +253,9 @@ &QuicStreamFactoryTestBase::OnFailedOnDefaultNetwork, base::Unretained(this))), failed_on_default_network_(false), - store_server_configs_in_properties_(false), - close_sessions_on_ip_change_(false), - goaway_sessions_on_ip_change_(false), - idle_connection_timeout_seconds_(kIdleConnectionTimeoutSeconds), - reduced_ping_timeout_seconds_(quic::kPingTimeoutSecs), - max_time_before_crypto_handshake_seconds_( - quic::kMaxTimeForCryptoHandshakeSecs), - max_idle_time_before_crypto_handshake_seconds_( - quic::kInitialIdleTimeoutSecs), - migrate_sessions_on_network_change_v2_(false), - migrate_sessions_early_v2_(false), - retry_on_alternate_network_before_handshake_(false), - race_stale_dns_on_connection_(false), - go_away_on_path_degrading_(false), - allow_server_migration_(false), - race_cert_verification_(false), - estimate_initial_rtt_(false) { + store_server_configs_in_properties_(false) { + test_params_.quic_headers_include_h2_stream_dependency = + client_headers_include_h2_stream_dependency; clock_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1)); } @@ -284,23 +268,31 @@ cert_transparency_verifier_.get(), /*SocketPerformanceWatcherFactory*/ nullptr, &crypto_client_stream_factory_, &random_generator_, &clock_, - quic::kDefaultMaxPacketSize, string(), - store_server_configs_in_properties_, close_sessions_on_ip_change_, - goaway_sessions_on_ip_change_, - /*mark_quic_broken_when_network_blackholes*/ false, - idle_connection_timeout_seconds_, reduced_ping_timeout_seconds_, - max_time_before_crypto_handshake_seconds_, - max_idle_time_before_crypto_handshake_seconds_, - migrate_sessions_on_network_change_v2_, migrate_sessions_early_v2_, - retry_on_alternate_network_before_handshake_, - base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs), - kMaxMigrationsToNonDefaultNetworkOnWriteError, - kMaxMigrationsToNonDefaultNetworkOnPathDegrading, - allow_server_migration_, race_stale_dns_on_connection_, - go_away_on_path_degrading_, race_cert_verification_, - estimate_initial_rtt_, client_headers_include_h2_stream_dependency_, - connection_options_, client_connection_options_, - /*enable_socket_recv_optimization*/ false)); + test_params_.quic_max_packet_length, test_params_.quic_user_agent_id, + store_server_configs_in_properties_, + test_params_.quic_close_sessions_on_ip_change, + test_params_.quic_goaway_sessions_on_ip_change, + test_params_.mark_quic_broken_when_network_blackholes, + test_params_.quic_idle_connection_timeout_seconds, + test_params_.quic_reduced_ping_timeout_seconds, + test_params_.quic_max_time_before_crypto_handshake_seconds, + test_params_.quic_max_idle_time_before_crypto_handshake_seconds, + test_params_.quic_migrate_sessions_on_network_change_v2, + test_params_.quic_migrate_sessions_early_v2, + test_params_.quic_retry_on_alternate_network_before_handshake, + test_params_.quic_max_time_on_non_default_network, + test_params_.quic_max_migrations_to_non_default_network_on_write_error, + test_params_ + .quic_max_migrations_to_non_default_network_on_path_degrading, + test_params_.quic_allow_server_migration, + test_params_.quic_race_stale_dns_on_connection, + test_params_.quic_go_away_on_path_degrading, + test_params_.quic_race_cert_verification, + test_params_.quic_estimate_initial_rtt, + test_params_.quic_headers_include_h2_stream_dependency, + test_params_.quic_connection_options, + test_params_.quic_client_connection_options, + test_params_.quic_enable_socket_recv_optimization)); } void InitializeConnectionMigrationV2Test( @@ -311,8 +303,8 @@ scoped_mock_network_change_notifier_->mock_network_change_notifier(); mock_ncn->ForceNetworkHandlesSupported(); mock_ncn->SetConnectedNetworksList(connected_networks); - migrate_sessions_on_network_change_v2_ = true; - migrate_sessions_early_v2_ = true; + test_params_.quic_migrate_sessions_on_network_change_v2 = true; + test_params_.quic_migrate_sessions_early_v2 = true; socket_factory_.reset(new TestConnectionMigrationSocketFactory); Initialize(); } @@ -520,7 +512,7 @@ // Helper method for server migration tests. void VerifyServerMigration(const quic::QuicConfig& config, IPEndPoint expected_address) { - allow_server_migration_ = true; + test_params_.quic_allow_server_migration = true; Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -593,7 +585,7 @@ // Verifies that the QUIC stream factory is initialized correctly. void VerifyInitialization() { store_server_configs_in_properties_ = true; - idle_connection_timeout_seconds_ = 500; + test_params_.quic_idle_connection_timeout_seconds = 500; Initialize(); factory_->set_require_confirmation(false); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -846,7 +838,6 @@ quic::MockClock clock_; scoped_refptr<TestTaskRunner> runner_; const quic::QuicTransportVersion version_; - const bool client_headers_include_h2_stream_dependency_; QuicTestPacketMaker client_maker_; QuicTestPacketMaker server_maker_; HttpServerPropertiesImpl http_server_properties_; @@ -871,23 +862,8 @@ NetErrorDetails net_error_details_; // Variables to configure QuicStreamFactory. + HttpNetworkSession::Params test_params_; bool store_server_configs_in_properties_; - bool close_sessions_on_ip_change_; - bool goaway_sessions_on_ip_change_; - int idle_connection_timeout_seconds_; - int reduced_ping_timeout_seconds_; - int max_time_before_crypto_handshake_seconds_; - int max_idle_time_before_crypto_handshake_seconds_; - bool migrate_sessions_on_network_change_v2_; - bool migrate_sessions_early_v2_; - bool retry_on_alternate_network_before_handshake_; - bool race_stale_dns_on_connection_; - bool go_away_on_path_degrading_; - bool allow_server_migration_; - bool race_cert_verification_; - bool estimate_initial_rtt_; - quic::QuicTagVector connection_options_; - quic::QuicTagVector client_connection_options_; }; class QuicStreamFactoryTest : public QuicStreamFactoryTestBase, @@ -1123,7 +1099,7 @@ stats.srtt = base::TimeDelta::FromMilliseconds(10); http_server_properties_.SetServerNetworkStats(url::SchemeHostPort(url_), stats); - estimate_initial_rtt_ = true; + test_params_.quic_estimate_initial_rtt = true; Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -1156,7 +1132,7 @@ ScopedMockNetworkChangeNotifier notifier; notifier.mock_network_change_notifier()->SetConnectionType( NetworkChangeNotifier::CONNECTION_2G); - estimate_initial_rtt_ = true; + test_params_.quic_estimate_initial_rtt = true; Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -1189,7 +1165,7 @@ ScopedMockNetworkChangeNotifier notifier; notifier.mock_network_change_notifier()->SetConnectionType( NetworkChangeNotifier::CONNECTION_3G); - estimate_initial_rtt_ = true; + test_params_.quic_estimate_initial_rtt = true; Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -2026,7 +2002,7 @@ } TEST_P(QuicStreamFactoryTest, CloseSessionsOnIPAddressChanged) { - close_sessions_on_ip_change_ = true; + test_params_.quic_close_sessions_on_ip_change = true; Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); @@ -2110,7 +2086,7 @@ // as going away on IP address change instead of being closed. New requests will // go to a new connection. TEST_P(QuicStreamFactoryTest, GoAwaySessionsOnIPAddressChanged) { - goaway_sessions_on_ip_change_ = true; + test_params_.quic_goaway_sessions_on_ip_change = true; Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); @@ -3646,7 +3622,7 @@ // This test verifies that the session marks itself GOAWAY on path degrading // and it does not receive any new request TEST_P(QuicStreamFactoryTest, GoawayOnPathDegrading) { - go_away_on_path_degrading_ = true; + test_params_.quic_go_away_on_path_degrading = true; Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); @@ -4996,7 +4972,7 @@ quic::QuicErrorCode quic_error) { DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT || quic_error == quic::QUIC_HANDSHAKE_TIMEOUT); - retry_on_alternate_network_before_handshake_ = true; + test_params_.quic_retry_on_alternate_network_before_handshake = true; InitializeConnectionMigrationV2Test( {kDefaultNetworkForTests, kNewNetworkForTests}); @@ -5148,7 +5124,7 @@ // is triggered before handshake is confirmed and connection migration is turned // on. TEST_P(QuicStreamFactoryTest, MigrationOnWriteErrorBeforeHandshakeConfirmed) { - DCHECK(!retry_on_alternate_network_before_handshake_); + DCHECK(!test_params_.quic_retry_on_alternate_network_before_handshake); InitializeConnectionMigrationV2Test( {kDefaultNetworkForTests, kNewNetworkForTests}); @@ -5218,7 +5194,7 @@ // on, a new connection will be retried on the alternate network. TEST_P(QuicStreamFactoryTest, RetryConnectionOnWriteErrorBeforeHandshakeConfirmed) { - retry_on_alternate_network_before_handshake_ = true; + test_params_.quic_retry_on_alternate_network_before_handshake = true; InitializeConnectionMigrationV2Test( {kDefaultNetworkForTests, kNewNetworkForTests}); @@ -7272,7 +7248,7 @@ } TEST_P(QuicStreamFactoryTest, ServerMigration) { - allow_server_migration_ = true; + test_params_.quic_allow_server_migration = true; Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -7413,7 +7389,7 @@ } TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv6Fails) { - allow_server_migration_ = true; + test_params_.quic_allow_server_migration = true; Initialize(); // Add a resolver rule to make initial connection to an IPv4 address. @@ -7663,7 +7639,7 @@ } TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) { - reduced_ping_timeout_seconds_ = 10; + test_params_.quic_reduced_ping_timeout_seconds = 10; Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); @@ -8480,18 +8456,19 @@ // Passes connection options and client connection options to QuicStreamFactory, // then checks that its internal quic::QuicConfig is correct. TEST_P(QuicStreamFactoryTest, ConfigConnectionOptions) { - connection_options_.push_back(quic::kTIME); - connection_options_.push_back(quic::kTBBR); - connection_options_.push_back(quic::kREJ); + test_params_.quic_connection_options.push_back(quic::kTIME); + test_params_.quic_connection_options.push_back(quic::kTBBR); + test_params_.quic_connection_options.push_back(quic::kREJ); - client_connection_options_.push_back(quic::kTBBR); - client_connection_options_.push_back(quic::k1RTT); + test_params_.quic_client_connection_options.push_back(quic::kTBBR); + test_params_.quic_client_connection_options.push_back(quic::k1RTT); Initialize(); const quic::QuicConfig* config = QuicStreamFactoryPeer::GetConfig(factory_.get()); - EXPECT_EQ(connection_options_, config->SendConnectionOptions()); + EXPECT_EQ(test_params_.quic_connection_options, + config->SendConnectionOptions()); EXPECT_TRUE(config->HasClientRequestedIndependentOption( quic::kTBBR, quic::Perspective::IS_CLIENT)); EXPECT_TRUE(config->HasClientRequestedIndependentOption( @@ -8564,13 +8541,12 @@ EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->request_priority(2)); } -// Passes |max_time_before_crypto_handshake_seconds| and -// |max_idle_time_before_crypto_handshake_seconds| to QuicStreamFactory, then +// Passes |quic_max_time_before_crypto_handshake_seconds| and +// |quic_max_idle_time_before_crypto_handshake_seconds| to QuicStreamFactory, // checks that its internal quic::QuicConfig is correct. TEST_P(QuicStreamFactoryTest, ConfigMaxTimeBeforeCryptoHandshake) { - max_time_before_crypto_handshake_seconds_ = 11; - max_idle_time_before_crypto_handshake_seconds_ = 13; - + test_params_.quic_max_time_before_crypto_handshake_seconds = 11; + test_params_.quic_max_idle_time_before_crypto_handshake_seconds = 13; Initialize(); const quic::QuicConfig* config = @@ -8825,7 +8801,7 @@ // the final connection is established through the resolved DNS. No racing // connection. TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceAndHostResolutionSync) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -8874,7 +8850,6 @@ // host resolver, connection should be successful and through resolved DNS. No // racing connection. TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceAndHostResolutionAsync) { - race_stale_dns_on_connection_ = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -8923,7 +8898,7 @@ // With dns race experiment on, DNS resolve returns async, stale dns used, // connects synchrounously, and then the resolved DNS matches. TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncStaleMatch) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -8982,7 +8957,7 @@ // async, and then the result matches. TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncConnectAsyncStaleMatch) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -9050,7 +9025,7 @@ // return, then connection finishes and matches with the result. TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncStaleMatchConnectAsync) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -9114,7 +9089,7 @@ // sync, but dns no match TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncStaleSyncNoMatch) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -9186,7 +9161,7 @@ // With dns race experiment on, dns resolve async, stale used and connects // async, finishes before dns, but no match TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleAsyncResolveAsyncNoMatch) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -9260,7 +9235,7 @@ // With dns race experiment on, dns resolve async, stale used and connects // async, dns finishes first, but no match TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncStaleAsyncNoMatch) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -9331,7 +9306,7 @@ // With dns race experiment on, dns resolve returns error sync, same behavior // as experiment is not on TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveError) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -9356,7 +9331,7 @@ // With dns race experiment on, no cache available, dns resolve returns error // async TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncError) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -9385,7 +9360,7 @@ // With dns race experiment on, dns resolve async, staled used and connects // sync, dns returns error and no connection is established. TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleSyncHostResolveError) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -9439,7 +9414,7 @@ // With dns race experiment on, dns resolve async, stale used and connection // return error, then dns matches TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSMatches) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -9487,7 +9462,7 @@ // With dns race experiment on, dns resolve async, stale used and connection // returns error, dns no match, new connection is established TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSNoMatch) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -9551,7 +9526,7 @@ // With dns race experiment on, dns resolve async, stale used and connection // returns error, dns no match, new connection error TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSNoMatchError) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -9603,7 +9578,7 @@ // With dns race experiment on, dns resolve async and stale connect async, dns // resolve returns error and then preconnect finishes TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncErrorStaleAsync) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -9657,7 +9632,7 @@ // resolve returns error and then preconnect fails. TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncErrorStaleAsyncError) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -9710,7 +9685,7 @@ // With dns race experiment on, test that host resolution callback behaves // normal as experiment is not on TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsync) { - race_stale_dns_on_connection_ = true; + test_params_.quic_race_stale_dns_on_connection = true; host_resolver_ = std::make_unique<MockCachingHostResolver>(); Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
diff --git a/net/third_party/quic/core/crypto/quic_crypto_server_config.cc b/net/third_party/quic/core/crypto/quic_crypto_server_config.cc index 632d2cfd..2da7627 100644 --- a/net/third_party/quic/core/crypto/quic_crypto_server_config.cc +++ b/net/third_party/quic/core/crypto/quic_crypto_server_config.cc
@@ -1015,10 +1015,7 @@ auto out_diversification_nonce = QuicMakeUnique<DiversificationNonce>(); if (!info.sni.empty()) { - std::unique_ptr<char[]> sni_tmp(new char[info.sni.length() + 1]); - memcpy(sni_tmp.get(), info.sni.data(), info.sni.length()); - sni_tmp[info.sni.length()] = 0; - params->sni = QuicHostnameUtils::NormalizeHostname(sni_tmp.get()); + params->sni = QuicHostnameUtils::NormalizeHostname(info.sni); } QuicString hkdf_suffix;
diff --git a/net/third_party/quic/platform/api/quic_hostname_utils.cc b/net/third_party/quic/platform/api/quic_hostname_utils.cc index 97ffff9..90e8ef1 100644 --- a/net/third_party/quic/platform/api/quic_hostname_utils.cc +++ b/net/third_party/quic/platform/api/quic_hostname_utils.cc
@@ -4,8 +4,6 @@ #include "net/third_party/quic/platform/api/quic_hostname_utils.h" -using std::string; - namespace quic { // static @@ -14,7 +12,7 @@ } // static -char* QuicHostnameUtils::NormalizeHostname(char* hostname) { +QuicString QuicHostnameUtils::NormalizeHostname(QuicStringPiece hostname) { return QuicHostnameUtilsImpl::NormalizeHostname(hostname); }
diff --git a/net/third_party/quic/platform/api/quic_hostname_utils.h b/net/third_party/quic/platform/api/quic_hostname_utils.h index e4fd1c7f..797d7964 100644 --- a/net/third_party/quic/platform/api/quic_hostname_utils.h +++ b/net/third_party/quic/platform/api/quic_hostname_utils.h
@@ -6,6 +6,7 @@ #define NET_THIRD_PARTY_QUIC_PLATFORM_API_QUIC_HOSTNAME_UTILS_H_ #include "net/third_party/quic/platform/api/quic_export.h" +#include "net/third_party/quic/platform/api/quic_string.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" #include "net/third_party/quic/platform/impl/quic_hostname_utils_impl.h" @@ -21,9 +22,10 @@ // (3) contains at least one dot. static bool IsValidSNI(QuicStringPiece sni); - // Convert hostname to lowercase and remove the trailing '.'. - // WARNING: mutates |hostname| in place and returns |hostname|. - static char* NormalizeHostname(char* hostname); + // Canonicalizes the specified hostname. This involves a wide variety of + // transformations, including lowercasing, removing trailing dots and IDNA + // conversion. + static QuicString NormalizeHostname(QuicStringPiece hostname); }; } // namespace quic
diff --git a/net/third_party/quic/platform/api/quic_hostname_utils_test.cc b/net/third_party/quic/platform/api/quic_hostname_utils_test.cc index 2919d79..ed4aa789 100644 --- a/net/third_party/quic/platform/api/quic_hostname_utils_test.cc +++ b/net/third_party/quic/platform/api/quic_hostname_utils_test.cc
@@ -58,14 +58,28 @@ "www.google.com........", "www.google.com", }, + { + "", + "", + }, + { + ".", + "", + }, + { + "........", + "", + }, + { + "\xe5\x85\x89.google.com", + "xn--54q.google.com", + }, }; // clang-format on for (size_t i = 0; i < QUIC_ARRAYSIZE(tests); ++i) { - char buf[256]; - snprintf(buf, sizeof(buf), "%s", tests[i].input); EXPECT_EQ(QuicString(tests[i].expected), - QuicHostnameUtils::NormalizeHostname(buf)); + QuicHostnameUtils::NormalizeHostname(tests[i].input)); } }
diff --git a/net/third_party/quic/platform/impl/quic_hostname_utils_impl.cc b/net/third_party/quic/platform/impl/quic_hostname_utils_impl.cc index ab3770e2..c452d58 100644 --- a/net/third_party/quic/platform/impl/quic_hostname_utils_impl.cc +++ b/net/third_party/quic/platform/impl/quic_hostname_utils_impl.cc
@@ -8,8 +8,6 @@ #include "url/gurl.h" #include "url/url_canon.h" -using std::string; - namespace quic { // static @@ -20,16 +18,18 @@ // would consider valid. By far the most common hostname character NOT // accepted by the above spec is '_'. url::CanonHostInfo host_info; - string canonicalized_host(net::CanonicalizeHost(sni.as_string(), &host_info)); + std::string canonicalized_host( + net::CanonicalizeHost(sni.as_string(), &host_info)); return !host_info.IsIPAddress() && net::IsCanonicalizedHostCompliant(canonicalized_host) && - sni.find_last_of('.') != string::npos; + sni.find_last_of('.') != std::string::npos; } // static -char* QuicHostnameUtilsImpl::NormalizeHostname(char* hostname) { +QuicString QuicHostnameUtilsImpl::NormalizeHostname(QuicStringPiece hostname) { url::CanonHostInfo host_info; - string host(net::CanonicalizeHost(hostname, &host_info)); + std::string host(net::CanonicalizeHost( + base::StringPiece(hostname.data(), hostname.size()), &host_info)); // Walk backwards over the string, stopping at the first trailing dot. size_t host_end = host.length(); @@ -42,10 +42,7 @@ host.erase(host_end, host.length() - host_end); } - memcpy(hostname, host.c_str(), host.length()); - hostname[host.length()] = '\0'; - - return hostname; + return host; } } // namespace quic
diff --git a/net/third_party/quic/platform/impl/quic_hostname_utils_impl.h b/net/third_party/quic/platform/impl/quic_hostname_utils_impl.h index 6d4f9b0..0c560de9 100644 --- a/net/third_party/quic/platform/impl/quic_hostname_utils_impl.h +++ b/net/third_party/quic/platform/impl/quic_hostname_utils_impl.h
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "net/third_party/quic/platform/api/quic_export.h" +#include "net/third_party/quic/platform/api/quic_string.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" namespace quic { @@ -21,7 +22,7 @@ // Convert hostname to lowercase and remove the trailing '.'. // WARNING: mutates |hostname| in place and returns |hostname|. - static char* NormalizeHostname(char* hostname); + static QuicString NormalizeHostname(QuicStringPiece hostname); private: DISALLOW_COPY_AND_ASSIGN(QuicHostnameUtilsImpl);
diff --git a/printing/backend/cups_ipp_util.cc b/printing/backend/cups_ipp_util.cc index eca4e0b..cb0ae5ba 100644 --- a/printing/backend/cups_ipp_util.cc +++ b/printing/backend/cups_ipp_util.cc
@@ -131,6 +131,10 @@ return gfx::Size{width_microns, height_microns}; } +// We read the media name expressed by |value| and return a Paper +// with the vendor_id and size_um members populated. +// We don't handle l10n here, so we don't populate the display_name +// member, deferring that to the caller. PrinterSemanticCapsAndDefaults::Paper ParsePaper(base::StringPiece value) { // <name>_<width>x<height>{in,mm} // e.g. na_letter_8.5x11in, iso_a4_210x297mm @@ -141,16 +145,9 @@ if (pieces.size() < 2) return PrinterSemanticCapsAndDefaults::Paper(); - std::string display = pieces[0].as_string(); - for (size_t i = 1; i <= pieces.size() - 2; ++i) { - display.append(" "); - pieces[i].AppendToString(&display); - } - base::StringPiece dimensions = pieces.back(); PrinterSemanticCapsAndDefaults::Paper paper; - paper.display_name = display; paper.vendor_id = value.as_string(); paper.size_um = DimensionsToMicrons(dimensions);
diff --git a/printing/backend/cups_ipp_util_unittest.cc b/printing/backend/cups_ipp_util_unittest.cc index d78da45..add81a4 100644 --- a/printing/backend/cups_ipp_util_unittest.cc +++ b/printing/backend/cups_ipp_util_unittest.cc
@@ -173,7 +173,9 @@ CapsAndDefaultsFromPrinter(*printer_, &caps); PrinterSemanticCapsAndDefaults::Paper paper = caps.papers[0]; - EXPECT_EQ("iso a4", paper.display_name); + // media display name localization is handled in + // GetPrinterCapabilitiesOnBlockingPoolThread(). + EXPECT_EQ("", paper.display_name); EXPECT_EQ("iso_a4_210x297mm", paper.vendor_id); EXPECT_EQ(210000, paper.size_um.width()); EXPECT_EQ(297000, paper.size_um.height()); @@ -184,8 +186,9 @@ PrinterSemanticCapsAndDefaults caps; CapsAndDefaultsFromPrinter(*printer_, &caps); - - EXPECT_EQ("na legal", caps.default_paper.display_name); + // media display name localization is handled in + // GetPrinterCapabilitiesOnBlockingPoolThread(). + EXPECT_EQ("", caps.default_paper.display_name); EXPECT_EQ("na_legal_8.5x14in", caps.default_paper.vendor_id); EXPECT_EQ(215900, caps.default_paper.size_um.width()); EXPECT_EQ(355600, caps.default_paper.size_um.height());
diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc index 59a5390..352d366 100644 --- a/remoting/client/plugin/chromoting_instance.cc +++ b/remoting/client/plugin/chromoting_instance.cc
@@ -228,17 +228,14 @@ // Initialize TaskScheduler. TaskScheduler::StartWithDefaultParams() doesn't // work on NACL. base::TaskScheduler::Create("RemotingChromeApp"); - constexpr int kBackgroundMaxThreads = 1; - constexpr int kBackgroundBlockingMaxThreads = 2; - constexpr int kForegroundMaxThreads = 1; - constexpr int kForegroundBlockingMaxThreads = 2; + // TODO(etiennep): Change this to 2 in future CL. + constexpr int kBackgroundMaxThreads = 3; + constexpr int kForegroundMaxThreads = 3; constexpr base::TimeDelta kSuggestedReclaimTime = base::TimeDelta::FromSeconds(30); base::TaskScheduler::GetInstance()->Start( {{kBackgroundMaxThreads, kSuggestedReclaimTime}, - {kBackgroundBlockingMaxThreads, kSuggestedReclaimTime}, - {kForegroundMaxThreads, kSuggestedReclaimTime}, - {kForegroundBlockingMaxThreads, kSuggestedReclaimTime}}); + {kForegroundMaxThreads, kSuggestedReclaimTime}}); return true; }
diff --git a/remoting/host/clipboard_x11.cc b/remoting/host/clipboard_x11.cc index 7f83e8b..fd88eed 100644 --- a/remoting/host/clipboard_x11.cc +++ b/remoting/host/clipboard_x11.cc
@@ -54,6 +54,7 @@ } ClipboardX11::~ClipboardX11() { + x_connection_watch_controller_ = nullptr; if (display_) XCloseDisplay(display_); }
diff --git a/remoting/host/file_transfer/file_chooser_linux.cc b/remoting/host/file_transfer/file_chooser_linux.cc index 8ff9145e2..e80a389 100644 --- a/remoting/host/file_transfer/file_chooser_linux.cc +++ b/remoting/host/file_transfer/file_chooser_linux.cc
@@ -9,6 +9,7 @@ #include <utility> #include "base/bind.h" +#include "base/memory/weak_ptr.h" #include "base/threading/sequence_bound.h" #include "base/threading/sequenced_task_runner_handle.h" #include "remoting/base/string_resources.h" @@ -19,11 +20,13 @@ namespace { +class FileChooserLinux; + class GtkFileChooserOnUiThread { public: GtkFileChooserOnUiThread( - scoped_refptr<base::SequencedTaskRunner> source_task_runner, - FileChooser::ResultCallback callback); + scoped_refptr<base::SequencedTaskRunner> caller_task_runner, + base::WeakPtr<FileChooserLinux> file_chooser_linux); ~GtkFileChooserOnUiThread(); @@ -37,12 +40,12 @@ GtkWidget*, int); - void RunCallback(FileChooser::Result file); + void RunCallback(FileChooser::Result result); void CleanUp(); GObject* file_dialog_ = nullptr; - scoped_refptr<base::SequencedTaskRunner> source_task_runner_; - FileChooser::ResultCallback callback_; + scoped_refptr<base::SequencedTaskRunner> caller_task_runner_; + base::WeakPtr<FileChooserLinux> file_chooser_linux_; DISALLOW_COPY_AND_ASSIGN(GtkFileChooserOnUiThread); }; @@ -57,17 +60,21 @@ // FileChooser implementation. void Show() override; + void RunCallback(FileChooser::Result result); + private: - base::SequenceBound<GtkFileChooserOnUiThread> gtk_file_chooser_; + FileChooser::ResultCallback callback_; + base::SequenceBound<GtkFileChooserOnUiThread> gtk_file_chooser_on_ui_thread_; + base::WeakPtrFactory<FileChooserLinux> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(FileChooserLinux); }; GtkFileChooserOnUiThread::GtkFileChooserOnUiThread( - scoped_refptr<base::SequencedTaskRunner> source_task_runner, - FileChooser::ResultCallback callback) - : source_task_runner_(std::move(source_task_runner)), - callback_(std::move(callback)) {} + scoped_refptr<base::SequencedTaskRunner> caller_task_runner, + base::WeakPtr<FileChooserLinux> file_chooser_linux) + : caller_task_runner_(std::move(caller_task_runner)), + file_chooser_linux_(std::move(file_chooser_linux)) {} GtkFileChooserOnUiThread::~GtkFileChooserOnUiThread() { // Delete the dialog if it hasn't been already. @@ -108,9 +115,10 @@ #endif } -void GtkFileChooserOnUiThread::RunCallback(FileChooser::Result file) { - source_task_runner_->PostTask( - FROM_HERE, base::BindOnce(std::move(callback_), std::move(file))); +void GtkFileChooserOnUiThread::RunCallback(FileChooser::Result result) { + caller_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&FileChooserLinux::RunCallback, + file_chooser_linux_, std::move(result))); } void GtkFileChooserOnUiThread::CleanUp() { @@ -140,12 +148,20 @@ FileChooserLinux::FileChooserLinux( scoped_refptr<base::SequencedTaskRunner> ui_task_runner, ResultCallback callback) - : gtk_file_chooser_(ui_task_runner, - base::SequencedTaskRunnerHandle::Get(), - std::move(callback)) {} + : callback_(std::move(callback)), weak_ptr_factory_(this) { + gtk_file_chooser_on_ui_thread_ = + base::SequenceBound<GtkFileChooserOnUiThread>( + ui_task_runner, base::SequencedTaskRunnerHandle::Get(), + weak_ptr_factory_.GetWeakPtr()); +} void FileChooserLinux::Show() { - gtk_file_chooser_.Post(FROM_HERE, &GtkFileChooserOnUiThread::Show); + gtk_file_chooser_on_ui_thread_.Post(FROM_HERE, + &GtkFileChooserOnUiThread::Show); +} + +void FileChooserLinux::RunCallback(FileChooser::Result result) { + std::move(callback_).Run(std::move(result)); } FileChooserLinux::~FileChooserLinux() = default;
diff --git a/services/device/public/mojom/screen_orientation.mojom b/services/device/public/mojom/screen_orientation.mojom index 5054616..575880e 100644 --- a/services/device/public/mojom/screen_orientation.mojom +++ b/services/device/public/mojom/screen_orientation.mojom
@@ -12,21 +12,9 @@ UnlockOrientation(); }; -// ScreenOrientationListener is expected to be used when the platform requires -// heavy work in order to accurately know the screen orientation. -// For example, on Android, this is required for Jelly Bean, where there is no -// API to be notified of a screen orientation change of 180 degrees. +// NOTE: this could probably be merged with `ScreenOrientation`. It used to be a +// separate service for Android Jelly Bean devices. interface ScreenOrientationListener { - // The renderer process is now using the Screen Orientation API and informs - // the browser process that it should start accurately listening to the screen - // orientation if it wasn't already. - Start(); - - // The renderer process is no longer using the Screen Orientation API and - // informs the browser process that it can stop accurately listening to the - // screen orientation if no other process cares about it. - Stop(); - // Queries whether accelerometer auto rotation of screen orientation is // enabled, or the user has locked the screen orientation at the OS level. // This can be called at any time, whether or not the listener is started.
diff --git a/services/device/screen_orientation/android/java/src/org/chromium/device/screen_orientation/ScreenOrientationListener.java b/services/device/screen_orientation/android/java/src/org/chromium/device/screen_orientation/ScreenOrientationListener.java index f6f9c9a3..f825756 100644 --- a/services/device/screen_orientation/android/java/src/org/chromium/device/screen_orientation/ScreenOrientationListener.java +++ b/services/device/screen_orientation/android/java/src/org/chromium/device/screen_orientation/ScreenOrientationListener.java
@@ -7,10 +7,8 @@ import android.provider.Settings; import org.chromium.base.ContextUtils; -import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; -import org.chromium.ui.display.DisplayAndroid; /** * Android implementation details for device::ScreenOrientationListenerAndroid. @@ -18,26 +16,6 @@ @JNINamespace("device") class ScreenOrientationListener { @CalledByNative - static void startAccurateListening() { - ThreadUtils.runOnUiThread(new Runnable() { - @Override - public void run() { - DisplayAndroid.startAccurateListening(); - } - }); - } - - @CalledByNative - static void stopAccurateListening() { - ThreadUtils.runOnUiThread(new Runnable() { - @Override - public void run() { - DisplayAndroid.stopAccurateListening(); - } - }); - } - - @CalledByNative static boolean isAutoRotateEnabledByUser() { return Settings.System.getInt(ContextUtils.getApplicationContext().getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0)
diff --git a/services/device/screen_orientation/screen_orientation_listener_android.cc b/services/device/screen_orientation/screen_orientation_listener_android.cc index 9927b33..11f69ce 100644 --- a/services/device/screen_orientation/screen_orientation_listener_android.cc +++ b/services/device/screen_orientation/screen_orientation_listener_android.cc
@@ -19,40 +19,10 @@ std::move(request)); } -ScreenOrientationListenerAndroid::ScreenOrientationListenerAndroid() - : listeners_count_(0) {} +ScreenOrientationListenerAndroid::ScreenOrientationListenerAndroid() = default; ScreenOrientationListenerAndroid::~ScreenOrientationListenerAndroid() { DCHECK(base::MessageLoopCurrentForIO::IsSet()); - if (listeners_count_ > 0) { - Java_ScreenOrientationListener_startAccurateListening( - base::android::AttachCurrentThread()); - } -} - -void ScreenOrientationListenerAndroid::Start() { - DCHECK(base::MessageLoopCurrentForIO::IsSet()); - ++listeners_count_; - if (listeners_count_ == 1) { - // Ask the ScreenOrientationListener (Java) to start accurately listening to - // the screen orientation. It keep track of the number of start request if - // it is already running an accurate listening. - Java_ScreenOrientationListener_startAccurateListening( - base::android::AttachCurrentThread()); - } -} - -void ScreenOrientationListenerAndroid::Stop() { - DCHECK(base::MessageLoopCurrentForIO::IsSet()); - DCHECK(listeners_count_ > 0); - --listeners_count_; - if (listeners_count_ == 0) { - // Ask the ScreenOrientationListener (Java) to stop accurately listening to - // the screen orientation. It will actually stop only if the number of stop - // requests matches the number of start requests. - Java_ScreenOrientationListener_stopAccurateListening( - base::android::AttachCurrentThread()); - } } void ScreenOrientationListenerAndroid::IsAutoRotateEnabledByUser(
diff --git a/services/device/screen_orientation/screen_orientation_listener_android.h b/services/device/screen_orientation/screen_orientation_listener_android.h index e86012d..5c10cb7 100644 --- a/services/device/screen_orientation/screen_orientation_listener_android.h +++ b/services/device/screen_orientation/screen_orientation_listener_android.h
@@ -21,13 +21,9 @@ ScreenOrientationListenerAndroid(); // mojom::ScreenOrientationListener: - void Start() override; - void Stop() override; void IsAutoRotateEnabledByUser( IsAutoRotateEnabledByUserCallback callback) override; - int listeners_count_; - DISALLOW_COPY_AND_ASSIGN(ScreenOrientationListenerAndroid); };
diff --git a/services/media_session/controlling_media_playback.md b/services/media_session/controlling_media_playback.md index e2936b1..848d501 100644 --- a/services/media_session/controlling_media_playback.md +++ b/services/media_session/controlling_media_playback.md
@@ -10,12 +10,6 @@ # Audio Focus -To get started the following flags should be enabled: - -* #enable-audio-focus - This enables audio focus on Chrome. -* #enable-arc-unified-audio-focus - enables ARC++ integration. This means that - ARC++ apps will request audio focus from Chrome (Chrome OS only). - When audio focus is enabled all the different media sessions will request audio focus. A media session can request three different types of audio focus: @@ -63,12 +57,16 @@ session changes. This can be used to determine whether there is any current media playback. -# Active Media Controller +# Media Controller Manager -The media session service also exposes a [MediaController](https://cs.chromium.org/chromium/src/services/media_session/public/mojom/media_controller.mojom) -mojo API. This can be used to control the active media session. It will -automatically route commands to the active media session, even if the media -session changes. +The media session service also exposes a [MediaControllerManager](https://cs.chromium.org/chromium/src/services/media_session/public/mojom/media_controller.mojom) +mojo API. This can be used to create a [MediaController](https://cs.chromium.org/chromium/src/services/media_session/public/mojom/media_controller.mojom) +instance. These can be used to control and observe a media session. This can +be an individual media session or the active media session. + +If the controller is created using `CreateActiveMediaController` then it will +follow the active media session. This means you do not need to create a new +media controller if the active media session changes. **There is also a MediaSession mojo API. This is used for session / service communication and should not be used for control.**. @@ -92,4 +90,13 @@ [//services/media_session/public/cpp/test](https://cs.chromium.org/chromium/src/services/media_session/public/cpp/test/) directory also contains a number of other useful test utilities. +# Current Media Session service integrations + +The following clients are integrated with the media session service and expose +a media session and request audio focus: + +* content::WebContents +* ARC++ apps (requires Android Pie) +* Assistant + Questions? - Feel free to reach out to beccahughes@chromium.org.
diff --git a/services/service_manager/sandbox/linux/sandbox_linux.cc b/services/service_manager/sandbox/linux/sandbox_linux.cc index 570ba812..253787b 100644 --- a/services/service_manager/sandbox/linux/sandbox_linux.cc +++ b/services/service_manager/sandbox/linux/sandbox_linux.cc
@@ -107,10 +107,15 @@ base::CommandLine::ForCurrentProcess()->InitFromArgv(exec); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - command_line->AppendSwitchASCII( - switches::kProcessType, - command_line->GetSwitchValueASCII(switches::kProcessType) - .append("-broker")); + std::string new_process_type = + command_line->GetSwitchValueASCII(switches::kProcessType); + if (!new_process_type.empty()) { + new_process_type.append("-broker"); + } else { + new_process_type = "broker"; + } + + command_line->AppendSwitchASCII(switches::kProcessType, new_process_type); if (broker_side_hook) CHECK(std::move(broker_side_hook).Run(options));
diff --git a/services/ws/client_root.cc b/services/ws/client_root.cc index b11c60d..4e4d284 100644 --- a/services/ws/client_root.cc +++ b/services/ws/client_root.cc
@@ -52,7 +52,10 @@ ClientRoot::ClientRoot(WindowTree* window_tree, aura::Window* window, bool is_top_level) - : window_tree_(window_tree), window_(window), is_top_level_(is_top_level) { + : window_tree_(window_tree), + window_(window), + is_top_level_(is_top_level), + last_visible_(!is_top_level && window->IsVisible()) { window_->AddObserver(this); if (window_->GetHost()) window->GetHost()->AddObserver(this); @@ -282,6 +285,18 @@ ProxyWindow::GetMayBeNull(window_)->local_surface_id_allocation()); } +void ClientRoot::NotifyClientOfVisibilityChange(bool new_value) { + if (is_top_level_ || last_visible_ == new_value) + return; + + last_visible_ = new_value; + if (!window_tree_->property_change_tracker_->IsProcessingChangeForWindow( + window_, ClientChangeType::kVisibility)) { + window_tree_->window_tree_client_->OnWindowVisibilityChanged( + window_tree_->TransportIdForWindow(window_), last_visible_); + } +} + void ClientRoot::OnPositionInRootChanged() { DCHECK(!is_top_level_); gfx::Rect bounds_in_screen = window_->GetBoundsInScreen(); @@ -350,6 +365,8 @@ HandleBoundsOrScaleFactorChange(window->GetBoundsInScreen()); else CheckForScaleFactorChange(); + + NotifyClientOfVisibilityChange(window_->IsVisible()); } void ClientRoot::OnWindowRemovingFromRootWindow(aura::Window* window, @@ -357,6 +374,8 @@ DCHECK_EQ(window, window_); DCHECK(window->GetHost()); window->GetHost()->RemoveObserver(this); + if (!new_root) + NotifyClientOfVisibilityChange(false); } void ClientRoot::OnWillMoveWindowToDisplay(aura::Window* window, @@ -374,6 +393,14 @@ } } +void ClientRoot::OnWindowVisibilityChanged(aura::Window* window, bool visible) { + if (!is_top_level_ && + !window_tree_->property_change_tracker_->IsProcessingChangeForWindow( + window, ClientChangeType::kVisibility)) { + NotifyClientOfVisibilityChange(window_->IsVisible()); + } +} + void ClientRoot::OnHostResized(aura::WindowTreeHost* host) { // This function is also called when the device-scale-factor changes too. CheckForScaleFactorChange();
diff --git a/services/ws/client_root.h b/services/ws/client_root.h index 0b8fc66..6c33a76 100644 --- a/services/ws/client_root.h +++ b/services/ws/client_root.h
@@ -121,6 +121,10 @@ void NotifyClientOfNewBounds(const gfx::Rect& old_bounds); + // If necessary, notifies the client that the visibility of the Window is + // |new_value|. This does nothing for top-levels. + void NotifyClientOfVisibilityChange(bool new_value); + // Callback when the position of |window_|, relative to the root, changes. // This is *only* called for non-top-levels. void OnPositionInRootChanged(); @@ -139,6 +143,7 @@ void OnWillMoveWindowToDisplay(aura::Window* window, int64_t new_display_id) override; void OnDidMoveWindowToDisplay(aura::Window* window) override; + void OnWindowVisibilityChanged(aura::Window* window, bool visible) override; // aura::WindowTreeHostObserver: void OnHostResized(aura::WindowTreeHost* host) override; @@ -174,6 +179,9 @@ // Last bounds sent to the client. gfx::Rect last_bounds_; + // Last visibility value sent to the client. This is not used for top-levels. + bool last_visible_; + // If true, SetBoundsInScreenFromClient() is setting the window bounds. bool setting_bounds_from_client_ = false;
diff --git a/services/ws/client_root_unittest.cc b/services/ws/client_root_unittest.cc index 2bf941a..f47cc5f4 100644 --- a/services/ws/client_root_unittest.cc +++ b/services/ws/client_root_unittest.cc
@@ -5,6 +5,7 @@ #include "services/ws/client_root.h" #include <string> +#include <vector> #include "services/ws/public/cpp/property_type_converters.h" #include "services/ws/public/mojom/window_manager.mojom.h" @@ -120,5 +121,131 @@ EXPECT_EQ(gfx::Rect(112, 64, 3, 4), iter->bounds2); } +TEST(ClientRoot, EmbedWindowServerVisibilityChanges) { + WindowServiceTestSetup setup; + aura::Window* embed_window = setup.window_tree_test_helper()->NewWindow(); + embed_window->SetBounds(gfx::Rect(1, 2, 3, 4)); + aura::Window* window = setup.window_tree_test_helper()->NewWindow(); + aura::Window* top_level = + setup.window_tree_test_helper()->NewTopLevelWindow(); + std::unique_ptr<EmbeddingHelper> embedding_helper = + setup.CreateEmbedding(embed_window); + ASSERT_TRUE(embedding_helper); + window->AddChild(embed_window); + top_level->AddChild(window); + std::vector<Change>* embedding_changes = embedding_helper->changes(); + embedding_changes->clear(); + embed_window->Show(); + // As |top_level| isn't shown, no change yet. + EXPECT_TRUE(embedding_changes->empty()); + top_level->Show(); + EXPECT_TRUE(embedding_changes->empty()); + + // As all ancestor are visible, showing the window should notify the client. + window->Show(); + ASSERT_EQ(1u, embedding_changes->size()); + { + const Change& show_change = (*embedding_changes)[0]; + EXPECT_EQ(CHANGE_TYPE_NODE_VISIBILITY_CHANGED, show_change.type); + EXPECT_TRUE(show_change.bool_value); + EXPECT_EQ(embedding_helper->window_tree_test_helper->TransportIdForWindow( + embed_window), + show_change.window_id); + } + embedding_changes->clear(); + + // Hiding an ancestor should trigger hiding the window. + top_level->Hide(); + ASSERT_EQ(1u, embedding_changes->size()); + { + const Change& hide_change = (*embedding_changes)[0]; + EXPECT_EQ(CHANGE_TYPE_NODE_VISIBILITY_CHANGED, hide_change.type); + EXPECT_FALSE(hide_change.bool_value); + EXPECT_EQ(embedding_helper->window_tree_test_helper->TransportIdForWindow( + embed_window), + hide_change.window_id); + } + embedding_changes->clear(); + + // Showing an ancestor should trigger showing the window. + top_level->Show(); + ASSERT_EQ(1u, embedding_changes->size()); + { + const Change& show_change = (*embedding_changes)[0]; + EXPECT_EQ(CHANGE_TYPE_NODE_VISIBILITY_CHANGED, show_change.type); + EXPECT_TRUE(show_change.bool_value); + EXPECT_EQ(embedding_helper->window_tree_test_helper->TransportIdForWindow( + embed_window), + show_change.window_id); + } + embedding_changes->clear(); + + // Removing an ancestor from the WindowTreeHost implicitly hides the window. + top_level->RemoveChild(window); + ASSERT_EQ(1u, embedding_changes->size()); + { + const Change& hide_change = (*embedding_changes)[0]; + EXPECT_EQ(CHANGE_TYPE_NODE_VISIBILITY_CHANGED, hide_change.type); + EXPECT_FALSE(hide_change.bool_value); + EXPECT_EQ(embedding_helper->window_tree_test_helper->TransportIdForWindow( + embed_window), + hide_change.window_id); + } + embedding_changes->clear(); + + // Adding an ancestor to the WindowTreeHost implicitly shows the window. + top_level->AddChild(window); + { + auto iter = FirstChangeOfType(*embedding_changes, + CHANGE_TYPE_NODE_VISIBILITY_CHANGED); + ASSERT_NE(iter, embedding_changes->end()); + const Change& show_change = *iter; + EXPECT_EQ(CHANGE_TYPE_NODE_VISIBILITY_CHANGED, show_change.type); + EXPECT_TRUE(show_change.bool_value); + EXPECT_EQ(embedding_helper->window_tree_test_helper->TransportIdForWindow( + embed_window), + show_change.window_id); + } + embedding_changes->clear(); + + embed_window->Hide(); + ASSERT_EQ(1u, embedding_changes->size()); + { + const Change& hide_change = (*embedding_changes)[0]; + EXPECT_EQ(CHANGE_TYPE_NODE_VISIBILITY_CHANGED, hide_change.type); + EXPECT_FALSE(hide_change.bool_value); + EXPECT_EQ(embedding_helper->window_tree_test_helper->TransportIdForWindow( + embed_window), + hide_change.window_id); + } +} + +TEST(ClientRoot, EmbedWindowClientVisibilityChanges) { + WindowServiceTestSetup setup; + aura::Window* embed_window = setup.window_tree_test_helper()->NewWindow(); + embed_window->SetBounds(gfx::Rect(1, 2, 3, 4)); + aura::Window* window = setup.window_tree_test_helper()->NewWindow(); + aura::Window* top_level = + setup.window_tree_test_helper()->NewTopLevelWindow(); + std::unique_ptr<EmbeddingHelper> embedding_helper = + setup.CreateEmbedding(embed_window); + ASSERT_TRUE(embedding_helper); + window->AddChild(embed_window); + top_level->AddChild(window); + std::vector<Change>* embedding_changes = embedding_helper->changes(); + embedding_changes->clear(); + + // Changes initiated by the client should not callback to the client. + embedding_helper->window_tree_test_helper->SetWindowVisibility(embed_window, + true); + EXPECT_TRUE(embed_window->TargetVisibility()); + EXPECT_TRUE(embedding_changes->empty()); + + embedding_helper->window_tree_test_helper->SetWindowVisibility(embed_window, + false); + EXPECT_FALSE(embed_window->TargetVisibility()); + EXPECT_TRUE(embedding_changes->empty()); +} + } // namespace } // namespace ws
diff --git a/services/ws/window_tree.cc b/services/ws/window_tree.cc index 876495a..4aef294 100644 --- a/services/ws/window_tree.cc +++ b/services/ws/window_tree.cc
@@ -682,6 +682,7 @@ parent = nullptr; if (!IsWindowKnown(transient_parent)) transient_parent = nullptr; + const bool is_top_level = IsTopLevel(window); mojom::WindowDataPtr window_data(mojom::WindowData::New()); window_data->parent_id = parent ? TransportIdForWindow(parent) : kInvalidTransportId; @@ -691,10 +692,12 @@ transient_parent ? TransportIdForWindow(transient_parent) : kInvalidTransportId; window_data->bounds = - IsTopLevel(window) ? window->GetBoundsInScreen() : window->bounds(); + is_top_level ? window->GetBoundsInScreen() : window->bounds(); window_data->properties = window_service_->property_converter()->GetTransportProperties(window); - window_data->visible = window->TargetVisibility(); + window_data->visible = (!IsClientRootWindow(window) || is_top_level) + ? window->TargetVisibility() + : window->IsVisible(); return window_data; }
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 7e9331e..b2712d5 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -4102,6 +4102,12 @@ "test": "media_unittests" }, { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "modular_unittests" + }, + { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_unittests.filter" ], @@ -4147,19 +4153,19 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "web_engine_browsertests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "web_engine_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "web_runner_integration_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "webrunner_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "webrunner_unittests" } ] }, @@ -4304,6 +4310,17 @@ "test": "media_unittests" }, { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1" + } + ] + }, + "test": "modular_unittests" + }, + { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_unittests.filter" ], @@ -4384,29 +4401,29 @@ } ] }, + "test": "web_engine_browsertests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1" + } + ] + }, + "test": "web_engine_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1" + } + ] + }, "test": "web_runner_integration_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1" - } - ] - }, - "test": "webrunner_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1" - } - ] - }, - "test": "webrunner_unittests" } ] }, @@ -4551,6 +4568,17 @@ "test": "media_unittests" }, { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1" + } + ] + }, + "test": "modular_unittests" + }, + { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_unittests.filter" ], @@ -4645,29 +4673,29 @@ } ] }, + "test": "web_engine_browsertests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1" + } + ] + }, + "test": "web_engine_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1" + } + ] + }, "test": "web_runner_integration_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1" - } - ] - }, - "test": "webrunner_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1" - } - ] - }, - "test": "webrunner_unittests" } ], "isolated_scripts": [
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index ace672ef..72d3422 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -822,6 +822,20 @@ }, { "args": [ + "--qemu-require-kvm" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1" + } + ] + }, + "test": "modular_unittests" + }, + { + "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_unittests.filter", "--qemu-require-kvm" ], @@ -933,35 +947,35 @@ } ] }, + "test": "web_engine_browsertests" + }, + { + "args": [ + "--qemu-require-kvm" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1" + } + ] + }, + "test": "web_engine_unittests" + }, + { + "args": [ + "--qemu-require-kvm" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1" + } + ] + }, "test": "web_runner_integration_tests" - }, - { - "args": [ - "--qemu-require-kvm" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1" - } - ] - }, - "test": "webrunner_browsertests" - }, - { - "args": [ - "--qemu-require-kvm" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1" - } - ] - }, - "test": "webrunner_unittests" } ] },
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 80512bb..a47920b 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -1572,6 +1572,10 @@ "label": "//third_party/minizip:minizip_uncompress_fuzzer", "type": "fuzzer", }, + "modular_unittests": { + "label": "//fuchsia/modular:modular_unittests", + "type": "console_test_launcher", + }, "mojo_core_channel_fuzzer": { "label": "//mojo/core:mojo_core_channel_fuzzer", "type": "fuzzer", @@ -2675,6 +2679,14 @@ "label": "//components/exo/wayland:wayland_client_perftests", "type": "windowed_test_launcher", }, + "web_engine_browsertests": { + "label": "//fuchsia/engine:web_engine_browsertests", + "type": "console_test_launcher", + }, + "web_engine_unittests": { + "label": "//fuchsia/engine:web_engine_unittests", + "type": "console_test_launcher", + }, "web_icon_sizes_fuzzer": { "label": "//third_party/blink/renderer/platform:web_icon_sizes_fuzzer", "type": "fuzzer", @@ -2760,14 +2772,6 @@ "label": "//third_party/blink/renderer/controller:webkit_unit_tests", "type": "console_test_launcher", }, - "webrunner_browsertests": { - "label": "//fuchsia:webrunner_browsertests", - "type": "console_test_launcher", - }, - "webrunner_unittests": { - "label": "//fuchsia:webrunner_unittests", - "type": "console_test_launcher", - }, "webusb_descriptors_fuzzer": { "label": "//device/usb:webusb_descriptors_fuzzer", "type": "fuzzer",
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 27c8800..888e6b5 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -2754,6 +2754,7 @@ 'http_service_tests': {}, 'ipc_tests': {}, 'media_unittests': {}, + 'modular_unittests': {}, 'mojo_unittests': { 'args': [ '--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_unittests.filter', @@ -2773,9 +2774,9 @@ '--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ui_base_unittests.filter', ], }, + 'web_engine_browsertests': {}, + 'web_engine_unittests': {}, 'web_runner_integration_tests': {}, - 'webrunner_browsertests': {}, - 'webrunner_unittests': {}, }, 'gl_gtests': {
diff --git a/testing/scripts/run_performance_tests.py b/testing/scripts/run_performance_tests.py index f795877..deabbfa 100755 --- a/testing/scripts/run_performance_tests.py +++ b/testing/scripts/run_performance_tests.py
@@ -29,19 +29,21 @@ It currently runs several benchmarks. The benchmarks it will execute are based on the shard it is running on and the sharding_map_path. -If this is executed with a non-telemetry perf test, the flag --non-telemetry +If this is executed with a gtest perf test, the flag --non-telemetry has to be passed in to the script so the script knows it is running an executable and not the run_benchmark command. The results of running the benchmark are put in separate directories per benchmark. Two files will be present in each directory; perf_results.json, which -is the perf specific results (with unenforced format, could be histogram, -legacy, or chartjson), and test_results.json, which is a JSON test results +is the perf specific results (with unenforced format, could be histogram or +graph json), and test_results.json, which is a JSON test results format file -(https://www.chromium.org/developers/the-json-test-results-format) +https://chromium.googlesource.com/chromium/src/+/master/docs/testing/json_test_results_format.md -This script was derived from run_telemetry_benchmark_as_googletest, and calls -into that script. +TESTING: +To test changes to this script, please run +cd tools/perf +./run_tests ScriptsSmokeTest.testRunPerformanceTests """ import argparse @@ -73,30 +75,39 @@ # (it seems to unset DISPLAY). CHROME_SANDBOX_ENV = 'CHROME_DEVEL_SANDBOX' CHROME_SANDBOX_PATH = '/opt/chromium/chrome_sandbox' +SHARD_MAPS_DIRECTORY = os.path.join( + os.path.dirname(__file__), '..', '..', 'tools', 'perf', 'core', + 'shard_maps') -def get_sharding_map_path(args): - return os.path.join( - os.path.dirname(__file__), '..', '..', 'tools', 'perf', 'core', - 'shard_maps', args.test_shard_map_filename) +class OutputFilePaths(object): + """Provide paths to where results outputs should be written. -def write_results( - perf_test_name, perf_results, json_test_results, benchmark_log, - isolated_out_dir, encoded): - benchmark_path = os.path.join(isolated_out_dir, perf_test_name) + The process_perf_results.py merge script later will pull all of these + together, so that's why they aren't in the standard locations. Also, + note that because of the OBBS (One Build Bot Step), Telemetry + has multiple tests running on a single shard, so we need to prefix + these locations with a directory named by the benchmark name. + """ - os.makedirs(benchmark_path) - with open(os.path.join(benchmark_path, 'perf_results.json'), 'w') as f: - # non telemetry perf results are already json encoded - if encoded: - f.write(perf_results) - else: - json.dump(perf_results, f) - with open(os.path.join(benchmark_path, 'test_results.json'), 'w') as f: - json.dump(json_test_results, f) + def __init__(self, isolated_out_dir, perf_test_name): + self.benchmark_path = os.path.join(isolated_out_dir, perf_test_name) - with open(os.path.join(benchmark_path, 'benchmark_log.txt'), 'w') as f: - f.write(benchmark_log) + def SetUp(self): + os.makedirs(self.benchmark_path) + return self + + @property + def perf_results(self): + return os.path.join(self.benchmark_path, 'perf_results.json') + + @property + def test_results(self): + return os.path.join(self.benchmark_path, 'test_results.json') + + @property + def logs(self): + return os.path.join(self.benchmark_path, 'benchmark_log.txt') def print_duration(step, start): @@ -107,131 +118,242 @@ return sys.platform == 'cygwin' or sys.platform.startswith('win') -def execute_gtest_perf_test(args, rest_args): +class GtestCommandGenerator(object): + def __init__(self, options): + self._options = options + + def generate(self): + """Generate the command to run to start the gtest perf test. + + Returns: + list of strings, the executable and its arguments. + """ + return ([self._get_executable()] + + self._generate_filter_args() + + self._generate_repeat_args() + + self._generate_also_run_disabled_tests_args() + + self._generate_output_args() + + self._get_passthrough_args() + ) + + def _get_executable(self): + executable = self._options.executable + if IsWindows(): + return r'.\%s.exe' % executable + else: + return './%s' % executable + + def _get_passthrough_args(self): + return self._options.passthrough_args + + def _generate_filter_args(self): + if self._options.isolated_script_test_filter: + filter_list = common.extract_filter_list( + self._options.isolated_script_test_filter) + return ['--gtest_filter=' + ':'.join(filter_list)] + return [] + + def _generate_repeat_args(self): + # TODO(crbug.com/920002): Support --isolated-script-test-repeat. + return [] + + def _generate_also_run_disabled_tests_args(self): + # TODO(crbug.com/920002): Support + # --isolated-script-test-also-run-disabled-tests. + return [] + + def _generate_output_args(self): + output_args = [] + # These flags are to make sure that test output perf metrics in the log. + if not '--verbose' in self._options.passthrough_args: + output_args.append('--verbose') + if (not '--test-launcher-print-test-stdio=always' + in self._options.passthrough_args): + output_args.append('--test-launcher-print-test-stdio=always') + return output_args + + +def write_legacy_test_results(return_code, output_filepath): + # TODO(crbug.com/920002): Fix to output + # https://chromium.googlesource.com/chromium/src/+/master/docs/testing/json_test_results_format.md + valid = (return_code == 0) + failures = [] if valid else ['(entire test suite)'] + output_json = { + 'valid': valid, + 'failures': failures, + } + with open(output_filepath, 'w') as fh: + json.dump(output_json, fh) + + +def execute_gtest_perf_test(command_generator, output_paths, use_xvfb=False): env = os.environ.copy() # Assume we want to set up the sandbox environment variables all the # time; doing so is harmless on non-Linux platforms and is needed # all the time on Linux. env[CHROME_SANDBOX_ENV] = CHROME_SANDBOX_PATH + env['CHROME_HEADLESS'] = '1' - rc = 0 + return_code = 0 try: - executable = rest_args[0] - extra_flags = [] - if len(rest_args) > 1: - extra_flags = rest_args[1:] - - # These flags are to make sure that test output perf metrics in the log. - if not '--verbose' in extra_flags: - extra_flags.append('--verbose') - if not '--test-launcher-print-test-stdio=always' in extra_flags: - extra_flags.append('--test-launcher-print-test-stdio=always') - if args.isolated_script_test_filter: - filter_list = common.extract_filter_list( - args.isolated_script_test_filter) - extra_flags.append('--gtest_filter=' + ':'.join(filter_list)) - - if IsWindows(): - executable = '.\%s.exe' % executable + command = command_generator.generate() + if use_xvfb: + return_code = xvfb.run_executable( + command, env, stdoutfile=output_paths.logs) else: - executable = './%s' % executable - with common.temporary_file() as tempfile_path: - env['CHROME_HEADLESS'] = '1' - cmd = [executable] + extra_flags - - if args.xvfb: - rc = xvfb.run_executable(cmd, env, stdoutfile=tempfile_path) - else: - rc = test_env.run_command_with_output(cmd, env=env, - stdoutfile=tempfile_path) - - # Now get the correct json format from the stdout to write to the perf - # results file - results_processor = ( - generate_legacy_perf_dashboard_json.LegacyResultsProcessor()) - charts = results_processor.GenerateJsonResults(tempfile_path) + return_code = test_env.run_command_with_output( + command, env=env, stdoutfile=output_paths.logs) + # Get the correct json format from the stdout to write to the perf + # results file. + results_processor = generate_legacy_perf_dashboard_json.\ + LegacyResultsProcessor() + graph_json_string = results_processor.GenerateJsonResults( + output_paths.logs) + with open(output_paths.perf_results, 'w') as fh: + fh.write(graph_json_string) except Exception: traceback.print_exc() - rc = 1 + return_code = 1 + write_legacy_test_results(return_code, output_paths.test_results) + return return_code - valid = (rc == 0) - failures = [] if valid else ['(entire test suite)'] - output_json = { - 'valid': valid, - 'failures': failures, - } - return rc, charts, output_json + +class TelemetryCommandGenerator(object): + def __init__(self, benchmark, options, + stories=None, is_reference=False): + self.benchmark = benchmark + self._options = options + self._stories = stories + self._is_reference = is_reference + + def generate(self, output_dir): + """Generate the command to run to start the benchmark. + + Args: + output_dir: The directory to configure the command to put output files + into. + + Returns: + list of strings, the executable and its arguments. + """ + return ([sys.executable, self._options.executable] + + [self.benchmark] + + self._generate_filter_args() + + self._generate_repeat_args() + + self._generate_also_run_disabled_tests_args() + + self._generate_output_args(output_dir) + + self._generate_story_range_args() + + self._generate_reference_build_args() + + self._get_passthrough_args() + ) + + def _get_passthrough_args(self): + return self._options.passthrough_args + + def _generate_filter_args(self): + if self._options.isolated_script_test_filter: + filter_list = common.extract_filter_list( + self._options.isolated_script_test_filter) + # Need to convert this to a valid regex. + filter_regex = '(' + '|'.join(filter_list) + ')' + return ['--story-filter=' + filter_regex] + return [] + + def _generate_repeat_args(self): + if self._options.isolated_script_test_repeat: + return ['--pageset-repeat=' + str( + self._options.isolated_script_test_repeat)] + return [] + + def _generate_also_run_disabled_tests_args(self): + if self._options.isolated_script_test_also_run_disabled_tests: + return ['--also-run-disabled-tests'] + return [] + + def _generate_output_args(self, output_dir): + return ['--output-format=json-test-results', + '--output-format=histograms', + '--output-dir=' + output_dir] + + def _generate_story_range_args(self): + """Returns arguments that limit the stories to be run inside the benchmark. + """ + range_arguments = [] + if self._stories: + if 'begin' in self._stories.keys(): + range_arguments.append('--story-shard-begin-index=%d' % ( + self._stories['begin'])) + if 'end' in self._stories.keys(): + range_arguments.append('--story-shard-end-index=%d' % ( + self._stories['end'])) + return range_arguments + + def _generate_reference_build_args(self): + if self._is_reference: + return ['--browser=reference', + '--max-failures=5', + '--output-trace-tag=_ref'] + return [] def execute_telemetry_benchmark( - benchmark, isolated_out_dir, args, rest_args, is_reference, stories=None): + command_generator, output_paths, use_xvfb=False): start = time.time() - # While we are between chartjson and histogram set we need - # to determine which output format to look for or see if it was - # already passed in in which case that format applies to all benchmarks - # in this run. - is_histograms = append_output_format(args, rest_args) - # Insert benchmark name as first argument to run_benchmark call - # which is the first argument in the rest_args. Also need to append - # output format and smoke test mode. - per_benchmark_args = (rest_args[:1] + [benchmark] + rest_args[1:]) - benchmark_name = benchmark - if is_reference: - # Telemetry uses the last argument for --browser, so it's okay - # to not check for an existing browser argument. See crbug.com/928928. - per_benchmark_args.append('--browser=reference') - per_benchmark_args.append('--max-failures=5') - per_benchmark_args.append('--output-trace-tag=_ref') - benchmark_name = benchmark + '.reference' - # If we are only running a subset of stories, add in the begin and end - # index. - if stories: - if 'begin' in stories.keys(): - per_benchmark_args.append( - ('--story-shard-begin-index=%d' % stories['begin'])) - if 'end' in stories.keys(): - per_benchmark_args.append( - ('--story-shard-end-index=%d' % stories['end'])) + env = os.environ.copy() + env['CHROME_HEADLESS'] = '1' + # Assume we want to set up the sandbox environment variables all the + # time; doing so is harmless on non-Linux platforms and is needed + # all the time on Linux. + env[CHROME_SANDBOX_ENV] = CHROME_SANDBOX_PATH - # We don't care exactly what these are. In particular, the perf results - # could be any format (chartjson, legacy, histogram). We just pass these - # through, and expose these as results for this task. - rc, perf_results, json_test_results, benchmark_log = ( - execute_telemetry_benchmark_helper( - args, per_benchmark_args, is_histograms)) + return_code = 1 + temp_dir = tempfile.mkdtemp('telemetry') + try: + command = command_generator.generate(temp_dir) + if use_xvfb: + return_code = xvfb.run_executable( + command, env=env, stdoutfile=output_paths.logs) + else: + return_code = test_env.run_command_with_output( + command, env=env, stdoutfile=output_paths.logs) + expected_perf_filename = os.path.join(temp_dir, 'histograms.json') + shutil.move(expected_perf_filename, output_paths.perf_results) + expected_results_filename = os.path.join(temp_dir, 'test-results.json') + shutil.move(expected_results_filename, output_paths.test_results) + except Exception: + print ('The following exception may have prevented the code from ' + 'outputing structured test results and perf results output:') + print traceback.format_exc() + finally: + # Add ignore_errors=True because otherwise rmtree may fail due to leaky + # processes of tests are still holding opened handles to files under + # |tempfile_dir|. For example, see crbug.com/865896 + shutil.rmtree(temp_dir, ignore_errors=True) - write_results( - benchmark_name, perf_results, json_test_results, benchmark_log, - isolated_out_dir, False) + print_duration('executing benchmark %s' % command_generator.benchmark, start) - print_duration('executing benchmark %s' % benchmark_name, start) - return rc + if return_code: + return return_code + return 0 - -def execute_telemetry_benchmark_helper(args, rest_args, histogram_results): - """Run benchmark with args. - - Args: - args: the option object resulted from parsing commandline args required for - IsolatedScriptTest contract (see - https://cs.chromium.org/chromium/build/scripts/slave/recipe_modules/chromium_tests/steps.py?rcl=d31f256fb860701e6dc02544f2beffe4e17c9b92&l=1639). - rest_args: the args (list of strings) for running Telemetry benchmark. - histogram_results: a boolean describes whether to output histograms format - for the benchmark. - - Returns: a tuple of (rc, perf_results, json_test_results, benchmark_log) - rc: the return code of benchmark - perf_results: json object contains the perf test results - json_test_results: json object contains the Pass/Fail data of the benchmark. - benchmark_log: string contains the stdout/stderr of the benchmark run. - """ - # TODO(crbug.com/920002): These arguments cannot go into - # run_performance_tests.py because - # run_gtest_perf_tests.py does not yet support them. Note that ideally - # we would use common.BaseIsolatedScriptArgsAdapter, but this will take - # a good deal of refactoring to accomplish. +def parse_arguments(args): parser = argparse.ArgumentParser() + parser.add_argument('executable', help='The name of the executable to run.') + parser.add_argument( + '--isolated-script-test-output', required=True) + # The following two flags may be passed in sometimes by Pinpoint + # or by the recipe, but they don't do anything. crbug.com/927482. + parser.add_argument( + '--isolated-script-test-chartjson-output', required=False) + parser.add_argument( + '--isolated-script-test-perf-output', required=False) + + parser.add_argument( + '--isolated-script-test-filter', type=str, required=False) + + # Note that the following three arguments are only supported by Telemetry + # tests right now. See crbug.com/920002. parser.add_argument( '--isolated-script-test-repeat', type=int, required=False) parser.add_argument( @@ -240,126 +362,6 @@ parser.add_argument( '--isolated-script-test-also-run-disabled-tests', default=False, action='store_true', required=False) - # Parse leftover args not already parsed in run_performance_tests.py or in - # main(). - args, rest_args = parser.parse_known_args(args=rest_args, namespace=args) - - env = os.environ.copy() - env['CHROME_HEADLESS'] = '1' - - # Assume we want to set up the sandbox environment variables all the - # time; doing so is harmless on non-Linux platforms and is needed - # all the time on Linux. - env[CHROME_SANDBOX_ENV] = CHROME_SANDBOX_PATH - tempfile_dir = tempfile.mkdtemp('telemetry') - benchmark_log = '' - stdoutfile = os.path.join(tempfile_dir, 'benchmark_log.txt') - valid = True - num_failures = 0 - perf_results = None - json_test_results = None - - results = None - cmd_args = rest_args - if args.isolated_script_test_filter: - filter_list = common.extract_filter_list(args.isolated_script_test_filter) - # Need to convert this to a valid regex. - filter_regex = '(' + '|'.join(filter_list) + ')' - cmd_args.append('--story-filter=' + filter_regex) - if args.isolated_script_test_repeat: - cmd_args.append('--pageset-repeat=' + str(args.isolated_script_test_repeat)) - if args.isolated_script_test_also_run_disabled_tests: - cmd_args.append('--also-run-disabled-tests') - cmd_args.append('--output-dir=' + tempfile_dir) - cmd_args.append('--output-format=json-test-results') - cmd = [sys.executable] + cmd_args - rc = 1 # Set default returncode in case there is an exception. - try: - if args.xvfb: - rc = xvfb.run_executable(cmd, env=env, stdoutfile=stdoutfile) - else: - rc = test_env.run_command_with_output(cmd, env=env, stdoutfile=stdoutfile) - - with open(stdoutfile) as f: - benchmark_log = f.read() - - # If we have also output chartjson read it in and return it. - # results-chart.json is the file name output by telemetry when the - # chartjson output format is included - tempfile_name = None - if histogram_results: - tempfile_name = os.path.join(tempfile_dir, 'histograms.json') - else: - tempfile_name = os.path.join(tempfile_dir, 'results-chart.json') - - if tempfile_name is not None: - with open(tempfile_name) as f: - perf_results = json.load(f) - - # test-results.json is the file name output by telemetry when the - # json-test-results format is included - tempfile_name = os.path.join(tempfile_dir, 'test-results.json') - with open(tempfile_name) as f: - json_test_results = json.load(f) - num_failures = json_test_results['num_failures_by_type'].get('FAIL', 0) - valid = bool(rc == 0 or num_failures != 0) - - except Exception: - traceback.print_exc() - if results: - print 'results, which possibly caused exception: %s' % json.dumps( - results, indent=2) - valid = False - finally: - # Add ignore_errors=True because otherwise rmtree may fail due to leaky - # processes of tests are still holding opened handles to files under - # |tempfile_dir|. For example, see crbug.com/865896 - shutil.rmtree(tempfile_dir, ignore_errors=True) - - if not valid and num_failures == 0: - if rc == 0: - rc = 1 # Signal an abnormal exit. - - return rc, perf_results, json_test_results, benchmark_log - - -def append_output_format(args, rest_args): - # We need to determine if the output format is already passed in - # or if we need to define it for this benchmark - perf_output_specified = False - is_histograms = False - if args.output_format: - for output_format in args.output_format: - if 'histograms' in output_format: - perf_output_specified = True - is_histograms = True - if 'chartjson' in output_format: - perf_output_specified = True - rest_args.append('--output-format=' + output_format) - # When crbug.com/744736 is resolved we no longer have to check - # the type of format per benchmark and can rely on it being passed - # in as an arg as all benchmarks will output the same format. - if not perf_output_specified: - rest_args.append('--output-format=histograms') - is_histograms = True - return is_histograms - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument( - '--isolated-script-test-output', required=True) - # These two flags are passed in from the swarming recipe - # but will no longer be needed when we migrate to this new recipe. - # For now we need to recognize them so they don't get passed - # through to telemetry. - parser.add_argument( - '--isolated-script-test-chartjson-output', required=False) - parser.add_argument( - '--isolated-script-test-perf-output', required=False) - - parser.add_argument( - '--isolated-script-test-filter', type=str, required=False) parser.add_argument('--xvfb', help='Start xvfb.', action='store_true') parser.add_argument('--non-telemetry', help='Type of perf test', type=bool, default=False) @@ -374,76 +376,103 @@ # Some executions may have a different sharding scheme and/or set of tests. # These files must live in src/tools/perf/core/shard_maps parser.add_argument('--test-shard-map-filename', type=str, required=False) - parser.add_argument('--output-format', action='append') parser.add_argument('--run-ref-build', help='Run test on reference browser', action='store_true') + parser.add_argument('--passthrough-arg', + help='Arguments to pass directly through to the test ' + 'executable.', action='append', + dest='passthrough_args', + default=[]) + options, leftover_args = parser.parse_known_args(args) + options.passthrough_args.extend(leftover_args) + return options - args, rest_args = parser.parse_known_args() - isolated_out_dir = os.path.dirname(args.isolated_script_test_output) - return_code = 0 - if args.non_telemetry: - benchmark_name = args.gtest_benchmark_name +def main(): + args = sys.argv[1:] # Skip program name. + options = parse_arguments(args) + isolated_out_dir = os.path.dirname(options.isolated_script_test_output) + overall_return_code = 0 + + if options.non_telemetry: + command_generator = GtestCommandGenerator(options) + benchmark_name = options.gtest_benchmark_name # Fallback to use the name of the executable if flag isn't set. # TODO(crbug.com/870899): remove fallback logic and raise parser error if - # -non-telemetry is set but --gtest-benchmark-name is not set once pinpoint + # --non-telemetry is set but --gtest-benchmark-name is not set once pinpoint # is converted to always pass --gtest-benchmark-name flag. if not benchmark_name: - benchmark_name = rest_args[0] - return_code, charts, output_json = execute_gtest_perf_test( - args, rest_args) - - write_results(benchmark_name, charts, output_json, - benchmark_log='Not available for C++ perf test', - isolated_out_dir=isolated_out_dir, encoded=True) + benchmark_name = options.executable + output_paths = OutputFilePaths(isolated_out_dir, benchmark_name).SetUp() + overall_return_code = execute_gtest_perf_test( + command_generator, output_paths, options.xvfb) else: # If the user has supplied a list of benchmark names, execute those instead - # of the entire suite of benchmarks. - if args.benchmarks: - benchmarks = args.benchmarks.split(',') + # of using the shard map. + if options.benchmarks: + benchmarks = options.benchmarks.split(',') for benchmark in benchmarks: - return_code = (execute_telemetry_benchmark( - benchmark, isolated_out_dir, args, rest_args, False) or return_code) - else: + output_paths = OutputFilePaths(isolated_out_dir, benchmark).SetUp() + command_generator = TelemetryCommandGenerator( + benchmark, options) + return_code = execute_telemetry_benchmark( + command_generator, output_paths, options.xvfb) + overall_return_code = return_code or overall_return_code + if options.run_ref_build: + print ('Not running reference build. --run-ref-build argument is only ' + 'supported for sharded benchmarks. It is simple to support ' + 'this for unsharded --benchmarks if needed.') + elif options.test_shard_map_filename: # First determine what shard we are running on to know how to - # index into the bot map to get list of benchmarks to run. + # index into the bot map to get list of telemetry benchmarks to run. total_shards = None shard_index = None - + shard_map_path = os.path.join(SHARD_MAPS_DIRECTORY, + options.test_shard_map_filename) env = os.environ.copy() if 'GTEST_TOTAL_SHARDS' in env: total_shards = env['GTEST_TOTAL_SHARDS'] if 'GTEST_SHARD_INDEX' in env: shard_index = env['GTEST_SHARD_INDEX'] - - if not (total_shards or shard_index): - raise Exception('Shard indicators must be present for perf tests') - - sharding_map_path = get_sharding_map_path(args) - - # Copy sharding map file to isolated_out_dir so that the collect script + if not total_shards or not shard_index: + raise Exception( + 'Sharded Telemetry perf tests must either specify --benchmarks ' + 'list or have shard indicator environment variables present.') + # Copy sharding map file to isolated_out_dir so that the merge script # can collect it later. + # TODO(crouleau): Move this step over to merge script + # (process_perf_results.py). shutil.copyfile( - sharding_map_path, + shard_map_path, os.path.join(isolated_out_dir, 'benchmarks_shard_map.json')) + with open(shard_map_path) as f: + shard_map = json.load(f) + benchmarks_and_stories = shard_map[shard_index]['benchmarks'] - with open(sharding_map_path) as f: - sharding_map = json.load(f) - sharding = sharding_map[shard_index]['benchmarks'] - - for benchmark, stories in sharding.iteritems(): - # Need to run the benchmark twice on browser and reference build - return_code = (execute_telemetry_benchmark( - benchmark, isolated_out_dir, args, rest_args, - False, stories=stories) or return_code) - # We ignore the return code of the reference build since we do not - # monitor it. - if args.run_ref_build: + for benchmark, stories in benchmarks_and_stories.iteritems(): + # Need to run the benchmark on both latest browser and reference build. + output_paths = OutputFilePaths(isolated_out_dir, benchmark).SetUp() + command_generator = TelemetryCommandGenerator( + benchmark, options, stories=stories) + return_code = execute_telemetry_benchmark( + command_generator, output_paths, options.xvfb) + overall_return_code = return_code or overall_return_code + if options.run_ref_build: + reference_benchmark = benchmark + '.reference' + reference_output_paths = OutputFilePaths( + isolated_out_dir, reference_benchmark).SetUp() + reference_command_generator = TelemetryCommandGenerator( + reference_benchmark, options, + stories=stories, is_reference=True) + # We intentionally ignore the return code of the reference build. execute_telemetry_benchmark( - benchmark, isolated_out_dir, args, rest_args, True, - stories=stories) + reference_command_generator, reference_output_paths, + options.xvfb) + else: + raise Exception('Telemetry tests must provide either a shard map or a ' + '--benchmarks list so that we know which stories to run.') - return return_code + return overall_return_code # This is not really a "script test" so does not need to manually add
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 3bc3ff6..4f1bc3ef 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -434,7 +434,6 @@ "web/web_frame_load_type.h", "web/web_frame_owner_properties.h", "web/web_frame_serializer.h", - "web/web_frame_serializer_cache_control_policy.h", "web/web_frame_serializer_client.h", "web/web_frame_widget.h", "web/web_global_object_reuse_policy.h",
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index 90428d78..fc29734 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -59,6 +59,7 @@ "notifications/notification.mojom", "page/display_cutout.mojom", "payments/payment_app.mojom", + "picture_in_picture/picture_in_picture.mojom", "plugins/plugin_registry.mojom", "presentation/presentation.mojom", "quota/quota_dispatcher_host.mojom", @@ -110,6 +111,7 @@ "//services/device/public/mojom", "//services/network/public/mojom", "//services/service_manager/public/mojom", + "//services/viz/public/interfaces", "//skia/public/interfaces", "//third_party/blink/public:web_feature_mojo_bindings", "//third_party/blink/public/mojom/usb",
diff --git a/fuchsia/common/OWNERS b/third_party/blink/public/mojom/picture_in_picture/OWNERS similarity index 100% copy from fuchsia/common/OWNERS copy to third_party/blink/public/mojom/picture_in_picture/OWNERS
diff --git a/third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom b/third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom new file mode 100644 index 0000000..9146179e --- /dev/null +++ b/third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom
@@ -0,0 +1,58 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module blink.mojom; + +import "services/viz/public/interfaces/compositing/surface_id.mojom"; +import "ui/gfx/geometry/mojo/geometry.mojom"; + +// PictureInPictureDelegate is associated to a PictureInPictureService. It will +// be notified by running its callbacks when a change happened to the running +// Picture-in-Picture session. +interface PictureInPictureDelegate { + PictureInPictureWindowSizeChanged(gfx.mojom.Size size); +}; + +// PictureInPictureService is a Document-associated interface that lives in +// the browser process. It is responsible for implementing the browser-side +// support for https://wicg.github.io/picture-in-picture and manages all +// picture-in-picture interactions for Document. Picture-in-picture allows +// a Document to display a video in an always-on-top floating window with +// basic playback functionality (e.g. play and pause). +interface PictureInPictureService { + // Notify the service that it should start a Picture-in-Picture session. + // player_id: WebMediaPlayer id used to control playback via the + // Picture-in-Picture window. + // surface_id: SurfaceId to be shown in the Picture-in-Picture window. + // natural_size: Size of the video frames. + // show_play_pause_button: Whether a play/pause control should be offered in + // the Picture-in-Picture window. + // NOTE: this method shouldn't be called twice in a raw. An interleaved call + // to EndSession() would be expected. In case of some parameters have changed, + // UpdateSession() should be called. + StartSession( + uint32 player_id, + viz.mojom.SurfaceId? surface_id, + gfx.mojom.Size natural_size, + bool show_play_pause_button) => (gfx.mojom.Size size); + + // Notify the service to end the Picture-in-Picture session. It will close + // the Picture-in-Picture window. + EndSession() => (); + + // Notify the service that some information about the client have change. All + // information associated with the Picture-in-Picture session are sent again. + // A Picture-in-Picture session must already be active from a previous call to + // StartSession(). + UpdateSession( + uint32 player_id, + viz.mojom.SurfaceId? surface_id, + gfx.mojom.Size natural_size, + bool show_play_pause_button); + + // Associate a PictureInPictureDelegate with the service. All changes in + // Picture-in-Picture states will be sent to the delegate. Only one delegate + // can be set at a time. + SetDelegate(PictureInPictureDelegate delegate); +};
diff --git a/third_party/blink/public/platform/web_layer_tree_view.h b/third_party/blink/public/platform/web_layer_tree_view.h index 08ee91c9..ca17af9 100644 --- a/third_party/blink/public/platform/web_layer_tree_view.h +++ b/third_party/blink/public/platform/web_layer_tree_view.h
@@ -78,10 +78,6 @@ // Initialization and lifecycle -------------------------------------- - // Sets the root of the tree. The root is set by way of the constructor. - virtual void SetRootLayer(scoped_refptr<cc::Layer>) {} - virtual void ClearRootLayer() {} - // TODO(loyso): This should use CompositorAnimationHost. crbug.com/584551 virtual cc::AnimationHost* CompositorAnimationHost() { return nullptr; }
diff --git a/third_party/blink/public/platform/web_media_player.h b/third_party/blink/public/platform/web_media_player.h index edfea4c..55115e8 100644 --- a/third_party/blink/public/platform/web_media_player.h +++ b/third_party/blink/public/platform/web_media_player.h
@@ -31,7 +31,9 @@ #ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_MEDIA_PLAYER_H_ #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_MEDIA_PLAYER_H_ +#include "base/optional.h" #include "base/time/time.h" +#include "components/viz/common/surfaces/surface_id.h" #include "third_party/blink/public/platform/web_callbacks.h" #include "third_party/blink/public/platform/web_content_decryption_module.h" #include "third_party/blink/public/platform/web_media_source.h" @@ -137,14 +139,6 @@ kAlways, }; - // Callback to get notified when the Picture-in-Picture window is opened. - using PipWindowOpenedCallback = base::OnceCallback<void(const WebSize&)>; - // Callback to get notified when Picture-in-Picture window is closed. - using PipWindowClosedCallback = base::OnceClosure; - // Callback to get notified when the Picture-in-Picture window is resized. - using PipWindowResizedCallback = - base::RepeatingCallback<void(const WebSize&)>; - virtual ~WebMediaPlayer() = default; virtual LoadTiming Load(LoadType, const WebMediaPlayerSource&, CorsMode) = 0; @@ -158,16 +152,13 @@ // Enter Picture-in-Picture and notifies Blink with window size // when video successfully enters Picture-in-Picture. - virtual void EnterPictureInPicture(PipWindowOpenedCallback) = 0; + // TODO(mlamouri): rename to "OnRequestPictureInPicture". + virtual void EnterPictureInPicture() = 0; // Exit Picture-in-Picture and notifies Blink when it's done. - virtual void ExitPictureInPicture(PipWindowClosedCallback) = 0; + virtual void ExitPictureInPicture() = 0; // Assign custom controls to the Picture-in-Picture window. virtual void SetPictureInPictureCustomControls( const std::vector<PictureInPictureControlInfo>&) = 0; - // Register a callback that will be run when the Picture-in-Picture window - // is resized. - virtual void RegisterPictureInPictureWindowResizeCallback( - PipWindowResizedCallback) = 0; virtual void RequestRemotePlayback() {} virtual void RequestRemotePlaybackControl() {} @@ -411,6 +402,18 @@ virtual void OnBecameVisible() {} virtual bool IsOpaque() const { return false; } + + // Returns the id given by the WebMediaPlayerDelegate. This is used by the + // Blink code to pass a player id to mojo services. + // TODO(mlamouri): remove this and move the id handling to Blink. + virtual int GetDelegateId() { return -1; }; + + // Returns the SurfaceId the video element is currently using. + // Returns base::nullopt if the element isn't a video or doesn't have a + // SurfaceId associated to it. + virtual base::Optional<viz::SurfaceId> GetSurfaceId() { + return base::nullopt; + } }; } // namespace blink
diff --git a/third_party/blink/public/platform/web_media_player_client.h b/third_party/blink/public/platform/web_media_player_client.h index 092556d..b8ae775 100644 --- a/third_party/blink/public/platform/web_media_player_client.h +++ b/third_party/blink/public/platform/web_media_player_client.h
@@ -179,6 +179,15 @@ // Request the player to pause playback. virtual void RequestPause() = 0; + // Notify the client that one of the state used by Picture-in-Picture has + // changed. The client will then have to poll the states from the associated + // WebMediaPlayer. + // The states are: + // - Delegate ID; + // - Surface ID; + // - Natural Size. + virtual void OnPictureInPictureStateChange() = 0; + protected: ~WebMediaPlayerClient() = default; };
diff --git a/third_party/blink/public/web/web_frame_serializer.h b/third_party/blink/public/web/web_frame_serializer.h index 6d6a2cdc..0c1d1c9 100644 --- a/third_party/blink/public/web/web_frame_serializer.h +++ b/third_party/blink/public/web/web_frame_serializer.h
@@ -35,7 +35,6 @@ #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_thread_safe_data.h" #include "third_party/blink/public/platform/web_url.h" -#include "third_party/blink/public/web/web_frame_serializer_cache_control_policy.h" namespace blink {
diff --git a/third_party/blink/public/web/web_frame_serializer_cache_control_policy.h b/third_party/blink/public/web/web_frame_serializer_cache_control_policy.h deleted file mode 100644 index 0ab5c95..0000000 --- a/third_party/blink/public/web/web_frame_serializer_cache_control_policy.h +++ /dev/null
@@ -1,25 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_FRAME_SERIALIZER_CACHE_CONTROL_POLICY_H_ -#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_FRAME_SERIALIZER_CACHE_CONTROL_POLICY_H_ - -namespace blink { - -// WebFrameSerializerCacheControlPolicy configures how WebFrameSerializer -// processes resources with different Cache-Control headers. By default, frame -// serialization encompasses all resources in a page. If it is desirable to -// serialize only those resources that could be stored by a http cache, the -// other options may be used. -// TODO(dewittj): Add more policies for subframes and subresources. -enum class WebFrameSerializerCacheControlPolicy { - kNone = 0, - kFailForNoStoreMainFrame, - kSkipAnyFrameOrResourceMarkedNoStore, - kLast = kSkipAnyFrameOrResourceMarkedNoStore, -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_FRAME_SERIALIZER_CACHE_CONTROL_POLICY_H_
diff --git a/third_party/blink/public/web/web_widget_client.h b/third_party/blink/public/web/web_widget_client.h index d9db9bc..12c49040 100644 --- a/third_party/blink/public/web/web_widget_client.h +++ b/third_party/blink/public/web/web_widget_client.h
@@ -64,6 +64,10 @@ public: virtual ~WebWidgetClient() = default; + // Sets the root layer of the tree in the compositor. It may be null to remove + // the root layer in which case nothing would be shown by the compositor. + virtual void SetRootLayer(scoped_refptr<cc::Layer>) {} + // Called to request a BeginMainFrame from the compositor. For tests with // single thread and no scheduler, the impl should schedule a task to run // a synchronous composite.
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index e01fe47..1f6a622 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -28,9 +28,6 @@ # Config for code that builds as part of core. config("config") { defines = [ "BLINK_CORE_IMPLEMENTATION=1" ] - if (is_chromecast) { - defines += [ "BLINK_MEDIA_LOG=LOG(INFO)" ] - } if (blink_animation_use_time_delta) { defines += [ "BLINK_ANIMATION_USE_TIME_DELTA" ] }
diff --git a/third_party/blink/renderer/core/exported/web_frame_serializer.cc b/third_party/blink/renderer/core/exported/web_frame_serializer.cc index 1da02c7..c97eeab 100644 --- a/third_party/blink/renderer/core/exported/web_frame_serializer.cc +++ b/third_party/blink/renderer/core/exported/web_frame_serializer.cc
@@ -37,7 +37,6 @@ #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_document_loader.h" #include "third_party/blink/public/web/web_frame.h" -#include "third_party/blink/public/web/web_frame_serializer_cache_control_policy.h" #include "third_party/blink/public/web/web_frame_serializer_client.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/element.h"
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc index 50746d2..78061fc 100644 --- a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc +++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -360,17 +360,10 @@ WidgetClient()->SetWindowRect(rect_in_screen); } -void WebPagePopupImpl::SetRootLayer(cc::Layer* layer) { - root_layer_ = layer; - +void WebPagePopupImpl::SetRootLayer(scoped_refptr<cc::Layer> layer) { is_accelerated_compositing_active_ = !!layer; - if (layer_tree_view_) { - if (root_layer_) { - layer_tree_view_->SetRootLayer(root_layer_); - } else { - layer_tree_view_->ClearRootLayer(); - } - } + root_layer_ = std::move(layer); + widget_client_->SetRootLayer(root_layer_); } void WebPagePopupImpl::SetSuppressFrameRequestsWorkaroundFor704763Only(
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.h b/third_party/blink/renderer/core/exported/web_page_popup_impl.h index b23e0cc..f2e2c01 100644 --- a/third_party/blink/renderer/core/exported/web_page_popup_impl.h +++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.h
@@ -117,7 +117,7 @@ explicit WebPagePopupImpl(WebWidgetClient*); void DestroyPage(); - void SetRootLayer(cc::Layer*); + void SetRootLayer(scoped_refptr<cc::Layer>); WebRect WindowRectInScreen() const;
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index 9841972..ccfafca 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -3202,7 +3202,7 @@ visual_viewport_container_layer_ = visual_viewport.ContainerLayer(); root_layer_ = root_graphics_layer_->CcLayer(); UpdateDeviceEmulationTransform(); - layer_tree_view_->SetRootLayer(root_layer_); + AsWidget().client->SetRootLayer(root_layer_); // We register viewport layers here since there may not be a layer // tree view prior to this point. RegisterViewportLayersWithCompositor(); @@ -3214,7 +3214,7 @@ // commits until Blink generates invalidations so we don't // attempt to paint too early in the next page load. scoped_defer_main_frame_update_ = layer_tree_view_->DeferMainFrameUpdate(); - layer_tree_view_->ClearRootLayer(); + AsWidget().client->SetRootLayer(nullptr); layer_tree_view_->ClearViewportLayers(); } } @@ -3223,16 +3223,14 @@ if (!layer_tree_view_) return; - if (layer) { - root_layer_ = layer; - layer_tree_view_->SetRootLayer(root_layer_); - } else { - root_layer_ = nullptr; + root_layer_ = std::move(layer); + AsWidget().client->SetRootLayer(root_layer_); + + if (!root_layer_) { // This means that we're transitioning to a new page. Suppress // commits until Blink generates invalidations so we don't // attempt to paint too early in the next page load. scoped_defer_main_frame_update_ = layer_tree_view_->DeferMainFrameUpdate(); - layer_tree_view_->ClearRootLayer(); layer_tree_view_->ClearViewportLayers(); } }
diff --git a/third_party/blink/renderer/core/frame/frame_serializer.cc b/third_party/blink/renderer/core/frame/frame_serializer.cc index 2f4ef44..f40bb3e68 100644 --- a/third_party/blink/renderer/core/frame/frame_serializer.cc +++ b/third_party/blink/renderer/core/frame/frame_serializer.cc
@@ -470,12 +470,8 @@ void FrameSerializer::AddToResources( const String& mime_type, - ResourceHasCacheControlNoStoreHeader has_cache_control_no_store_header, scoped_refptr<const SharedBuffer> data, const KURL& url) { - if (delegate_.ShouldSkipResource(has_cache_control_no_store_header)) - return; - if (!data) { DLOG(ERROR) << "No data for resource " << url.GetString(); return; @@ -502,9 +498,6 @@ scoped_refptr<const SharedBuffer> data = image->GetImage()->Data(); AddToResources(image->GetResponse().MimeType(), - image->HasCacheControlNoStoreHeader() - ? kHasCacheControlNoStoreHeader - : kNoCacheControlNoStoreHeader, data, url); // If we're already reporting time for CSS serialization don't report it for @@ -526,11 +519,7 @@ scoped_refptr<const SharedBuffer> data(font.ResourceBuffer()); - AddToResources(font.GetResponse().MimeType(), - font.HasCacheControlNoStoreHeader() - ? kHasCacheControlNoStoreHeader - : kNoCacheControlNoStoreHeader, - data, font.Url()); + AddToResources(font.GetResponse().MimeType(), data, font.Url()); } void FrameSerializer::RetrieveResourcesForProperties(
diff --git a/third_party/blink/renderer/core/frame/frame_serializer.h b/third_party/blink/renderer/core/frame/frame_serializer.h index d372a97..28491e7 100644 --- a/third_party/blink/renderer/core/frame/frame_serializer.h +++ b/third_party/blink/renderer/core/frame/frame_serializer.h
@@ -63,11 +63,6 @@ STACK_ALLOCATED(); public: - enum ResourceHasCacheControlNoStoreHeader { - kNoCacheControlNoStoreHeader, - kHasCacheControlNoStoreHeader - }; - class Delegate { public: virtual ~Delegate() = default; @@ -97,11 +92,6 @@ // with a given URI. Used to deduplicate resources across multiple frames. virtual bool ShouldSkipResourceWithURL(const KURL&) { return false; } - // Tells whether to skip serialization of a subresource. - virtual bool ShouldSkipResource(ResourceHasCacheControlNoStoreHeader) { - return false; - } - // Returns custom attributes that need to add in order to serialize the // element. virtual Vector<Attribute> GetCustomAttributes(const Element&) { @@ -145,7 +135,6 @@ bool ShouldAddURL(const KURL&); void AddToResources(const String& mime_type, - ResourceHasCacheControlNoStoreHeader, scoped_refptr<const SharedBuffer>, const KURL&); void AddImageToResources(ImageResourceContent*, const KURL&);
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.cc b/third_party/blink/renderer/core/frame/frame_test_helpers.cc index 7bc1a38..5cdac28 100644 --- a/third_party/blink/renderer/core/frame/frame_test_helpers.cc +++ b/third_party/blink/renderer/core/frame/frame_test_helpers.cc
@@ -621,6 +621,10 @@ layer_tree_view_ = layer_tree_view_factory_.Initialize(delegate); } +void TestWebWidgetClient::SetRootLayer(scoped_refptr<cc::Layer> layer) { + layer_tree_view_->layer_tree_host()->SetRootLayer(std::move(layer)); +} + void TestWebWidgetClient::DidMeaningfulLayout( WebMeaningfulLayout meaningful_layout) { switch (meaningful_layout) {
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.h b/third_party/blink/renderer/core/frame/frame_test_helpers.h index 61158071..8d4bd567 100644 --- a/third_party/blink/renderer/core/frame/frame_test_helpers.h +++ b/third_party/blink/renderer/core/frame/frame_test_helpers.h
@@ -195,6 +195,7 @@ // WebWidgetClient: void ScheduleAnimation() override { animation_scheduled_ = true; } + void SetRootLayer(scoped_refptr<cc::Layer> layer) override; content::LayerTreeView* layer_tree_view() { return layer_tree_view_; }
diff --git a/third_party/blink/renderer/core/frame/picture_in_picture_controller.h b/third_party/blink/renderer/core/frame/picture_in_picture_controller.h index 98b35b80..87d82d73 100644 --- a/third_party/blink/renderer/core/frame/picture_in_picture_controller.h +++ b/third_party/blink/renderer/core/frame/picture_in_picture_controller.h
@@ -83,6 +83,8 @@ HTMLVideoElement*, const std::vector<PictureInPictureControlInfo>&) = 0; + // Notifies that one of the states used by Picture-in-Picture has changed. + virtual void OnPictureInPictureStateChange() = 0; void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index 526c8d9..7134994 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -1022,7 +1022,7 @@ TRACE_EVENT0("blink", "WebFrameWidgetImpl::SetIsAcceleratedCompositingActive(true)"); - layer_tree_view_->SetRootLayer(root_layer_); + Client()->SetRootLayer(root_layer_); UpdateLayerTreeViewport(); is_accelerated_compositing_active_ = true; } @@ -1039,15 +1039,15 @@ root_graphics_layer_ = layer; root_layer_ = layer ? layer->CcLayer() : nullptr; - SetIsAcceleratedCompositingActive(layer); + SetIsAcceleratedCompositingActive(!!layer); + // TODO(danakj): Is this called after Close?? (With a null layer?) if (!layer_tree_view_) return; - if (root_layer_) - layer_tree_view_->SetRootLayer(root_layer_); - else - layer_tree_view_->ClearRootLayer(); + // TODO(danakj): SetIsAcceleratedCompositingActive() also sets the root layer + // if it's not null.. + Client()->SetRootLayer(root_layer_); } void WebFrameWidgetImpl::SetRootLayer(scoped_refptr<cc::Layer> layer) { @@ -1055,13 +1055,13 @@ SetIsAcceleratedCompositingActive(!!layer); + // TODO(danakj): Is this called after Close?? (With a null layer?) if (!layer_tree_view_) return; - if (root_layer_) - layer_tree_view_->SetRootLayer(root_layer_); - else - layer_tree_view_->ClearRootLayer(); + // TODO(danakj): SetIsAcceleratedCompositingActive() also sets the root layer + // if it's not null.. + Client()->SetRootLayer(root_layer_); } WebLayerTreeView* WebFrameWidgetImpl::GetLayerTreeView() const {
diff --git a/third_party/blink/renderer/core/html/media/DEPS b/third_party/blink/renderer/core/html/media/DEPS new file mode 100644 index 0000000..7e0f628 --- /dev/null +++ b/third_party/blink/renderer/core/html/media/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+media/base/logging_override_if_enabled.h", +]
diff --git a/third_party/blink/renderer/core/html/media/html_audio_element.h b/third_party/blink/renderer/core/html/media/html_audio_element.h index 2463517..b6076b7 100644 --- a/third_party/blink/renderer/core/html/media/html_audio_element.h +++ b/third_party/blink/renderer/core/html/media/html_audio_element.h
@@ -55,6 +55,7 @@ void PictureInPictureControlClicked(const WebString& control_id) override { NOTREACHED(); } + void OnPictureInPictureStateChange() final { NOTREACHED(); } }; } // namespace blink
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc index c6b5f3c6..735bb92d 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element.cc +++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -32,6 +32,7 @@ #include "base/auto_reset.h" #include "base/debug/crash_logging.h" #include "base/memory/ptr_util.h" +#include "media/base/logging_override_if_enabled.h" #include "third_party/blink/public/platform/modules/remoteplayback/web_remote_playback_availability.h" #include "third_party/blink/public/platform/modules/remoteplayback/web_remote_playback_client.h" #include "third_party/blink/public/platform/modules/remoteplayback/web_remote_playback_state.h" @@ -109,10 +110,6 @@ #include "third_party/blink/renderer/platform/wtf/text/cstring.h" #include "third_party/blink/renderer/platform/wtf/time.h" -#ifndef BLINK_MEDIA_LOG -#define BLINK_MEDIA_LOG DVLOG(3) -#endif - #ifndef LOG_MEDIA_EVENTS // Default to not logging events because so many are generated they can // overwhelm the rest of the logging. @@ -520,7 +517,7 @@ media_controls_(nullptr), controls_list_(HTMLMediaElementControlsList::Create(this)), lazy_load_visibility_observer_(nullptr) { - BLINK_MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")"; + DVLOG(1) << "HTMLMediaElement(" << (void*)this << ")"; LocalFrame* frame = document.GetFrame(); if (frame) { @@ -535,7 +532,7 @@ } HTMLMediaElement::~HTMLMediaElement() { - BLINK_MEDIA_LOG << "~HTMLMediaElement(" << (void*)this << ")"; + DVLOG(1) << "~HTMLMediaElement(" << (void*)this << ")"; // audio_source_node_ is explicitly cleared by AudioNode::dispose(). // Since AudioNode::dispose() is guaranteed to be always called before @@ -556,7 +553,7 @@ } void HTMLMediaElement::DidMoveToNewDocument(Document& old_document) { - BLINK_MEDIA_LOG << "didMoveToNewDocument(" << (void*)this << ")"; + DVLOG(3) << "didMoveToNewDocument(" << (void*)this << ")"; load_timer_.MoveToNewTaskRunner( GetDocument().GetTaskRunner(TaskType::kInternalMedia)); @@ -627,9 +624,9 @@ const AttributeModificationParams& params) { const QualifiedName& name = params.name; if (name == kSrcAttr) { - BLINK_MEDIA_LOG << "parseAttribute(" << (void*)this - << ", kSrcAttr, old=" << params.old_value - << ", new=" << params.new_value << ")"; + DVLOG(2) << "parseAttribute(" << (void*)this + << ", kSrcAttr, old=" << params.old_value + << ", new=" << params.new_value << ")"; // Trigger a reload, as long as the 'src' attribute is present. if (!params.new_value.IsNull()) { ignore_preload_none_ = false; @@ -702,8 +699,7 @@ Node::InsertionNotificationRequest HTMLMediaElement::InsertedInto( ContainerNode& insertion_point) { - BLINK_MEDIA_LOG << "insertedInto(" << (void*)this << ", " << insertion_point - << ")"; + DVLOG(3) << "insertedInto(" << (void*)this << ", " << insertion_point << ")"; HTMLElement::InsertedInto(insertion_point); if (insertion_point.isConnected()) { @@ -723,8 +719,7 @@ } void HTMLMediaElement::RemovedFrom(ContainerNode& insertion_point) { - BLINK_MEDIA_LOG << "removedFrom(" << (void*)this << ", " << insertion_point - << ")"; + DVLOG(3) << "removedFrom(" << (void*)this << ", " << insertion_point << ")"; removed_from_document_timer_.StartOneShot(TimeDelta(), FROM_HERE); @@ -744,7 +739,7 @@ } void HTMLMediaElement::ScheduleTextTrackResourceLoad() { - BLINK_MEDIA_LOG << "scheduleTextTrackResourceLoad(" << (void*)this << ")"; + DVLOG(3) << "scheduleTextTrackResourceLoad(" << (void*)this << ")"; pending_action_flags_ |= kLoadTextTrackResource; @@ -767,8 +762,8 @@ void HTMLMediaElement::ScheduleEvent(Event* event) { #if LOG_MEDIA_EVENTS - BLINK_MEDIA_LOG << "ScheduleEvent(" << (void*)this << ")" - << " - scheduling '" << event->type() << "'"; + DVLOG(3) << "ScheduleEvent(" << (void*)this << ")" + << " - scheduling '" << event->type() << "'"; #endif async_event_queue_->EnqueueEvent(FROM_HERE, *event); } @@ -801,7 +796,7 @@ } void HTMLMediaElement::SetSrcObject(MediaStreamDescriptor* src_object) { - BLINK_MEDIA_LOG << "setSrcObject(" << (void*)this << ")"; + DVLOG(1) << "setSrcObject(" << (void*)this << ")"; src_object_ = src_object; InvokeLoadAlgorithm(); } @@ -828,14 +823,14 @@ break; } - BLINK_MEDIA_LOG << "canPlayType(" << (void*)this << ", " << mime_type - << ") -> " << can_play; + DVLOG(2) << "canPlayType(" << (void*)this << ", " << mime_type << ") -> " + << can_play; return can_play; } void HTMLMediaElement::load() { - BLINK_MEDIA_LOG << "load(" << (void*)this << ")"; + DVLOG(1) << "load(" << (void*)this << ")"; autoplay_policy_->TryUnlockingUserGesture(); @@ -848,7 +843,7 @@ // once microtask is implemented for "Await a stable state" step // in resource selection algorithm. void HTMLMediaElement::InvokeLoadAlgorithm() { - BLINK_MEDIA_LOG << "invokeLoadAlgorithm(" << (void*)this << ")"; + DVLOG(3) << "invokeLoadAlgorithm(" << (void*)this << ")"; // Perform the cleanup required for the resource load algorithm to run. StopPeriodicTimers(); @@ -979,7 +974,7 @@ } void HTMLMediaElement::InvokeResourceSelectionAlgorithm() { - BLINK_MEDIA_LOG << "invokeResourceSelectionAlgorithm(" << (void*)this << ")"; + DVLOG(3) << "invokeResourceSelectionAlgorithm(" << (void*)this << ")"; // The resource selection algorithm // 1 - Set the networkState to NETWORK_NO_SOURCE SetNetworkState(kNetworkNoSource); @@ -1025,7 +1020,7 @@ } void HTMLMediaElement::SelectMediaResource() { - BLINK_MEDIA_LOG << "selectMediaResource(" << (void*)this << ")"; + DVLOG(3) << "selectMediaResource(" << (void*)this << ")"; enum Mode { kObject, kAttribute, kChildren, kNothing }; Mode mode = kNothing; @@ -1067,8 +1062,7 @@ } UpdateDisplayState(); - BLINK_MEDIA_LOG << "selectMediaResource(" << (void*)this - << "), nothing to load"; + DVLOG(3) << "selectMediaResource(" << (void*)this << "), nothing to load"; return; } @@ -1083,18 +1077,18 @@ switch (mode) { case kObject: LoadSourceFromObject(); - BLINK_MEDIA_LOG << "selectMediaResource(" << (void*)this - << ", using 'srcObject' attribute"; + DVLOG(3) << "selectMediaResource(" << (void*)this + << ", using 'srcObject' attribute"; break; case kAttribute: LoadSourceFromAttribute(); - BLINK_MEDIA_LOG << "selectMediaResource(" << (void*)this - << "), using 'src' attribute url"; + DVLOG(3) << "selectMediaResource(" << (void*)this + << "), using 'src' attribute url"; break; case kChildren: LoadNextSourceChild(); - BLINK_MEDIA_LOG << "selectMediaResource(" << (void*)this - << "), using source element"; + DVLOG(3) << "selectMediaResource(" << (void*)this + << "), using source element"; break; default: NOTREACHED(); @@ -1117,8 +1111,7 @@ // If the src attribute's value is the empty string ... jump down to the // failed step below if (src_value.IsEmpty()) { - BLINK_MEDIA_LOG << "LoadSourceFromAttribute(" << (void*)this - << "), empty 'src'"; + DVLOG(3) << "LoadSourceFromAttribute(" << (void*)this << "), empty 'src'"; MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError, BuildElementErrorMessage("Empty src attribute")); return; @@ -1159,8 +1152,8 @@ if (source.IsURL()) { url = source.GetAsURL(); DCHECK(IsSafeToLoadURL(url, kComplain)); - BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ", " - << UrlForLoggingMedia(url) << ", " << content_type << ")"; + DVLOG(3) << "loadResource(" << (void*)this << ", " + << UrlForLoggingMedia(url) << ", " << content_type << ")"; } LocalFrame* frame = GetDocument().GetFrame(); @@ -1186,8 +1179,8 @@ // until proved otherwise. RemotePlaybackCompatibilityChanged(current_src_, false); - BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ") - current_src_ -> " - << UrlForLoggingMedia(current_src_); + DVLOG(3) << "loadResource(" << (void*)this << ") - current_src_ -> " + << UrlForLoggingMedia(current_src_); StartProgressEventTimer(); @@ -1219,8 +1212,8 @@ // including MediaSource blob URLs. if (!source.IsMediaStream() && !url.ProtocolIs("blob") && EffectivePreloadType() == WebMediaPlayer::kPreloadNone) { - BLINK_MEDIA_LOG << "loadResource(" << (void*)this - << ") : Delaying load because preload == 'none'"; + DVLOG(3) << "loadResource(" << (void*)this + << ") : Delaying load because preload == 'none'"; DeferLoad(); } else { StartPlayerLoad(); @@ -1470,9 +1463,8 @@ bool HTMLMediaElement::IsSafeToLoadURL(const KURL& url, InvalidURLAction action_if_invalid) { if (!url.IsValid()) { - BLINK_MEDIA_LOG << "isSafeToLoadURL(" << (void*)this << ", " - << UrlForLoggingMedia(url) - << ") -> FALSE because url is invalid"; + DVLOG(3) << "isSafeToLoadURL(" << (void*)this << ", " + << UrlForLoggingMedia(url) << ") -> FALSE because url is invalid"; return false; } @@ -1483,16 +1475,16 @@ kSecurityMessageSource, kErrorMessageLevel, "Not allowed to load local resource: " + url.ElidedString())); } - BLINK_MEDIA_LOG << "isSafeToLoadURL(" << (void*)this << ", " - << UrlForLoggingMedia(url) - << ") -> FALSE rejected by SecurityOrigin"; + DVLOG(3) << "isSafeToLoadURL(" << (void*)this << ", " + << UrlForLoggingMedia(url) + << ") -> FALSE rejected by SecurityOrigin"; return false; } if (!GetDocument().GetContentSecurityPolicy()->AllowMediaFromSource(url)) { - BLINK_MEDIA_LOG << "isSafeToLoadURL(" << (void*)this << ", " - << UrlForLoggingMedia(url) - << ") -> rejected by Content Security Policy"; + DVLOG(3) << "isSafeToLoadURL(" << (void*)this << ", " + << UrlForLoggingMedia(url) + << ") -> rejected by Content Security Policy"; return false; } @@ -1525,7 +1517,7 @@ } void HTMLMediaElement::WaitForSourceChange() { - BLINK_MEDIA_LOG << "waitForSourceChange(" << (void*)this << ")"; + DVLOG(3) << "waitForSourceChange(" << (void*)this << ")"; StopPeriodicTimers(); load_state_ = kWaitingForSource; @@ -1545,8 +1537,8 @@ } void HTMLMediaElement::NoneSupported(const String& input_message) { - BLINK_MEDIA_LOG << "NoneSupported(" << (void*)this << ", message='" - << input_message << "')"; + DVLOG(3) << "NoneSupported(" << (void*)this << ", message='" << input_message + << "')"; StopPeriodicTimers(); load_state_ = kWaitingForSource; @@ -1590,8 +1582,8 @@ void HTMLMediaElement::MediaEngineError(MediaError* err) { DCHECK_GE(ready_state_, kHaveMetadata); - BLINK_MEDIA_LOG << "mediaEngineError(" << (void*)this << ", " - << static_cast<int>(err->code()) << ")"; + DVLOG(3) << "mediaEngineError(" << (void*)this << ", " + << static_cast<int>(err->code()) << ")"; // 1 - The user agent should cancel the fetching process. StopPeriodicTimers(); @@ -1616,7 +1608,7 @@ } void HTMLMediaElement::CancelPendingEventsAndCallbacks() { - BLINK_MEDIA_LOG << "cancelPendingEventsAndCallbacks(" << (void*)this << ")"; + DVLOG(3) << "cancelPendingEventsAndCallbacks(" << (void*)this << ")"; async_event_queue_->CancelAllEvents(); for (HTMLSourceElement* source = @@ -1631,9 +1623,8 @@ void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error, const String& input_message) { - BLINK_MEDIA_LOG << "MediaLoadingFailed(" << (void*)this << ", " - << static_cast<int>(error) << ", message='" << input_message - << "')"; + DVLOG(3) << "MediaLoadingFailed(" << (void*)this << ", " + << static_cast<int>(error) << ", message='" << input_message << "')"; bool should_be_opaque = MediaShouldBeOpaque(); if (should_be_opaque) @@ -1654,8 +1645,8 @@ if (current_source_node_) { current_source_node_->ScheduleErrorEvent(); } else { - BLINK_MEDIA_LOG << "mediaLoadingFailed(" << (void*)this - << ") - error event not sent, <source> was removed"; + DVLOG(3) << "mediaLoadingFailed(" << (void*)this + << ") - error event not sent, <source> was removed"; } // 9.Otherwise.10 - Asynchronously await a stable state. The synchronous @@ -1667,12 +1658,12 @@ ForgetResourceSpecificTracks(); if (HavePotentialSourceChild()) { - BLINK_MEDIA_LOG << "mediaLoadingFailed(" << (void*)this - << ") - scheduling next <source>"; + DVLOG(3) << "mediaLoadingFailed(" << (void*)this + << ") - scheduling next <source>"; ScheduleNextSourceChild(); } else { - BLINK_MEDIA_LOG << "mediaLoadingFailed(" << (void*)this - << ") - no more <source> elements, waiting"; + DVLOG(3) << "mediaLoadingFailed(" << (void*)this + << ") - no more <source> elements, waiting"; WaitForSourceChange(); } @@ -1702,9 +1693,9 @@ } void HTMLMediaElement::SetNetworkState(WebMediaPlayer::NetworkState state) { - BLINK_MEDIA_LOG << "setNetworkState(" << (void*)this << ", " - << static_cast<int>(state) << ") - current state is " - << static_cast<int>(network_state_); + DVLOG(3) << "setNetworkState(" << (void*)this << ", " + << static_cast<int>(state) << ") - current state is " + << static_cast<int>(network_state_); if (state == WebMediaPlayer::kNetworkStateEmpty) { // Just update the cached state and leave, we can't do anything. @@ -1758,9 +1749,8 @@ } void HTMLMediaElement::SetReadyState(ReadyState state) { - BLINK_MEDIA_LOG << "setReadyState(" << (void*)this << ", " - << static_cast<int>(state) << ") - current state is " - << static_cast<int>(ready_state_); + DVLOG(3) << "setReadyState(" << (void*)this << ", " << static_cast<int>(state) + << ") - current state is " << static_cast<int>(ready_state_); // Set "wasPotentiallyPlaying" BEFORE updating ready_state_, // potentiallyPlaying() uses it @@ -1958,8 +1948,8 @@ } void HTMLMediaElement::AddPlayedRange(double start, double end) { - BLINK_MEDIA_LOG << "addPlayedRange(" << (void*)this << ", " << start << ", " - << end << ")"; + DVLOG(3) << "addPlayedRange(" << (void*)this << ", " << start << ", " << end + << ")"; if (!played_time_ranges_) played_time_ranges_ = TimeRanges::Create(); played_time_ranges_->Add(start, end); @@ -2016,13 +2006,13 @@ } void HTMLMediaElement::SetIgnorePreloadNone() { - BLINK_MEDIA_LOG << "setIgnorePreloadNone(" << (void*)this << ")"; + DVLOG(3) << "setIgnorePreloadNone(" << (void*)this << ")"; ignore_preload_none_ = true; SetPlayerPreload(); } void HTMLMediaElement::Seek(double time) { - BLINK_MEDIA_LOG << "seek(" << (void*)this << ", " << time << ")"; + DVLOG(2) << "seek(" << (void*)this << ", " << time << ")"; // 2 - If the media element's readyState is HAVE_NOTHING, abort these steps. // FIXME: remove web_media_player_ check once we figure out how @@ -2064,8 +2054,8 @@ // will never be cleared and we will never fire a 'seeked' event. double media_time = GetWebMediaPlayer()->MediaTimeForTimeValue(time); if (time != media_time) { - BLINK_MEDIA_LOG << "seek(" << (void*)this << ", " << time - << ") - media timeline equivalent is " << media_time; + DVLOG(3) << "seek(" << (void*)this << ", " << time + << ") - media timeline equivalent is " << media_time; time = media_time; } @@ -2099,7 +2089,7 @@ } void HTMLMediaElement::FinishSeek() { - BLINK_MEDIA_LOG << "finishSeek(" << (void*)this << ")"; + DVLOG(3) << "finishSeek(" << (void*)this << ")"; // 14 - Set the seeking IDL attribute to false. seeking_ = false; @@ -2158,9 +2148,8 @@ return GetWebMediaPlayer()->CurrentTime(); if (ready_state_ >= kHaveMetadata) { - BLINK_MEDIA_LOG - << __func__ << " readyState = " << ready_state_ - << " but no webMediaPlayer to provide currentPlaybackPosition"; + DVLOG(3) << __func__ << " readyState = " << ready_state_ + << " but no webMediaPlayer to provide currentPlaybackPosition"; } return 0; @@ -2183,9 +2172,8 @@ double delta = std::abs(official_playback_position_ - CurrentPlaybackPosition()); if (delta > kMinCachedDeltaForWarning) { - BLINK_MEDIA_LOG << "CurrentTime(" << (void*)this - << ") - WARNING, cached time is " << delta - << "seconds off of media time when paused/waiting"; + DVLOG(3) << "CurrentTime(" << (void*)this << ") - WARNING, cached time is " + << delta << "seconds off of media time when paused/waiting"; } #endif @@ -2194,9 +2182,8 @@ void HTMLMediaElement::SetOfficialPlaybackPosition(double position) const { #if LOG_OFFICIAL_TIME_STATUS - BLINK_MEDIA_LOG << "SetOfficialPlaybackPosition(" << (void*)this - << ") was:" << official_playback_position_ - << " now:" << position; + DVLOG(3) << "SetOfficialPlaybackPosition(" << (void*)this + << ") was:" << official_playback_position_ << " now:" << position; #endif // Internal player position may advance slightly beyond duration because @@ -2206,9 +2193,9 @@ std::isnan(duration()) ? position : std::min(duration(), position); if (official_playback_position_ != position) { - BLINK_MEDIA_LOG << "setOfficialPlaybackPosition(" << (void*)this - << ") position:" << position - << " truncated to duration:" << official_playback_position_; + DVLOG(3) << "setOfficialPlaybackPosition(" << (void*)this + << ") position:" << position + << " truncated to duration:" << official_playback_position_; } // Once set, official playback position should hold steady until the next @@ -2231,8 +2218,8 @@ return default_playback_start_position_; if (seeking_) { - BLINK_MEDIA_LOG << "currentTime(" << (void*)this - << ") - seeking, returning " << last_seek_time_; + DVLOG(3) << "currentTime(" << (void*)this << ") - seeking, returning " + << last_seek_time_; return last_seek_time_; } @@ -2283,7 +2270,7 @@ void HTMLMediaElement::setPlaybackRate(double rate, ExceptionState& exception_state) { - BLINK_MEDIA_LOG << "setPlaybackRate(" << (void*)this << ", " << rate << ")"; + DVLOG(3) << "setPlaybackRate(" << (void*)this << ", " << rate << ")"; if (GetLoadType() == WebMediaPlayer::kLoadTypeMediaStream) return; @@ -2341,7 +2328,7 @@ } void HTMLMediaElement::setPreload(const AtomicString& preload) { - BLINK_MEDIA_LOG << "setPreload(" << (void*)this << ", " << preload << ")"; + DVLOG(2) << "setPreload(" << (void*)this << ", " << preload << ")"; if (GetLoadType() == WebMediaPlayer::kLoadTypeMediaStream) return; setAttribute(kPreloadAttr, preload); @@ -2437,7 +2424,7 @@ } base::Optional<DOMExceptionCode> HTMLMediaElement::Play() { - BLINK_MEDIA_LOG << "play(" << (void*)this << ")"; + DVLOG(2) << "play(" << (void*)this << ")"; base::Optional<DOMExceptionCode> exception_code = autoplay_policy_->RequestPlay(); @@ -2465,7 +2452,7 @@ } void HTMLMediaElement::PlayInternal() { - BLINK_MEDIA_LOG << "playInternal(" << (void*)this << ")"; + DVLOG(3) << "playInternal(" << (void*)this << ")"; // Playback aborts any lazy loading. if (lazy_load_visibility_observer_) { @@ -2502,14 +2489,14 @@ } void HTMLMediaElement::pause() { - BLINK_MEDIA_LOG << "pause(" << (void*)this << ")"; + DVLOG(2) << "pause(" << (void*)this << ")"; autoplay_policy_->StopAutoplayMutedWhenVisible(); PauseInternal(); } void HTMLMediaElement::PauseInternal() { - BLINK_MEDIA_LOG << "pauseInternal(" << (void*)this << ")"; + DVLOG(3) << "pauseInternal(" << (void*)this << ")"; if (network_state_ == kNetworkEmpty) InvokeResourceSelectionAlgorithm(); @@ -2571,7 +2558,7 @@ } void HTMLMediaElement::SetLoop(bool b) { - BLINK_MEDIA_LOG << "setLoop(" << (void*)this << ", " << BoolString(b) << ")"; + DVLOG(3) << "setLoop(" << (void*)this << ", " << BoolString(b) << ")"; SetBooleanAttribute(kLoopAttr, b); } @@ -2621,7 +2608,7 @@ } void HTMLMediaElement::setVolume(double vol, ExceptionState& exception_state) { - BLINK_MEDIA_LOG << "setVolume(" << (void*)this << ", " << vol << ")"; + DVLOG(2) << "setVolume(" << (void*)this << ", " << vol << ")"; if (volume_ == vol) return; @@ -2647,8 +2634,7 @@ } void HTMLMediaElement::setMuted(bool muted) { - BLINK_MEDIA_LOG << "setMuted(" << (void*)this << ", " << BoolString(muted) - << ")"; + DVLOG(2) << "setMuted(" << (void*)this << ", " << BoolString(muted) << ")"; if (muted_ == muted) return; @@ -2751,9 +2737,9 @@ } void HTMLMediaElement::AudioTrackChanged(AudioTrack* track) { - BLINK_MEDIA_LOG << "audioTrackChanged(" << (void*)this - << ") trackId= " << String(track->id()) - << " enabled=" << BoolString(track->enabled()); + DVLOG(3) << "audioTrackChanged(" << (void*)this + << ") trackId= " << String(track->id()) + << " enabled=" << BoolString(track->enabled()); DCHECK(MediaTracksEnabledInternally()); audioTracks().ScheduleChangeEvent(); @@ -2783,10 +2769,9 @@ const WebString& language, bool enabled) { AtomicString kind_string = AudioKindToString(kind); - BLINK_MEDIA_LOG << "addAudioTrack(" << (void*)this << ", '" << (String)id - << "', ' " << (AtomicString)kind_string << "', '" - << (String)label << "', '" << (String)language << "', " - << BoolString(enabled) << ")"; + DVLOG(3) << "addAudioTrack(" << (void*)this << ", '" << (String)id << "', ' " + << (AtomicString)kind_string << "', '" << (String)label << "', '" + << (String)language << "', " << BoolString(enabled) << ")"; AudioTrack* audio_track = AudioTrack::Create(id, kind_string, label, language, enabled); @@ -2796,7 +2781,7 @@ } void HTMLMediaElement::RemoveAudioTrack(WebMediaPlayer::TrackId track_id) { - BLINK_MEDIA_LOG << "removeAudioTrack(" << (void*)this << ")"; + DVLOG(3) << "removeAudioTrack(" << (void*)this << ")"; audioTracks().Remove(track_id); } @@ -2806,9 +2791,9 @@ } void HTMLMediaElement::SelectedVideoTrackChanged(VideoTrack* track) { - BLINK_MEDIA_LOG << "selectedVideoTrackChanged(" << (void*)this - << ") selectedTrackId=" - << (track->selected() ? String(track->id()) : "none"); + DVLOG(3) << "selectedVideoTrackChanged(" << (void*)this + << ") selectedTrackId=" + << (track->selected() ? String(track->id()) : "none"); DCHECK(MediaTracksEnabledInternally()); if (track->selected()) @@ -2831,10 +2816,9 @@ const WebString& language, bool selected) { AtomicString kind_string = VideoKindToString(kind); - BLINK_MEDIA_LOG << "addVideoTrack(" << (void*)this << ", '" << (String)id - << "', '" << (AtomicString)kind_string << "', '" - << (String)label << "', '" << (String)language << "', " - << BoolString(selected) << ")"; + DVLOG(3) << "addVideoTrack(" << (void*)this << ", '" << (String)id << "', '" + << (AtomicString)kind_string << "', '" << (String)label << "', '" + << (String)language << "', " << BoolString(selected) << ")"; // If another track was selected (potentially by the user), leave it selected. if (selected && videoTracks().selectedIndex() != -1) @@ -2848,7 +2832,7 @@ } void HTMLMediaElement::RemoveVideoTrack(WebMediaPlayer::TrackId track_id) { - BLINK_MEDIA_LOG << "removeVideoTrack(" << (void*)this << ")"; + DVLOG(3) << "removeVideoTrack(" << (void*)this << ")"; videoTracks().Remove(track_id); } @@ -2984,8 +2968,8 @@ void HTMLMediaElement::DidRemoveTrackElement(HTMLTrackElement* track_element) { KURL url = track_element->GetNonEmptyURLAttribute(kSrcAttr); - BLINK_MEDIA_LOG << "didRemoveTrackElement(" << (void*)this << ") - 'src' is " - << UrlForLoggingMedia(url); + DVLOG(3) << "didRemoveTrackElement(" << (void*)this << ") - 'src' is " + << UrlForLoggingMedia(url); TextTrack* text_track = track_element->track(); if (!text_track) @@ -3052,12 +3036,12 @@ // <source> elements. bool should_log = action_if_invalid != kDoNothing; if (should_log) - BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ")"; + DVLOG(3) << "selectNextSourceChild(" << (void*)this << ")"; if (!next_child_node_to_consider_) { if (should_log) { - BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this - << ") -> 0x0000, \"\""; + DVLOG(3) << "selectNextSourceChild(" << (void*)this + << ") -> 0x0000, \"\""; } return KURL(); } @@ -3091,8 +3075,8 @@ // step below const AtomicString& src_value = source->FastGetAttribute(kSrcAttr); if (should_log) { - BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this - << ") - 'src' is " << UrlForLoggingMedia(media_url); + DVLOG(3) << "selectNextSourceChild(" << (void*)this << ") - 'src' is " + << UrlForLoggingMedia(media_url); } if (src_value.IsEmpty()) goto checkAgain; @@ -3116,8 +3100,8 @@ type = MimeTypeFromDataURL(media_url); if (!type.IsEmpty()) { if (should_log) { - BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this - << ") - 'type' is '" << type << "'"; + DVLOG(3) << "selectNextSourceChild(" << (void*)this << ") - 'type' is '" + << type << "'"; } if (!GetSupportsType(ContentType(type))) goto checkAgain; @@ -3142,21 +3126,20 @@ } if (should_log) { - BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ") -> " - << current_source_node_.Get() << ", " - << (can_use_source_element ? UrlForLoggingMedia(media_url) - : ""); + DVLOG(3) << "selectNextSourceChild(" << (void*)this << ") -> " + << current_source_node_.Get() << ", " + << (can_use_source_element ? UrlForLoggingMedia(media_url) : ""); } return can_use_source_element ? media_url : KURL(); } void HTMLMediaElement::SourceWasAdded(HTMLSourceElement* source) { - BLINK_MEDIA_LOG << "sourceWasAdded(" << (void*)this << ", " << source << ")"; + DVLOG(3) << "sourceWasAdded(" << (void*)this << ", " << source << ")"; KURL url = source->GetNonEmptyURLAttribute(kSrcAttr); - BLINK_MEDIA_LOG << "sourceWasAdded(" << (void*)this << ") - 'src' is " - << UrlForLoggingMedia(url); + DVLOG(3) << "sourceWasAdded(" << (void*)this << ") - 'src' is " + << UrlForLoggingMedia(url); // We should only consider a <source> element when there is not src attribute // at all. @@ -3175,8 +3158,8 @@ } if (current_source_node_ && source == current_source_node_->nextSibling()) { - BLINK_MEDIA_LOG << "sourceWasAdded(" << (void*)this - << ") - <source> inserted immediately after current source"; + DVLOG(3) << "sourceWasAdded(" << (void*)this + << ") - <source> inserted immediately after current source"; // Ignore current |next_child_node_to_consider_| and consider |source|. next_child_node_to_consider_ = source; return; @@ -3207,12 +3190,11 @@ } void HTMLMediaElement::SourceWasRemoved(HTMLSourceElement* source) { - BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this << ", " << source - << ")"; + DVLOG(3) << "sourceWasRemoved(" << (void*)this << ", " << source << ")"; KURL url = source->GetNonEmptyURLAttribute(kSrcAttr); - BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this << ") - 'src' is " - << UrlForLoggingMedia(url); + DVLOG(3) << "sourceWasRemoved(" << (void*)this << ") - 'src' is " + << UrlForLoggingMedia(url); if (source != current_source_node_ && source != next_child_node_to_consider_) return; @@ -3220,9 +3202,9 @@ if (source == next_child_node_to_consider_) { if (current_source_node_) next_child_node_to_consider_ = current_source_node_->nextSibling(); - BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this - << ") - next_child_node_to_consider_ set to " - << next_child_node_to_consider_.Get(); + DVLOG(3) << "sourceWasRemoved(" << (void*)this + << ") - next_child_node_to_consider_ set to " + << next_child_node_to_consider_.Get(); } else if (source == current_source_node_) { // Clear the current source node pointer, but don't change the movie as the // spec says: @@ -3230,13 +3212,13 @@ // element is already inserted in a video or audio element will have no // effect. current_source_node_ = nullptr; - BLINK_MEDIA_LOG << "SourceWasRemoved(" << (void*)this - << ") - current_source_node_ set to 0"; + DVLOG(3) << "SourceWasRemoved(" << (void*)this + << ") - current_source_node_ set to 0"; } } void HTMLMediaElement::TimeChanged() { - BLINK_MEDIA_LOG << "timeChanged(" << (void*)this << ")"; + DVLOG(3) << "timeChanged(" << (void*)this << ")"; GetCueTimeline().UpdateActiveCues(currentTime()); @@ -3281,7 +3263,7 @@ } void HTMLMediaElement::DurationChanged() { - BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ")"; + DVLOG(3) << "durationChanged(" << (void*)this << ")"; // durationChanged() is triggered by media player. CHECK(web_media_player_); @@ -3294,15 +3276,15 @@ } void HTMLMediaElement::DurationChanged(double duration, bool request_seek) { - BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ", " << duration - << ", " << BoolString(request_seek) << ")"; + DVLOG(3) << "durationChanged(" << (void*)this << ", " << duration << ", " + << BoolString(request_seek) << ")"; // Abort if duration unchanged. if (duration_ == duration) return; - BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ") : " << duration_ - << " -> " << duration; + DVLOG(3) << "durationChanged(" << (void*)this << ") : " << duration_ << " -> " + << duration; duration_ = duration; ScheduleEvent(event_type_names::kDurationchange); @@ -3394,7 +3376,7 @@ } void HTMLMediaElement::SizeChanged() { - BLINK_MEDIA_LOG << "sizeChanged(" << (void*)this << ")"; + DVLOG(3) << "sizeChanged(" << (void*)this << ")"; DCHECK(HasVideo()); // "resize" makes no sense in absence of video. if (ready_state_ > kHaveNothing && IsHTMLVideoElement()) @@ -3495,9 +3477,9 @@ bool is_playing = GetWebMediaPlayer() && !GetWebMediaPlayer()->Paused(); bool should_be_playing = PotentiallyPlaying(); - BLINK_MEDIA_LOG << "updatePlayState(" << (void*)this - << ") - shouldBePlaying = " << BoolString(should_be_playing) - << ", isPlaying = " << BoolString(is_playing); + DVLOG(3) << "updatePlayState(" << (void*)this + << ") - shouldBePlaying = " << BoolString(should_be_playing) + << ", isPlaying = " << BoolString(is_playing); if (should_be_playing && !muted_) was_always_muted_ = false; @@ -3591,7 +3573,7 @@ } void HTMLMediaElement::ContextDestroyed(ExecutionContext*) { - BLINK_MEDIA_LOG << "contextDestroyed(" << (void*)this << ")"; + DVLOG(3) << "contextDestroyed(" << (void*)this << ")"; // Close the async event queue so that no events are enqueued. CancelPendingEventsAndCallbacks(); @@ -3747,14 +3729,14 @@ } void HTMLMediaElement::UpdateTextTrackDisplay() { - BLINK_MEDIA_LOG << "updateTextTrackDisplay(" << (void*)this << ")"; + DVLOG(3) << "updateTextTrackDisplay(" << (void*)this << ")"; EnsureTextTrackContainer().UpdateDisplay( *this, TextTrackContainer::kDidNotStartExposingControls); } void HTMLMediaElement::MediaControlsDidBecomeVisible() { - BLINK_MEDIA_LOG << "mediaControlsDidBecomeVisible(" << (void*)this << ")"; + DVLOG(3) << "mediaControlsDidBecomeVisible(" << (void*)this << ")"; // When the user agent starts exposing a user interface for a video element, // the user agent should run the rules for updating the text track rendering @@ -3831,8 +3813,8 @@ if (should_delay_load_event_ == should_delay) return; - BLINK_MEDIA_LOG << "setShouldDelayLoadEvent(" << (void*)this << ", " - << BoolString(should_delay) << ")"; + DVLOG(3) << "setShouldDelayLoadEvent(" << (void*)this << ", " + << BoolString(should_delay) << ")"; should_delay_load_event_ = should_delay; if (should_delay) @@ -3895,7 +3877,7 @@ void HTMLMediaElement::ConfigureTextTrackDisplay() { DCHECK(text_tracks_); - BLINK_MEDIA_LOG << "configureTextTrackDisplay(" << (void*)this << ")"; + DVLOG(3) << "configureTextTrackDisplay(" << (void*)this << ")"; if (processing_preference_change_) return;
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.h b/third_party/blink/renderer/core/html/media/html_media_element.h index e0ee8d2..4e059f9c 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element.h +++ b/third_party/blink/renderer/core/html/media/html_media_element.h
@@ -333,6 +333,8 @@ // becomes visible again. bool PausedWhenVisible() const; + void SetCcLayerForTesting(cc::Layer* layer) { SetCcLayer(layer); } + protected: HTMLMediaElement(const QualifiedName&, Document&); ~HTMLMediaElement() override;
diff --git a/third_party/blink/renderer/core/html/media/html_video_element.cc b/third_party/blink/renderer/core/html/media/html_video_element.cc index 642053f..e29450c 100644 --- a/third_party/blink/renderer/core/html/media/html_video_element.cc +++ b/third_party/blink/renderer/core/html/media/html_video_element.cc
@@ -502,8 +502,10 @@ void HTMLVideoElement::DidEnterFullscreen() { UpdateControlsVisibility(); - if (DisplayType() == WebMediaPlayer::DisplayType::kPictureInPicture) - exitPictureInPicture(base::DoNothing()); + if (DisplayType() == WebMediaPlayer::DisplayType::kPictureInPicture) { + PictureInPictureController::From(GetDocument()) + .ExitPictureInPicture(this, nullptr); + } if (GetWebMediaPlayer()) { // FIXME: There is no embedder-side handling in web test mode. @@ -661,19 +663,12 @@ PictureInPictureController::Status::kEnabled; } -void HTMLVideoElement::enterPictureInPicture( - WebMediaPlayer::PipWindowOpenedCallback callback) { +void HTMLVideoElement::enterPictureInPicture() { if (DisplayType() == WebMediaPlayer::DisplayType::kFullscreen) Fullscreen::ExitFullscreen(GetDocument()); if (GetWebMediaPlayer()) - GetWebMediaPlayer()->EnterPictureInPicture(std::move(callback)); -} - -void HTMLVideoElement::exitPictureInPicture( - WebMediaPlayer::PipWindowClosedCallback callback) { - if (GetWebMediaPlayer()) - GetWebMediaPlayer()->ExitPictureInPicture(std::move(callback)); + GetWebMediaPlayer()->EnterPictureInPicture(); } void HTMLVideoElement::SendCustomControlsToPipWindow() { @@ -712,6 +707,16 @@ return is_auto_picture_in_picture_; } +void HTMLVideoElement::OnPictureInPictureStateChange() { + if (DisplayType() != WebMediaPlayer::DisplayType::kPictureInPicture || + IsInAutoPIP()) { + return; + } + + PictureInPictureController::From(GetDocument()) + .OnPictureInPictureStateChange(); +} + void HTMLVideoElement::OnEnteredPictureInPicture() { if (!picture_in_picture_interstitial_) { picture_in_picture_interstitial_ =
diff --git a/third_party/blink/renderer/core/html/media/html_video_element.h b/third_party/blink/renderer/core/html/media/html_video_element.h index 9e6a0a1..925fae2 100644 --- a/third_party/blink/renderer/core/html/media/html_video_element.h +++ b/third_party/blink/renderer/core/html/media/html_video_element.h
@@ -175,14 +175,14 @@ void MediaRemotingStarted(const WebString& remote_device_friendly_name) final; bool SupportsPictureInPicture() const final; - void enterPictureInPicture(WebMediaPlayer::PipWindowOpenedCallback callback); - void exitPictureInPicture(WebMediaPlayer::PipWindowClosedCallback callback); + void enterPictureInPicture(); void SendCustomControlsToPipWindow(); void PictureInPictureStopped() final; void PictureInPictureControlClicked(const WebString& control_id) final; void MediaRemotingStopped(WebLocalizedString::Name error_msg) final; WebMediaPlayer::DisplayType DisplayType() const final; bool IsInAutoPIP() const final; + void OnPictureInPictureStateChange() final; // Used by the PictureInPictureController as callback when the video element // enters or exits Picture-in-Picture state.
diff --git a/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc b/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc index 8fd93c8e..bc01a5ee 100644 --- a/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc +++ b/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/html/media/video_wake_lock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom-blink.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/frame/picture_in_picture_controller.h" #include "third_party/blink/renderer/core/html/media/html_media_test_helper.h" @@ -15,23 +16,107 @@ namespace blink { -class VideoWakeLockMediaPlayer : public EmptyWebMediaPlayer { +// The VideoWakeLockPictureInPictureService implements the PictureInPicture +// service in the same process as the test and guarantees that the callbacks are +// called in order for the events to be fired. set_run_loop() MUST be called +// before each attempt to enter/leave Picture-in-Picture. +class VideoWakeLockPictureInPictureService + : public mojom::blink::PictureInPictureService { public: - void EnterPictureInPicture(PipWindowOpenedCallback callback) final { + VideoWakeLockPictureInPictureService() : binding_(this) {} + ~VideoWakeLockPictureInPictureService() override = default; + + void Bind(mojo::ScopedMessagePipeHandle handle) { + binding_.Bind( + mojom::blink::PictureInPictureServiceRequest(std::move(handle))); + } + + void StartSession(uint32_t, + const base::Optional<viz::SurfaceId>&, + const blink::WebSize&, + bool, + StartSessionCallback callback) final { std::move(callback).Run(WebSize()); } - void ExitPictureInPicture(PipWindowClosedCallback callback) final { + void EndSession(EndSessionCallback callback) final { std::move(callback).Run(); } + + void UpdateSession(uint32_t, + const base::Optional<viz::SurfaceId>&, + const blink::WebSize&, + bool) final {} + void SetDelegate(mojom::blink::PictureInPictureDelegatePtr) final {} + + private: + mojo::Binding<mojom::blink::PictureInPictureService> binding_; +}; + +class VideoWakeLockFrameClient : public test::MediaStubLocalFrameClient { + public: + static VideoWakeLockFrameClient* Create( + std::unique_ptr<WebMediaPlayer> player) { + return MakeGarbageCollected<VideoWakeLockFrameClient>(std::move(player)); + } + + explicit VideoWakeLockFrameClient(std::unique_ptr<WebMediaPlayer> player) + : test::MediaStubLocalFrameClient(std::move(player)), + interface_provider_(new service_manager::InterfaceProvider()) {} + + service_manager::InterfaceProvider* GetInterfaceProvider() override { + return interface_provider_.get(); + } + + private: + std::unique_ptr<service_manager::InterfaceProvider> interface_provider_; + + DISALLOW_COPY_AND_ASSIGN(VideoWakeLockFrameClient); }; class VideoWakeLockTest : public PageTestBase { public: + // Helper class that will block running the test until the given event is + // fired on the given element. + class WaitForEvent : public NativeEventListener { + public: + static WaitForEvent* Create(Element* element, const AtomicString& name) { + return MakeGarbageCollected<WaitForEvent>(element, name); + } + + WaitForEvent(Element* element, const AtomicString& name) + : element_(element), name_(name) { + element_->addEventListener(name_, this); + run_loop_.Run(); + } + + void Invoke(ExecutionContext*, Event*) final { + run_loop_.Quit(); + element_->removeEventListener(name_, this); + } + + void Trace(Visitor* visitor) final { + NativeEventListener::Trace(visitor); + visitor->Trace(element_); + } + + private: + base::RunLoop run_loop_; + Member<Element> element_; + AtomicString name_; + }; + void SetUp() override { PageTestBase::SetupPageWithClients( - nullptr, test::MediaStubLocalFrameClient::Create( - std::make_unique<VideoWakeLockMediaPlayer>())); + nullptr, VideoWakeLockFrameClient::Create( + std::make_unique<EmptyWebMediaPlayer>())); + + service_manager::InterfaceProvider::TestApi test_api( + GetFrame().Client()->GetInterfaceProvider()); + test_api.SetBinderForName( + mojom::blink::PictureInPictureService::Name_, + WTF::BindRepeating(&VideoWakeLockPictureInPictureService::Bind, + WTF::Unretained(&pip_service_))); video_ = HTMLVideoElement::Create(GetDocument()); video_wake_lock_ = MakeGarbageCollected<VideoWakeLock>(*video_.Get()); @@ -57,16 +142,24 @@ void SimulateEnterPictureInPicture() { PictureInPictureController::From(GetDocument()) .EnterPictureInPicture(Video(), nullptr); + + WaitForEvent::Create(video_.Get(), + event_type_names::kEnterpictureinpicture); } void SimulateLeavePictureInPicture() { PictureInPictureController::From(GetDocument()) .ExitPictureInPicture(Video(), nullptr); + + WaitForEvent::Create(video_.Get(), + event_type_names::kLeavepictureinpicture); } private: Persistent<HTMLVideoElement> video_; Persistent<VideoWakeLock> video_wake_lock_; + + VideoWakeLockPictureInPictureService pip_service_; }; TEST_F(VideoWakeLockTest, NoLockByDefault) {
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser.cc b/third_party/blink/renderer/core/html/parser/html_document_parser.cc index 174d8f8..caa8623 100644 --- a/third_party/blink/renderer/core/html/parser/html_document_parser.cc +++ b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
@@ -1228,7 +1228,16 @@ "WebCore.HTMLDocumentParser.PreloadScannerAppCacheDelayTime", delta, base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromMilliseconds(1000), 50); - DCHECK(GetDocument()->documentElement()); + Document* document = GetDocument(); + DCHECK(document); + LocalFrame* frame = document->GetFrame(); + if (frame && frame->IsMainFrame()) { + UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES( + "WebCore.HTMLDocumentParser.PreloadScannerAppCacheDelayTime.MainFrame", + delta, base::TimeDelta::FromMicroseconds(1), + base::TimeDelta::FromMilliseconds(1000), 50); + } + DCHECK(document->documentElement()); FetchQueuedPreloads(); }
diff --git a/third_party/blink/renderer/core/paint/image_element_timing.cc b/third_party/blink/renderer/core/paint/image_element_timing.cc index b1180b73..753af4e 100644 --- a/third_party/blink/renderer/core/paint/image_element_timing.cc +++ b/third_party/blink/renderer/core/paint/image_element_timing.cc
@@ -65,7 +65,7 @@ DCHECK(layout_image->GetDocument().GetSecurityOrigin()); if (!Performance::PassesTimingAllowCheck( layout_image->CachedImage()->GetResponse(), - *layout_image->GetDocument().GetSecurityOrigin(), AtomicString(), + *layout_image->GetDocument().GetSecurityOrigin(), &layout_image->GetDocument())) return;
diff --git a/third_party/blink/renderer/core/streams/queue_with_sizes.cc b/third_party/blink/renderer/core/streams/queue_with_sizes.cc index c98cf1d..3130e85 100644 --- a/third_party/blink/renderer/core/streams/queue_with_sizes.cc +++ b/third_party/blink/renderer/core/streams/queue_with_sizes.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/core/streams/queue_with_sizes.h" +#include <math.h> + #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h" #include "third_party/blink/renderer/platform/heap/visitor.h"
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc index 7f08fdf..291f56a0 100644 --- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc +++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
@@ -494,19 +494,20 @@ if (begin_or_end == kEnd) has_end_event_conditions_ = false; HashSet<SMILTime> existing; - for (unsigned n = 0; n < time_list.size(); ++n) { - if (!time_list[n].Time().IsUnresolved()) - existing.insert(time_list[n].Time().Value()); + for (const auto& instance_time : time_list) { + if (!instance_time.Time().IsUnresolved()) + existing.insert(instance_time.Time()); } Vector<String> split_string; parse_string.Split(';', split_string); - for (unsigned n = 0; n < split_string.size(); ++n) { - SMILTime value = ParseClockValue(split_string[n]); - if (value.IsUnresolved()) - ParseCondition(split_string[n], begin_or_end); - else if (!existing.Contains(value.Value())) + for (const auto& item : split_string) { + SMILTime value = ParseClockValue(item); + if (value.IsUnresolved()) { + ParseCondition(item, begin_or_end); + } else if (!existing.Contains(value)) { time_list.push_back( SMILTimeWithOrigin(value, SMILTimeWithOrigin::kParserOrigin)); + } } SortTimeList(time_list); }
diff --git a/third_party/blink/renderer/core/timing/performance.cc b/third_party/blink/renderer/core/timing/performance.cc index 7fdf28fb..e57ec3c 100644 --- a/third_party/blink/renderer/core/timing/performance.cc +++ b/third_party/blink/renderer/core/timing/performance.cc
@@ -405,7 +405,6 @@ bool Performance::PassesTimingAllowCheck( const ResourceResponse& response, const SecurityOrigin& initiator_security_origin, - const AtomicString& original_timing_allow_origin, ExecutionContext* context) { const KURL& response_url = response.ResponseUrl(); scoped_refptr<const SecurityOrigin> resource_origin = @@ -414,9 +413,7 @@ return true; const AtomicString& timing_allow_origin_string = - original_timing_allow_origin.IsEmpty() - ? response.HttpHeaderField(http_names::kTimingAllowOrigin) - : original_timing_allow_origin; + response.HttpHeaderField(http_names::kTimingAllowOrigin); if (timing_allow_origin_string.IsEmpty() || EqualIgnoringASCIICase(timing_allow_origin_string, "null")) return false; @@ -455,12 +452,11 @@ const SecurityOrigin& initiator_security_origin, ExecutionContext* context) { if (!PassesTimingAllowCheck(final_response, initiator_security_origin, - AtomicString(), context)) + context)) return false; for (const ResourceResponse& response : redirect_chain) { - if (!PassesTimingAllowCheck(response, initiator_security_origin, - AtomicString(), context)) + if (!PassesTimingAllowCheck(response, initiator_security_origin, context)) return false; } @@ -495,8 +491,7 @@ result.finish_time = info.LoadFinishTime(); result.allow_timing_details = PassesTimingAllowCheck( - final_response, destination_origin, info.OriginalTimingAllowOrigin(), - &context_for_use_counter); + final_response, destination_origin, &context_for_use_counter); const Vector<ResourceResponse>& redirect_chain = info.RedirectChain(); if (!redirect_chain.IsEmpty()) {
diff --git a/third_party/blink/renderer/core/timing/performance.h b/third_party/blink/renderer/core/timing/performance.h index d19ee68..67a78e8 100644 --- a/third_party/blink/renderer/core/timing/performance.h +++ b/third_party/blink/renderer/core/timing/performance.h
@@ -253,7 +253,6 @@ // TODO(npm): is the AtomicString parameter here actually needed? static bool PassesTimingAllowCheck(const ResourceResponse&, const SecurityOrigin&, - const AtomicString&, ExecutionContext*); static bool AllowsTimingRedirect(const Vector<ResourceResponse>&,
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn index c8af8ce..39cd2f2 100644 --- a/third_party/blink/renderer/modules/BUILD.gn +++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -25,13 +25,6 @@ config("modules_implementation") { defines = [ "BLINK_MODULES_IMPLEMENTATION=1" ] - - if (is_chromecast) { - defines += [ - "BLINK_MSLOG=LOG(INFO)", - "BLINK_SBLOG=LOG(INFO)", - ] - } } make_names("module_names") { @@ -328,6 +321,7 @@ "peerconnection/rtc_quic_transport_test.cc", "peerconnection/rtc_quic_transport_test.h", "picture_in_picture/html_video_element_picture_in_picture_test.cc", + "picture_in_picture/picture_in_picture_controller_test.cc", "presentation/mock_presentation_service.h", "presentation/presentation_availability_state_test.cc", "presentation/presentation_availability_test.cc",
diff --git a/third_party/blink/renderer/modules/mediasource/DEPS b/third_party/blink/renderer/modules/mediasource/DEPS index d4085473..d96729c3 100644 --- a/third_party/blink/renderer/modules/mediasource/DEPS +++ b/third_party/blink/renderer/modules/mediasource/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "-third_party/blink/renderer/modules", + "+media/base/logging_override_if_enabled.h", "+third_party/blink/renderer/modules/event_modules.h", "+third_party/blink/renderer/modules/event_target_modules.h", "+third_party/blink/renderer/modules/mediasource",
diff --git a/third_party/blink/renderer/modules/mediasource/media_source.cc b/third_party/blink/renderer/modules/mediasource/media_source.cc index 0262fe6..9dfdf64c 100644 --- a/third_party/blink/renderer/modules/mediasource/media_source.cc +++ b/third_party/blink/renderer/modules/mediasource/media_source.cc
@@ -33,6 +33,7 @@ #include <memory> #include "base/memory/ptr_util.h" +#include "media/base/logging_override_if_enabled.h" #include "third_party/blink/public/platform/web_media_source.h" #include "third_party/blink/public/platform/web_source_buffer.h" #include "third_party/blink/renderer/core/dom/events/event.h" @@ -52,10 +53,6 @@ #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/text/cstring.h" -#ifndef BLINK_MSLOG -#define BLINK_MSLOG DVLOG(3) -#endif - using blink::WebMediaSource; using blink::WebSourceBuffer; @@ -123,30 +120,30 @@ async_event_queue_.Get())), live_seekable_range_(TimeRanges::Create()), added_to_registry_counter_(0) { - BLINK_MSLOG << __func__ << " this=" << this; + DVLOG(1) << __func__ << " this=" << this; } MediaSource::~MediaSource() { - BLINK_MSLOG << __func__ << " this=" << this; + DVLOG(1) << __func__ << " this=" << this; } void MediaSource::LogAndThrowDOMException(ExceptionState& exception_state, DOMExceptionCode error, const String& message) { - BLINK_MSLOG << __func__ << " (error=" << ToExceptionCode(error) - << ", message=" << message << ")"; + DVLOG(1) << __func__ << " (error=" << ToExceptionCode(error) + << ", message=" << message << ")"; exception_state.ThrowDOMException(error, message); } void MediaSource::LogAndThrowTypeError(ExceptionState& exception_state, const String& message) { - BLINK_MSLOG << __func__ << " (message=" << message << ")"; + DVLOG(1) << __func__ << " (message=" << message << ")"; exception_state.ThrowTypeError(message); } SourceBuffer* MediaSource::addSourceBuffer(const String& type, ExceptionState& exception_state) { - BLINK_MSLOG << __func__ << " this=" << this << " type=" << type; + DVLOG(2) << __func__ << " this=" << this << " type=" << type; // 2.2 // https://www.w3.org/TR/media-source/#dom-mediasource-addsourcebuffer @@ -214,14 +211,14 @@ } // 9. Return the new object to the caller. - BLINK_MSLOG << __func__ << " this=" << this << " type=" << type << " -> " - << buffer; + DVLOG(3) << __func__ << " this=" << this << " type=" << type << " -> " + << buffer; return buffer; } void MediaSource::removeSourceBuffer(SourceBuffer* buffer, ExceptionState& exception_state) { - BLINK_MSLOG << __func__ << " this=" << this << " buffer=" << buffer; + DVLOG(2) << __func__ << " this=" << this << " buffer=" << buffer; // 2.2 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-MediaSource-removeSourceBuffer-void-SourceBuffer-sourceBuffer @@ -292,7 +289,7 @@ // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#widl-MediaSource-isTypeSupported-boolean-DOMString-type // 1. If type is an empty string, then return false. if (type.IsEmpty()) { - BLINK_MSLOG << __func__ << "(" << type << ") -> false (empty input)"; + DVLOG(1) << __func__ << "(" << type << ") -> false (empty input)"; return false; } @@ -301,7 +298,7 @@ // 2. If type does not contain a valid MIME type string, then return false. if (content_type.GetType().IsEmpty()) { - BLINK_MSLOG << __func__ << "(" << type << ") -> false (invalid mime type)"; + DVLOG(1) << __func__ << "(" << type << ") -> false (invalid mime type)"; return false; } @@ -311,8 +308,8 @@ // HTMLMediaElement knows it cannot play. if (HTMLMediaElement::GetSupportsType(content_type) == MIMETypeRegistry::kIsNotSupported) { - BLINK_MSLOG << __func__ << "(" << type - << ") -> false (not supported by HTMLMediaElement)"; + DVLOG(1) << __func__ << "(" << type + << ") -> false (not supported by HTMLMediaElement)"; return false; } @@ -325,8 +322,7 @@ // 6. Return true. bool result = MIMETypeRegistry::IsSupportedMediaSourceMIMEType( content_type.GetType(), codecs); - BLINK_MSLOG << __func__ << "(" << type << ") -> " - << (result ? "true" : "false"); + DVLOG(2) << __func__ << "(" << type << ") -> " << (result ? "true" : "false"); return result; } @@ -505,7 +501,7 @@ void MediaSource::setDuration(double duration, ExceptionState& exception_state) { - BLINK_MSLOG << __func__ << " this=" << this << " : duration=" << duration; + DVLOG(3) << __func__ << " this=" << this << " : duration=" << duration; // 2.1 https://www.w3.org/TR/media-source/#widl-MediaSource-duration // 1. If the value being set is negative or NaN then throw a TypeError @@ -608,8 +604,8 @@ state == EndedKeyword()); AtomicString old_state = readyState(); - BLINK_MSLOG << __func__ << " this=" << this << " : " << old_state << " -> " - << state; + DVLOG(3) << __func__ << " this=" << this << " : " << old_state << " -> " + << state; if (state == ClosedKeyword()) { web_media_source_.reset(); @@ -628,7 +624,7 @@ DEFINE_STATIC_LOCAL(const AtomicString, network, ("network")); DEFINE_STATIC_LOCAL(const AtomicString, decode, ("decode")); - BLINK_MSLOG << __func__ << " this=" << this << " : error=" << error; + DVLOG(3) << __func__ << " this=" << this << " : error=" << error; // https://www.w3.org/TR/media-source/#dom-mediasource-endofstream // 1. If the readyState attribute is not in the "open" state then throw an @@ -655,8 +651,8 @@ void MediaSource::setLiveSeekableRange(double start, double end, ExceptionState& exception_state) { - BLINK_MSLOG << __func__ << " this=" << this << " : start=" << start - << ", end=" << end; + DVLOG(3) << __func__ << " this=" << this << " : start=" << start + << ", end=" << end; // http://w3c.github.io/media-source/#widl-MediaSource-setLiveSeekableRange-void-double-start-double-end // 1. If the readyState attribute is not "open" then throw an @@ -687,7 +683,7 @@ } void MediaSource::clearLiveSeekableRange(ExceptionState& exception_state) { - BLINK_MSLOG << __func__ << " this=" << this; + DVLOG(3) << __func__ << " this=" << this; // http://w3c.github.io/media-source/#widl-MediaSource-clearLiveSeekableRange-void // 1. If the readyState attribute is not "open" then throw an
diff --git a/third_party/blink/renderer/modules/mediasource/source_buffer.cc b/third_party/blink/renderer/modules/mediasource/source_buffer.cc index 3dadf562..32b2f09 100644 --- a/third_party/blink/renderer/modules/mediasource/source_buffer.cc +++ b/third_party/blink/renderer/modules/mediasource/source_buffer.cc
@@ -34,6 +34,7 @@ #include <memory> #include <sstream> +#include "media/base/logging_override_if_enabled.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/platform/web_source_buffer.h" #include "third_party/blink/renderer/core/dom/events/event.h" @@ -59,10 +60,6 @@ #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" -#ifndef BLINK_SBLOG -#define BLINK_SBLOG DVLOG(3) -#endif - using blink::WebSourceBuffer; namespace blink { @@ -130,7 +127,7 @@ pending_append_data_offset_(0), pending_remove_start_(-1), pending_remove_end_(-1) { - BLINK_SBLOG << __func__ << " this=" << this; + DVLOG(1) << __func__ << " this=" << this; DCHECK(web_source_buffer_); DCHECK(source_); @@ -141,7 +138,7 @@ } SourceBuffer::~SourceBuffer() { - BLINK_SBLOG << __func__ << " this=" << this; + DVLOG(1) << __func__ << " this=" << this; } void SourceBuffer::Dispose() { @@ -162,7 +159,7 @@ void SourceBuffer::setMode(const AtomicString& new_mode, ExceptionState& exception_state) { - BLINK_SBLOG << __func__ << " this=" << this << " new_mode=" << new_mode; + DVLOG(3) << __func__ << " this=" << this << " new_mode=" << new_mode; // Section 3.1 On setting mode attribute steps. // https://www.w3.org/TR/media-source/#dom-sourcebuffer-mode // 1. If this object has been removed from the sourceBuffers attribute of the @@ -238,7 +235,7 @@ void SourceBuffer::setTimestampOffset(double offset, ExceptionState& exception_state) { - BLINK_SBLOG << __func__ << " this=" << this << " offset=" << offset; + DVLOG(3) << __func__ << " this=" << this << " offset=" << offset; // Section 3.1 timestampOffset attribute setter steps. // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#widl-SourceBuffer-timestampOffset // 1. Let new timestamp offset equal the new value being assigned to this @@ -292,7 +289,7 @@ void SourceBuffer::setAppendWindowStart(double start, ExceptionState& exception_state) { - BLINK_SBLOG << __func__ << " this=" << this << " start=" << start; + DVLOG(3) << __func__ << " this=" << this << " start=" << start; // Section 3.1 appendWindowStart attribute setter steps. // https://www.w3.org/TR/media-source/#widl-SourceBuffer-appendWindowStart // 1. If this object has been removed from the sourceBuffers attribute of the @@ -327,7 +324,7 @@ void SourceBuffer::setAppendWindowEnd(double end, ExceptionState& exception_state) { - BLINK_SBLOG << __func__ << " this=" << this << " end=" << end; + DVLOG(3) << __func__ << " this=" << this << " end=" << end; // Section 3.1 appendWindowEnd attribute setter steps. // https://www.w3.org/TR/media-source/#widl-SourceBuffer-appendWindowEnd // 1. If this object has been removed from the sourceBuffers attribute of the @@ -364,8 +361,8 @@ void SourceBuffer::appendBuffer(DOMArrayBuffer* data, ExceptionState& exception_state) { double media_time = GetMediaTime(); - BLINK_SBLOG << __func__ << " this=" << this << " media_time=" << media_time - << " size=" << data->ByteLength(); + DVLOG(2) << __func__ << " this=" << this << " media_time=" << media_time + << " size=" << data->ByteLength(); // Section 3.2 appendBuffer() // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data AppendBufferInternal(media_time, @@ -376,8 +373,8 @@ void SourceBuffer::appendBuffer(NotShared<DOMArrayBufferView> data, ExceptionState& exception_state) { double media_time = GetMediaTime(); - BLINK_SBLOG << __func__ << " this=" << this << " media_time=" << media_time - << " size=" << data.View()->byteLength(); + DVLOG(3) << __func__ << " this=" << this << " media_time=" << media_time + << " size=" << data.View()->byteLength(); // Section 3.2 appendBuffer() // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data AppendBufferInternal( @@ -386,7 +383,7 @@ } void SourceBuffer::abort(ExceptionState& exception_state) { - BLINK_SBLOG << __func__ << " this=" << this; + DVLOG(2) << __func__ << " this=" << this; // http://w3c.github.io/media-source/#widl-SourceBuffer-abort-void // 1. If this object has been removed from the sourceBuffers attribute of the // parent media source then throw an InvalidStateError exception and abort @@ -443,8 +440,8 @@ void SourceBuffer::remove(double start, double end, ExceptionState& exception_state) { - BLINK_SBLOG << __func__ << " this=" << this << " start=" << start - << " end=" << end; + DVLOG(2) << __func__ << " this=" << this << " start=" << start + << " end=" << end; // Section 3.2 remove() method steps. // https://www.w3.org/TR/media-source/#widl-SourceBuffer-remove-void-double-start-unrestricted-double-end @@ -513,7 +510,7 @@ void SourceBuffer::changeType(const String& type, ExceptionState& exception_state) { - BLINK_SBLOG << __func__ << " this=" << this << " type=" << type; + DVLOG(2) << __func__ << " this=" << this << " type=" << type; // Per 30 May 2018 Codec Switching feature incubation spec: // https://rawgit.com/WICG/media-source/3b3742ea788999bb7ae4a4553ac7d574b0547dbe/index.html#dom-sourcebuffer-changetype @@ -646,7 +643,7 @@ if (IsRemoved()) return; - BLINK_SBLOG << __func__ << " this=" << this; + DVLOG(3) << __func__ << " this=" << this; if (pending_remove_start_ != -1) { CancelRemove(); } else { @@ -671,7 +668,7 @@ DCHECK(!IsRemoved()); double pts = web_source_buffer_->HighestPresentationTimestamp(); - BLINK_SBLOG << __func__ << " this=" << this << ", pts=" << pts; + DVLOG(3) << __func__ << " this=" << this << ", pts=" << pts; return pts; } @@ -842,8 +839,7 @@ bool SourceBuffer::InitializationSegmentReceived( const WebVector<MediaTrackInfo>& new_tracks) { - BLINK_SBLOG << __func__ << " this=" << this - << " tracks=" << new_tracks.size(); + DVLOG(3) << __func__ << " this=" << this << " tracks=" << new_tracks.size(); DCHECK(source_); DCHECK(source_->MediaElement()); DCHECK(updating_); @@ -874,28 +870,27 @@ if (first_initialization_segment_received_) track = FindExistingTrackById(videoTracks(), track_info.id); } else { - BLINK_SBLOG << __func__ << " this=" << this - << " failed: unsupported track type " - << track_info.track_type; + DVLOG(3) << __func__ << " this=" << this + << " failed: unsupported track type " << track_info.track_type; // TODO(servolk): Add handling of text tracks. NOTREACHED(); } if (first_initialization_segment_received_ && !track) { - BLINK_SBLOG << __func__ << " this=" << this - << " failed: tracks mismatch the first init segment."; + DVLOG(3) << __func__ << " this=" << this + << " failed: tracks mismatch the first init segment."; return false; } #if DCHECK_IS_ON() const char* log_track_type_str = (track_info.track_type == WebMediaPlayer::kAudioTrack) ? "audio" : "video"; - BLINK_SBLOG << __func__ << " this=" << this << " : " << log_track_type_str - << " track " - << " id=" << String(track_info.id) << " byteStreamTrackID=" - << String(track_info.byte_stream_track_id) - << " kind=" << String(track_info.kind) - << " label=" << String(track_info.label) - << " language=" << String(track_info.language); + DVLOG(3) << __func__ << " this=" << this << " : " << log_track_type_str + << " track " + << " id=" << String(track_info.id) + << " byteStreamTrackID=" << String(track_info.byte_stream_track_id) + << " kind=" << String(track_info.kind) + << " label=" << String(track_info.label) + << " language=" << String(track_info.language); #endif } @@ -906,8 +901,8 @@ // run the append error algorithm with the decode error parameter set to // true and abort these steps. if (new_tracks.size() == 0) { - BLINK_SBLOG << __func__ << " this=" << this - << " failed: no tracks found in the init segment."; + DVLOG(3) << __func__ << " this=" << this + << " failed: no tracks found in the init segment."; // The append error algorithm will be called at the top level after we // return false here to indicate failure. return false; @@ -955,8 +950,8 @@ } if (!tracks_match_first_init_segment) { - BLINK_SBLOG << __func__ << " this=" << this - << " failed: tracks mismatch the first init segment."; + DVLOG(3) << __func__ << " this=" << this + << " failed: tracks mismatch the first init segment."; // The append error algorithm will be called at the top level after we // return false here to indicate failure. return false; @@ -1218,8 +1213,7 @@ if (!EvictCodedFrames(media_time, new_data_size)) { // 6. If the buffer full flag equals true, then throw a QUOTA_EXCEEDED_ERR // exception and abort these steps. - BLINK_SBLOG << __func__ << " this=" << this - << " -> throw QuotaExceededError"; + DVLOG(3) << __func__ << " this=" << this << " -> throw QuotaExceededError"; MediaSource::LogAndThrowDOMException(exception_state, DOMExceptionCode::kQuotaExceededError, "The SourceBuffer is full, and cannot " @@ -1245,10 +1239,10 @@ bool result = web_source_buffer_->EvictCodedFrames(media_time, new_data_size); if (!result) { - BLINK_SBLOG << __func__ << " this=" << this - << " failed. newDataSize=" << new_data_size - << " media_time=" << media_time << " buffered=" - << WebTimeRangesToString(web_source_buffer_->Buffered()); + DVLOG(3) << __func__ << " this=" << this + << " failed. newDataSize=" << new_data_size + << " media_time=" << media_time << " buffered=" + << WebTimeRangesToString(web_source_buffer_->Buffered()); } return result; } @@ -1362,9 +1356,9 @@ TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendBuffer", this); double media_time = GetMediaTime(); - BLINK_SBLOG << __func__ << " done. this=" << this - << " media_time=" << media_time << " buffered=" - << WebTimeRangesToString(web_source_buffer_->Buffered()); + DVLOG(3) << __func__ << " done. this=" << this << " media_time=" << media_time + << " buffered=" + << WebTimeRangesToString(web_source_buffer_->Buffered()); } void SourceBuffer::RemoveAsyncPart() { @@ -1394,7 +1388,7 @@ } void SourceBuffer::AppendError() { - BLINK_SBLOG << __func__ << " this=" << this; + DVLOG(3) << __func__ << " this=" << this; // Section 3.5.3 Append Error Algorithm // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-append-error
diff --git a/third_party/blink/renderer/modules/picture_in_picture/DEPS b/third_party/blink/renderer/modules/picture_in_picture/DEPS index 03fe8e3..c3389f6 100644 --- a/third_party/blink/renderer/modules/picture_in_picture/DEPS +++ b/third_party/blink/renderer/modules/picture_in_picture/DEPS
@@ -2,5 +2,6 @@ "-third_party/blink/renderer/modules", "+third_party/blink/renderer/modules/event_modules.h", "+third_party/blink/renderer/modules/event_target_modules.h", + "+third_party/blink/renderer/modules/modules_export.h", "+third_party/blink/renderer/modules/picture_in_picture", ] \ No newline at end of file
diff --git a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc index 3039b1c..3b96446 100644 --- a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc +++ b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc
@@ -4,7 +4,11 @@ #include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h" +#include <limits> +#include <utility> + #include "base/bind_helpers.h" +#include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/manifest/web_display_mode.h" #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -20,7 +24,14 @@ namespace blink { -PictureInPictureControllerImpl::~PictureInPictureControllerImpl() = default; +namespace { + +bool ShouldShowPlayPauseButton(const HTMLVideoElement& element) { + return element.GetLoadType() != WebMediaPlayer::kLoadTypeMediaStream && + element.duration() != std::numeric_limits<double>::infinity(); +} + +} // namespace // static PictureInPictureControllerImpl* PictureInPictureControllerImpl::Create( @@ -88,19 +99,32 @@ void PictureInPictureControllerImpl::EnterPictureInPicture( HTMLVideoElement* element, ScriptPromiseResolver* resolver) { - if (picture_in_picture_element_ != element) { - element->enterPictureInPicture( - WTF::Bind(&PictureInPictureControllerImpl::OnEnteredPictureInPicture, - WrapPersistent(this), WrapPersistent(element), - WrapPersistent(resolver))); - // If the media element has already been given custom controls, this will - // ensure that they get set. Otherwise, this will do nothing. - element->SendCustomControlsToPipWindow(); + if (picture_in_picture_element_ == element) { + if (resolver) + resolver->Resolve(picture_in_picture_window_); + return; } - if (resolver) - resolver->Resolve(picture_in_picture_window_); + element->enterPictureInPicture(); + + DCHECK(element->GetWebMediaPlayer()); + + if (!EnsureService()) + return; + + picture_in_picture_service_->StartSession( + element->GetWebMediaPlayer()->GetDelegateId(), + element->GetWebMediaPlayer()->GetSurfaceId(), + element->GetWebMediaPlayer()->NaturalSize(), + ShouldShowPlayPauseButton(*element), + WTF::Bind(&PictureInPictureControllerImpl::OnEnteredPictureInPicture, + WrapPersistent(this), WrapPersistent(element), + WrapPersistent(resolver))); + + // If the media element has already been given custom controls, this will + // ensure that they get set. Otherwise, this will do nothing. + element->SendCustomControlsToPipWindow(); } void PictureInPictureControllerImpl::OnEnteredPictureInPicture( @@ -112,7 +136,7 @@ resolver->Reject( DOMException::Create(DOMExceptionCode::kInvalidStateError, "")); } - element->exitPictureInPicture(base::DoNothing()); + ExitPictureInPicture(element, nullptr); return; } @@ -132,11 +156,15 @@ event_type_names::kEnterpictureinpicture, WrapPersistent(picture_in_picture_window_.Get()))); - if (element->GetWebMediaPlayer()) { - element->GetWebMediaPlayer()->RegisterPictureInPictureWindowResizeCallback( - WTF::BindRepeating(&PictureInPictureWindow::OnResize, - WrapPersistent(picture_in_picture_window_.Get()))); - } + if (!EnsureService()) + return; + + if (delegate_binding_.is_bound()) + delegate_binding_.Close(); + + mojom::blink::PictureInPictureDelegatePtr delegate; + delegate_binding_.Bind(mojo::MakeRequest(&delegate)); + picture_in_picture_service_->SetDelegate(std::move(delegate)); if (resolver) resolver->Resolve(picture_in_picture_window_); @@ -145,9 +173,16 @@ void PictureInPictureControllerImpl::ExitPictureInPicture( HTMLVideoElement* element, ScriptPromiseResolver* resolver) { - element->exitPictureInPicture( + if (element->GetWebMediaPlayer()) + element->GetWebMediaPlayer()->ExitPictureInPicture(); + + if (!EnsureService()) + return; + + picture_in_picture_service_->EndSession( WTF::Bind(&PictureInPictureControllerImpl::OnExitedPictureInPicture, WrapPersistent(this), WrapPersistent(resolver))); + delegate_binding_.Close(); } void PictureInPictureControllerImpl::SetPictureInPictureCustomControls( @@ -243,7 +278,6 @@ // Auto Picture-in-Picture is allowed only in a PWA window. if (!GetSupplementable()->GetFrame() || - !GetSupplementable()->GetFrame()->View() || GetSupplementable()->GetFrame()->View()->DisplayMode() == WebDisplayMode::kWebDisplayModeBrowser) { return; @@ -274,17 +308,53 @@ } } +void PictureInPictureControllerImpl::ContextDestroyed(Document*) { + picture_in_picture_service_.reset(); + delegate_binding_.Close(); +} + +void PictureInPictureControllerImpl::OnPictureInPictureStateChange() { + DCHECK(picture_in_picture_element_); + DCHECK(picture_in_picture_element_->GetWebMediaPlayer()); + + picture_in_picture_service_->UpdateSession( + picture_in_picture_element_->GetWebMediaPlayer()->GetDelegateId(), + picture_in_picture_element_->GetWebMediaPlayer()->GetSurfaceId(), + picture_in_picture_element_->GetWebMediaPlayer()->NaturalSize(), + ShouldShowPlayPauseButton(*picture_in_picture_element_)); +} + +void PictureInPictureControllerImpl::PictureInPictureWindowSizeChanged( + const blink::WebSize& size) { + if (picture_in_picture_window_) + picture_in_picture_window_->OnResize(size); +} + void PictureInPictureControllerImpl::Trace(blink::Visitor* visitor) { visitor->Trace(picture_in_picture_element_); visitor->Trace(auto_picture_in_picture_elements_); visitor->Trace(picture_in_picture_window_); PictureInPictureController::Trace(visitor); PageVisibilityObserver::Trace(visitor); + DocumentShutdownObserver::Trace(visitor); } PictureInPictureControllerImpl::PictureInPictureControllerImpl( Document& document) : PictureInPictureController(document), - PageVisibilityObserver(document.GetPage()) {} + PageVisibilityObserver(document.GetPage()), + delegate_binding_(this) {} + +bool PictureInPictureControllerImpl::EnsureService() { + if (picture_in_picture_service_) + return true; + + if (!GetSupplementable()->GetFrame()) + return false; + + GetSupplementable()->GetFrame()->GetInterfaceProvider().GetInterface( + mojo::MakeRequest(&picture_in_picture_service_)); + return true; +} } // namespace blink
diff --git a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h index af8a3f9..f0e16f1f 100644 --- a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h +++ b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h
@@ -5,8 +5,11 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_CONTROLLER_IMPL_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_CONTROLLER_IMPL_H_ +#include "third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom-blink.h" +#include "third_party/blink/renderer/core/dom/document_shutdown_observer.h" #include "third_party/blink/renderer/core/frame/picture_in_picture_controller.h" #include "third_party/blink/renderer/core/page/page_visibility_observer.h" +#include "third_party/blink/renderer/modules/modules_export.h" namespace blink { @@ -23,14 +26,17 @@ // PictureInPictureControllerImpl instance is associated to a Document. It is // supplement and therefore can be lazy-initiated. Callers should consider // whether they want to instantiate an object when they make a call. -class PictureInPictureControllerImpl : public PictureInPictureController, - public PageVisibilityObserver { +class MODULES_EXPORT PictureInPictureControllerImpl + : public PictureInPictureController, + public PageVisibilityObserver, + public DocumentShutdownObserver, + public blink::mojom::blink::PictureInPictureDelegate { USING_GARBAGE_COLLECTED_MIXIN(PictureInPictureControllerImpl); WTF_MAKE_NONCOPYABLE(PictureInPictureControllerImpl); public: explicit PictureInPictureControllerImpl(Document&); - ~PictureInPictureControllerImpl() override; + ~PictureInPictureControllerImpl() override = default; // Meant to be called internally by PictureInPictureController::From() // through ModulesInitializer. @@ -67,12 +73,24 @@ const std::vector<PictureInPictureControlInfo>&) override; Status IsElementAllowed(const HTMLVideoElement&) const override; bool IsPictureInPictureElement(const Element*) const override; + void OnPictureInPictureStateChange() override; - // PageVisibilityObserver implementation. + // Implementation of PictureInPictureDelegate. + void PictureInPictureWindowSizeChanged(const blink::WebSize&) override; + + // Implementation of PageVisibilityObserver. void PageVisibilityChanged() override; + // Implementation of DocumentShutdownObserver. + void ContextDestroyed(Document*) override; + void Trace(blink::Visitor*) override; + mojo::Binding<mojom::blink::PictureInPictureDelegate>& + GetDelegateBindingForTesting() { + return delegate_binding_; + } + private: void OnEnteredPictureInPicture(HTMLVideoElement*, ScriptPromiseResolver*, @@ -80,6 +98,10 @@ void OnExitedPictureInPicture(ScriptPromiseResolver*) override; void OnPictureInPictureControlClicked(const WebString& control_id) override; + // Makes sure the `picture_in_picture_service_` is set. Returns whether it was + // initialized successfully. + bool EnsureService(); + // The Picture-in-Picture element for the associated document. Member<HTMLVideoElement> picture_in_picture_element_; @@ -89,6 +111,12 @@ // The Picture-in-Picture window for the associated document. Member<PictureInPictureWindow> picture_in_picture_window_; + + // Mojo bindings for the delegate interface implemented by |this|. + mojo::Binding<mojom::blink::PictureInPictureDelegate> delegate_binding_; + + // Picture-in-Picture service living in the browser process. + mojom::blink::PictureInPictureServicePtr picture_in_picture_service_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc new file mode 100644 index 0000000..05239c5 --- /dev/null +++ b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc
@@ -0,0 +1,321 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h" + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom-blink.h" +#include "third_party/blink/public/platform/web_media_stream.h" +#include "third_party/blink/public/platform/web_media_stream_track.h" +#include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/core/dom/events/native_event_listener.h" +#include "third_party/blink/renderer/core/html/media/html_media_test_helper.h" +#include "third_party/blink/renderer/core/html/media/html_video_element.h" +#include "third_party/blink/renderer/core/testing/page_test_base.h" +#include "third_party/blink/renderer/platform/testing/empty_web_media_player.h" +#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" + +using ::testing::_; + +namespace blink { + +// The MockPictureInPictureService implements the PictureInPicture service in +// the same process as the test and guarantees that the callbacks are called in +// order for the events to be fired. +class MockPictureInPictureService + : public mojom::blink::PictureInPictureService { + public: + MockPictureInPictureService() : binding_(this) { + // Setup default implementations. + ON_CALL(*this, StartSession(_, _, _, _, _)) + .WillByDefault([](uint32_t, const base::Optional<viz::SurfaceId>&, + const blink::WebSize&, bool, + StartSessionCallback callback) { + std::move(callback).Run(WebSize()); + }); + ON_CALL(*this, EndSession(_)) + .WillByDefault( + [](EndSessionCallback callback) { std::move(callback).Run(); }); + } + ~MockPictureInPictureService() override = default; + + void Bind(mojo::ScopedMessagePipeHandle handle) { + binding_.Bind( + mojom::blink::PictureInPictureServiceRequest(std::move(handle))); + } + + MOCK_METHOD5(StartSession, + void(uint32_t, + const base::Optional<viz::SurfaceId>&, + const blink::WebSize&, + bool, + StartSessionCallback)); + MOCK_METHOD1(EndSession, void(EndSessionCallback)); + MOCK_METHOD4(UpdateSession, + void(uint32_t, + const base::Optional<viz::SurfaceId>&, + const blink::WebSize&, + bool)); + MOCK_METHOD1(SetDelegate, void(mojom::blink::PictureInPictureDelegatePtr)); + + private: + mojo::Binding<mojom::blink::PictureInPictureService> binding_; + + DISALLOW_COPY_AND_ASSIGN(MockPictureInPictureService); +}; + +// Helper class that will block running the test until the given event is fired +// on the given element. +class WaitForEvent : public NativeEventListener { + public: + static WaitForEvent* Create(Element* element, const AtomicString& name) { + return MakeGarbageCollected<WaitForEvent>(element, name); + } + + WaitForEvent(Element* element, const AtomicString& name) + : element_(element), name_(name) { + element_->addEventListener(name_, this); + run_loop_.Run(); + } + + void Invoke(ExecutionContext*, Event*) final { + run_loop_.Quit(); + element_->removeEventListener(name_, this); + } + + void Trace(Visitor* visitor) final { + NativeEventListener::Trace(visitor); + visitor->Trace(element_); + } + + private: + base::RunLoop run_loop_; + Member<Element> element_; + AtomicString name_; +}; + +class PictureInPictureControllerFrameClient + : public test::MediaStubLocalFrameClient { + public: + static PictureInPictureControllerFrameClient* Create( + std::unique_ptr<WebMediaPlayer> player) { + return MakeGarbageCollected<PictureInPictureControllerFrameClient>( + std::move(player)); + } + + explicit PictureInPictureControllerFrameClient( + std::unique_ptr<WebMediaPlayer> player) + : test::MediaStubLocalFrameClient(std::move(player)), + interface_provider_(new service_manager::InterfaceProvider()) {} + + service_manager::InterfaceProvider* GetInterfaceProvider() override { + return interface_provider_.get(); + } + + private: + std::unique_ptr<service_manager::InterfaceProvider> interface_provider_; + + DISALLOW_COPY_AND_ASSIGN(PictureInPictureControllerFrameClient); +}; + +// TODO: can probably be removed. +class PictureInPictureControllerPlayer : public EmptyWebMediaPlayer { + public: + PictureInPictureControllerPlayer() = default; + ~PictureInPictureControllerPlayer() final = default; + + double Duration() const final { + if (infinity_duration_) + return std::numeric_limits<double>::infinity(); + return EmptyWebMediaPlayer::Duration(); + } + + void set_infinity_duration(bool value) { infinity_duration_ = value; } + + private: + bool infinity_duration_ = false; + + DISALLOW_COPY_AND_ASSIGN(PictureInPictureControllerPlayer); +}; + +class PictureInPictureControllerTest : public PageTestBase { + public: + void SetUp() override { + PageTestBase::SetupPageWithClients( + nullptr, PictureInPictureControllerFrameClient::Create( + std::make_unique<PictureInPictureControllerPlayer>())); + + service_manager::InterfaceProvider::TestApi test_api( + GetFrame().Client()->GetInterfaceProvider()); + test_api.SetBinderForName( + mojom::blink::PictureInPictureService::Name_, + WTF::BindRepeating(&MockPictureInPictureService::Bind, + WTF::Unretained(&mock_service_))); + + video_ = HTMLVideoElement::Create(GetDocument()); + layer_ = cc::Layer::Create(); + video_->SetCcLayerForTesting(layer_.get()); + + std::string test_name = + testing::UnitTest::GetInstance()->current_test_info()->name(); + if (test_name.find("MediaSource") != std::string::npos) { + blink::WebMediaStream web_media_stream; + blink::WebVector<blink::WebMediaStreamTrack> dummy_tracks; + web_media_stream.Initialize(dummy_tracks, dummy_tracks); + Video()->SetSrcObject(web_media_stream); + } else { + video_->SetSrc("http://example.com/foo.mp4"); + } + + test::RunPendingTasks(); + } + + HTMLVideoElement* Video() const { return video_.Get(); } + MockPictureInPictureService& Service() { return mock_service_; } + + private: + Persistent<HTMLVideoElement> video_; + MockPictureInPictureService mock_service_; + scoped_refptr<cc::Layer> layer_; +}; + +TEST_F(PictureInPictureControllerTest, EnterPictureInPictureFiresEvent) { + EXPECT_EQ(nullptr, PictureInPictureControllerImpl::From(GetDocument()) + .PictureInPictureElement()); + + WebMediaPlayer* player = Video()->GetWebMediaPlayer(); + EXPECT_CALL(Service(), + StartSession(player->GetDelegateId(), player->GetSurfaceId(), + player->NaturalSize(), true, _)); + EXPECT_CALL(Service(), SetDelegate(_)); + + PictureInPictureControllerImpl::From(GetDocument()) + .EnterPictureInPicture(Video(), nullptr); + + WaitForEvent::Create(Video(), event_type_names::kEnterpictureinpicture); + + EXPECT_NE(nullptr, PictureInPictureControllerImpl::From(GetDocument()) + .PictureInPictureElement()); + + // `SetDelegate()` may or may not have been called yet. Waiting a bit for it. + test::RunPendingTasks(); +} + +TEST_F(PictureInPictureControllerTest, ExitPictureInPictureFiresEvent) { + EXPECT_EQ(nullptr, PictureInPictureControllerImpl::From(GetDocument()) + .PictureInPictureElement()); + + WebMediaPlayer* player = Video()->GetWebMediaPlayer(); + EXPECT_CALL(Service(), + StartSession(player->GetDelegateId(), player->GetSurfaceId(), + player->NaturalSize(), true, _)); + EXPECT_CALL(Service(), EndSession(_)); + EXPECT_CALL(Service(), SetDelegate(_)); + + PictureInPictureControllerImpl::From(GetDocument()) + .EnterPictureInPicture(Video(), nullptr); + WaitForEvent::Create(Video(), event_type_names::kEnterpictureinpicture); + + PictureInPictureControllerImpl::From(GetDocument()) + .ExitPictureInPicture(Video(), nullptr); + WaitForEvent::Create(Video(), event_type_names::kLeavepictureinpicture); + + EXPECT_EQ(nullptr, PictureInPictureControllerImpl::From(GetDocument()) + .PictureInPictureElement()); +} + +TEST_F(PictureInPictureControllerTest, StartObserving) { + EXPECT_FALSE(PictureInPictureControllerImpl::From(GetDocument()) + .GetDelegateBindingForTesting() + .is_bound()); + + WebMediaPlayer* player = Video()->GetWebMediaPlayer(); + EXPECT_CALL(Service(), + StartSession(player->GetDelegateId(), player->GetSurfaceId(), + player->NaturalSize(), true, _)); + EXPECT_CALL(Service(), SetDelegate(_)); + + PictureInPictureControllerImpl::From(GetDocument()) + .EnterPictureInPicture(Video(), nullptr); + + WaitForEvent::Create(Video(), event_type_names::kEnterpictureinpicture); + + EXPECT_TRUE(PictureInPictureControllerImpl::From(GetDocument()) + .GetDelegateBindingForTesting() + .is_bound()); + + // `SetDelegate()` may or may not have been called yet. Waiting a bit for it. + test::RunPendingTasks(); +} + +TEST_F(PictureInPictureControllerTest, StopObserving) { + EXPECT_FALSE(PictureInPictureControllerImpl::From(GetDocument()) + .GetDelegateBindingForTesting() + .is_bound()); + + WebMediaPlayer* player = Video()->GetWebMediaPlayer(); + EXPECT_CALL(Service(), + StartSession(player->GetDelegateId(), player->GetSurfaceId(), + player->NaturalSize(), true, _)); + EXPECT_CALL(Service(), EndSession(_)); + EXPECT_CALL(Service(), SetDelegate(_)); + + PictureInPictureControllerImpl::From(GetDocument()) + .EnterPictureInPicture(Video(), nullptr); + WaitForEvent::Create(Video(), event_type_names::kEnterpictureinpicture); + + PictureInPictureControllerImpl::From(GetDocument()) + .ExitPictureInPicture(Video(), nullptr); + WaitForEvent::Create(Video(), event_type_names::kLeavepictureinpicture); + + EXPECT_FALSE(PictureInPictureControllerImpl::From(GetDocument()) + .GetDelegateBindingForTesting() + .is_bound()); +} + +TEST_F(PictureInPictureControllerTest, PlayPauseButton_InfiniteDuration) { + EXPECT_EQ(nullptr, PictureInPictureControllerImpl::From(GetDocument()) + .PictureInPictureElement()); + + Video()->DurationChanged(std::numeric_limits<double>::infinity(), false); + + WebMediaPlayer* player = Video()->GetWebMediaPlayer(); + EXPECT_CALL(Service(), + StartSession(player->GetDelegateId(), player->GetSurfaceId(), + player->NaturalSize(), false, _)); + EXPECT_CALL(Service(), SetDelegate(_)); + + PictureInPictureControllerImpl::From(GetDocument()) + .EnterPictureInPicture(Video(), nullptr); + + WaitForEvent::Create(Video(), event_type_names::kEnterpictureinpicture); + + // `SetDelegate()` may or may not have been called yet. Waiting a bit for it. + test::RunPendingTasks(); +} + +TEST_F(PictureInPictureControllerTest, PlayPauseButton_MediaSource) { + EXPECT_EQ(nullptr, PictureInPictureControllerImpl::From(GetDocument()) + .PictureInPictureElement()); + + // The test automatically setup the WebMediaPlayer with a MediaSource based on + // the test name. + + WebMediaPlayer* player = Video()->GetWebMediaPlayer(); + EXPECT_CALL(Service(), + StartSession(player->GetDelegateId(), player->GetSurfaceId(), + player->NaturalSize(), false, _)); + EXPECT_CALL(Service(), SetDelegate(_)); + + PictureInPictureControllerImpl::From(GetDocument()) + .EnterPictureInPicture(Video(), nullptr); + + WaitForEvent::Create(Video(), event_type_names::kEnterpictureinpicture); + + // `SetDelegate()` may or may not have been called yet. Waiting a bit for it. + test::RunPendingTasks(); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/screen_orientation/BUILD.gn b/third_party/blink/renderer/modules/screen_orientation/BUILD.gn index 3f2228b..9d4427f3 100644 --- a/third_party/blink/renderer/modules/screen_orientation/BUILD.gn +++ b/third_party/blink/renderer/modules/screen_orientation/BUILD.gn
@@ -12,8 +12,6 @@ "screen_orientation.h", "screen_orientation_controller_impl.cc", "screen_orientation_controller_impl.h", - "screen_orientation_dispatcher.cc", - "screen_orientation_dispatcher.h", "screen_screen_orientation.cc", "screen_screen_orientation.h", "web_lock_orientation_callback.h",
diff --git a/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc b/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc index e533cab2..f4fde9a 100644 --- a/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc +++ b/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc
@@ -17,7 +17,6 @@ #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/modules/screen_orientation/screen_orientation.h" -#include "third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.h" #include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -39,7 +38,7 @@ LocalFrame& frame) : ScreenOrientationController(frame), ContextLifecycleObserver(frame.GetDocument()), - PlatformEventController(frame.GetDocument()), + PageVisibilityObserver(frame.GetPage()), dispatch_event_timer_( frame.GetTaskRunner(TaskType::kMiscPlatformAPI), this, @@ -90,9 +89,8 @@ void ScreenOrientationControllerImpl::UpdateOrientation() { DCHECK(orientation_); - DCHECK(GetFrame()); - DCHECK(GetFrame()->GetPage()); - ChromeClient& chrome_client = GetFrame()->GetPage()->GetChromeClient(); + DCHECK(GetPage()); + ChromeClient& chrome_client = GetPage()->GetChromeClient(); WebScreenInfo screen_info = chrome_client.GetScreenInfo(); WebScreenOrientationType orientation_type = screen_info.orientation_type; if (orientation_type == kWebScreenOrientationUndefined) { @@ -120,21 +118,15 @@ } void ScreenOrientationControllerImpl::PageVisibilityChanged() { - NotifyDispatcher(); - if (!IsActiveAndVisible()) return; - DCHECK(GetFrame()); - DCHECK(GetFrame()->GetPage()); + DCHECK(GetPage()); // The orientation type and angle are tied in a way that if the angle has // changed, the type must have changed. - unsigned short current_angle = GetFrame() - ->GetPage() - ->GetChromeClient() - .GetScreenInfo() - .orientation_angle; + unsigned short current_angle = + GetPage()->GetChromeClient().GetScreenInfo().orientation_angle; // FIXME: sendOrientationChangeEvent() currently send an event all the // children of the frame, so it should only be called on the frame on @@ -181,7 +173,6 @@ orientation_ = orientation; if (orientation_) UpdateOrientation(); - NotifyDispatcher(); } void ScreenOrientationControllerImpl::lock( @@ -224,40 +215,16 @@ orientation_->DispatchEvent(*Event::Create(event_type_names::kChange)); } -void ScreenOrientationControllerImpl::DidUpdateData() { - // Do nothing. -} - -void ScreenOrientationControllerImpl::RegisterWithDispatcher() { - ScreenOrientationDispatcher::Instance().AddController(this); -} - -void ScreenOrientationControllerImpl::UnregisterWithDispatcher() { - ScreenOrientationDispatcher::Instance().RemoveController(this); -} - -bool ScreenOrientationControllerImpl::HasLastData() { - return true; -} - void ScreenOrientationControllerImpl::ContextDestroyed(ExecutionContext*) { - StopUpdating(); screen_orientation_service_ = nullptr; active_lock_ = false; } -void ScreenOrientationControllerImpl::NotifyDispatcher() { - if (orientation_ && GetPage()->IsPageVisible()) - StartUpdating(); - else - StopUpdating(); -} - void ScreenOrientationControllerImpl::Trace(blink::Visitor* visitor) { visitor->Trace(orientation_); ContextLifecycleObserver::Trace(visitor); + PageVisibilityObserver::Trace(visitor); Supplement<LocalFrame>::Trace(visitor); - PlatformEventController::Trace(visitor); } void ScreenOrientationControllerImpl::SetScreenOrientationAssociatedPtrForTests(
diff --git a/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.h b/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.h index 4ce2346..c35d59a 100644 --- a/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.h +++ b/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.h
@@ -10,8 +10,8 @@ #include "third_party/blink/public/common/screen_orientation/web_screen_orientation_lock_type.h" #include "third_party/blink/public/common/screen_orientation/web_screen_orientation_type.h" #include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/frame/platform_event_controller.h" #include "third_party/blink/renderer/core/frame/screen_orientation_controller.h" +#include "third_party/blink/renderer/core/page/page_visibility_observer.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/screen_orientation/web_lock_orientation_callback.h" @@ -25,7 +25,7 @@ class MODULES_EXPORT ScreenOrientationControllerImpl final : public ScreenOrientationController, public ContextLifecycleObserver, - public PlatformEventController { + public PageVisibilityObserver { USING_GARBAGE_COLLECTED_MIXIN(ScreenOrientationControllerImpl); WTF_MAKE_NONCOPYABLE(ScreenOrientationControllerImpl); @@ -56,18 +56,10 @@ static WebScreenOrientationType ComputeOrientation(const IntRect&, uint16_t); - // Inherited from PlatformEventController. - void DidUpdateData() override; - void RegisterWithDispatcher() override; - void UnregisterWithDispatcher() override; - bool HasLastData() override; - // Inherited from ContextLifecycleObserver and PageVisibilityObserver. void ContextDestroyed(ExecutionContext*) override; void PageVisibilityChanged() override; - void NotifyDispatcher(); - void UpdateOrientation(); void DispatchEventTimerFired(TimerBase*);
diff --git a/third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.cc b/third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.cc deleted file mode 100644 index 2688832..0000000 --- a/third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.cc +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.h" - -#include "services/device/public/mojom/constants.mojom-blink.h" -#include "services/service_manager/public/cpp/connector.h" -#include "third_party/blink/public/platform/platform.h" - -namespace blink { - -ScreenOrientationDispatcher& ScreenOrientationDispatcher::Instance() { - DEFINE_STATIC_LOCAL(Persistent<ScreenOrientationDispatcher>, - screen_orientation_dispatcher, - (MakeGarbageCollected<ScreenOrientationDispatcher>())); - return *screen_orientation_dispatcher; -} - -ScreenOrientationDispatcher::ScreenOrientationDispatcher() = default; - -ScreenOrientationDispatcher::~ScreenOrientationDispatcher() { - DCHECK(!listener_); -} - -void ScreenOrientationDispatcher::Trace(blink::Visitor* visitor) { - PlatformEventDispatcher::Trace(visitor); -} - -void ScreenOrientationDispatcher::StartListening(LocalFrame* frame) { - DCHECK(!listener_); - - Platform::Current()->GetConnector()->BindInterface( - device::mojom::blink::kServiceName, mojo::MakeRequest(&listener_)); - listener_->Start(); -} - -void ScreenOrientationDispatcher::StopListening() { - DCHECK(listener_); - - listener_->Stop(); - listener_.reset(); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.h b/third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.h deleted file mode 100644 index 8b22668..0000000 --- a/third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.h +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SCREEN_ORIENTATION_SCREEN_ORIENTATION_DISPATCHER_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_SCREEN_ORIENTATION_SCREEN_ORIENTATION_DISPATCHER_H_ - -#include "base/macros.h" -#include "services/device/public/mojom/screen_orientation.mojom-blink.h" -#include "third_party/blink/renderer/core/frame/platform_event_dispatcher.h" -#include "third_party/blink/renderer/platform/heap/handle.h" - -namespace blink { - -// ScreenOrientationDispatcher is a singleton that handles whether the current -// Blink instance should be listening to the screen orientation platform events. -// It is not a common implementation of PlatformEventDispatcher in the sense -// that it doesn't actually dispatch events but simply start/stop listening. The -// reason being that screen orientation events are always sent to the WebFrame's -// but some platforms require to poll to have an accurate reporting. When -// ScreenOrientationDispatcher is listening, that means that the platform should -// be polling if required. -class ScreenOrientationDispatcher final - : public GarbageCollectedFinalized<ScreenOrientationDispatcher>, - public PlatformEventDispatcher { - USING_GARBAGE_COLLECTED_MIXIN(ScreenOrientationDispatcher); - - public: - static ScreenOrientationDispatcher& Instance(); - - ScreenOrientationDispatcher(); - ~ScreenOrientationDispatcher(); - - void Trace(blink::Visitor*) override; - - private: - // Inherited from PlatformEventDispatcher. - void StartListening(LocalFrame*) override; - void StopListening() override; - - device::mojom::blink::ScreenOrientationListenerPtr listener_; - - DISALLOW_COPY_AND_ASSIGN(ScreenOrientationDispatcher); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SCREEN_ORIENTATION_SCREEN_ORIENTATION_DISPATCHER_H_
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc index 6653bcb..cd6b3dfc 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -588,7 +588,14 @@ const auto& lca = LowestCommonAncestor(*current_.clip, *target_clip).Unalias(); while (current_.clip != &lca) { - DCHECK(IsCurrentCcEffectSynthetic()); + if (!IsCurrentCcEffectSynthetic()) { + // This happens in pre-CompositeAfterPaint due to some clip-escaping + // corner cases that are very difficult to fix in legacy architecture. + // In CompositeAfterPaint this should never happen. + if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + NOTREACHED(); + return delegated_blend; + } const auto* pre_exit_clip = current_.clip; CloseCcEffect(); // We may run past the lowest common ancestor because it may not have
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index c1fc16c..7bb9bee 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -1142,13 +1142,6 @@ scoped_refptr<ResourceTimingInfo> info = ResourceTimingInfo::Create(fetch_initiator, CurrentTimeTicks()); - if (resource->IsCacheValidator()) { - const AtomicString& timing_allow_origin = - resource->GetResponse().HttpHeaderField(http_names::kTimingAllowOrigin); - if (!timing_allow_origin.IsEmpty()) - info->SetOriginalTimingAllowOrigin(timing_allow_origin); - } - resource_timing_info_map_.insert(resource, std::move(info)); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h b/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h index 541ef06..b6203dc 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h
@@ -56,14 +56,6 @@ const AtomicString& InitiatorType() const { return type_; } - void SetOriginalTimingAllowOrigin( - const AtomicString& original_timing_allow_origin) { - original_timing_allow_origin_ = original_timing_allow_origin; - } - const AtomicString& OriginalTimingAllowOrigin() const { - return original_timing_allow_origin_; - } - void SetLoadFinishTime(TimeTicks time) { load_finish_time_ = time; } TimeTicks LoadFinishTime() const { return load_finish_time_; } @@ -102,7 +94,6 @@ : type_(type), initial_time_(time) {} AtomicString type_; - AtomicString original_timing_allow_origin_; TimeTicks initial_time_; TimeTicks load_finish_time_; KURL initial_url_;
diff --git a/third_party/blink/renderer/platform/testing/empty_web_media_player.h b/third_party/blink/renderer/platform/testing/empty_web_media_player.h index 205fde99..fea2a40 100644 --- a/third_party/blink/renderer/platform/testing/empty_web_media_player.h +++ b/third_party/blink/renderer/platform/testing/empty_web_media_player.h
@@ -28,12 +28,10 @@ void Seek(double seconds) override {} void SetRate(double) override {} void SetVolume(double) override {} - void EnterPictureInPicture(PipWindowOpenedCallback) override {} - void ExitPictureInPicture(PipWindowClosedCallback) override {} + void EnterPictureInPicture() override {} + void ExitPictureInPicture() override {} void SetPictureInPictureCustomControls( const std::vector<PictureInPictureControlInfo>&) override {} - void RegisterPictureInPictureWindowResizeCallback( - PipWindowResizedCallback) override {} SurfaceLayerMode GetVideoSurfaceLayerMode() const override { return SurfaceLayerMode::kNever; }
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint index d0d1a1e..60332bb3 100644 --- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint +++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
@@ -89,6 +89,7 @@ Bug(none) compositing/layer-creation/spanOverlapsCanvas.html [ Failure ] Bug(none) compositing/layer-creation/squashing-into-ancestor-clipping-layer-change.html [ Failure ] Bug(none) compositing/masks/mask-with-removed-filters.html [ Failure ] +Bug(none) compositing/nested-multicol-mask-composited-filter-crash.html [ Crash ] Bug(none) compositing/overflow/accelerated-overflow-scroll-should-not-affect-perspective.html [ Failure ] Bug(none) compositing/overflow/accelerated-scrolling-with-clip-path.html [ Failure ] Bug(none) compositing/overflow/avoid-ancestor-clip-for-scroll-children.html [ Failure ]
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index 15975b60..d3c46ea 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -2017,6 +2017,10 @@ external/wpt/payment-request/algorithms-manual.https.html [ WontFix ] external/wpt/payment-request/change-shipping-option-manual.https.html [ WontFix ] external/wpt/payment-request/change-shipping-option-select-last-manual.https.html [ WontFix ] +external/wpt/payment-request/payment-request-abort-method-manual.https.html [ WontFix ] +external/wpt/payment-request/payment-request-canmakepayment-method-manual.https.html [ WontFix ] +external/wpt/payment-request/payment-request-multiple-show-manual.https.html [ WontFix ] +external/wpt/payment-request/payment-request-show-method-manual.https.html [ WontFix ] external/wpt/payment-request/payment-response/complete-method-manual.https.html [ WontFix ] external/wpt/payment-request/payment-response/methodName-attribute-manual.https.html [ WontFix ] external/wpt/payment-request/payment-response/onpayerdetailchange-attribute-manual.https.html [ WontFix ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index d38b620..2fde11a 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3073,6 +3073,19 @@ crbug.com/918664 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/sizing/block-size-with-min-or-max-content-table-1a.html [ Failure Pass ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/webrtc/RTCIceConnectionState-candidate-pair.https.html [ Timeout ] +crbug.com/626703 [ Linux ] external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html [ Timeout ] +crbug.com/626703 [ Win7 ] external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html [ Failure Timeout ] +crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007v.html [ Failure ] +crbug.com/626703 [ Mac10.11 ] external/wpt/mimesniff/mime-types/parsing.any.html [ Timeout ] +crbug.com/626703 [ Linux ] external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-8.html [ Timeout ] +crbug.com/626703 [ Win7 ] external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-8.html [ Failure Timeout ] +crbug.com/626703 external/wpt/css/css-writing-modes/baseline-with-orthogonal-flow-001.html [ Failure ] +crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007.html [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252.html [ Timeout ] +crbug.com/626703 [ Win10 ] external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252.html [ Failure Timeout ] +crbug.com/626703 [ Win7 ] external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252.html [ Failure Timeout ] +crbug.com/626703 external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/navigation.sub.html?encoding=windows-1252 [ Timeout ] crbug.com/626703 external/wpt/css/css-values/calc-positive-fraction-001.html [ Failure ] crbug.com/626703 external/wpt/css/css-values/ch-unit-011.html [ Failure ] crbug.com/626703 external/wpt/css/css-values/attr-invalid-type-008.html [ Failure ] @@ -3185,7 +3198,6 @@ crbug.com/626703 [ Mac10.13 ] external/wpt/html/browsers/browsing-the-web/read-media/pageload-video.html [ Crash ] crbug.com/626703 [ Mac10.13 ] external/wpt/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Crash ] crbug.com/626703 [ Retina ] external/wpt/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Crash ] -crbug.com/626703 [ Retina ] external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html [ Crash ] crbug.com/626703 [ Retina ] external/wpt/feature-policy/picture-in-picture-allowed-by-feature-policy.https.sub.html [ Crash ] crbug.com/626703 [ Mac10.13 ] external/wpt/html/semantics/embedded-content/the-video-element/intrinsic_sizes.htm [ Crash ] crbug.com/626703 [ Retina ] external/wpt/html/semantics/embedded-content/the-video-element/intrinsic_sizes.htm [ Crash ] @@ -3197,7 +3209,6 @@ crbug.com/626703 [ Retina ] virtual/unified-autoplay/external/wpt/feature-policy/picture-in-picture-default-feature-policy.https.sub.html [ Crash ] crbug.com/626703 [ Mac10.13 ] external/wpt/media-source/mediasource-detach.html [ Crash ] crbug.com/626703 [ Retina ] external/wpt/media-source/mediasource-detach.html [ Crash ] -crbug.com/626703 [ Retina ] external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252.html [ Crash ] crbug.com/626703 external/wpt/infrastructure/testdriver/actions/pause.html [ Timeout ] crbug.com/626703 external/wpt/infrastructure/testdriver/actions/eventOrder.html [ Timeout ] crbug.com/626703 external/wpt/css/css-text/writing-system/writing-system-segment-break-001.html [ Failure ] @@ -3935,7 +3946,6 @@ crbug.com/626703 external/wpt/IndexedDB/request-abort-ordering.html [ Pass Failure ] crbug.com/626703 external/wpt/media-source/mediasource-avtracks.html [ Failure Crash ] crbug.com/626703 external/wpt/media-source/mediasource-getvideoplaybackquality.html [ Timeout Failure ] -crbug.com/626703 external/wpt/payment-request/payment-request-show-method.https.html [ Pass Failure ] crbug.com/626703 external/wpt/performance-timeline/po-observe.html [ Timeout ] crbug.com/626703 external/wpt/pointerevents/pointerevent_disabled_form_control-manual.html [ Timeout Pass ] crbug.com/626703 external/wpt/presentation-api/controlling-ua/getAvailability.https.html [ Timeout ]
diff --git a/third_party/blink/web_tests/compositing/nested-multicol-mask-composited-filter-crash.html b/third_party/blink/web_tests/compositing/nested-multicol-mask-composited-filter-crash.html new file mode 100644 index 0000000..720c8e83 --- /dev/null +++ b/third_party/blink/web_tests/compositing/nested-multicol-mask-composited-filter-crash.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script>test(function(){});</script> +<style> +@keyframes Rotation{ + 0% { transform: rotate(0deg) } + 100% { transform: rotate(360deg) } +} +</style> +<div style="columns: 82"> + <div id="target" style="columns: 82; visibility: hidden; -webkit-mask: url(#foo); width: 10px"> + <div style="animation: rotation 1s infinite; filter: blur(5px)"></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json index 7ce3e4c..9b37617 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -127,15 +127,15 @@ {} ] ], - "clipboard-apis/async-write-dttext-read-dttext-manual.https.html": [ + "clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html": [ [ - "/clipboard-apis/async-write-dttext-read-dttext-manual.https.html", + "/clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html", {} ] ], - "clipboard-apis/async-write-dttext-read-text-manual.https.html": [ + "clipboard-apis/async-write-blobtext-read-text-manual.https.html": [ [ - "/clipboard-apis/async-write-dttext-read-text-manual.https.html", + "/clipboard-apis/async-write-blobtext-read-text-manual.https.html", {} ] ], @@ -145,9 +145,9 @@ {} ] ], - "clipboard-apis/async-write-text-read-dttext-manual.https.html": [ + "clipboard-apis/async-write-text-read-blobtext-manual.https.html": [ [ - "/clipboard-apis/async-write-text-read-dttext-manual.https.html", + "/clipboard-apis/async-write-text-read-blobtext-manual.https.html", {} ] ], @@ -5527,6 +5527,24 @@ {} ] ], + "payment-request/payment-request-abort-method-manual.https.html": [ + [ + "/payment-request/payment-request-abort-method-manual.https.html", + {} + ] + ], + "payment-request/payment-request-multiple-show-manual.https.html": [ + [ + "/payment-request/payment-request-multiple-show-manual.https.html", + {} + ] + ], + "payment-request/payment-request-show-method-manual.https.html": [ + [ + "/payment-request/payment-request-show-method-manual.https.html", + {} + ] + ], "payment-request/payment-response/complete-method-manual.https.html": [ [ "/payment-request/payment-response/complete-method-manual.https.html", @@ -6777,6 +6795,30 @@ {} ] ], + "animation-worklet/worklet-animation-local-time-after-duration.https.html": [ + [ + "/animation-worklet/worklet-animation-local-time-after-duration.https.html", + [ + [ + "/animation-worklet/worklet-animation-local-time-after-duration-ref.html", + "==" + ] + ], + {} + ] + ], + "animation-worklet/worklet-animation-local-time-before-start.https.html": [ + [ + "/animation-worklet/worklet-animation-local-time-before-start.https.html", + [ + [ + "/animation-worklet/worklet-animation-local-time-before-start-ref.html", + "==" + ] + ], + {} + ] + ], "apng/animated-png-timeout.html": [ [ "/apng/animated-png-timeout.html", @@ -30137,6 +30179,30 @@ {} ] ], + "css/css-align/baseline-of-scrollable-1a.html": [ + [ + "/css/css-align/baseline-of-scrollable-1a.html", + [ + [ + "/css/css-align/reference/baseline-of-scrollable-1-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-align/baseline-of-scrollable-1b.html": [ + [ + "/css/css-align/baseline-of-scrollable-1b.html", + [ + [ + "/css/css-align/reference/baseline-of-scrollable-1-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-align/content-distribution/place-content-shorthand-007.html": [ [ "/css/css-align/content-distribution/place-content-shorthand-007.html", @@ -84829,6 +84895,18 @@ {} ] ], + "css/css-writing-modes/baseline-with-orthogonal-flow-001.html": [ + [ + "/css/css-writing-modes/baseline-with-orthogonal-flow-001.html", + [ + [ + "/css/css-writing-modes/reference/baseline-with-orthogonal-flow-001-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-writing-modes/bidi-embed-001.html": [ [ "/css/css-writing-modes/bidi-embed-001.html", @@ -91621,6 +91699,18 @@ {} ] ], + "css/cssom-view/long_scroll_composited.html": [ + [ + "/css/cssom-view/long_scroll_composited.html", + [ + [ + "/css/cssom-view/long_scroll_composited-ref.html", + "==" + ] + ], + {} + ] + ], "css/cssom-view/offsetTopLeftInline.html": [ [ "/css/cssom-view/offsetTopLeftInline.html", @@ -91753,18 +91843,6 @@ {} ] ], - "css/filter-effects/backdrop-filter-border-radius.html": [ - [ - "/css/filter-effects/backdrop-filter-border-radius.html", - [ - [ - "/css/filter-effects/backdrop-filter-border-radius-ref.html", - "==" - ] - ], - {} - ] - ], "css/filter-effects/backdrop-filter-clip-rect.html": [ [ "/css/filter-effects/backdrop-filter-clip-rect.html", @@ -97957,6 +98035,30 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007-ref.html", + "==" + ] + ], + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007v.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007v.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007-ref.html", + "==" + ] + ], + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-items-as-stacking-contexts-001.xhtml": [ [ "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-items-as-stacking-contexts-001.xhtml", @@ -116394,6 +116496,16 @@ {} ] ], + "animation-worklet/worklet-animation-local-time-after-duration-ref.html": [ + [ + {} + ] + ], + "animation-worklet/worklet-animation-local-time-before-start-ref.html": [ + [ + {} + ] + ], "apng/META.yml": [ [ {} @@ -125764,6 +125876,11 @@ {} ] ], + "css/css-align/reference/baseline-of-scrollable-1-ref.html": [ + [ + {} + ] + ], "css/css-align/reference/ttwf-reftest-alignContent-ref.html": [ [ {} @@ -140629,6 +140746,11 @@ {} ] ], + "css/css-overscroll-behavior/parsing/overscroll-behavior-valid-expected.txt": [ + [ + {} + ] + ], "css/css-paint-api/META.yml": [ [ {} @@ -147104,11 +147226,6 @@ {} ] ], - "css/css-transitions/transitioncancel-001-expected.txt": [ - [ - {} - ] - ], "css/css-typed-om/CSSMatrixComponent-DOMMatrix-mutable-expected.txt": [ [ {} @@ -149864,6 +149981,11 @@ {} ] ], + "css/css-writing-modes/reference/baseline-with-orthogonal-flow-001-ref.html": [ + [ + {} + ] + ], "css/css-writing-modes/reference/bidi-embed-001.html": [ [ {} @@ -152099,6 +152221,11 @@ {} ] ], + "css/cssom-view/long_scroll_composited-ref.html": [ + [ + {} + ] + ], "css/cssom-view/resources/elementsFromPoint.js": [ [ {} @@ -152744,11 +152871,6 @@ {} ] ], - "css/filter-effects/backdrop-filter-border-radius-ref.html": [ - [ - {} - ] - ], "css/filter-effects/backdrop-filter-clip-rect-ref.html": [ [ {} @@ -153279,11 +153401,6 @@ {} ] ], - "css/mediaqueries/prefers-reduced-motion-expected.txt": [ - [ - {} - ] - ], "css/mediaqueries/reference/ref-green-body.xht": [ [ {} @@ -155174,6 +155291,11 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007-ref.html": [ + [ + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-items-as-stacking-contexts-001-ref.xhtml": [ [ {} @@ -157119,6 +157241,11 @@ {} ] ], + "domparsing/XMLSerializer-serializeToString-expected.txt": [ + [ + {} + ] + ], "domparsing/innerhtml-01-expected.txt": [ [ {} @@ -157849,6 +157976,11 @@ {} ] ], + "element-timing/resources/TAOImage.py": [ + [ + {} + ] + ], "element-timing/resources/circle.svg": [ [ {} @@ -159864,6 +159996,16 @@ {} ] ], + "feature-policy/reporting/serial-report-only.https.html.headers": [ + [ + {} + ] + ], + "feature-policy/reporting/serial-reporting.https.html.headers": [ + [ + {} + ] + ], "feature-policy/reporting/sync-xhr-report-only.html.headers": [ [ {} @@ -159954,6 +160096,21 @@ {} ] ], + "feature-policy/resources/feature-policy-serial-worker.html": [ + [ + {} + ] + ], + "feature-policy/resources/feature-policy-serial-worker.js": [ + [ + {} + ] + ], + "feature-policy/resources/feature-policy-serial.html": [ + [ + {} + ] + ], "feature-policy/resources/feature-policy-usb-worker.html": [ [ {} @@ -163449,11 +163606,6 @@ {} ] ], - "html/browsers/origin/relaxing-the-same-origin-restriction/support/document_domain_frame.html": [ - [ - {} - ] - ], "html/browsers/origin/relaxing-the-same-origin-restriction/support/document_domain_setter_iframe.html": [ [ {} @@ -168744,11 +168896,21 @@ {} ] ], + "html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub_encoding=windows-1252-expected.txt": [ + [ + {} + ] + ], "html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub_encoding=x-cp1251-expected.txt": [ [ {} ] ], + "html/infrastructure/urls/resolving-urls/query-encoding/location.sub_encoding=windows-1252-expected.txt": [ + [ + {} + ] + ], "html/infrastructure/urls/resolving-urls/query-encoding/location.sub_encoding=x-cp1251-expected.txt": [ [ {} @@ -168799,11 +168961,6 @@ {} ] ], - "html/infrastructure/urls/resolving-urls/query-encoding/windows-1252-expected.txt": [ - [ - {} - ] - ], "html/input/the-placeholder-attribute/multiline-ref.html": [ [ {} @@ -175049,6 +175206,11 @@ {} ] ], + "lifecycle/resources/subframe.html": [ + [ + {} + ] + ], "lifecycle/resources/window.html": [ [ {} @@ -178039,11 +178201,6 @@ {} ] ], - "payment-request/payment-request-abort-method.https-expected.txt": [ - [ - {} - ] - ], "payment-request/payment-request-canmakepayment-method-protection.https-expected.txt": [ [ {} @@ -182529,6 +182686,26 @@ {} ] ], + "serial/resources/serial-allowed-by-feature-policy-worker.js": [ + [ + {} + ] + ], + "serial/resources/serial-disabled-by-feature-policy-worker.js": [ + [ + {} + ] + ], + "serial/serial-allowed-by-feature-policy.https.sub.html.headers": [ + [ + {} + ] + ], + "serial/serial-disabled-by-feature-policy.https.sub.html.headers": [ + [ + {} + ] + ], "server-timing/META.yml": [ [ {} @@ -188684,11 +188861,6 @@ {} ] ], - "webaudio/the-audio-api/the-audiobuffersourcenode-interface/resources/sub-sample-scheduling.html": [ - [ - {} - ] - ], "webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js": [ [ {} @@ -188834,6 +189006,81 @@ {} ] ], + "webdriver/META.yml": [ + [ + {} + ] + ], + "webdriver/README.md": [ + [ + {} + ] + ], + "webdriver/tests/__init__.py": [ + [ + {} + ] + ], + "webdriver/tests/conftest.py": [ + [ + {} + ] + ], + "webdriver/tests/navigate_to/__init__.py": [ + [ + {} + ] + ], + "webdriver/tests/support/__init__.py": [ + [ + {} + ] + ], + "webdriver/tests/support/asserts.py": [ + [ + {} + ] + ], + "webdriver/tests/support/defaults.py": [ + [ + {} + ] + ], + "webdriver/tests/support/fixtures.py": [ + [ + {} + ] + ], + "webdriver/tests/support/helpers.py": [ + [ + {} + ] + ], + "webdriver/tests/support/http_request.py": [ + [ + {} + ] + ], + "webdriver/tests/support/image.py": [ + [ + {} + ] + ], + "webdriver/tests/support/inline.py": [ + [ + {} + ] + ], + "webdriver/tests/support/merge_dictionaries.py": [ + [ + {} + ] + ], + "webdriver/tests/support/sync.py": [ + [ + {} + ] + ], "webmessaging/META.yml": [ [ {} @@ -202498,6 +202745,12 @@ {} ] ], + "animation-worklet/playback-rate.https.html": [ + [ + "/animation-worklet/playback-rate.https.html", + {} + ] + ], "animation-worklet/scroll-timeline-writing-modes.https.html": [ [ "/animation-worklet/scroll-timeline-writing-modes.https.html", @@ -212780,6 +213033,18 @@ {} ] ], + "css/css-overscroll-behavior/parsing/overscroll-behavior-invalid.html": [ + [ + "/css/css-overscroll-behavior/parsing/overscroll-behavior-invalid.html", + {} + ] + ], + "css/css-overscroll-behavior/parsing/overscroll-behavior-valid.html": [ + [ + "/css/css-overscroll-behavior/parsing/overscroll-behavior-valid.html", + {} + ] + ], "css/css-paint-api/idlharness.html": [ [ "/css/css-paint-api/idlharness.html", @@ -225240,15 +225505,21 @@ {} ] ], - "element-timing/cross-origin-element.html": [ + "element-timing/cross-origin-element.sub.html": [ [ - "/element-timing/cross-origin-element.html", + "/element-timing/cross-origin-element.sub.html", {} ] ], - "element-timing/cross-origin-iframe-element.html": [ + "element-timing/cross-origin-iframe-element.sub.html": [ [ - "/element-timing/cross-origin-iframe-element.html", + "/element-timing/cross-origin-iframe-element.sub.html", + {} + ] + ], + "element-timing/image-TAO-wildcard.sub.html": [ + [ + "/element-timing/image-TAO-wildcard.sub.html", {} ] ], @@ -234660,6 +234931,22 @@ } ] ], + "feature-policy/reporting/serial-report-only.https.html": [ + [ + "/feature-policy/reporting/serial-report-only.https.html", + { + "testdriver": true + } + ] + ], + "feature-policy/reporting/serial-reporting.https.html": [ + [ + "/feature-policy/reporting/serial-reporting.https.html", + { + "testdriver": true + } + ] + ], "feature-policy/reporting/sync-xhr-report-only.html": [ [ "/feature-policy/reporting/sync-xhr-report-only.html", @@ -238088,12 +238375,6 @@ {} ] ], - "html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter_null.tentative.html": [ - [ - "/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter_null.tentative.html", - {} - ] - ], "html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter_srcdoc.html": [ [ "/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter_srcdoc.html", @@ -239652,6 +239933,10 @@ {} ], [ + "/html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub.html?encoding=windows-1252", + {} + ], + [ "/html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub.html?encoding=x-cp1251", {} ] @@ -239662,6 +239947,10 @@ {} ], [ + "/html/infrastructure/urls/resolving-urls/query-encoding/location.sub.html?encoding=windows-1252", + {} + ], + [ "/html/infrastructure/urls/resolving-urls/query-encoding/location.sub.html?encoding=x-cp1251", {} ] @@ -239672,6 +239961,10 @@ {} ], [ + "/html/infrastructure/urls/resolving-urls/query-encoding/navigation.sub.html?encoding=windows-1252", + {} + ], + [ "/html/infrastructure/urls/resolving-urls/query-encoding/navigation.sub.html?encoding=x-cp1251", {} ] @@ -240304,18 +240597,6 @@ {} ] ], - "html/semantics/document-metadata/the-link-element/link-multiple-error-events.html": [ - [ - "/html/semantics/document-metadata/the-link-element/link-multiple-error-events.html", - {} - ] - ], - "html/semantics/document-metadata/the-link-element/link-multiple-load-events.html": [ - [ - "/html/semantics/document-metadata/the-link-element/link-multiple-load-events.html", - {} - ] - ], "html/semantics/document-metadata/the-link-element/link-rel-attribute.html": [ [ "/html/semantics/document-metadata/the-link-element/link-rel-attribute.html", @@ -250564,6 +250845,12 @@ {} ] ], + "lifecycle/child-display-none.tentative.html": [ + [ + "/lifecycle/child-display-none.tentative.html", + {} + ] + ], "lifecycle/freeze.html": [ [ "/lifecycle/freeze.html", @@ -250666,13 +250953,9 @@ {} ] ], - "longtask-timing/supported-longtask-types.any.js": [ + "longtask-timing/supported-longtask-types.window.js": [ [ - "/longtask-timing/supported-longtask-types.any.html", - {} - ], - [ - "/longtask-timing/supported-longtask-types.any.worker.html", + "/longtask-timing/supported-longtask-types.window.html", {} ] ], @@ -254672,13 +254955,9 @@ {} ] ], - "navigation-timing/supported_navigation_type.any.js": [ + "navigation-timing/supported_navigation_type.window.js": [ [ - "/navigation-timing/supported_navigation_type.any.html", - {} - ], - [ - "/navigation-timing/supported_navigation_type.any.worker.html", + "/navigation-timing/supported_navigation_type.window.html", {} ] ], @@ -264538,13 +264817,9 @@ {} ] ], - "paint-timing/supported-paint-type.any.js": [ + "paint-timing/supported-paint-type.window.js": [ [ - "/paint-timing/supported-paint-type.any.html", - {} - ], - [ - "/paint-timing/supported-paint-type.any.worker.html", + "/paint-timing/supported-paint-type.window.html", {} ] ], @@ -264903,9 +265178,7 @@ "payment-request/payment-request-show-method.https.html": [ [ "/payment-request/payment-request-show-method.https.html", - { - "testdriver": true - } + {} ] ], "payment-request/payment-response/onpayerdetailchange-attribute.https.html": [ @@ -276518,6 +276791,36 @@ {} ] ], + "serial/serial-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html": [ + [ + "/serial/serial-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html", + {} + ] + ], + "serial/serial-allowed-by-feature-policy-attribute.https.sub.html": [ + [ + "/serial/serial-allowed-by-feature-policy-attribute.https.sub.html", + {} + ] + ], + "serial/serial-allowed-by-feature-policy.https.sub.html": [ + [ + "/serial/serial-allowed-by-feature-policy.https.sub.html", + {} + ] + ], + "serial/serial-default-feature-policy.https.sub.html": [ + [ + "/serial/serial-default-feature-policy.https.sub.html", + {} + ] + ], + "serial/serial-disabled-by-feature-policy.https.sub.html": [ + [ + "/serial/serial-disabled-by-feature-policy.https.sub.html", + {} + ] + ], "server-timing/cross_origin.https.html": [ [ "/server-timing/cross_origin.https.html", @@ -284418,6 +284721,18 @@ {} ] ], + "webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html": [ + [ + "/webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html", + {} + ] + ], + "webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-scheduling.html": [ + [ + "/webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-scheduling.html", + {} + ] + ], "webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp.html": [ [ "/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp.html", @@ -286226,6 +286541,14 @@ {} ] ], + "webrtc/RTCIceConnectionState-candidate-pair.https.html": [ + [ + "/webrtc/RTCIceConnectionState-candidate-pair.https.html", + { + "timeout": "long" + } + ] + ], "webrtc/RTCIceTransport-extension.https.html": [ [ "/webrtc/RTCIceTransport-extension.https.html", @@ -286322,9 +286645,9 @@ {} ] ], - "webrtc/RTCPeerConnection-iceConnectionState.html": [ + "webrtc/RTCPeerConnection-iceConnectionState.https.html": [ [ - "/webrtc/RTCPeerConnection-iceConnectionState.html", + "/webrtc/RTCPeerConnection-iceConnectionState.https.html", {} ] ], @@ -299539,6 +299862,18 @@ "/infrastructure/webdriver/tests/test_load_file.py", {} ] + ], + "webdriver/setup.py": [ + [ + "/webdriver/setup.py", + {} + ] + ], + "webdriver/tests/navigate_to/navigate.py": [ + [ + "/webdriver/tests/navigate_to/navigate.py", + {} + ] ] } }, @@ -307399,6 +307734,10 @@ "f73208c2a3c700d03ea1d39322a3e061b5caa5f7", "support" ], + "animation-worklet/playback-rate.https.html": [ + "9c975814f1ed09b3e78493df177c3c0eddf74cdd", + "testharness" + ], "animation-worklet/resources/animator-iframe.html": [ "e30cc281fcdefd8d029e7bf0ea92a1a9cd7af7e7", "support" @@ -307407,6 +307746,22 @@ "5b20f03bfadb5790c79ddd51e1f3d89a9f948852", "testharness" ], + "animation-worklet/worklet-animation-local-time-after-duration-ref.html": [ + "96acf1ad96c7c41e870429d55142269f4468bb97", + "support" + ], + "animation-worklet/worklet-animation-local-time-after-duration.https.html": [ + "adc90f1d3f6befa906473dd1bfb500b605431d0a", + "reftest" + ], + "animation-worklet/worklet-animation-local-time-before-start-ref.html": [ + "cda4ca4132cabcb13719f12248773026b0642df2", + "support" + ], + "animation-worklet/worklet-animation-local-time-before-start.https.html": [ + "addb16e7d1751280c8d4f3e0052b808ab807cd7e", + "reftest" + ], "animation-worklet/worklet-animation-with-fill-mode.https.html": [ "b910ab280ec80725eee7894e8331cf72f6c24492", "testharness" @@ -307500,7 +307855,7 @@ "support" ], "background-fetch/fetch.https.window.js": [ - "35b5709d22b84a5f8babad6137277e0afbc4d582", + "d4bc8bf128259e203569d0c9e03e8b11d5b42cd8", "testharness" ], "background-fetch/get-ids.https.window.js": [ @@ -308660,19 +309015,19 @@ "support" ], "client-hints/echo_client_hints_received.py": [ - "8f2ccaa2884f0382bdc4ef48b82b9c18b6093171", + "f7debdb7b0b7073ec1878ffc17a9816a61f5f4c3", "support" ], "client-hints/http_equiv_accept_ch.tentative.http.html": [ - "2bdced2ece762d71a13f2322325ef225fe2d489b", + "03c5799908b971ec6e6057fb8e5325e1bc2e203d", "testharness" ], "client-hints/http_equiv_accept_ch.tentative.https.html": [ - "3e4d638ffc320e5e460b3923881c2e002eb26baa", + "74eea344e90879e24568a76ba8e1197f6e9cede5", "testharness" ], "client-hints/http_equiv_accept_ch.tentative.sub.https.html": [ - "459b00e973bc1c69b3010146171683af12e33eb4", + "16617dccaf8c9c99011849b48d93e41f35ca374a", "testharness" ], "client-hints/http_equiv_accept_ch_lifetime.tentative.https.html": [ @@ -308748,27 +309103,27 @@ "testharness" ], "clipboard-apis/async-navigator-clipboard-basics.https.html": [ - "ea0ca2902c5ab4643a1d72f554ce21ef1780a4ad", + "5a23598fb0bd41dbc854cebb340d6f6ed8db54db", "testharness" ], - "clipboard-apis/async-write-dttext-read-dttext-manual.https.html": [ - "2930b47162289aa2927352633631255bae24212c", + "clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html": [ + "f860bf23db2ee381805ed5b4053c309a45954342", "manual" ], - "clipboard-apis/async-write-dttext-read-text-manual.https.html": [ - "1b178696f17ca0bc1bac0b7e1c285ae8d52d5360", + "clipboard-apis/async-write-blobtext-read-text-manual.https.html": [ + "685b6cb603ddeb66e68cd23efe85d744f8a17223", "manual" ], "clipboard-apis/async-write-image-read-image-manual.https.html": [ - "6117e469792ff61ff30015f2d94f1ceb2e3332ac", + "ee90e7e89a8994ba728d673e1da031c21cf38a04", "manual" ], - "clipboard-apis/async-write-text-read-dttext-manual.https.html": [ - "9f524b93d719b7b94cfcede77948d507bc0d4b57", + "clipboard-apis/async-write-text-read-blobtext-manual.https.html": [ + "69f72db82c07d2bca7446cf65d6d3056bebe24e2", "manual" ], "clipboard-apis/async-write-text-read-text-manual.https.html": [ - "3a3922e626a1eaffc9e41cb1b6b541d2aae17f33", + "496bdd78c7ab2ec0d26adafea6449ec18cc03340", "manual" ], "clipboard-apis/clipboard-events-synthetic.html": [ @@ -328827,6 +329182,14 @@ "01fa028a7d933a5a7480efb28cf565e7b7de845c", "support" ], + "css/css-align/baseline-of-scrollable-1a.html": [ + "a55e2318ca40f68500754bfccb582dd06c9f29c3", + "reftest" + ], + "css/css-align/baseline-of-scrollable-1b.html": [ + "79db8a85434beb60f7f6ef259bc2eff62d83bea3", + "reftest" + ], "css/css-align/content-distribution/parse-align-content-001.html": [ "c5cd4254f707824dacd0475eab9e8e1c59c02632", "testharness" @@ -329059,6 +329422,10 @@ "7e2fa130be24214fa8c21f58d0f88a744beb6b79", "testharness" ], + "css/css-align/reference/baseline-of-scrollable-1-ref.html": [ + "422660aff6b6b486ce3288469b4769e1497b071e", + "support" + ], "css/css-align/reference/ttwf-reftest-alignContent-ref.html": [ "a94c1d5e9e85dfe0aec20145b25e55dc5b1a673d", "support" @@ -350704,7 +351071,7 @@ "reftest" ], "css/css-lists/inheritance.html": [ - "ff1bcdcfb4690df571dc2d5c93df71b55ffad5e6", + "590319d63fd09466f4d5fffe6943b4ff0430fcee", "testharness" ], "css/css-lists/li-with-height-001-ref.html": [ @@ -353863,6 +354230,18 @@ "97f52984a51ae4157ec8ed91ddf4b3b8d405bec6", "manual" ], + "css/css-overscroll-behavior/parsing/overscroll-behavior-invalid.html": [ + "a29722f46570f89fafd76898ff2409017348b8a3", + "testharness" + ], + "css/css-overscroll-behavior/parsing/overscroll-behavior-valid-expected.txt": [ + "4b71db84cba966dde551a135edcb39ec60b5e42d", + "support" + ], + "css/css-overscroll-behavior/parsing/overscroll-behavior-valid.html": [ + "9dbd4fbb8f93df88e65b7515595ec22979f0ef18", + "testharness" + ], "css/css-paint-api/META.yml": [ "082a0977fa8569038eeab3e7595496256f87d725", "support" @@ -357852,7 +358231,7 @@ "support" ], "css/css-syntax/urange-parsing.html": [ - "0a69faa39c1d661e17084fe63d86c826cfa58848", + "2d34e05a98ba895cd0c98415bed32f248b235187", "testharness" ], "css/css-syntax/whitespace.html": [ @@ -369604,7 +369983,7 @@ "testharness" ], "css/css-transitions/event-dispatch.tentative-expected.txt": [ - "9a36521e952afb0a17a6fbc64efd290b90b90626", + "4a1fd79bfb4c30445f5442f3f96d471ec2292abf", "support" ], "css/css-transitions/event-dispatch.tentative.html": [ @@ -370267,10 +370646,6 @@ "5d89c45e0245ba4fedcd84905a59e3e8580319a8", "manual" ], - "css/css-transitions/transitioncancel-001-expected.txt": [ - "d5f009514e1facf1898a69d6170f9e92d27acdab", - "support" - ], "css/css-transitions/transitioncancel-001.html": [ "abc2f38b956096a4e09826c2e812dd8c606c0911", "testharness" @@ -376671,6 +377046,10 @@ "742c011d2c645f99e193671b3f665f260f0176d1", "reftest" ], + "css/css-writing-modes/baseline-with-orthogonal-flow-001.html": [ + "f054c59b6d7d7b253ec8221577de4713c955b237", + "reftest" + ], "css/css-writing-modes/bidi-embed-001.html": [ "d8215ad264d0fa47d855fd1a135c2cc05772c319", "reftest" @@ -378595,6 +378974,10 @@ "ef66b4e0d6248a8bc5b49c2654bfc77a2ac2e298", "support" ], + "css/css-writing-modes/reference/baseline-with-orthogonal-flow-001-ref.html": [ + "dda75ca1ef495507c75c27f4a1de638bbf5506f8", + "support" + ], "css/css-writing-modes/reference/bidi-embed-001.html": [ "24723ad3c6bdb0124ad41f23ad201055da19805a", "support" @@ -381755,6 +382138,14 @@ "d3de0cfa595381e0b7c0f3188ac9322ef10608f5", "testharness" ], + "css/cssom-view/long_scroll_composited-ref.html": [ + "6914cba30972387b929113817fa56c6bd1384387", + "support" + ], + "css/cssom-view/long_scroll_composited.html": [ + "aa91023c1ac456902f34ccf6a4df0fed1e852bf2", + "reftest" + ], "css/cssom-view/matchMedia.xht": [ "7ac875c6aa967187d8171f0876a5de15adfe5249", "testharness" @@ -382436,7 +382827,7 @@ "testharness" ], "css/cssom/interfaces-expected.txt": [ - "c108aed2d70ca4cb9fe2694e2a76d8b914bce76a", + "2b9315439abf433c978c1f041198ce56bc228109", "support" ], "css/cssom/interfaces.html": [ @@ -382823,14 +383214,6 @@ "711064e4de375df9f2fa819b4fff209b87721f8d", "reftest" ], - "css/filter-effects/backdrop-filter-border-radius-ref.html": [ - "e5712a23774b6f27c6c2a1dfcfe45931aa0301a4", - "support" - ], - "css/filter-effects/backdrop-filter-border-radius.html": [ - "ec93de698aaab5d41709f0999d9f2bab3381945d", - "reftest" - ], "css/filter-effects/backdrop-filter-clip-rect-ref.html": [ "d3c1f800e69bdfb72ca1d6d4d1ae73b8c8febcad", "support" @@ -383767,10 +384150,6 @@ "c6ca45ab17201466e01006cab78331a0765cc6c8", "testharness" ], - "css/mediaqueries/prefers-reduced-motion-expected.txt": [ - "00fbe2cebee7d39150d68444528cb9e3c2a8f1de", - "support" - ], "css/mediaqueries/prefers-reduced-motion.html": [ "2d9f88474598bcaa0c988639473821171f08b094", "testharness" @@ -388235,6 +388614,18 @@ "8c12fad8c791623a86ddca8936248189d698a0a4", "reftest" ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007-ref.html": [ + "ccde6012b5f74ede005dad74814be62cdffa9ac6", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007.html": [ + "ea9179c32ca7916792132f4a73c159fca89a19b6", + "reftest" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007v.html": [ + "2efb8b1c18fa65c2ea4b08c2c797476bdc79273e", + "reftest" + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-items-as-stacking-contexts-001-ref.xhtml": [ "7e02b799f0f75b5d238ecc3c7bbaf87a53572e88", "support" @@ -393043,8 +393434,12 @@ "5c2ac186c8c9d2c6befccda3e0f1f901e9df885b", "support" ], + "domparsing/XMLSerializer-serializeToString-expected.txt": [ + "8729df1bec06a66ec792c0cbe940247f282a4ae1", + "support" + ], "domparsing/XMLSerializer-serializeToString.html": [ - "7c084e78ded7258eaf7f9576d6f837f9518b862f", + "d71da494fe7dbce56af5e45926739c7b6a232676", "testharness" ], "domparsing/createContextualFragment.html": [ @@ -393160,7 +393555,7 @@ "support" ], "domxpath/document.tentative.html": [ - "c44ebd9937574ff071c7f0f2484ba5ea0ee15125", + "b75c0f0d66dacb47a825ae2aa00bb63a19616433", "testharness" ], "domxpath/evaluator-constructor.html": [ @@ -393907,12 +394302,16 @@ "4d59d4afc9f8e501a0a764cbce980d0d276250fe", "testharness" ], - "element-timing/cross-origin-element.html": [ - "1b899b00e3abc5425bb8e97528c8635d6aabff75", + "element-timing/cross-origin-element.sub.html": [ + "ed820d0e66558d1db01109a6c4227c960f15644b", "testharness" ], - "element-timing/cross-origin-iframe-element.html": [ - "7f73881cc9726fa72c896fd1fbd1a496ade46695", + "element-timing/cross-origin-iframe-element.sub.html": [ + "a369d25bd43c6565ab4367b0a381ab39ec8664b7", + "testharness" + ], + "element-timing/image-TAO-wildcard.sub.html": [ + "6d5abe21c3c353e55b058655684197ba986d8e64", "testharness" ], "element-timing/image-not-fully-visible.html": [ @@ -393920,7 +394319,7 @@ "testharness" ], "element-timing/observe-child-element.html": [ - "5bb8290893a7d80749e2dd03239c9c3f2f158b88", + "83cc2ef94b3fe929ffd87b6c4a49f7424e6be29b", "testharness" ], "element-timing/observe-elementtiming.html": [ @@ -393939,6 +394338,10 @@ "6fdff39d53848546e113b72ca17e38fd9b0dabc7", "testharness" ], + "element-timing/resources/TAOImage.py": [ + "5d042c48941d09ca2d494f054d3625503beaeef0", + "support" + ], "element-timing/resources/circle.svg": [ "209b9f4e5b5d55b45b5ec80dac25873d06dfb593", "support" @@ -397183,6 +397586,22 @@ "1759381fdc4141302f1b95868550ead76d9f5ca7", "support" ], + "feature-policy/reporting/serial-report-only.https.html": [ + "11913a2ef77159c3f0c4769cd3cfaf09d942f1ba", + "testharness" + ], + "feature-policy/reporting/serial-report-only.https.html.headers": [ + "d408ccf6b15685be3db91c1e19a26bdbc42c78cb", + "support" + ], + "feature-policy/reporting/serial-reporting.https.html": [ + "827bc89367c56141938d962edcfe69452309b8f3", + "testharness" + ], + "feature-policy/reporting/serial-reporting.https.html.headers": [ + "be3e6afd423f767369725724eb3509447c852a59", + "support" + ], "feature-policy/reporting/sync-xhr-report-only.html": [ "76d26ed502743549fe426703eef4da38a4076f64", "testharness" @@ -397295,6 +397714,18 @@ "2f33c449536d1b0253a9a1c0b52073bc500121f3", "support" ], + "feature-policy/resources/feature-policy-serial-worker.html": [ + "9e6a7d02ba2b8eef1fcc12d8049af830688e6946", + "support" + ], + "feature-policy/resources/feature-policy-serial-worker.js": [ + "2e8e6f5433a5e8fe9180b5660a9f301c936637dc", + "support" + ], + "feature-policy/resources/feature-policy-serial.html": [ + "caf716d37ac53c492f2eeb5815af533fc840eec7", + "support" + ], "feature-policy/resources/feature-policy-usb-worker.html": [ "fa8a2d70eb8d12933479e094e90375fedd062f5e", "support" @@ -402395,10 +402826,6 @@ "a55d85dfdf293adc0b7160ed1bce213967d9822e", "testharness" ], - "html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter_null.tentative.html": [ - "314a7035d009b75fc8372159324f4a687613668d", - "testharness" - ], "html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter_srcdoc.html": [ "65a7f5c8981130c15b4cb91d460a11e2b529b0ce", "testharness" @@ -402411,10 +402838,6 @@ "82e8023d0ba61851af5747ee2ccba154193d1875", "support" ], - "html/browsers/origin/relaxing-the-same-origin-restriction/support/document_domain_frame.html": [ - "42e8137db2cb362772271d5b151ca812b647d397", - "support" - ], "html/browsers/origin/relaxing-the-same-origin-restriction/support/document_domain_setter_iframe.html": [ "d3d5260af3f143edd702400879cc3d5db4aea40d", "support" @@ -408276,23 +408699,31 @@ "testharness" ], "html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub.html": [ - "c3d550a39b3f1a8d419e2b7fc16a5f8c400df2d5", + "d596f37716835209a7ca161e6ec039ce8e7a7927", "testharness" ], + "html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub_encoding=windows-1252-expected.txt": [ + "6e364ba06bd65e875dca9efe30b7c567941bb1ec", + "support" + ], "html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub_encoding=x-cp1251-expected.txt": [ "e09fab1984dfee3abe55b7860af737c00489fa98", "support" ], "html/infrastructure/urls/resolving-urls/query-encoding/location.sub.html": [ - "3ad228b0b271716b8bb775a84a8c57258a3a371e", + "a5c131e2bece1d4a92d4eb782fbcc5b0c42306a1", "testharness" ], + "html/infrastructure/urls/resolving-urls/query-encoding/location.sub_encoding=windows-1252-expected.txt": [ + "3e52ba438993bc62a322b439ef9c67e3a0de9058", + "support" + ], "html/infrastructure/urls/resolving-urls/query-encoding/location.sub_encoding=x-cp1251-expected.txt": [ "163d1356ed2ff327dea9d646c352a70d57bfb425", "support" ], "html/infrastructure/urls/resolving-urls/query-encoding/navigation.sub.html": [ - "80cf75104fc818b4e1502225184d2f19da8468f6", + "bca61372b4c8b1589c420b7612fd87b60dce37e6", "testharness" ], "html/infrastructure/urls/resolving-urls/query-encoding/resources/blank.py": [ @@ -408312,7 +408743,7 @@ "support" ], "html/infrastructure/urls/resolving-urls/query-encoding/resources/resolve-url.js": [ - "cf175eb4d3ae688ece3fffa2e9d3d90a6ec69657", + "77f8fff5b5701ae2b3138116429974c4e9f2608f", "support" ], "html/infrastructure/urls/resolving-urls/query-encoding/resources/resource.py": [ @@ -408332,7 +408763,7 @@ "testharness" ], "html/infrastructure/urls/resolving-urls/query-encoding/utf-8-expected.txt": [ - "7750662336f1e729a894b73ff062a9e1443326da", + "483a3016d98e3586155c2feb545c6169ac67f3f3", "support" ], "html/infrastructure/urls/resolving-urls/query-encoding/utf-8.html": [ @@ -408340,17 +408771,13 @@ "testharness" ], "html/infrastructure/urls/resolving-urls/query-encoding/windows-1251-expected.txt": [ - "4de5bd1c620d6c4e889971eb345355805b3ca6d8", + "e0140d8677ded972714d3b09a6fb8ba4c3d22f01", "support" ], "html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html": [ "23d33f9f73350b2a174b7becc1489da5645b406b", "testharness" ], - "html/infrastructure/urls/resolving-urls/query-encoding/windows-1252-expected.txt": [ - "5c1e4a73472656071a79d7dcb7e8d56d1d77aad6", - "support" - ], "html/infrastructure/urls/resolving-urls/query-encoding/windows-1252.html": [ "642c82ab4f05a685eb75b67f654df3e13810f397", "testharness" @@ -409791,14 +410218,6 @@ "a809cc44b19796e50b7564b852a3234cca7e51f0", "testharness" ], - "html/semantics/document-metadata/the-link-element/link-multiple-error-events.html": [ - "ea7e496ae8ea36f4241f565714952f4ac2c1968a", - "testharness" - ], - "html/semantics/document-metadata/the-link-element/link-multiple-load-events.html": [ - "24cd5ba701184308d7fe28195119552d6431b87d", - "testharness" - ], "html/semantics/document-metadata/the-link-element/link-rel-attribute.html": [ "14d06227ac862be169c2c1745fd6ec8913836394", "testharness" @@ -420448,7 +420867,7 @@ "support" ], "interfaces/cssom.idl": [ - "7d9536d943f8679902f6f8e362b15aa584259f2c", + "a914ac0d78c627722262587a84e5a30ef367a6f0", "support" ], "interfaces/dedicated-workers.idl": [ @@ -421139,6 +421558,10 @@ "c1fcbca4c1f8366da1dd9eb91bc9427edeef1153", "support" ], + "lifecycle/child-display-none.tentative.html": [ + "f76b4e7b608d3e4e97dfac100bee6fa63602e0bb", + "testharness" + ], "lifecycle/freeze.html": [ "88e32c9d3b01eb2622ce90699548d95fba5eb960", "testharness" @@ -421147,6 +421570,10 @@ "403d01060821820b9d3a772b28a826698c8796e6", "support" ], + "lifecycle/resources/subframe.html": [ + "2f1d70a80a792401891d93f6ddebaea0876400b3", + "support" + ], "lifecycle/resources/window.html": [ "69fdbc0986633793d501a4bddfee9e88f76e1348", "support" @@ -421251,7 +421678,7 @@ "9d0273e19263f026ff588ac59c12c765a341df8b", "support" ], - "longtask-timing/supported-longtask-types.any.js": [ + "longtask-timing/supported-longtask-types.window.js": [ "3c68c01d32d614dab435d91a0dce39244f8d7e09", "testharness" ], @@ -421364,75 +421791,75 @@ "support" ], "mathml/presentation-markup/fractions/frac-1.html": [ - "fc650eb4c4a65cc49031e870229f463b3422b609", + "748fbdf1f40182ea6e785110ab05c32639218c6f", "testharness" ], "mathml/presentation-markup/fractions/frac-parameters-1.html": [ - "a047a30873c7765dafa5678fc99072bbe2f017e4", + "1c20b9d75b3dd3c034e49af4e349c3c63fb54664", "testharness" ], "mathml/presentation-markup/fractions/frac-parameters-2.html": [ - "544511388685a3ed79eaa2e80875205c19e7a62f", + "bc9fb36412fb6553a7f42969a4694d281ab30a82", "testharness" ], "mathml/presentation-markup/operators/mo-axis-height-1.html": [ - "327a72e30b53a6b0a619ef2b33f21bfeb7fd4a63", + "e409f982aeb3189e6da5c08d0f97a2fb688a3e68", "testharness" ], "mathml/presentation-markup/radicals/root-parameters-1.html": [ - "67a4613813421ed55a7fb44622b52f2c1f0f2b0f", + "4fc6e6f869ce20ae307ec11b5ddd7a07ccafe3b3", "testharness" ], "mathml/presentation-markup/scripts/subsup-1.html": [ - "2ff14a694c99461f4474af1d9b283ed3082f7b8b", + "026cfa35c54adb63cbb82f04a67ce0bdc4d4f2fd", "testharness" ], "mathml/presentation-markup/scripts/subsup-2.html": [ - "abef28d12df64ffac355fd627fe2493ae7b43ff9", + "8f62d9257cb9d8ab320c1b04720c056031e8af26", "testharness" ], "mathml/presentation-markup/scripts/subsup-3.html": [ - "c49718979c30b9fa782fda0dc49686e7f7f362bb", + "18ede4004235ba56234570eee63336f5c21f52b0", "testharness" ], "mathml/presentation-markup/scripts/subsup-4.html": [ - "2acc7746c4fb1e754f7c3abbc2d424b244ce9876", + "44a2ff41fb1079ebb200c612dd23e39634079984", "testharness" ], "mathml/presentation-markup/scripts/subsup-5.html": [ - "19b6eee66747795b00776768aa1738006725e3c0", + "a1fd0c0fb2323eec5bf3c7feb48215e37728b7e7", "testharness" ], "mathml/presentation-markup/scripts/subsup-parameters-1.html": [ - "9bc6bcbf277c1352d2d23c889048a2afc745ee9f", + "23e65c12dce57ee5a5e62373cff5a3649dbaf7a3", "testharness" ], "mathml/presentation-markup/scripts/subsup-parameters-2.html": [ - "eaa4f0ffab154aff2ca1072f306c115a8d0bcf13", + "5ba66b86c3dadf5b4e4d3ddfa4c27d6286e137f1", "testharness" ], "mathml/presentation-markup/scripts/underover-1.html": [ - "6e039b9d609d65933ebc736a9a9ff91d2da572b5", + "d355f1186783500771cb993239f8401f79aea47b", "testharness" ], "mathml/presentation-markup/scripts/underover-parameters-1.html": [ - "1e5a6606b03a19487b2394b95eac26bd4ac0cb4e", + "bd6c5f13c4211e5748ffd28517773de513f33bf9", "testharness" ], "mathml/presentation-markup/scripts/underover-parameters-2.html": [ - "c28f29c99e69761ddd2e9205b4f942e65014afc8", + "73a7c5b236390132f36d84eca6ad7cd18b73541d", "testharness" ], "mathml/presentation-markup/scripts/underover-parameters-3.html": [ - "0172ff1c700924e3412e84cd2e1445a009e61b5e", + "3fb57c01dde3c5dea258678f5607385a8b892471", "testharness" ], "mathml/presentation-markup/scripts/underover-parameters-4.html": [ - "061cda79af9f9e7157ac37736f755ac233bf0a6f", + "6dee35ca6f0b6f8c2c23abb65c3c52e69686b707", "testharness" ], "mathml/presentation-markup/spaces/space-1.html": [ - "adb36377842295e1bf0ec298d7ec19aa5adaeeb4", + "dc2622db9a309091ac225f8e8151f6921fe6721f", "testharness" ], "mathml/presentation-markup/spaces/space-2-ref.html": [ @@ -421440,11 +421867,11 @@ "support" ], "mathml/presentation-markup/spaces/space-2.html": [ - "544cfb1f6689a51b69c4492af5403a207032800a", + "072f2bda542f9b9ee64acd3161f2949c31fbf955", "reftest" ], "mathml/presentation-markup/tables/table-axis-height.html": [ - "50c3491e487bfb3c22d444266e4a1aedb070641a", + "4d2b4462dba6f428ad72eb8f741dd28607452151", "testharness" ], "mathml/relations/css-styling/color-1-ref.html": [ @@ -421460,7 +421887,7 @@ "support" ], "mathml/relations/css-styling/display-1.html": [ - "551f6402d85924005491cf50f3b9d4fcd547f8fe", + "a7d6277d70d1658bf291c5d46ed14aa2e1f7ec90", "reftest" ], "mathml/relations/css-styling/displaystyle-1.html": [ @@ -421668,7 +422095,7 @@ "support" ], "mathml/relations/html5-tree/href-click-1.html": [ - "80e4c754d805ce85744f8d6157c1901f471be2a9", + "6164346dc079da139855de96937f9d5b7861c285", "reftest" ], "mathml/relations/html5-tree/href-click-2-ref.html": [ @@ -421676,7 +422103,7 @@ "support" ], "mathml/relations/html5-tree/href-click-2.html": [ - "1e41f77cc4375f7cf8568cecb7b8d169da0be14f", + "6e5049392bd9c62e42086f3d1a7cdc9583fd29a9", "reftest" ], "mathml/relations/html5-tree/href-manual.html": [ @@ -423528,7 +423955,7 @@ "support" ], "mixed-content/imageset.https.sub.html": [ - "dd371566161dcf4a22fd14bd2cd02ef0b06462a9", + "1f3d0471fbd2b38649894619494750ef221d72c9", "testharness" ], "mixed-content/img-tag/http-csp/cross-origin-http/top-level/keep-scheme-redirect/optionally-blockable/opt-in-blocks.https.html": [ @@ -425855,7 +426282,7 @@ "3efb52783f1e5dcb0d42aad11aec2a9e47257d33", "support" ], - "navigation-timing/supported_navigation_type.any.js": [ + "navigation-timing/supported_navigation_type.window.js": [ "3239c7d29ffb11cbfebda12b4e5420bca0131094", "testharness" ], @@ -432952,7 +433379,7 @@ "testharness" ], "paint-timing/idlharness.window.js": [ - "115af73dfc801acc442a1be8942d0b3b519dbb3c", + "049f0f18f1be64ad5d250f045b0dda3edbc931a4", "testharness" ], "paint-timing/paint-visited.html": [ @@ -432979,7 +433406,7 @@ "d4197e8a35c444401b0a7dc84f0fc5a279193ca0", "testharness" ], - "paint-timing/supported-paint-type.any.js": [ + "paint-timing/supported-paint-type.window.js": [ "36acf82ca3b646b32977c3d0212a397c6fa8ea09", "testharness" ], @@ -433367,12 +433794,12 @@ "650b76d61f72d82fce1644be95e1ee2b99a90d95", "testharness" ], - "payment-request/payment-request-abort-method.https-expected.txt": [ - "2f5a0739ca28d3c470da1577dc361002c5e8c606", - "support" + "payment-request/payment-request-abort-method-manual.https.html": [ + "a24bac864aad00afdfe830e04b40ef81a583b341", + "manual" ], "payment-request/payment-request-abort-method.https.html": [ - "75e39a011c390fb8c3bbbeba2dbe8826ea6291e1", + "cf16401d0b0d3e97f3ab14c337880a4ec0d9ea7f", "testharness" ], "payment-request/payment-request-canmakepayment-method-protection.https-expected.txt": [ @@ -433415,6 +433842,10 @@ "02122203d51eaff6c6639c9762b1495173bbf66e", "testharness" ], + "payment-request/payment-request-multiple-show-manual.https.html": [ + "cc412171a6d74cd242c32a2bb50b83eaaf156478", + "manual" + ], "payment-request/payment-request-not-exposed.https.worker.js": [ "e5576e673520ea33504d8ddea0e862d54b28e8fb", "testharness" @@ -433439,8 +433870,12 @@ "11f75b1c862224b5655cb724d8c8f5b25ab1af00", "testharness" ], + "payment-request/payment-request-show-method-manual.https.html": [ + "6ef98e85a6092a648897bfbca966d78a5a2195f8", + "manual" + ], "payment-request/payment-request-show-method.https.html": [ - "3d362596c41c6f6ac7058e752c6c6f0e4f6b3781", + "dd04987092b49bbfb5d525da7ce0af63fa60a495", "testharness" ], "payment-request/payment-response/complete-method-manual.https.html": [ @@ -433700,7 +434135,7 @@ "testharness" ], "picture-in-picture/request-picture-in-picture-twice.html": [ - "17e494bbe88b52b68a6e34e5be37a346479087e1", + "fd8541bc1deeaedb765b7fc8e88ec7214fc1ab67", "testharness" ], "picture-in-picture/request-picture-in-picture.html": [ @@ -434268,11 +434703,11 @@ "support" ], "preload/avoid-delaying-onload-link-preload.html": [ - "77838c37741990153df68bdf746bd93b63d3d7a1", + "a1b19c81c6783477f8914bf94d8e58d8644e06f3", "testharness" ], "preload/delaying-onload-link-preload-after-discovery.html": [ - "095d89ad90ca15eac57a142d051f60207cf94f92", + "1c856d16d409479746f4c18c65028c38a026fbba", "testharness" ], "preload/download-resources-expected.txt": [ @@ -434280,15 +434715,15 @@ "support" ], "preload/download-resources.html": [ - "dc2b4693cf11fe224e599b97ba8556894a9e0240", + "510ebb480457e9e1b0d6ea788a8bd36c825bc634", "testharness" ], "preload/dynamic-adding-preload-imagesrcset.tentative.html": [ - "be8f0afcd5bdcc7daa61fa2666220780acf37ebf", + "e1b8431d7bcaca618014496342055d533ba7399c", "testharness" ], "preload/dynamic-adding-preload-nonce.html": [ - "10dae6b99586450367852cf5bb006d8511cf2865", + "19e09472eef3813c9fb25ff7b6549477615c760e", "testharness" ], "preload/dynamic-adding-preload-nonce.html.headers": [ @@ -434296,15 +434731,15 @@ "support" ], "preload/dynamic-adding-preload.html": [ - "2a299bd8446bf049d7e29b69c7fa6e0249f9ae6d", + "0cecc1983eaa50fbaa00b7d70031c8b11b84c4e7", "testharness" ], "preload/link-header-on-subresource.html": [ - "a02bc7c819eb7c5049788b493556f8e34cc15091", + "087a3429e649348d2b35fd92bf03ebc6307c72dc", "testharness" ], "preload/link-header-preload-delay-onload.html": [ - "7f38f8c9ee53d27614b20df9a76a493f3b4aabcf", + "a445d800a586357a6eb5d0ef11778b55fbc301d4", "testharness" ], "preload/link-header-preload-delay-onload.html.headers": [ @@ -434312,7 +434747,7 @@ "support" ], "preload/link-header-preload-nonce.html": [ - "240d6f11dd5979457ed8a4d6ab3c97e9d1ce9f9c", + "dc1ec100776916319a637daa0397589a05a23804", "testharness" ], "preload/link-header-preload-nonce.html.headers": [ @@ -434320,7 +434755,7 @@ "support" ], "preload/link-header-preload-srcset.tentative.html": [ - "024da965796fb5960bc43cdf4de1806fbef74ffe", + "8d057549a1930dea4502ef7400f44c9113ec3e62", "testharness" ], "preload/link-header-preload-srcset.tentative.html.headers": [ @@ -434328,7 +434763,7 @@ "support" ], "preload/link-header-preload.html": [ - "94a731bdcebb0eea04e5fe09152dfc013bb37afa", + "0ca364bdef71ad98fcf12db36e8e71c414745b57", "testharness" ], "preload/link-header-preload.html.headers": [ @@ -434344,7 +434779,7 @@ "support" ], "preload/onerror-event.html": [ - "5fae70d3bcab22bf50448c817f856c4b90f110a0", + "8190be87a4b7caf69ba07d07d239ff8143be3b05", "testharness" ], "preload/onload-event-expected.txt": [ @@ -434352,15 +434787,15 @@ "support" ], "preload/onload-event.html": [ - "6af2d64a1c1d73adb8a6504a300cb35de9807038", + "f9348b8ceb392117a2da6560e64118df2482dfdf", "testharness" ], "preload/preload-csp.sub.html": [ - "8e5e45b9a1cdac572650bfa270a57930154e7bbc", + "7fe06eb079133a245472c085068bb311dabebc68", "testharness" ], "preload/preload-default-csp.sub.html": [ - "cb080e62ba3efecbd86139c3952f3b4461735a51", + "7813e36d4d8ada4bd4e5f79a583f2ff89519c5eb", "testharness" ], "preload/preload-strict-dynamic.html": [ @@ -434372,7 +434807,7 @@ "support" ], "preload/preload-with-type.html": [ - "8578143a23495e1828d313ddc6a9310df75fcdb0", + "83eafc5848b9c514e9136cbedfc64df6665d5aa9", "testharness" ], "preload/reflected-as-value-expected.txt": [ @@ -434452,7 +434887,7 @@ "support" ], "preload/resources/preload_helper.js": [ - "b2cf8323db0145fa4876fb40d0d1ed3ff1c6413b", + "f464908fa513353917901d49af150d53cfd99945", "support" ], "preload/resources/sound_5.oga": [ @@ -434484,11 +434919,11 @@ "support" ], "preload/single-download-late-used-preload.html": [ - "5549cb84fdb9ff03e348c6d005b5850b7294536b", + "51533ba71445cc5b9edb235aaf28215671a1ca62", "testharness" ], "preload/single-download-preload.html": [ - "e8f261787107ff976b9df36b408c9dc5ce2a50ac", + "16d893ca7e54adde5fec3744b95a14f7e2cf3f34", "testharness" ], "presentation-api/META.yml": [ @@ -445079,6 +445514,42 @@ "7be8ba61bc20cd2efe262de6b68a43fd3310b59e", "testharness" ], + "serial/resources/serial-allowed-by-feature-policy-worker.js": [ + "46c338e9a33a9ee0148ca48d09fc9c3bec37736b", + "support" + ], + "serial/resources/serial-disabled-by-feature-policy-worker.js": [ + "b64b1a861ecfa431fab2ec383dcf420326a47bde", + "support" + ], + "serial/serial-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html": [ + "7c3a88dd51f93d74dc86882c12aab6bd2c25afb0", + "testharness" + ], + "serial/serial-allowed-by-feature-policy-attribute.https.sub.html": [ + "1420c5c01434a852661e40287ae24585bcce5aa4", + "testharness" + ], + "serial/serial-allowed-by-feature-policy.https.sub.html": [ + "316256bbbb4d49f10747d6244eb438228617df6f", + "testharness" + ], + "serial/serial-allowed-by-feature-policy.https.sub.html.headers": [ + "113ce29ae9f5aeafbf68388c03be1c776c889c60", + "support" + ], + "serial/serial-default-feature-policy.https.sub.html": [ + "61a872f9b5c400bd9d0cb97c2ecadc69ce6ccc30", + "testharness" + ], + "serial/serial-disabled-by-feature-policy.https.sub.html": [ + "cddf157e8ae5a9dc53ce2b5ad9bf499c61b0db04", + "testharness" + ], + "serial/serial-disabled-by-feature-policy.https.sub.html.headers": [ + "be3e6afd423f767369725724eb3509447c852a59", + "support" + ], "server-timing/META.yml": [ "f20b425fc5e69d41083c40b8a5d76d69efe510cf", "support" @@ -454184,7 +454655,7 @@ "support" ], "web-animations/testcommon.js": [ - "5dbf6fd7f29f4985d3f2fbce4407f6594d80fac7", + "e6dad7cbf8d42b67660753fc5932e44ac531893c", "support" ], "web-animations/timing-model/animation-effects/active-time.html": [ @@ -454911,14 +455382,18 @@ "ab9d5fe5a9dbd736a079f0cfd7966d5e064ed7ef", "support" ], - "webaudio/the-audio-api/the-audiobuffersourcenode-interface/resources/sub-sample-scheduling.html": [ - "27ac0984a79ef276f6f6e32dc9814131487de31a", - "support" - ], "webaudio/the-audio-api/the-audiobuffersourcenode-interface/sample-accurate-scheduling.html": [ "5fafd024eef9b476f4d97b2ebaa2190a4ca520d5", "testharness" ], + "webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html": [ + "b69cb0e81259a4e47cff1ae11befbe63341d4849", + "testharness" + ], + "webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-scheduling.html": [ + "27ac0984a79ef276f6f6e32dc9814131487de31a", + "testharness" + ], "webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp.html": [ "952f38b1edceb62ab3f99c25777ebdb2c59e691a", "testharness" @@ -455691,6 +456166,74 @@ "6c9aabd11ea3a51688962890dde29d5c41ec6c6f", "testharness" ], + "webdriver/META.yml": [ + "a397b497c32234d3889c738f51b96a3ba3b2a96f", + "support" + ], + "webdriver/README.md": [ + "78d9aba7b9bc0c132bdb4b0e54af641409f15456", + "support" + ], + "webdriver/setup.py": [ + "c473961cb64f424e3402b265746a612b09cb7dfe", + "wdspec" + ], + "webdriver/tests/__init__.py": [ + "0ba172ff2e2734e5cbf324e816867be0a26b278e", + "support" + ], + "webdriver/tests/conftest.py": [ + "42b82c9ecf29a1aed48bfa959c20aba6edd1319e", + "support" + ], + "webdriver/tests/navigate_to/__init__.py": [ + "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "support" + ], + "webdriver/tests/navigate_to/navigate.py": [ + "e478e10b76b0953d854416dffdc7a400087aee95", + "wdspec" + ], + "webdriver/tests/support/__init__.py": [ + "e5e43c4e655170d57d3de7a85d4ebb639c31aee0", + "support" + ], + "webdriver/tests/support/asserts.py": [ + "67711987d4b7cf683ff4e6d1ace3ad0189b7ec91", + "support" + ], + "webdriver/tests/support/defaults.py": [ + "c2020527a6f38a628b2c1a4199caaff46cf0c36b", + "support" + ], + "webdriver/tests/support/fixtures.py": [ + "149350c1fef696acbcbf58f00e03c05a76cbcfbe", + "support" + ], + "webdriver/tests/support/helpers.py": [ + "a0e6a757b81e9c8b139aaf6ff26018d69e84d11e", + "support" + ], + "webdriver/tests/support/http_request.py": [ + "5e46d97017e14ba009d4d1ed6d62bb5012f48d15", + "support" + ], + "webdriver/tests/support/image.py": [ + "81dd933943f78b4bad69967c26729b70b992acb6", + "support" + ], + "webdriver/tests/support/inline.py": [ + "8b4f1657cffb193511da346bc4c236aac1d70308", + "support" + ], + "webdriver/tests/support/merge_dictionaries.py": [ + "cf06c9b433cee167c5c98e06d64cc7a2e68faff3", + "support" + ], + "webdriver/tests/support/sync.py": [ + "561fcd8415cbc0f37b200c814abe073ed9bba0c5", + "support" + ], "webmessaging/Channel_postMessage_Blob.htm": [ "c8c247ef59dc7b513c54459fc83fd1aa6fcec8dd", "testharness" @@ -456419,6 +456962,10 @@ "344007ded2b4d4496171402896d738817cdde12e", "testharness" ], + "webrtc/RTCIceConnectionState-candidate-pair.https.html": [ + "7280d040856370f448796a4de2f92f82f9c78c53", + "testharness" + ], "webrtc/RTCIceTransport-expected.txt": [ "8fcf2e214bb23a9f5f023c4d69398c918ca8e49d", "support" @@ -456536,21 +457083,21 @@ "testharness" ], "webrtc/RTCPeerConnection-helper.js": [ - "d1056d90f393d06713feeccb04d589c41690089e", + "1ff5f54015e6a65a47cd4a277818acb9c57318bc", "support" ], "webrtc/RTCPeerConnection-iceConnectionState-expected.txt": [ "b28601423de0b987c27db05d4b4061ece60f0129", "support" ], - "webrtc/RTCPeerConnection-iceConnectionState.html": [ - "b647b3d3e35e31f16b33422f67cb30b917d1d0af", - "testharness" - ], "webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt": [ "c5fd94e3f5ca952dc8b0fa85c50b56c6b8ecc8ed", "support" ], + "webrtc/RTCPeerConnection-iceConnectionState.https.html": [ + "8acabf49766ba08999b8857d8cb6589d1587c843", + "testharness" + ], "webrtc/RTCPeerConnection-iceGatheringState-expected.txt": [ "cf325d504c3bb9819ed291c8aade04daea91877f", "support" @@ -456680,7 +457227,7 @@ "support" ], "webrtc/RTCPeerConnection-track-stats.https.html": [ - "2d45c343d861f0b62a7d3d1f979ff7702862e5d7", + "e394e63e50d78b96dd8b6815700a0cc8408ce239", "testharness" ], "webrtc/RTCPeerConnection-transceivers.https.html": [ @@ -456764,7 +457311,7 @@ "support" ], "webrtc/RTCRtpReceiver-getSynchronizationSources.https.html": [ - "36460b479903231e15427f303f15c3b6a3de16e8", + "82ce3bd8467b6a29e4b40a105151b50314b5bf46", "testharness" ], "webrtc/RTCRtpSender-getCapabilities.html": [ @@ -461528,7 +462075,7 @@ "support" ], "webxr/idlharness.https.window-expected.txt": [ - "1e286cea44f62c70bb4ef8bf74557209d51223cb", + "6e0c787dc8ba4a8e0560ed843da2b6f6b9eded77", "support" ], "webxr/idlharness.https.window.js": [ @@ -461540,7 +462087,7 @@ "support" ], "webxr/resources/webxr_util.js": [ - "7344fa05f655cded22a3ba9b099a8726a0c4beb3", + "26e30c48f36f22d1cb7ef6ffe0e6b9e11979f7b9", "support" ], "webxr/webGLCanvasContext_create_xrcompatible.https.html": [ @@ -461596,7 +462143,7 @@ "testharness" ], "webxr/xrSession_identity_referenceSpace.https.html": [ - "6f4f1e805a060853eaa557a16111acd73d78fe42", + "6cb25019fcd4d95f5e312bbf49186d0579a31ddc", "testharness" ], "webxr/xrSession_mode.https.html": [ @@ -461612,11 +462159,11 @@ "testharness" ], "webxr/xrSession_requestAnimationFrame_data_valid.https.html": [ - "f873a11588045d612cb16f2487a6efa14b555679", + "41801bcd3643b9173e0b447545967beb60cee330", "testharness" ], "webxr/xrSession_requestAnimationFrame_getViewerPose.https.html": [ - "ca6a71758c691e16aad512e68c83e2fd42a8efbb", + "618dc13e4fe6eb6eda2c81eef53e722da3b09190", "testharness" ], "webxr/xrSession_requestReferenceSpace.https.html": [
diff --git a/third_party/blink/web_tests/external/wpt/animation-worklet/playback-rate.https.html b/third_party/blink/web_tests/external/wpt/animation-worklet/playback-rate.https.html new file mode 100644 index 0000000..9c97581 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/animation-worklet/playback-rate.https.html
@@ -0,0 +1,140 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>The playback rate of a worklet animation</title> +<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +'use strict'; +// Presence of playback rate adds FP operations to calculating start_time +// and current_time of animations. That's why it's needed to increase FP error +// for comparing times in these tests. +window.assert_times_equal = (actual, expected, description) => { + assert_approx_equals(actual, expected, 0.002, description); +}; +</script> +<script src="/web-animations/testcommon.js"></script> +<script src="common.js"></script> +<body> +<div id="log"></div> +<script> +'use strict'; + +function InstantiateWorkletAnimation(test) { + const DURATION = 10000; // ms + const KEYFRAMES = { height : ['100px', '50px'] }; + return new WorkletAnimation('passthrough', new KeyframeEffect(createDiv(test), + KEYFRAMES, DURATION), document.timeline); +} + +promise_test(async t => { + await registerPassthroughAnimator(); + const animation = InstantiateWorkletAnimation(t); + + animation.playbackRate = 0.5; + animation.play(); + assert_equals(animation.currentTime, 0, + 'Zero current time is not affected by playbackRate.'); +}, 'Zero current time is not affected by playbackRate set while the animation is in idle state.'); + +promise_test(async t => { + await registerPassthroughAnimator(); + const animation = InstantiateWorkletAnimation(t); + + animation.play(); + animation.playbackRate = 0.5; + assert_equals(animation.currentTime, 0, + 'Zero current time is not affected by playbackRate.'); +}, 'Zero current time is not affected by playbackRate set while the animation is in play-pending state.'); + +promise_test(async t => { + await registerPassthroughAnimator(); + const animation = InstantiateWorkletAnimation(t); + const playbackRate = 2; + + animation.play(); + + await waitForNextFrame(); + + // Set playback rate while the animation is playing. + const prevCurrentTime = animation.currentTime; + animation.playbackRate = playbackRate; + + assert_times_equal(animation.currentTime, prevCurrentTime, + 'The current time should stay unaffected by setting playback rate.'); +}, 'Non zero current time is not affected by playbackRate set while the animation is in play state.'); + +promise_test(async t => { + await registerPassthroughAnimator(); + const animation = InstantiateWorkletAnimation(t); + const playbackRate = 2; + + animation.play(); + + await waitForNextFrame(); + + // Set playback rate while the animation is playing + const prevCurrentTime = animation.currentTime; + const prevTimelineTime = document.timeline.currentTime; + animation.playbackRate = playbackRate; + + // Play the animation some more. + await waitForNextFrame(); + + const currentTime = animation.currentTime; + const currentTimelineTime = document.timeline.currentTime; + + assert_times_equal(currentTime - prevCurrentTime, (currentTimelineTime - prevTimelineTime) * playbackRate, + 'The current time should increase two times faster than timeline.'); + +}, 'The playback rate affects the rate of progress of the current time.'); + +promise_test(async t => { + await registerPassthroughAnimator(); + const animation = InstantiateWorkletAnimation(t);; + const playbackRate = 2; + + // Set playback rate while the animation is in 'idle' state. + animation.playbackRate = playbackRate; + animation.play(); + const prevTimelineTime = document.timeline.currentTime; + + await waitForNextFrame(); + + const currentTime = animation.currentTime; + const timelineTime = document.timeline.currentTime; + assert_times_equal(currentTime, (timelineTime - prevTimelineTime) * playbackRate, + 'The current time should increase two times faster than timeline.'); +}, 'The playback rate set before the animation started playing affects the ' + + 'rate of progress of the current time'); + +promise_test(async t => { + await registerPassthroughAnimator(); + const timing = { duration: 100, + easing: 'linear', + fill: 'none', + iterations: 1 + }; + const target = createDiv(t); + const keyframeEffect = new KeyframeEffect(target, { opacity: [0, 1] }, timing); + const animation = new WorkletAnimation('passthrough', keyframeEffect, document.timeline); + const playbackRate = 2; + + animation.play(); + animation.playbackRate = playbackRate; + + await waitForNextFrame(); + + assert_times_equal(keyframeEffect.getComputedTiming().localTime, animation.currentTime, + 'When playback rate is set on WorkletAnimation, the underlying effect\'s timing should be properly updated.'); + + assert_approx_equals(Number(getComputedStyle(target).opacity), + animation.currentTime / 100, 0.001, + 'When playback rate is set on WorkletAnimation, the underlying effect should produce correct visual result.'); + +}, 'When playback rate is updated, the underlying effect is properly updated ' + + 'with the current time of its WorkletAnimation and produces correct ' + + 'visual result.'); + +</script> +</body> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/client-hints/echo_client_hints_received.py b/third_party/blink/web_tests/external/wpt/client-hints/echo_client_hints_received.py index 8f2ccaa2..f7debdb 100644 --- a/third_party/blink/web_tests/external/wpt/client-hints/echo_client_hints_received.py +++ b/third_party/blink/web_tests/external/wpt/client-hints/echo_client_hints_received.py
@@ -18,3 +18,5 @@ response.headers.set("downlink-received", request.headers.get("downlink")) if "ect" in request.headers: response.headers.set("ect-received", request.headers.get("ect")) + if "Sec-CH-Lang" in request.headers: + response.headers.set("lang-received", request.headers.get("Sec-CH-Lang"))
diff --git a/third_party/blink/web_tests/external/wpt/client-hints/http_equiv_accept_ch.tentative.http.html b/third_party/blink/web_tests/external/wpt/client-hints/http_equiv_accept_ch.tentative.http.html index 2bdced2..03c5799 100644 --- a/third_party/blink/web_tests/external/wpt/client-hints/http_equiv_accept_ch.tentative.http.html +++ b/third_party/blink/web_tests/external/wpt/client-hints/http_equiv_accept_ch.tentative.http.html
@@ -1,5 +1,5 @@ <html> -<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect"> +<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect, lang"> <title>Accept-CH http-equiv insecure transport test</title> <body> <script src="/resources/testharness.js"></script> @@ -27,6 +27,7 @@ assert_false(r.headers.has("rtt-received"), "rtt-received"); assert_false(r.headers.has("downlink-received"), "downlink-received"); assert_false(r.headers.has("ect-received"), "ect-received"); + assert_false(r.headers.has("lang-received"), "lang-received"); }); }, "Accept-CH http-equiv test over insecure transport");
diff --git a/third_party/blink/web_tests/external/wpt/client-hints/http_equiv_accept_ch.tentative.https.html b/third_party/blink/web_tests/external/wpt/client-hints/http_equiv_accept_ch.tentative.https.html index 3e4d638..74eea34 100644 --- a/third_party/blink/web_tests/external/wpt/client-hints/http_equiv_accept_ch.tentative.https.html +++ b/third_party/blink/web_tests/external/wpt/client-hints/http_equiv_accept_ch.tentative.https.html
@@ -1,5 +1,5 @@ <html> -<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect"> +<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect, lang"> <title>Accept-CH http-equiv cross-navigation test</title> <body> <script src="/resources/testharness.js"></script> @@ -39,9 +39,9 @@ // not persisted for the origin. window.open("resources/do_not_expect_client_hints_headers.html"); async_test(t => { -window.addEventListener('message', function(event) { - t.done(); -}) + window.addEventListener('message', t.step_func_done(e => { + assert_equals(e.data, 'PASS'); + })); }, "Loading of resources/do_not_expect_client_hints_headers.html did not finish."); </script>
diff --git a/third_party/blink/web_tests/external/wpt/client-hints/http_equiv_accept_ch.tentative.sub.https.html b/third_party/blink/web_tests/external/wpt/client-hints/http_equiv_accept_ch.tentative.sub.https.html index 459b00e..16617dc 100644 --- a/third_party/blink/web_tests/external/wpt/client-hints/http_equiv_accept_ch.tentative.sub.https.html +++ b/third_party/blink/web_tests/external/wpt/client-hints/http_equiv_accept_ch.tentative.sub.https.html
@@ -1,5 +1,5 @@ <html> -<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect"> +<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect, lang"> <title>Accept-CH http-equiv same-origin and cross-origin test</title> <body> <script src="/resources/testharness.js"></script> @@ -38,6 +38,8 @@ assert_in_array(r.headers.get("ect-received"), ["slow-2g", "2g", "3g", "4g"], 'ect-received is unexpected'); + + assert_true(r.headers.has("lang-received"), "lang-received"); }); }, "Same origin Accept-CH http-equiv test"); @@ -52,6 +54,7 @@ assert_false(r.headers.has("rtt-received"), "rtt-received"); assert_false(r.headers.has("downlink-received"), "downlink-received"); assert_false(r.headers.has("ect-received"), "ect-received"); + assert_false(r.headers.has("lang-received"), "lang-received"); }); }, "Cross-Origin Accept-CH http-equiv test");
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/baseline-of-scrollable-1a.html b/third_party/blink/web_tests/external/wpt/css/css-align/baseline-of-scrollable-1a.html new file mode 100644 index 0000000..a55e231 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-align/baseline-of-scrollable-1a.html
@@ -0,0 +1,58 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title> + CSS Test: baseline of scrollable element should be taken from its + contents. (Except if the scrollable element is an inline-block, which gets + baseline from its margin-box.) + </title> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="author" title="Mozilla" href="https://www.mozilla.org"> + <link rel="help" href="https://drafts.csswg.org/css-align/#baseline-export"> + <link rel="match" href="reference/baseline-of-scrollable-1-ref.html"> + <style> + .container { + overflow: hidden; + height: 50px; + width: 100px; + border-style: solid; + border-width: 2px 3px 4px 5px; + padding: 4px 5px 7px 8px; + margin: 1px 2px 3px 4px; + } + .inline-block { + display: inline-block; + } + .inline-flex { + display: inline-flex; + } + .inline-grid { + display: inline-grid; + } +</style> +</head> +<body> + Test passes if the a/b text aligns with the bottom margin-edge of the "block" + rect and baseline-aligns with the "flex" and "grid" text. + <br><br> + + <!-- Note: for this first "inline-block" case, the element's baseline is + synthesized from its margin box. For the other cases, the element's + baseline is taken from its contents, i.e. the text inside of it. --> + a + <div class="container inline-block">block</div> + b + <br> + + a + <div class="container inline-flex">flex</div> + b + <br> + + a + <div class="container inline-grid">grid</div> + b + +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/baseline-of-scrollable-1b.html b/third_party/blink/web_tests/external/wpt/css/css-align/baseline-of-scrollable-1b.html new file mode 100644 index 0000000..79db8a8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-align/baseline-of-scrollable-1b.html
@@ -0,0 +1,67 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title> + CSS Test: baseline of scrollable element (for use by a parent inline-block) + should be taken from its contents. (Except if the scrollable element is a + block, which gets baseline from its margin-box.) + </title> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="author" title="Mozilla" href="https://www.mozilla.org"> + <link rel="help" href="https://drafts.csswg.org/css-align/#baseline-export"> + <link rel="match" href="reference/baseline-of-scrollable-1-ref.html"> + <style> + .container { + overflow: hidden; + height: 50px; + width: 100px; + border-style: solid; + border-width: 2px 3px 4px 5px; + padding: 4px 5px 7px 8px; + margin: 1px 2px 3px 4px; + } + .inline-block { + display: inline-block; + } + .block { + display: block; + } + .flex { + display: flex; + } + .grid { + display: grid; + } +</style> +</head> +<body> + Test passes if the a/b text aligns with the bottom margin-edge of the "block" + rect and baseline-aligns with the "flex" and "grid" text. + <br><br> + + <!-- Note: for this first "inline-block" case, the element's baseline is + synthesized from its margin box. For the other cases, the element's + baseline is taken from its contents, i.e. the text inside of it. --> + a + <div class="inline-block"> + <div class="container block">block</div> + </div> + b + <br> + + a + <div class="inline-block"> + <div class="container flex">flex</div> + </div> + b + <br> + + a + <div class="inline-block"> + <div class="container grid">grid</div> + </div> + b + +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/reference/baseline-of-scrollable-1-ref.html b/third_party/blink/web_tests/external/wpt/css/css-align/reference/baseline-of-scrollable-1-ref.html new file mode 100644 index 0000000..422660a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-align/reference/baseline-of-scrollable-1-ref.html
@@ -0,0 +1,58 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title> + CSS Reference Case + </title> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="author" title="Mozilla" href="https://www.mozilla.org"> + <link rel="help" href="https://drafts.csswg.org/css-align/#baseline-export"> + <style> + .container { + /* In this reference case, we leave 'overflow' at its initial value. */ + height: 50px; + width: 100px; + border-style: solid; + border-width: 2px 3px 4px 5px; + padding: 4px 5px 7px 8px; + margin: 1px 2px 3px 4px; + } + .inline-block { + display: inline-block; + } + .inline-flex { + display: inline-flex; + } + .inline-grid { + display: inline-grid; + } +</style> +</head> +<body> + Test passes if the a/b text aligns with the bottom margin-edge of the "block" + rect and baseline-aligns with the "flex" and "grid" text. + <br><br> + + <!-- Note: for this first "inline-block" case, we take the inner text out of + flow, to force the inline-block to synthesize its baseline from its + margin box. (This is how the corresponding piece of the testcase is + supposed to render). --> + a + <div class="container inline-block"> + <div style="position: absolute">block</div> + </div> + b + <br> + + a + <div class="container inline-flex">flex</div> + b + <br> + + a + <div class="container inline-grid">grid</div> + b + +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/inheritance.html b/third_party/blink/web_tests/external/wpt/css/css-lists/inheritance.html index ff1bcdc..590319d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-lists/inheritance.html +++ b/third_party/blink/web_tests/external/wpt/css/css-lists/inheritance.html
@@ -17,7 +17,7 @@ <script> assert_not_inherited('counter-increment', 'none', 'foo 123'); assert_not_inherited('counter-reset', 'none', 'foo 123'); -assert_inherited('list-style-image', 'none', 'url("https://example.com/")'); +assert_inherited('list-style-image', 'none', 'url("data:,a")'); assert_inherited('list-style-position', 'outside', 'inside'); assert_inherited('list-style-type', 'disc', 'square'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overscroll-behavior/parsing/overscroll-behavior-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-overscroll-behavior/parsing/overscroll-behavior-invalid.html new file mode 100644 index 0000000..a29722f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overscroll-behavior/parsing/overscroll-behavior-invalid.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Overscroll Behavior: parsing overscroll-behavior with invalid values</title> +<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-overscroll-behavior/#propdef-overscroll-behavior"> +<meta name="assert" content="overscroll-behavior supports only the grammar '[ contain | none | auto ]{1,2}'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +'use strict'; +test_invalid_value("overscroll-behavior", "normal"); +test_invalid_value("overscroll-behavior", "0"); +test_invalid_value("overscroll-behavior", "contain contain contain"); + + +for (let property of ["overscroll-behavior-x", "overscroll-behavior-y"]) { + test_invalid_value(property, "normal"); + test_invalid_value(property, "0"); + test_invalid_value(property, "contain contain"); +} +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overscroll-behavior/parsing/overscroll-behavior-valid-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-overscroll-behavior/parsing/overscroll-behavior-valid-expected.txt new file mode 100644 index 0000000..4b71db8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overscroll-behavior/parsing/overscroll-behavior-valid-expected.txt
@@ -0,0 +1,18 @@ +This is a testharness.js-based test. +FAIL e.style['overscroll-behavior'] = "contain" should set the property value assert_equals: serialization should be canonical expected "contain" but got "contain contain" +FAIL e.style['overscroll-behavior'] = "none" should set the property value assert_equals: serialization should be canonical expected "none" but got "none none" +FAIL e.style['overscroll-behavior'] = "auto" should set the property value assert_equals: serialization should be canonical expected "auto" but got "auto auto" +PASS e.style['overscroll-behavior'] = "contain none" should set the property value +PASS e.style['overscroll-behavior'] = "none auto" should set the property value +PASS e.style['overscroll-behavior'] = "auto contain" should set the property value +FAIL e.style['overscroll-behavior'] = "contain contain" should set the property value assert_equals: serialization should be canonical expected "contain" but got "contain contain" +FAIL e.style['overscroll-behavior'] = "none none" should set the property value assert_equals: serialization should be canonical expected "none" but got "none none" +FAIL e.style['overscroll-behavior'] = "auto auto" should set the property value assert_equals: serialization should be canonical expected "auto" but got "auto auto" +PASS e.style['overscroll-behavior-x'] = "contain" should set the property value +PASS e.style['overscroll-behavior-x'] = "none" should set the property value +PASS e.style['overscroll-behavior-x'] = "auto" should set the property value +PASS e.style['overscroll-behavior-y'] = "contain" should set the property value +PASS e.style['overscroll-behavior-y'] = "none" should set the property value +PASS e.style['overscroll-behavior-y'] = "auto" should set the property value +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overscroll-behavior/parsing/overscroll-behavior-valid.html b/third_party/blink/web_tests/external/wpt/css/css-overscroll-behavior/parsing/overscroll-behavior-valid.html new file mode 100644 index 0000000..9dbd4fb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overscroll-behavior/parsing/overscroll-behavior-valid.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Overscroll Behavior: parsing overscroll-behavior with valid values</title> +<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-overscroll-behavior/#propdef-overscroll-behavior"> +<meta name="assert" content="overscroll-behavior supports the full grammar '[ contain | none | auto ]{1,2}'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +'use strict'; +test_valid_value("overscroll-behavior", "contain"); +test_valid_value("overscroll-behavior", "none"); +test_valid_value("overscroll-behavior", "auto"); + +test_valid_value("overscroll-behavior", "contain none"); +test_valid_value("overscroll-behavior", "none auto"); +test_valid_value("overscroll-behavior", "auto contain"); + +test_valid_value("overscroll-behavior", "contain contain", "contain"); +test_valid_value("overscroll-behavior", "none none", "none"); +test_valid_value("overscroll-behavior", "auto auto", "auto"); + + +for (let property of ["overscroll-behavior-x", "overscroll-behavior-y"]) { + test_valid_value(property, "contain"); + test_valid_value(property, "none"); + test_valid_value(property, "auto"); +} +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-syntax/urange-parsing.html b/third_party/blink/web_tests/external/wpt/css/css-syntax/urange-parsing.html index 0a69faa3..2d34e05a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-syntax/urange-parsing.html +++ b/third_party/blink/web_tests/external/wpt/css/css-syntax/urange-parsing.html
@@ -21,17 +21,17 @@ function testUrange(input, expected) { test(()=>{ const rule = document.styleSheets[0].cssRules[0]; - rule.style.unicodeRange = "U+1357"; - rule.style.unicodeRange = input; - assert_equals(rule.style.unicodeRange.toUpperCase(), expected.toUpperCase()); + rule.style.setProperty("unicode-range", "U+1357"); + rule.style.setProperty("unicode-range", input); + assert_equals(rule.style.getPropertyValue("unicode-range").toUpperCase(), expected.toUpperCase()); }, `"${input}" => "${expected}"`) } function testInvalidUrange(input) { test(()=>{ const rule = document.styleSheets[0].cssRules[0]; - rule.style.unicodeRange = "U+1357"; - rule.style.unicodeRange = input; - assert_equals(rule.style.unicodeRange.toUpperCase(), "U+1357"); + rule.style.setProperty("unicode-range", "U+1357"); + rule.style.setProperty("unicode-range", input); + assert_equals(rule.style.getPropertyValue("unicode-range").toUpperCase(), "U+1357"); }, `"${input}" is invalid`); }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/baseline-with-orthogonal-flow-001.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/baseline-with-orthogonal-flow-001.html new file mode 100644 index 0000000..f054c59 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/baseline-with-orthogonal-flow-001.html
@@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title> + CSS Test: orthogonal-flow child should be skipped over when determining parent's last-baseline + </title> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="author" title="Mozilla" href="https://www.mozilla.org"> + <link rel="help" href="https://drafts.csswg.org/css-align/#baseline-export"> + <link rel="match" href="reference/baseline-with-orthogonal-flow-001-ref.html"> + <!-- The inline-blocks in this example are using last-baseline alignment, and + css-align-3 sec 9.1 says they should take their last-baseline position: + "from the ...(last) in-flow block-level child in the block container + that contributes a set of ... (last) baselines". + + The orthogonal-flow doesn't contribute a first/last baseline set (not + for its parent's writing-mode at least), so it should not affect the + baseline determination. + --> + <style> + .ib { + display: inline-block; + } + .vert { + writing-mode: vertical-rl; + color: transparent; + } + .overflow { + overflow: hidden; + } + </style> +</head> +<body> + Test passes if the visible characters below are baseline-aligned. + <br><br> + + aaa + + <div class="ib"> + bbb + <!-- This shouldn't influence the baseline of our inline block: --> + <div class="vert">vvv</div> + </div> + + <div class="ib"> + ccc + <!-- This shouldn't influence the baseline of our inline block: --> + <div class="vert overflow">ooo</div> + </div> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/reference/baseline-with-orthogonal-flow-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/reference/baseline-with-orthogonal-flow-001-ref.html new file mode 100644 index 0000000..dda75ca1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/reference/baseline-with-orthogonal-flow-001-ref.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title> + CSS Reference Case + </title> + <style> + .ib { + display: inline-block; + } + </style> +</head> +<body> + Test passes if the visible characters below are baseline-aligned. + <br><br> + + aaa + + <div class="ib"> + bbb + </div> + + <div class="ib"> + ccc + </div> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/interfaces-expected.txt b/third_party/blink/web_tests/external/wpt/css/cssom/interfaces-expected.txt index c108aed..2b93154 100644 --- a/third_party/blink/web_tests/external/wpt/css/cssom/interfaces-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/cssom/interfaces-expected.txt
@@ -1,7 +1,7 @@ This is a testharness.js-based test. -Found 376 tests; 321 PASS, 55 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 377 tests; 322 PASS, 55 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup -PASS Partial interface Document: original interface defined +PASS Partial interface mixin DocumentOrShadowRoot: original interface mixin defined PASS Partial interface Window: original interface defined PASS MediaList interface: existence and properties of interface object PASS MediaList interface object length @@ -376,6 +376,7 @@ PASS Document interface: attribute styleSheets PASS Document interface: document must inherit property "styleSheets" with the proper type PASS Document interface: new Document() must inherit property "styleSheets" with the proper type +PASS ShadowRoot interface: attribute styleSheets PASS ProcessingInstruction interface: attribute sheet PASS ProcessingInstruction interface: xmlss_pi must inherit property "sheet" with the proper type Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007-ref.html b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007-ref.html new file mode 100644 index 0000000..ccde6012 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007-ref.html
@@ -0,0 +1,128 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> + <head> + <meta charset="utf-8"> + <title>CSS Reftest Reference</title> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <style> + .flexbox { + border: 1px solid black; + margin: 0 2px 2px 0; /* (Just for spacing things out, visually) */ + width: 40px; + height: 40px; + + float: left; /* For testing in "rows" */ + } + img { + padding: 1px 2px 3px 4px; + box-sizing: border-box; + background: pink; + } + + br { clear: both; } + + .flexbox > * { + /* Disable "min-width:auto"/"min-height:auto" to focus purely on + later channels of influence. */ + min-width: 0; + min-height: 0; + vertical-align: top; + } + </style> + </head> + <body> + <!-- NOTE: solidblue.png has an intrinsic size of 16px by 16px. --> + + <!-- Row 1: no special sizing: --> + <div class="flexbox"> + <img src="support/solidblue.png"> + </div> + <br> + + <!-- Row 2: Specified main-size, cross-size, or flex-basis: --> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 30px; + height: 28px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 32px; + height: 30px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 30px; + height: 28px"> + </div> + <br> + + <!-- Row 3: min main-size OR min cross-size, or both --> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 34px; + height: 32px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 36px; + height: 34px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 36px; + height: 34px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 34px; + height: 32px"> + </div> + <br> + + <!-- Row 4: max main-size OR max cross-size, or both --> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 16px; + height: 14px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 18px; + height: 16px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 16px; + height: 14px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 14px; + height: 12px"> + </div> + <br> + + <!-- Row 5: min main-size vs. max cross-size, & vice versa --> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 30px; + height: 10px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 10px; + height: 30px"> + </div> + <br> + + <!-- Row 6: min|max main-size vs. explicit cross-size, & vice versa --> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 30px; + height: 10px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 30px; + height: 10px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 10px; + height: 30px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 10px; + height: 30px"> + </div> + </body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007.html b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007.html new file mode 100644 index 0000000..ea9179c3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007.html
@@ -0,0 +1,132 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> + <head> + <meta charset="utf-8"> + <title> + CSS Test: Testing how explicit main-size & cross-size constraints + influence sizing on non-stretched flex item w/ intrinsic ratio, + some padding, and box-sizing:border-box. + </title> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-main-size"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-cross-size"> + <link rel="match" href="flexbox-intrinsic-ratio-007-ref.html"> + <style> + .flexbox { + display: flex; + flex-direction: row; + border: 1px solid black; + margin: 0 2px 2px 0; /* (Just for spacing things out, visually) */ + width: 40px; + height: 40px; + + justify-content: flex-start; + align-items: flex-start; + + float: left; /* For testing in "rows" */ + } + img { + padding: 1px 2px 3px 4px; + box-sizing: border-box; + background: pink; + } + + br { clear: both; } + + .flexbox > * { + /* Disable "min-width:auto"/"min-height:auto" to focus purely on + later channels of influence. */ + min-width: 0; + min-height: 0; + } + </style> + </head> + <body> + <!-- NOTE: solidblue.png has an intrinsic size of 16px by 16px. --> + + <!-- Row 1: no special sizing: --> + <div class="flexbox"> + <img src="support/solidblue.png"> + </div> + <br> + + <!-- Row 2: Specified main-size, cross-size, or flex-basis: --> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 30px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="height: 30px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="flex: 0 0 30px"> + </div> + <br> + + <!-- Row 3: min main-size OR min cross-size, or both --> + <div class="flexbox"> + <img src="support/solidblue.png" style="min-width: 34px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="min-height: 34px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="min-width: 30px; + min-height: 34px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="min-width: 34px; + min-height: 30px"> + </div> + <br> + + <!-- Row 4: max main-size OR max cross-size, or both --> + <div class="flexbox"> + <img src="support/solidblue.png" style="max-width: 16px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="max-height: 16px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="max-width: 20px; + max-height: 14px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="max-width: 14px; + max-height: 20px"> + </div> + <br> + + <!-- Row 5: min main-size vs. max cross-size, & vice versa --> + <div class="flexbox"> + <img src="support/solidblue.png" style="min-width: 30px; + max-height: 10px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="max-width: 10px; + min-height: 30px"> + </div> + <br> + + <!-- Row 6: min|max main-size vs. explicit cross-size, & vice versa --> + <div class="flexbox"> + <img src="support/solidblue.png" style="min-width: 30px; + height: 10px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 30px; + max-height: 10px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="max-width: 10px; + height: 30px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 10px; + min-height: 30px"> + </div> + </body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007v.html b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007v.html new file mode 100644 index 0000000..2efb8b1c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007v.html
@@ -0,0 +1,134 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> + <head> + <meta charset="utf-8"> + <title> + CSS Test: Testing how explicit main-size & cross-size constraints + influence sizing on non-stretched flex item w/ intrinsic ratio, + some padding, box-sizing:border-box, and a vertical writing-mode. + </title> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-main-size"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-cross-size"> + <link rel="match" href="flexbox-intrinsic-ratio-007-ref.html"> + <style> + .flexbox { + display: flex; + flex-direction: row; + border: 1px solid black; + margin: 0 2px 2px 0; /* (Just for spacing things out, visually) */ + width: 40px; + height: 40px; + + justify-content: flex-start; + align-items: flex-start; + + float: left; /* For testing in "rows" */ + } + img { + padding: 1px 2px 3px 4px; + box-sizing: border-box; + background: pink; + } + + br { clear: both; } + + .flexbox > * { + writing-mode: vertical-lr; + + /* Disable "min-width:auto"/"min-height:auto" to focus purely on + later channels of influence. */ + min-width: 0; + min-height: 0; + } + </style> + </head> + <body> + <!-- NOTE: solidblue.png has an intrinsic size of 16px by 16px. --> + + <!-- Row 1: no special sizing: --> + <div class="flexbox"> + <img src="support/solidblue.png"> + </div> + <br> + + <!-- Row 2: Specified main-size, cross-size, or flex-basis: --> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 30px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="height: 30px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="flex: 0 0 30px"> + </div> + <br> + + <!-- Row 3: min main-size OR min cross-size, or both --> + <div class="flexbox"> + <img src="support/solidblue.png" style="min-width: 34px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="min-height: 34px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="min-width: 30px; + min-height: 34px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="min-width: 34px; + min-height: 30px"> + </div> + <br> + + <!-- Row 4: max main-size OR max cross-size, or both --> + <div class="flexbox"> + <img src="support/solidblue.png" style="max-width: 16px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="max-height: 16px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="max-width: 20px; + max-height: 14px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="max-width: 14px; + max-height: 20px"> + </div> + <br> + + <!-- Row 5: min main-size vs. max cross-size, & vice versa --> + <div class="flexbox"> + <img src="support/solidblue.png" style="min-width: 30px; + max-height: 10px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="max-width: 10px; + min-height: 30px"> + </div> + <br> + + <!-- Row 6: min|max main-size vs. explicit cross-size, & vice versa --> + <div class="flexbox"> + <img src="support/solidblue.png" style="min-width: 30px; + height: 10px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 30px; + max-height: 10px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="max-width: 10px; + height: 30px"> + </div> + <div class="flexbox"> + <img src="support/solidblue.png" style="width: 10px; + min-height: 30px"> + </div> + </body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/domxpath/document.tentative.html b/third_party/blink/web_tests/external/wpt/domxpath/document.tentative.html index c44ebd99..b75c0f0d 100644 --- a/third_party/blink/web_tests/external/wpt/domxpath/document.tentative.html +++ b/third_party/blink/web_tests/external/wpt/domxpath/document.tentative.html
@@ -16,5 +16,16 @@ matched.push(cur); } assert_array_equals(matched, [document]); + // Evaluate again, but reuse result from previous evaluation. + result = document.evaluate("..", // expression + document.documentElement, // context node + null, // resolver + XPathResult.ANY_TYPE, // type + result); // result + matched = []; + while ((cur = result.iterateNext()) !== null) { + matched.push(cur); + } + assert_array_equals(matched, [document]); }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub.html index c3d550a3..d596f377 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub.html +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub.html
@@ -1,5 +1,6 @@ <!doctype html> <meta charset={{GET[encoding]}}> <!-- ends up as <meta charset> by default which is windows-1252 --> +<meta name=variant content="?encoding=windows-1252"> <meta name=variant content="?encoding=x-cp1251"> <meta name=variant content="?encoding=utf8"> <script src=/resources/testharness.js></script>
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub_encoding=windows-1252-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub_encoding=windows-1252-expected.txt new file mode 100644 index 0000000..6e364ba0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub_encoding=windows-1252-expected.txt
@@ -0,0 +1,29 @@ +This is a testharness.js-based test. +PASS getComputedStyle <body background> +PASS getComputedStyle <table background> +PASS getComputedStyle <thead background> +PASS getComputedStyle <tbody background> +PASS getComputedStyle <tfoot background> +PASS getComputedStyle <tr background> +PASS getComputedStyle <td background> +PASS getComputedStyle <th background> +PASS Getting <iframe>.src +PASS Getting <a>.href +PASS Getting <area>.href +FAIL Getting <base>.href assert_true: http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub.html?%C3%BF did not end with ?%FF expected true got false +PASS Getting <link>.href +PASS Getting <img>.src +PASS Getting <embed>.src +PASS Getting <object>.data +PASS Getting <track>.src +PASS Getting <video>.src +PASS Getting <audio>.src +PASS Getting <input>.src +PASS Getting <form>.action +PASS Getting <input>.formAction +PASS Getting <button>.formAction +PASS Getting <script>.src +PASS Getting <a>.ping +PASS Getting <area>.ping +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/location.sub.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/location.sub.html index 3ad228b..a5c131e 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/location.sub.html +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/location.sub.html
@@ -1,5 +1,6 @@ <!doctype html> <meta charset={{GET[encoding]}}> <!-- ends up as <meta charset> by default which is windows-1252 --> +<meta name=variant content="?encoding=windows-1252"> <meta name=variant content="?encoding=x-cp1251"> <meta name=variant content="?encoding=utf8"> <script src=/resources/testharness.js></script>
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/location.sub_encoding=windows-1252-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/location.sub_encoding=windows-1252-expected.txt new file mode 100644 index 0000000..3e52ba43 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/location.sub_encoding=windows-1252-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +PASS location [PutForwards] +PASS location.assign() +PASS location.replace() +PASS location.href +FAIL location.search assert_equals: expected "?%FF" but got "?%C3%BF" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/navigation.sub.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/navigation.sub.html index 80cf751..bca61372 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/navigation.sub.html +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/navigation.sub.html
@@ -1,5 +1,6 @@ <!doctype html> <meta charset={{GET[encoding]}}> <!-- ends up as <meta charset> by default which is windows-1252 --> +<meta name=variant content="?encoding=windows-1252"> <meta name=variant content="?encoding=x-cp1251"> <meta name=variant content="?encoding=utf8"> <script src=/resources/testharness.js></script>
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/resources/resolve-url.js b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/resources/resolve-url.js index cf175eb4..77f8fff5 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/resources/resolve-url.js +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/resources/resolve-url.js
@@ -26,6 +26,29 @@ return 'expected substring '+expected+' got '+got; } + function poll_for_stash(test_obj, uuid, expected) { + var start = new Date(); + var poll = test_obj.step_func(function () { + var xhr = new XMLHttpRequest(); + xhr.open('GET', stash_take + uuid); + xhr.onload = test_obj.step_func(function(e) { + if (xhr.response == "") { + if (new Date() - start > 10000) { + // If we set the status to TIMEOUT here we avoid a race between the + // page and the test timing out + test_obj.force_timeout(); + } + test_obj.step_timeout(poll, 200); + } else { + assert_equals(xhr.response, expected); + test_obj.done(); + } + }); + xhr.send(); + }) + test_obj.step_timeout(poll, 200); + } + // loading html (or actually svg to support <embed>) function test_load_nested_browsing_context(tag, attr, spec_url) { async_test(function() {
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-8-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-8-expected.txt index 77506623..483a3016 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-8-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-8-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 101 tests; 61 PASS, 40 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 101 tests; 80 PASS, 19 FAIL, 2 TIMEOUT, 0 NOTRUN. PASS load nested browsing context <frame src> PASS load nested browsing context <iframe src> PASS load nested browsing context <object data> @@ -31,9 +31,9 @@ FAIL history.pushState assert_equals: url was resolved against the iframe's URL instead of the settings object's API base URL expected -1 but got 84 FAIL history.replaceState assert_equals: url was resolved against the iframe's URL instead of the settings object's API base URL expected -1 but got 84 PASS SVG <a> -FAIL SVG <feImage> poll_for_stash is not defined -FAIL SVG <image> poll_for_stash is not defined -FAIL SVG <use> poll_for_stash is not defined +PASS SVG <feImage> +PASS SVG <image> +PASS SVG <use> PASS XMLHttpRequest#open() PASS importScripts() in a dedicated worker PASS Worker() in a dedicated worker @@ -43,30 +43,30 @@ FAIL SharedWorker() in a shared worker assert_equals: expected "%C3%A5" but got "ReferenceError: SharedWorker is not defined" PASS WebSocket constructor PASS WebSocket#url -FAIL Parsing cache manifest (CACHE) poll_for_stash is not defined -FAIL Parsing cache manifest (FALLBACK) poll_for_stash is not defined -FAIL Parsing cache manifest (NETWORK) poll_for_stash is not defined -FAIL CSS <link> (utf-8) #<id> { background-image:<url> } poll_for_stash is not defined -FAIL CSS <link> (windows-1252) #<id> { background-image:<url> } poll_for_stash is not defined -FAIL CSS <style> #<id> { background-image:<url> } poll_for_stash is not defined -FAIL CSS <link> (utf-8) #<id> { border-image-source:<url> } poll_for_stash is not defined -FAIL CSS <link> (windows-1252) #<id> { border-image-source:<url> } poll_for_stash is not defined -FAIL CSS <style> #<id> { border-image-source:<url> } poll_for_stash is not defined -FAIL CSS <link> (utf-8) #<id>::before { content:<url> } poll_for_stash is not defined -FAIL CSS <link> (windows-1252) #<id>::before { content:<url> } poll_for_stash is not defined -FAIL CSS <style> #<id>::before { content:<url> } poll_for_stash is not defined -FAIL CSS <link> (utf-8) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } poll_for_stash is not defined -FAIL CSS <link> (windows-1252) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } poll_for_stash is not defined -FAIL CSS <style> @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } poll_for_stash is not defined -FAIL CSS <link> (utf-8) #<id> { display:list-item; list-style-image:<url> } poll_for_stash is not defined -FAIL CSS <link> (windows-1252) #<id> { display:list-item; list-style-image:<url> } poll_for_stash is not defined -FAIL CSS <style> #<id> { display:list-item; list-style-image:<url> } poll_for_stash is not defined -FAIL CSS <link> (utf-8) @import <url>; poll_for_stash is not defined -FAIL CSS <link> (windows-1252) @import <url>; poll_for_stash is not defined -FAIL CSS <style> @import <url>; poll_for_stash is not defined -FAIL CSS <link> (utf-8) #<id> { cursor:<url>, pointer } poll_for_stash is not defined -FAIL CSS <link> (windows-1252) #<id> { cursor:<url>, pointer } poll_for_stash is not defined -FAIL CSS <style> #<id> { cursor:<url>, pointer } poll_for_stash is not defined +TIMEOUT Parsing cache manifest (CACHE) Test timed out +TIMEOUT Parsing cache manifest (FALLBACK) Test timed out +PASS Parsing cache manifest (NETWORK) +PASS CSS <link> (utf-8) #<id> { background-image:<url> } +FAIL CSS <link> (windows-1252) #<id> { background-image:<url> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <style> #<id> { background-image:<url> } +PASS CSS <link> (utf-8) #<id> { border-image-source:<url> } +FAIL CSS <link> (windows-1252) #<id> { border-image-source:<url> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <style> #<id> { border-image-source:<url> } +PASS CSS <link> (utf-8) #<id>::before { content:<url> } +FAIL CSS <link> (windows-1252) #<id>::before { content:<url> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <style> #<id>::before { content:<url> } +PASS CSS <link> (utf-8) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } +FAIL CSS <link> (windows-1252) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <style> @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } +PASS CSS <link> (utf-8) #<id> { display:list-item; list-style-image:<url> } +FAIL CSS <link> (windows-1252) #<id> { display:list-item; list-style-image:<url> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <style> #<id> { display:list-item; list-style-image:<url> } +PASS CSS <link> (utf-8) @import <url>; +PASS CSS <link> (windows-1252) @import <url>; +PASS CSS <style> @import <url>; +PASS CSS <link> (utf-8) #<id> { cursor:<url>, pointer } +FAIL CSS <link> (windows-1252) #<id> { cursor:<url>, pointer } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <style> #<id> { cursor:<url>, pointer } PASS <?xml-stylesheet?> (CSS) PASS URL constructor, url PASS URL constructor, base
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251-expected.txt index 4de5bd1..e0140d8 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 101 tests; 51 PASS, 50 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 101 tests; 64 PASS, 35 FAIL, 2 TIMEOUT, 0 NOTRUN. PASS load nested browsing context <frame src> PASS load nested browsing context <iframe src> PASS load nested browsing context <object data> @@ -31,9 +31,9 @@ FAIL history.pushState assert_true: expected substring %26%23229%3B got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resources/resource.py?q=%C3%A5&encoding=windows-1251&type=html expected true got false FAIL history.replaceState assert_true: expected substring %26%23229%3B got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resources/resource.py?q=%C3%A5&encoding=windows-1251&type=html expected true got false PASS SVG <a> -FAIL SVG <feImage> poll_for_stash is not defined -FAIL SVG <image> poll_for_stash is not defined -FAIL SVG <use> poll_for_stash is not defined +PASS SVG <feImage> +PASS SVG <image> +PASS SVG <use> FAIL XMLHttpRequest#open() assert_equals: expected "%C3%A5" but got "%26%23229%3B" PASS importScripts() in a dedicated worker PASS Worker() in a dedicated worker @@ -43,30 +43,30 @@ FAIL SharedWorker() in a shared worker assert_equals: expected "%C3%A5" but got "ReferenceError: SharedWorker is not defined" PASS WebSocket constructor PASS WebSocket#url -FAIL Parsing cache manifest (CACHE) poll_for_stash is not defined -FAIL Parsing cache manifest (FALLBACK) poll_for_stash is not defined -FAIL Parsing cache manifest (NETWORK) poll_for_stash is not defined -FAIL CSS <link> (windows-1251) #<id> { background-image:<url> } poll_for_stash is not defined -FAIL CSS <link> (utf-8) #<id> { background-image:<url> } poll_for_stash is not defined -FAIL CSS <style> #<id> { background-image:<url> } poll_for_stash is not defined -FAIL CSS <link> (windows-1251) #<id> { border-image-source:<url> } poll_for_stash is not defined -FAIL CSS <link> (utf-8) #<id> { border-image-source:<url> } poll_for_stash is not defined -FAIL CSS <style> #<id> { border-image-source:<url> } poll_for_stash is not defined -FAIL CSS <link> (windows-1251) #<id>::before { content:<url> } poll_for_stash is not defined -FAIL CSS <link> (utf-8) #<id>::before { content:<url> } poll_for_stash is not defined -FAIL CSS <style> #<id>::before { content:<url> } poll_for_stash is not defined -FAIL CSS <link> (windows-1251) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } poll_for_stash is not defined -FAIL CSS <link> (utf-8) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } poll_for_stash is not defined -FAIL CSS <style> @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } poll_for_stash is not defined -FAIL CSS <link> (windows-1251) #<id> { display:list-item; list-style-image:<url> } poll_for_stash is not defined -FAIL CSS <link> (utf-8) #<id> { display:list-item; list-style-image:<url> } poll_for_stash is not defined -FAIL CSS <style> #<id> { display:list-item; list-style-image:<url> } poll_for_stash is not defined -FAIL CSS <link> (windows-1251) @import <url>; poll_for_stash is not defined -FAIL CSS <link> (utf-8) @import <url>; poll_for_stash is not defined -FAIL CSS <style> @import <url>; poll_for_stash is not defined -FAIL CSS <link> (windows-1251) #<id> { cursor:<url>, pointer } poll_for_stash is not defined -FAIL CSS <link> (utf-8) #<id> { cursor:<url>, pointer } poll_for_stash is not defined -FAIL CSS <style> #<id> { cursor:<url>, pointer } poll_for_stash is not defined +TIMEOUT Parsing cache manifest (CACHE) Test timed out +TIMEOUT Parsing cache manifest (FALLBACK) Test timed out +PASS Parsing cache manifest (NETWORK) +FAIL CSS <link> (windows-1251) #<id> { background-image:<url> } assert_equals: expected "%C3%A5" but got "%26%23229%3B" +PASS CSS <link> (utf-8) #<id> { background-image:<url> } +FAIL CSS <style> #<id> { background-image:<url> } assert_equals: expected "%C3%A5" but got "%26%23229%3B" +FAIL CSS <link> (windows-1251) #<id> { border-image-source:<url> } assert_equals: expected "%C3%A5" but got "%26%23229%3B" +PASS CSS <link> (utf-8) #<id> { border-image-source:<url> } +FAIL CSS <style> #<id> { border-image-source:<url> } assert_equals: expected "%C3%A5" but got "%26%23229%3B" +FAIL CSS <link> (windows-1251) #<id>::before { content:<url> } assert_equals: expected "%C3%A5" but got "%26%23229%3B" +PASS CSS <link> (utf-8) #<id>::before { content:<url> } +FAIL CSS <style> #<id>::before { content:<url> } assert_equals: expected "%C3%A5" but got "%26%23229%3B" +FAIL CSS <link> (windows-1251) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } assert_equals: expected "%C3%A5" but got "%26%23229%3B" +PASS CSS <link> (utf-8) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } +FAIL CSS <style> @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } assert_equals: expected "%C3%A5" but got "%26%23229%3B" +FAIL CSS <link> (windows-1251) #<id> { display:list-item; list-style-image:<url> } assert_equals: expected "%C3%A5" but got "%26%23229%3B" +PASS CSS <link> (utf-8) #<id> { display:list-item; list-style-image:<url> } +FAIL CSS <style> #<id> { display:list-item; list-style-image:<url> } assert_equals: expected "%C3%A5" but got "%26%23229%3B" +PASS CSS <link> (windows-1251) @import <url>; +PASS CSS <link> (utf-8) @import <url>; +PASS CSS <style> @import <url>; +FAIL CSS <link> (windows-1251) #<id> { cursor:<url>, pointer } assert_equals: expected "%C3%A5" but got "%26%23229%3B" +PASS CSS <link> (utf-8) #<id> { cursor:<url>, pointer } +FAIL CSS <style> #<id> { cursor:<url>, pointer } assert_equals: expected "%C3%A5" but got "%26%23229%3B" FAIL <?xml-stylesheet?> (CSS) assert_equals: expected "\"%C3%A5\"" but got "\"%26%23229%3B\"" PASS URL constructor, url PASS URL constructor, base
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/cssom.idl b/third_party/blink/web_tests/external/wpt/interfaces/cssom.idl index 7d9536d..a914ac0d7 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/cssom.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/cssom.idl
@@ -1,10 +1,17 @@ +// GENERATED PREAMBLE - DO NOT EDIT +// This preamble was added by reffy-reports for web-platform-tests. +// CSSOMString is an implementation-defined type of either DOMString or +// USVString in CSSOM: https://drafts.csswg.org/cssom/#cssomstring-type +// For web-platform-tests, use DOMString because USVString has additional +// requirements in type conversion and could result in spurious failures for +// implementations that use DOMString. +typedef DOMString CSSOMString; + // GENERATED CONTENT - DO NOT EDIT // Content was automatically extracted by Reffy into reffy-reports // (https://github.com/tidoust/reffy-reports) // Source: CSS Object Model (CSSOM) (https://drafts.csswg.org/cssom/) -typedef USVString CSSOMString; - [Exposed=Window] interface MediaList { stringifier attribute [TreatNullAs=EmptyString] CSSOMString mediaText; @@ -19,7 +26,7 @@ readonly attribute CSSOMString type; readonly attribute USVString? href; readonly attribute (Element or ProcessingInstruction)? ownerNode; - readonly attribute StyleSheet? parentStyleSheet; + readonly attribute CSSStyleSheet? parentStyleSheet; readonly attribute DOMString? title; [SameObject, PutForwards=mediaText] readonly attribute MediaList media; attribute boolean disabled; @@ -35,16 +42,16 @@ [Exposed=Window] interface StyleSheetList { - getter StyleSheet? item(unsigned long index); + getter CSSStyleSheet? item(unsigned long index); readonly attribute unsigned long length; }; -partial interface Document { +partial interface mixin DocumentOrShadowRoot { [SameObject] readonly attribute StyleSheetList styleSheets; }; interface mixin LinkStyle { - readonly attribute StyleSheet? sheet; + readonly attribute CSSStyleSheet? sheet; }; ProcessingInstruction includes LinkStyle;
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-1.html index fc650eb..748fbdf 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-1.html
@@ -83,44 +83,44 @@ <math> <mo id="axis">−</mo> <mfrac id="frac0"> - <mspace id="frac0num" width="15px" height="15px" mathbackground="blue"/> - <mspace id="frac0den" width="15px" height="15px" mathbackground="green"/> + <mspace id="frac0num" width="15px" height="15px" style="background: blue"/> + <mspace id="frac0den" width="15px" height="15px" style="background: green"/> </mfrac> <mfrac id="frac1"> - <mspace id="frac1num" width="30px" height="15px" mathbackground="blue"/> - <mspace id="frac1den" width="15px" height="15px" mathbackground="green"/> + <mspace id="frac1num" width="30px" height="15px" style="background: blue"/> + <mspace id="frac1den" width="15px" height="15px" style="background: green"/> </mfrac> <mfrac id="frac2"> - <mspace id="frac2num" width="15px" height="15px" mathbackground="blue"/> - <mspace id="frac2den" width="30px" height="15px" mathbackground="green"/> + <mspace id="frac2num" width="15px" height="15px" style="background: blue"/> + <mspace id="frac2den" width="30px" height="15px" style="background: green"/> </mfrac> <mfrac id="frac3"> - <mspace id="frac3num" width="15px" height="30px" mathbackground="blue"/> - <mspace id="frac3den" width="15px" height="15px" mathbackground="green"/> + <mspace id="frac3num" width="15px" height="30px" style="background: blue"/> + <mspace id="frac3den" width="15px" height="15px" style="background: green"/> </mfrac> <mfrac id="frac4"> - <mspace id="frac4num" width="15px" height="15px" mathbackground="blue"/> - <mspace id="frac4den" width="15px" height="30px" mathbackground="green"/> + <mspace id="frac4num" width="15px" height="15px" style="background: blue"/> + <mspace id="frac4den" width="15px" height="30px" style="background: green"/> </mfrac> <mfrac id="frac5" linethickness="0px"> - <mspace id="frac5num" width="15px" height="15px" mathbackground="blue"/> - <mspace id="frac5den" width="15px" height="15px" mathbackground="green"/> + <mspace id="frac5num" width="15px" height="15px" style="background: blue"/> + <mspace id="frac5den" width="15px" height="15px" style="background: green"/> </mfrac> <mfrac id="frac6" linethickness="0px"> - <mspace id="frac6num" width="30px" height="15px" mathbackground="blue"/> - <mspace id="frac6den" width="15px" height="15px" mathbackground="green"/> + <mspace id="frac6num" width="30px" height="15px" style="background: blue"/> + <mspace id="frac6den" width="15px" height="15px" style="background: green"/> </mfrac> <mfrac id="frac7" linethickness="0px"> - <mspace id="frac7num" width="15px" height="15px" mathbackground="blue"/> - <mspace id="frac7den" width="30px" height="15px" mathbackground="green"/> + <mspace id="frac7num" width="15px" height="15px" style="background: blue"/> + <mspace id="frac7den" width="30px" height="15px" style="background: green"/> </mfrac> <mfrac id="frac8" linethickness="0px"> - <mspace id="frac8num" width="15px" height="30px" mathbackground="blue"/> - <mspace id="frac8den" width="15px" height="15px" mathbackground="green"/> + <mspace id="frac8num" width="15px" height="30px" style="background: blue"/> + <mspace id="frac8den" width="15px" height="15px" style="background: green"/> </mfrac> <mfrac id="frac9" linethickness="0px"> - <mspace id="frac9num" width="15px" height="15px" mathbackground="blue"/> - <mspace id="frac9den" width="15px" height="30px" mathbackground="green"/> + <mspace id="frac9num" width="15px" height="15px" style="background: blue"/> + <mspace id="frac9den" width="15px" height="30px" style="background: green"/> </mfrac> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-1.html index a047a30..1c20b9d 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-1.html
@@ -135,9 +135,9 @@ <body> <p> <math style="font-family: axisheight7000-rulethickness1000;"> - <mspace id="ref0001" depth="1em" width="3em" mathbackground="green"/> + <mspace id="ref0001" depth="1em" width="3em" style="background: green"/> <mfrac> - <mspace width="3em" height="1em" id="num0001" mathbackground="blue"/> + <mspace width="3em" height="1em" id="num0001" style="background: blue"/> <mspace width="3em"/> </mfrac> </math> @@ -146,20 +146,20 @@ <p> <math display="block" style="font-family: denominatordisplaystylegapmin5000-rulethickness1000;"> <mspace id="ref0002" width="3em" - height=".5em" depth=".5em" mathbackground="green"/> + height=".5em" depth=".5em" style="background: green"/> <mfrac> <mspace width="3em"/> - <mspace width="3em" height="1em" id="den0002" mathbackground="blue"/> + <mspace width="3em" height="1em" id="den0002" style="background: blue"/> </mfrac> </math> </p> <hr/> <p> <math display="block" style="font-family: denominatordisplaystyleshiftdown6000-rulethickness1000;"> - <mspace id="ref0003" width="3em" height="1em" mathbackground="green"/> + <mspace id="ref0003" width="3em" height="1em" style="background: green"/> <mfrac> <mspace width="3em"/> - <mspace width="3em" depth="1em" id="den0003" mathbackground="blue"/> + <mspace width="3em" depth="1em" id="den0003" style="background: blue"/> </mfrac> </math> </p> @@ -167,20 +167,20 @@ <p> <math style="font-family: denominatorgapmin4000-rulethickness1000;"> <mspace id="ref0004" width="3em" - height=".5em" depth=".5em" mathbackground="green"/> + height=".5em" depth=".5em" style="background: green"/> <mfrac> <mspace width="3em"/> - <mspace width="3em" height="1em" id="den0004" mathbackground="blue"/> + <mspace width="3em" height="1em" id="den0004" style="background: blue"/> </mfrac> </math> </p> <hr/> <p> <math style="font-family: denominatorshiftdown3000-rulethickness1000;"> - <mspace id="ref0005" width="3em" height="1em" mathbackground="green"/> + <mspace id="ref0005" width="3em" height="1em" style="background: green"/> <mfrac> <mspace width="3em"/> - <mspace width="3em" depth="1em" id="den0005" mathbackground="blue"/> + <mspace width="3em" depth="1em" id="den0005" style="background: blue"/> </mfrac> </math> </p> @@ -188,9 +188,9 @@ <p> <math display="block" style="font-family: numeratordisplaystylegapmin8000-rulethickness1000;"> <mspace id="ref0006" width="3em" - height=".5em" depth=".5em" mathbackground="green"/> + height=".5em" depth=".5em" style="background: green"/> <mfrac> - <mspace width="3em" depth="1em" id="num0006" mathbackground="blue"/> + <mspace width="3em" depth="1em" id="num0006" style="background: blue"/> <mspace width="3em"/> </mfrac> </math> @@ -199,9 +199,9 @@ <p> <math display="block" style="font-family: numeratordisplaystyleshiftup2000-rulethickness1000;"> <mspace id="ref0007" width="3em" - depth="1em" mathbackground="green"/> + depth="1em" style="background: green"/> <mfrac> - <mspace width="3em" height="1em" id="num0007" mathbackground="blue"/> + <mspace width="3em" height="1em" id="num0007" style="background: blue"/> <mspace width="3em"/> </mfrac> </math> @@ -210,9 +210,9 @@ <p> <math style="font-family: numeratorgapmin9000-rulethickness1000;"> <mspace id="ref0008" width="3em" - height=".5em" depth=".5em" mathbackground="green"/> + height=".5em" depth=".5em" style="background: green"/> <mfrac> - <mspace width="3em" depth="1em" id="num0008" mathbackground="blue"/> + <mspace width="3em" depth="1em" id="num0008" style="background: blue"/> <mspace width="3em"/> </mfrac> </math> @@ -221,9 +221,9 @@ <p> <math style="font-family: numeratorshiftup11000-rulethickness1000;"> <mspace id="ref0009" width="3em" - depth="1em" mathbackground="green"/> + depth="1em" style="background: green"/> <mfrac> - <mspace width="3em" height="1em" id="num0009" mathbackground="blue"/> + <mspace width="3em" height="1em" id="num0009" style="background: blue"/> <mspace width="3em"/> </mfrac> </math> @@ -232,8 +232,8 @@ <p> <math style="font-family: rulethickness10000"> <mfrac> - <mspace width="3em" height="1em" id="num0010" mathbackground="blue"/> - <mspace width="3em" depth="1em" id="den0010" mathbackground="green"/> + <mspace width="3em" height="1em" id="num0010" style="background: blue"/> + <mspace width="3em" depth="1em" id="den0010" style="background: green"/> </mfrac> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-2.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-2.html index 5445113..bc9fb364 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-2.html
@@ -104,9 +104,9 @@ <body> <p> <math style="font-family: axisheight7000;"> - <mspace id="ref0001" depth="1em" width="3em" mathbackground="green"/> + <mspace id="ref0001" depth="1em" width="3em" style="background: green"/> <mfrac linethickness="0px"> - <mspace width="3em" height="1em" id="num0001" mathbackground="blue"/> + <mspace width="3em" height="1em" id="num0001" style="background: blue"/> <mspace width="3em"/> </mfrac> </math> @@ -114,20 +114,20 @@ <hr/> <p> <math display="block" style="font-family: bottomdisplaystyleshiftdown5000;"> - <mspace id="ref0002" width="3em" height="1em" mathbackground="green"/> + <mspace id="ref0002" width="3em" height="1em" style="background: green"/> <mfrac linethickness="0px"> <mspace width="3em"/> - <mspace width="3em" depth="1em" id="den0002" mathbackground="blue"/> + <mspace width="3em" depth="1em" id="den0002" style="background: blue"/> </mfrac> </math> </p> <hr/> <p> <math style="font-family: bottomshiftdown6000;"> - <mspace id="ref0003" width="3em" height="1em" mathbackground="green"/> + <mspace id="ref0003" width="3em" height="1em" style="background: green"/> <mfrac linethickness="0px"> <mspace width="3em"/> - <mspace width="3em" depth="1em" id="den0003" mathbackground="blue"/> + <mspace width="3em" depth="1em" id="den0003" style="background: blue"/> </mfrac> </math> </p> @@ -135,8 +135,8 @@ <p> <math display="block" style="font-family: displaystylegapmin4000;"> <mfrac linethickness="0px"> - <mspace width="3em" height="1em" id="num0004" mathbackground="blue"/> - <mspace width="3em" depth="1em" id="den0004" mathbackground="green"/> + <mspace width="3em" height="1em" id="num0004" style="background: blue"/> + <mspace width="3em" depth="1em" id="den0004" style="background: green"/> </mfrac> </math> </p> @@ -144,17 +144,17 @@ <p> <math style="font-family: gapmin8000;"> <mfrac linethickness="0px"> - <mspace width="3em" height="1em" id="num0005" mathbackground="blue"/> - <mspace width="3em" depth="1em" id="den0005" mathbackground="green"/> + <mspace width="3em" height="1em" id="num0005" style="background: blue"/> + <mspace width="3em" depth="1em" id="den0005" style="background: green"/> </mfrac> </math> </p> <hr/> <p> <math display="block" style="font-family: topdisplaystyleshiftup3000;"> - <mspace id="ref0006" width="3em" depth="1em" mathbackground="green"/> + <mspace id="ref0006" width="3em" depth="1em" style="background: green"/> <mfrac linethickness="0px"> - <mspace width="3em" height="1em" id="num0006" mathbackground="blue"/> + <mspace width="3em" height="1em" id="num0006" style="background: blue"/> <mspace width="3em"/> </mfrac> </math> @@ -162,9 +162,9 @@ <hr/> <p> <math style="font-family: topshiftup9000;"> - <mspace id="ref0007" width="3em" depth="1em" mathbackground="green"/> + <mspace id="ref0007" width="3em" depth="1em" style="background: green"/> <mfrac linethickness="0px"> - <mspace width="3em" height="1em" id="num0007" mathbackground="blue"/> + <mspace width="3em" height="1em" id="num0007" style="background: blue"/> <mspace width="3em"/> </mfrac> </math>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-axis-height-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-axis-height-1.html index 327a72e..e409f98 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-axis-height-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-axis-height-1.html
@@ -58,18 +58,18 @@ <p> <math style="font-family: axisheight5000-verticalarrow14000;"> <mrow> - <mspace id="baseline1" mathbackground="blue" width="50px" height="1px"/> - <mpadded voffset="50px"><mspace mathbackground="cyan" width="50px" height="1px"/></mpadded> - <mo id="mo1" symmetric="true" mathcolor="green">↨</mo> - <mspace mathbackground="gray" width="10px" height="50px"/> + <mspace id="baseline1" style="background: blue" width="50px" height="1px"/> + <mpadded voffset="50px"><mspace style="background: cyan" width="50px" height="1px"/></mpadded> + <mo id="mo1" symmetric="true" style="color: green">↨</mo> + <mspace style="background: gray" width="10px" height="50px"/> </mrow> </math> <math style="font-family: axisheight5000-verticalarrow14000;"> <mrow> - <mspace id="baseline2" mathbackground="blue" width="50px" height="1px"/> - <mpadded voffset="50px"><mspace mathbackground="cyan" width="50px" height="1px"/></mpadded> - <mo id="mo2" symmetric="true" mathcolor="green">↨</mo> - <mspace id="target2" mathbackground="gray" width="10px" height="200px"/> + <mspace id="baseline2" style="background: blue" width="50px" height="1px"/> + <mpadded voffset="50px"><mspace style="background: cyan" width="50px" height="1px"/></mpadded> + <mo id="mo2" symmetric="true" style="color: green">↨</mo> + <mspace id="target2" style="background: gray" width="10px" height="200px"/> </mrow> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/radicals/root-parameters-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/radicals/root-parameters-1.html index 67a4613..4fc6e6f 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/radicals/root-parameters-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/radicals/root-parameters-1.html
@@ -131,10 +131,10 @@ <body> <p> <math style="font-family: degreebottomraisepercent25-rulethickness1000;"> - <mspace id="ref001" width="3em" depth="1em" mathbackground="green"/> + <mspace id="ref001" width="3em" depth="1em" style="background: green"/> <mroot> - <mspace id="base001" width="3em" height="10em" mathbackground="green"/> - <mspace id="index001" width="3em" height="1em" mathbackground="blue"/> + <mspace id="base001" width="3em" height="10em" style="background: green"/> + <mspace id="index001" width="3em" height="1em" style="background: blue"/> </mroot> </math> </p> @@ -142,24 +142,24 @@ <p> <math display="block" style="font-family: displaystyleverticalgap7000-rulethickness1000;"> - <msqrt mathbackground="green" id="radical0021"> - <mspace id="base0021" width="3em" height="1em" mathbackground="blue"/> + <msqrt style="background: green" id="radical0021"> + <mspace id="base0021" width="3em" height="1em" style="background: blue"/> </msqrt> - <mroot mathbackground="green" id="radical0022"> - <mspace id="base0022" width="3em" height="1em" mathbackground="blue"/> - <mspace width="3em" height="1em" mathbackground="black"/> + <mroot style="background: green" id="radical0022"> + <mspace id="base0022" width="3em" height="1em" style="background: blue"/> + <mspace width="3em" height="1em" style="background: black"/> </mroot> </math> </p> <hr/> <p> <math style="font-family: extraascender3000-rulethickness1000;"> - <msqrt mathbackground="green" id="radical0031"> - <mspace id="base0031" width="3em" height="1em" mathbackground="blue"/> + <msqrt style="background: green" id="radical0031"> + <mspace id="base0031" width="3em" height="1em" style="background: blue"/> </msqrt> - <mroot mathbackground="green" id="radical0032"> - <mspace id="base0032" width="3em" height="1em" mathbackground="blue"/> - <mspace width="3em" height="1em" mathbackground="black"/> + <mroot style="background: green" id="radical0032"> + <mspace id="base0032" width="3em" height="1em" style="background: blue"/> + <mspace width="3em" height="1em" style="background: black"/> </mroot> </math> </p> @@ -167,40 +167,40 @@ <p> <math style="font-family: kernafterdegreeminus5000-rulethickness1000;"> <mroot> - <mspace id="base004" width="3em" height="2em" mathbackground="blue"/> - <mspace id="index004" width="7em" height="1em" mathbackground="green"/> + <mspace id="base004" width="3em" height="2em" style="background: blue"/> + <mspace id="index004" width="7em" height="1em" style="background: green"/> </mroot> </math> </p> <hr/> <p> <math style="font-family: kernbeforedegree4000-rulethickness1000;"> - <mroot id="radical005" mathbackground="blue"> + <mroot id="radical005" style="background: blue"> <mspace width="3em" height="1em"/> - <mspace id="index005" width="3em" height="1em" mathbackground="green"/> + <mspace id="index005" width="3em" height="1em" style="background: green"/> </mroot> </math> </p> <hr/> <p> <math style="font-family: rulethickness8000;"> - <msqrt mathbackground="green" id="radical0061"> - <mspace id="base0061" width="3em" height="1em" mathbackground="blue"/> + <msqrt style="background: green" id="radical0061"> + <mspace id="base0061" width="3em" height="1em" style="background: blue"/> </msqrt> - <mroot mathbackground="green" id="radical0062"> - <mspace id="base0062" width="3em" height="1em" mathbackground="blue"/> - <mspace width="3em" height="1em" mathbackground="black"/> + <mroot style="background: green" id="radical0062"> + <mspace id="base0062" width="3em" height="1em" style="background: blue"/> + <mspace width="3em" height="1em" style="background: black"/> </mroot> </math> </p> <p> <math style="font-family: verticalgap6000-rulethickness1000;"> - <msqrt mathbackground="green" id="radical0071"> - <mspace id="base0071" width="3em" height="1em" mathbackground="blue"/> + <msqrt style="background: green" id="radical0071"> + <mspace id="base0071" width="3em" height="1em" style="background: blue"/> </msqrt> - <mroot mathbackground="green" id="radical0072"> - <mspace id="base0072" width="3em" height="1em" mathbackground="blue"/> - <mspace width="3em" height="1em" mathbackground="black"/> + <mroot style="background: green" id="radical0072"> + <mspace id="base0072" width="3em" height="1em" style="background: blue"/> + <mspace width="3em" height="1em" style="background: black"/> </mroot> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-1.html index 2ff14a6..026cfa3 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-1.html
@@ -83,19 +83,19 @@ <body> <p> <math> - <mspace id="baseline" width="30px" height="2px" depth="0px" mathbackground="blue"/> - <msub id="msub" mathbackground="green"> - <mspace id="msubBase" width="30px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="msubSub" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="baseline" width="30px" height="2px" depth="0px" style="background: blue"/> + <msub id="msub" style="background: green"> + <mspace id="msubBase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msubSub" width="10px" height="5px" depth="5px" style="background: black"/> </msub> - <msup id="msup" mathbackground="blue"> - <mspace id="msupBase" width="30px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="msupSup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <msup id="msup" style="background: blue"> + <mspace id="msupBase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msupSup" width="10px" height="5px" depth="5px" style="background: black"/> </msup> - <msubsup id="msubsup" mathbackground="green"> - <mspace id="msubsupBase" width="30px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="msubsupSub" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="msubsupSup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <msubsup id="msubsup" style="background: green"> + <mspace id="msubsupBase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msubsupSub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="msubsupSup" width="10px" height="5px" depth="5px" style="background: black"/> </msubsup> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-2.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-2.html index abef28d..8f62d92 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-2.html
@@ -122,39 +122,39 @@ <body> <p> <math> - <mspace id="baseline" width="30px" height="2px" depth="0px" mathbackground="blue"/> - <mmultiscripts id="msub" mathbackground="green"> - <mspace id="msubBase" width="30px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="msubSub" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="baseline" width="30px" height="2px" depth="0px" style="background: blue"/> + <mmultiscripts id="msub" style="background: green"> + <mspace id="msubBase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msubSub" width="10px" height="5px" depth="5px" style="background: black"/> <none/> </mmultiscripts> - <mmultiscripts id="msup" mathbackground="green"> - <mspace id="msupBase" width="30px" height="15px" depth="15px" mathbackground="black"/> + <mmultiscripts id="msup" style="background: green"> + <mspace id="msupBase" width="30px" height="15px" depth="15px" style="background: black"/> <none/> - <mspace id="msupSup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="msupSup" width="10px" height="5px" depth="5px" style="background: black"/> </mmultiscripts> - <mmultiscripts id="msubsup" mathbackground="green"> - <mspace id="msubsupBase" width="30px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="msubsupSub" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="msubsupSup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mmultiscripts id="msubsup" style="background: green"> + <mspace id="msubsupBase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msubsupSub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="msubsupSup" width="10px" height="5px" depth="5px" style="background: black"/> </mmultiscripts> - <mmultiscripts id="premsub" mathbackground="green"> - <mspace id="premsubBase" width="30px" height="15px" depth="15px" mathbackground="black"/> + <mmultiscripts id="premsub" style="background: green"> + <mspace id="premsubBase" width="30px" height="15px" depth="15px" style="background: black"/> <mprescripts/> - <mspace id="premsubSub" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="premsubSub" width="10px" height="5px" depth="5px" style="background: black"/> <none/> </mmultiscripts> - <mmultiscripts id="premsup" mathbackground="green"> - <mspace id="premsupBase" width="30px" height="15px" depth="15px" mathbackground="black"/> + <mmultiscripts id="premsup" style="background: green"> + <mspace id="premsupBase" width="30px" height="15px" depth="15px" style="background: black"/> <mprescripts/> <none/> - <mspace id="premsupSup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="premsupSup" width="10px" height="5px" depth="5px" style="background: black"/> </mmultiscripts> - <mmultiscripts id="premsubsup" mathbackground="green"> - <mspace id="premsubsupBase" width="30px" height="15px" depth="15px" mathbackground="black"/> + <mmultiscripts id="premsubsup" style="background: green"> + <mspace id="premsubsupBase" width="30px" height="15px" depth="15px" style="background: black"/> <mprescripts/> - <mspace id="premsubsupSub" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="premsubsupSup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="premsubsupSub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="premsubsupSup" width="10px" height="5px" depth="5px" style="background: black"/> </mmultiscripts> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-3.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-3.html index c497189..18ede400 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-3.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-3.html
@@ -109,69 +109,69 @@ <body> <p> <math> - <mspace id="baseline" width="30px" height="2px" depth="0px" mathbackground="blue"/> - <mmultiscripts id="multi0" mathbackground="green"> - <mspace id="multi0base" width="30px" height="15px" depth="15px" mathbackground="black"/> + <mspace id="baseline" width="30px" height="2px" depth="0px" style="background: blue"/> + <mmultiscripts id="multi0" style="background: green"> + <mspace id="multi0base" width="30px" height="15px" depth="15px" style="background: black"/> </mmultiscripts> - <mmultiscripts id="multi1" mathbackground="green"> - <mspace id="multi1base" width="30px" height="15px" depth="15px" mathbackground="black"/> + <mmultiscripts id="multi1" style="background: green"> + <mspace id="multi1base" width="30px" height="15px" depth="15px" style="background: black"/> <mprescripts/> </mmultiscripts> - <mmultiscripts id="multi2" mathbackground="green"> - <mspace id="multi2base" width="30px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="multi2postsub1" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi2postsup1" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mmultiscripts id="multi2" style="background: green"> + <mspace id="multi2base" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="multi2postsub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi2postsup1" width="10px" height="5px" depth="5px" style="background: black"/> <mprescripts/> - <mspace id="multi2presub1" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi2presup1" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="multi2presub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi2presup1" width="10px" height="5px" depth="5px" style="background: black"/> </mmultiscripts> - <mmultiscripts id="multi3" mathbackground="green"> - <mspace id="multi3base" width="30px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="multi3postsub1" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi3postsup1" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi3postsub2" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi3postsup2" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mmultiscripts id="multi3" style="background: green"> + <mspace id="multi3base" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="multi3postsub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi3postsup1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi3postsub2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi3postsup2" width="10px" height="5px" depth="5px" style="background: black"/> <mprescripts/> - <mspace id="multi3presub1" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi3presup1" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi3presub2" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi3presup2" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="multi3presub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi3presup1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi3presub2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi3presup2" width="10px" height="5px" depth="5px" style="background: black"/> </mmultiscripts> - <mmultiscripts id="multi4" mathbackground="green"> - <mspace id="multi4base" width="30px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="multi4postsub1" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi4postsup1" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi4postsub2" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi4postsup2" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi4postsub3" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi4postsup3" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mmultiscripts id="multi4" style="background: green"> + <mspace id="multi4base" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="multi4postsub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4postsup1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4postsub2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4postsup2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4postsub3" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4postsup3" width="10px" height="5px" depth="5px" style="background: black"/> <mprescripts/> - <mspace id="multi4presub1" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi4presup1" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi4presub2" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi4presup2" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi4presub3" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi4presup3" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="multi4presub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4presup1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4presub2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4presup2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4presub3" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4presup3" width="10px" height="5px" depth="5px" style="background: black"/> </mmultiscripts> - <mmultiscripts id="multi5" mathbackground="green"> - <mspace id="multi5base" width="30px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="multi5postsub1" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi5postsup1" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi5postsub2" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi5postsup2" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi5postsub3" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi5postsup3" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi5postsub4" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi5postsup4" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mmultiscripts id="multi5" style="background: green"> + <mspace id="multi5base" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="multi5postsub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5postsup1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5postsub2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5postsup2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5postsub3" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5postsup3" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5postsub4" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5postsup4" width="10px" height="5px" depth="5px" style="background: black"/> <mprescripts/> - <mspace id="multi5presub1" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi5presup1" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi5presub2" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi5presup2" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi5presub3" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi5presup3" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi5presub4" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi5presup4" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="multi5presub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5presup1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5presub2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5presup2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5presub3" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5presup3" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5presub4" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5presup4" width="10px" height="5px" depth="5px" style="background: black"/> </mmultiscripts> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-4.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-4.html index 2acc774..44a2ff4 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-4.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-4.html
@@ -53,69 +53,69 @@ <body> <p> <math> - <mspace id="baseline" width="30px" height="2px" depth="0px" mathbackground="blue"/> + <mspace id="baseline" width="30px" height="2px" depth="0px" style="background: blue"/> <msub id="msub50"> - <mspace id="msub50base" width="30px" height="50px" depth="50px" mathbackground="black"/> - <mspace id="msub50sub" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="msub50base" width="30px" height="50px" depth="50px" style="background: black"/> + <mspace id="msub50sub" width="10px" height="5px" depth="5px" style="background: black"/> </msub> <msup id="msup50"> - <mspace id="msup50base" width="30px" height="50px" depth="50px" mathbackground="black"/> - <mspace id="msup50sup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="msup50base" width="30px" height="50px" depth="50px" style="background: black"/> + <mspace id="msup50sup" width="10px" height="5px" depth="5px" style="background: black"/> </msup> <msubsup id="msubsup50"> - <mspace id="msubsup50base" width="30px" height="50px" depth="50px" mathbackground="black"/> - <mspace id="msubsup50sub" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="msubsup50sup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="msubsup50base" width="30px" height="50px" depth="50px" style="background: black"/> + <mspace id="msubsup50sub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="msubsup50sup" width="10px" height="5px" depth="5px" style="background: black"/> </msubsup> <mmultiscripts id="multi50"> - <mspace id="multi50base" width="30px" height="50px" depth="50px" mathbackground="black"/> - <mspace id="multi50postsub" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi50postsup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="multi50base" width="30px" height="50px" depth="50px" style="background: black"/> + <mspace id="multi50postsub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi50postsup" width="10px" height="5px" depth="5px" style="background: black"/> <mprescripts/> - <mspace id="multi50presub" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi50presup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="multi50presub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi50presup" width="10px" height="5px" depth="5px" style="background: black"/> </mmultiscripts> <msub id="msub75"> - <mspace id="msub75base" width="30px" height="75px" depth="75px" mathbackground="black"/> - <mspace id="msub75sub" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="msub75base" width="30px" height="75px" depth="75px" style="background: black"/> + <mspace id="msub75sub" width="10px" height="5px" depth="5px" style="background: black"/> </msub> <msup id="msup75"> - <mspace id="msup75base" width="30px" height="75px" depth="75px" mathbackground="black"/> - <mspace id="msup75sup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="msup75base" width="30px" height="75px" depth="75px" style="background: black"/> + <mspace id="msup75sup" width="10px" height="5px" depth="5px" style="background: black"/> </msup> <msubsup id="msubsup75"> - <mspace id="msubsup75base" width="30px" height="75px" depth="75px" mathbackground="black"/> - <mspace id="msubsup75sub" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="msubsup75sup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="msubsup75base" width="30px" height="75px" depth="75px" style="background: black"/> + <mspace id="msubsup75sub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="msubsup75sup" width="10px" height="5px" depth="5px" style="background: black"/> </msubsup> <mmultiscripts id="multi75"> - <mspace id="multi75base" width="30px" height="75px" depth="75px" mathbackground="black"/> - <mspace id="multi75postsub" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi75postsup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="multi75base" width="30px" height="75px" depth="75px" style="background: black"/> + <mspace id="multi75postsub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi75postsup" width="10px" height="5px" depth="5px" style="background: black"/> <mprescripts/> - <mspace id="multi75presub" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi75presub" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="multi75presub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi75presub" width="10px" height="5px" depth="5px" style="background: black"/> </mmultiscripts> <msub id="msub100"> - <mspace id="msub100base" width="30px" height="100px" depth="100px" mathbackground="black"/> - <mspace id="msub100sub" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="msub100base" width="30px" height="100px" depth="100px" style="background: black"/> + <mspace id="msub100sub" width="10px" height="5px" depth="5px" style="background: black"/> </msub> <msup id="msup100"> - <mspace id="msup100base" width="30px" height="100px" depth="100px" mathbackground="black"/> - <mspace id="msup100sup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="msup100base" width="30px" height="100px" depth="100px" style="background: black"/> + <mspace id="msup100sup" width="10px" height="5px" depth="5px" style="background: black"/> </msup> <msubsup id="msubsup100"> - <mspace id="msubsup100base" width="30px" height="100px" depth="100px" mathbackground="black"/> - <mspace id="msubsup100sub" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="msubsup100sup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="msubsup100base" width="30px" height="100px" depth="100px" style="background: black"/> + <mspace id="msubsup100sub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="msubsup100sup" width="10px" height="5px" depth="5px" style="background: black"/> </msubsup> <mmultiscripts id="multi100"> - <mspace id="multi100base" width="30px" height="100px" depth="100px" mathbackground="black"/> - <mspace id="multi100postsub" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi100postsup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="multi100base" width="30px" height="100px" depth="100px" style="background: black"/> + <mspace id="multi100postsub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi100postsup" width="10px" height="5px" depth="5px" style="background: black"/> <mprescripts/> - <mspace id="multi100presub" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="multi100presup" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="multi100presub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi100presup" width="10px" height="5px" depth="5px" style="background: black"/> </mmultiscripts> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-5.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-5.html index 19b6eee66..a1fd0c0 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-5.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-5.html
@@ -61,27 +61,27 @@ <body> <p> <math> - <mspace id="baseline" width="30px" height="2px" depth="0px" mathbackground="blue"/> + <mspace id="baseline" width="30px" height="2px" depth="0px" style="background: blue"/> <msub id="msub"> - <mspace id="msubbase" width="30px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="msubsub" width="10px" height="50px" depth="50px" mathbackground="black"/> + <mspace id="msubbase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msubsub" width="10px" height="50px" depth="50px" style="background: black"/> </msub> <msup id="msup"> - <mspace id="msupbase" width="30px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="msupsup" width="10px" height="75px" depth="75px" mathbackground="black"/> + <mspace id="msupbase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msupsup" width="10px" height="75px" depth="75px" style="background: black"/> </msup> <msubsup id="msubsup"> - <mspace id="msubsupbase" width="30px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="msubsupsub" width="10px" height="50px" depth="50px" mathbackground="black"/> - <mspace id="msubsupsup" width="10px" height="75px" depth="75px" mathbackground="black"/> + <mspace id="msubsupbase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msubsupsub" width="10px" height="50px" depth="50px" style="background: black"/> + <mspace id="msubsupsup" width="10px" height="75px" depth="75px" style="background: black"/> </msubsup> <mmultiscripts id="multi"> - <mspace id="multibase" width="30px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="multipostsub" width="10px" height="50px" depth="50px" mathbackground="black"/> - <mspace id="multipostsup" width="10px" height="75px" depth="75px" mathbackground="black"/> + <mspace id="multibase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="multipostsub" width="10px" height="50px" depth="50px" style="background: black"/> + <mspace id="multipostsup" width="10px" height="75px" depth="75px" style="background: black"/> <mprescripts/> - <mspace id="multipresub" width="10px" height="50px" depth="50px" mathbackground="black"/> - <mspace id="multipresup" width="10px" height="75px" depth="75px" mathbackground="black"/> + <mspace id="multipresub" width="10px" height="50px" depth="50px" style="background: black"/> + <mspace id="multipresup" width="10px" height="75px" depth="75px" style="background: black"/> </mmultiscripts> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-1.html index 9bc6bcb..23e65c1 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-1.html
@@ -146,60 +146,60 @@ <p> <math style="font-family: spaceafterscript3000;"> <msub> - <mspace height="2em" width="2em" mathbackground="blue"/> - <mspace id="sub001" height="1em" width="1em" mathbackground="red"/> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sub001" height="1em" width="1em" style="background: red"/> </msub> - <mspace id="ref001" height="1em" width="1em" mathbackground="green"/> + <mspace id="ref001" height="1em" width="1em" style="background: green"/> </math> <math style="font-family: spaceafterscript3000;"> <msup> - <mspace height="2em" width="2em" mathbackground="blue"/> - <mspace id="sup002" height="1em" width="1em" mathbackground="red"/> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sup002" height="1em" width="1em" style="background: red"/> </msup> - <mspace id="ref002" height="1em" width="1em" mathbackground="green"/> + <mspace id="ref002" height="1em" width="1em" style="background: green"/> </math> <math style="font-family: spaceafterscript3000;"> <msubsup> - <mspace height="2em" width="2em" mathbackground="blue"/> + <mspace height="2em" width="2em" style="background: blue"/> <mspace/> - <mspace id="sup003" height="1em" width="1em" mathbackground="red"/> + <mspace id="sup003" height="1em" width="1em" style="background: red"/> </msubsup> - <mspace id="ref003" height="1em" width="1em" mathbackground="green"/> + <mspace id="ref003" height="1em" width="1em" style="background: green"/> </math> <math style="font-family: spaceafterscript3000;"> <mmultiscripts> - <mspace height="2em" width="2em" mathbackground="blue"/> + <mspace height="2em" width="2em" style="background: blue"/> <none/> - <mspace id="sup0041" height="1em" width="1em" mathbackground="red"/> + <mspace id="sup0041" height="1em" width="1em" style="background: red"/> <none/> - <mspace id="sup0042" height="1em" width="1em" mathbackground="red"/> + <mspace id="sup0042" height="1em" width="1em" style="background: red"/> <none/> - <mspace id="sup0043" height="1em" width="1em" mathbackground="red"/> + <mspace id="sup0043" height="1em" width="1em" style="background: red"/> </mmultiscripts> - <mspace id="ref004" height="1em" width="1em" mathbackground="green"/> + <mspace id="ref004" height="1em" width="1em" style="background: green"/> </math> </p> <hr/> <p> <math style="font-family: superscriptshiftup7000;"> - <mspace id="ref101" height="1em" width="1em" mathbackground="green"/> + <mspace id="ref101" height="1em" width="1em" style="background: green"/> <msup> - <mspace height="2em" width="2em" mathbackground="blue"/> - <mspace id="sup102" height="1em" width="1em" mathbackground="red"/> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sup102" height="1em" width="1em" style="background: red"/> </msup> <msubsup> - <mspace height="2em" width="2em" mathbackground="blue"/> - <mspace height="1em" width="1em" mathbackground="red"/> - <mspace id="sup103" height="1em" width="1em" mathbackground="red"/> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace height="1em" width="1em" style="background: red"/> + <mspace id="sup103" height="1em" width="1em" style="background: red"/> </msubsup> <mmultiscripts> - <mspace height="2em" width="2em" mathbackground="blue"/> + <mspace height="2em" width="2em" style="background: blue"/> <none/> - <mspace id="sup1041" height="1em" width="1em" mathbackground="red"/> + <mspace id="sup1041" height="1em" width="1em" style="background: red"/> <none/> - <mspace id="sup1042" height="1em" width="1em" mathbackground="red"/> + <mspace id="sup1042" height="1em" width="1em" style="background: red"/> <none/> - <mspace id="sup1043" height="1em" width="1em" mathbackground="red"/> + <mspace id="sup1043" height="1em" width="1em" style="background: red"/> </mmultiscripts> </math> </p> @@ -207,24 +207,24 @@ <p> <math style="font-family: superscriptshiftupcramped5000;"> <msqrt> - <mspace id="ref201" height="1em" width="1em" mathbackground="green"/> + <mspace id="ref201" height="1em" width="1em" style="background: green"/> <msup> - <mspace height="2em" width="2em" mathbackground="blue"/> - <mspace id="sup202" height="1em" width="1em" mathbackground="red"/> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sup202" height="1em" width="1em" style="background: red"/> </msup> <msubsup> - <mspace height="2em" width="2em" mathbackground="blue"/> - <mspace height="1em" width="1em" mathbackground="blue"/> - <mspace id="sup203" height="1em" width="1em" mathbackground="red"/> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace height="1em" width="1em" style="background: blue"/> + <mspace id="sup203" height="1em" width="1em" style="background: red"/> </msubsup> <mmultiscripts> - <mspace height="2em" width="2em" mathbackground="blue"/> + <mspace height="2em" width="2em" style="background: blue"/> <none/> - <mspace id="sup2041" height="1em" width="1em" mathbackground="red"/> + <mspace id="sup2041" height="1em" width="1em" style="background: red"/> <none/> - <mspace id="sup2042" height="1em" width="1em" mathbackground="red"/> + <mspace id="sup2042" height="1em" width="1em" style="background: red"/> <none/> - <mspace id="sup2043" height="1em" width="1em" mathbackground="red"/> + <mspace id="sup2043" height="1em" width="1em" style="background: red"/> </mmultiscripts> </msqrt> </math> @@ -232,21 +232,21 @@ <hr/> <p> <math style="font-family: subscriptshiftdown6000;"> - <mspace id="ref300" height="1em" width="1em" mathbackground="green"/> + <mspace id="ref300" height="1em" width="1em" style="background: green"/> <msub> - <mspace height="2em" width="2em" mathbackground="blue"/> - <mspace id="sub301" height="1em" width="1em" mathbackground="red"/> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sub301" height="1em" width="1em" style="background: red"/> </msub> <msubsup> - <mspace height="2em" width="2em" mathbackground="blue"/> - <mspace id="sub302" height="1em" width="1em" mathbackground="red"/> - <mspace height="1em" width="1em" mathbackground="blue"/> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sub302" height="1em" width="1em" style="background: red"/> + <mspace height="1em" width="1em" style="background: blue"/> </msubsup> <mmultiscripts> - <mspace height="2em" width="2em" mathbackground="blue"/> - <mspace id="sub303" height="1em" width="1em" mathbackground="red"/> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sub303" height="1em" width="1em" style="background: red"/> <none/> - <mspace id="sub304" height="1em" width="1em" mathbackground="red"/> + <mspace id="sub304" height="1em" width="1em" style="background: red"/> <none/> </mmultiscripts> </math> @@ -255,34 +255,34 @@ <p> <math style="font-family: subsuperscriptgapmin11000;"> <msubsup> - <mspace height="2em" width="2em" mathbackground="blue"/> - <mspace id="sub4011" height="1em" width="1em" mathbackground="red"/> - <mspace id="sup4012" height="1em" width="1em" mathbackground="red"/> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sub4011" height="1em" width="1em" style="background: red"/> + <mspace id="sup4012" height="1em" width="1em" style="background: red"/> </msubsup> <mmultiscripts> - <mspace height="2em" width="2em" mathbackground="blue"/> + <mspace height="2em" width="2em" style="background: blue"/> <none/> <none/> - <mspace id="sub4021" height="1em" width="1em" mathbackground="red"/> - <mspace id="sup4022" height="1em" width="1em" mathbackground="red"/> + <mspace id="sub4021" height="1em" width="1em" style="background: red"/> + <mspace id="sup4022" height="1em" width="1em" style="background: red"/> </mmultiscripts> </math> </p> <hr/> <p> <math style="font-family: subsuperscriptgapmin11000superscriptbottommaxwithsubscript3000;"> - <mspace id="ref500" height="1em" width="1em" mathbackground="green"/> + <mspace id="ref500" height="1em" width="1em" style="background: green"/> <msubsup> - <mspace height="2em" width="2em" mathbackground="blue"/> - <mspace id="sub501" height="1em" width="1em" mathbackground="red"/> - <mspace id="sup501" height="1em" width="1em" mathbackground="red"/> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sub501" height="1em" width="1em" style="background: red"/> + <mspace id="sup501" height="1em" width="1em" style="background: red"/> </msubsup> <mmultiscripts> - <mspace height="2em" width="2em" mathbackground="blue"/> + <mspace height="2em" width="2em" style="background: blue"/> <none/> <none/> - <mspace id="sub502" height="1em" width="1em" mathbackground="red"/> - <mspace id="sup502" height="1em" width="1em" mathbackground="red"/> + <mspace id="sub502" height="1em" width="1em" style="background: red"/> + <mspace id="sup502" height="1em" width="1em" style="background: red"/> </mmultiscripts> </math> </p> @@ -290,11 +290,11 @@ <p> <math style="font-family: subscripttopmax4000;"> <mspace id="ref600" height="1em" - width="1em" mathbackground="green"/> + width="1em" style="background: green"/> <msub> - <mspace height="2em" width="2em" mathbackground="blue"/> + <mspace height="2em" width="2em" style="background: blue"/> <mspace id="sub601" height="10em" - width="1em" mathbackground="red"/> + width="1em" style="background: red"/> </msub> </math> </p> @@ -302,11 +302,11 @@ <p> <math style="font-family: superscriptbottommin8000;"> <mspace id="ref700" height="1em" - width="1em" mathbackground="green"/> + width="1em" style="background: green"/> <msup> - <mspace height="2em" width="2em" mathbackground="blue"/> + <mspace height="2em" width="2em" style="background: blue"/> <mspace id="sub701" depth="1em" - width="1em" mathbackground="red"/> + width="1em" style="background: red"/> </msup> </math> </p> @@ -314,9 +314,9 @@ <p> <math style="font-family: subscriptbaselinedropmin9000;"> <msub> - <mspace id="base801" height="2em" width="2em" mathbackground="blue"/> + <mspace id="base801" height="2em" width="2em" style="background: blue"/> <mspace id="sub801" height="1em" - width="1em" mathbackground="red"/> + width="1em" style="background: red"/> </msub> </math> </p> @@ -324,9 +324,9 @@ <p> <math style="font-family: superscriptbaselinedropmax10000;"> <msup> - <mspace id="base901" height="15em" width="2em" mathbackground="blue"/> + <mspace id="base901" height="15em" width="2em" style="background: blue"/> <mspace id="sup901" height="1em" - width="1em" mathbackground="red"/> + width="1em" style="background: red"/> </msup> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-2.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-2.html index eaa4f0f..5ba66b86 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-2.html
@@ -69,30 +69,30 @@ <math displaystyle="true" style="font-family: largeop-displayoperatorminheight5000;"> <msub> <mo id="base001" lspace="0px" rspace="0px">⫿</mo> - <mspace id="sub001" height="1em" width="1em" mathbackground="blue"/> + <mspace id="sub001" height="1em" width="1em" style="background: blue"/> </msub> </math> <math displaystyle="true" style="font-family: largeop-displayoperatorminheight5000;"> <msup> <mo id="base002" lspace="0px" rspace="0px">⫿</mo> - <mspace id="sup002" height="1em" width="1em" mathbackground="blue"/> + <mspace id="sup002" height="1em" width="1em" style="background: blue"/> </msup> </math> <math displaystyle="true" style="font-family: largeop-displayoperatorminheight5000;"> <msubsup> <mo lspace="0px" rspace="0px">⫿</mo> - <mspace id="sub003" height="1em" width="1em" mathbackground="blue"/> - <mspace id="sup003" height="1em" width="1em" mathbackground="green"/> + <mspace id="sub003" height="1em" width="1em" style="background: blue"/> + <mspace id="sup003" height="1em" width="1em" style="background: green"/> </msubsup> </math> <math displaystyle="true" style="font-family: largeop-displayoperatorminheight5000;"> <mmultiscripts> <mo lspace="0px" rspace="0px">⫿</mo> - <mspace id="sub004" height="1em" width="1em" mathbackground="blue"/> - <mspace id="sup004" height="1em" width="1em" mathbackground="green"/> + <mspace id="sub004" height="1em" width="1em" style="background: blue"/> + <mspace id="sup004" height="1em" width="1em" style="background: green"/> <mprescripts/> - <mspace id="sub005" height="1em" width="1em" mathbackground="magenta"/> - <mspace id="sup005" height="1em" width="1em" mathbackground="cyan"/> + <mspace id="sub005" height="1em" width="1em" style="background: magenta"/> + <mspace id="sup005" height="1em" width="1em" style="background: cyan"/> </mmultiscripts> </math> </p> @@ -101,30 +101,30 @@ <math displaystyle="true" style="font-family: largeop-displayoperatorminheight2000-2AFF-italiccorrection3000;"> <msub> <mo id="base011" lspace="0px" rspace="0px">⫿</mo> - <mspace id="sub011" height="1em" width="1em" mathbackground="blue"/> + <mspace id="sub011" height="1em" width="1em" style="background: blue"/> </msub> </math> <math displaystyle="true" style="font-family: largeop-displayoperatorminheight2000-2AFF-italiccorrection3000;"> <msup> <mo id="base012" lspace="0px" rspace="0px">⫿</mo> - <mspace id="sup012" height="1em" width="1em" mathbackground="blue"/> + <mspace id="sup012" height="1em" width="1em" style="background: blue"/> </msup> </math> <math displaystyle="true" style="font-family: largeop-displayoperatorminheight2000-2AFF-italiccorrection3000;"> <msubsup> <mo lspace="0px" rspace="0px">⫿</mo> - <mspace id="sub013" height="1em" width="1em" mathbackground="blue"/> - <mspace id="sup013" height="1em" width="1em" mathbackground="green"/> + <mspace id="sub013" height="1em" width="1em" style="background: blue"/> + <mspace id="sup013" height="1em" width="1em" style="background: green"/> </msubsup> </math> <math displaystyle="true" style="font-family: largeop-displayoperatorminheight2000-2AFF-italiccorrection3000;"> <mmultiscripts> <mo lspace="0px" rspace="0px">⫿</mo> - <mspace id="sub014" height="1em" width="1em" mathbackground="blue"/> - <mspace id="sup014" height="1em" width="1em" mathbackground="green"/> + <mspace id="sub014" height="1em" width="1em" style="background: blue"/> + <mspace id="sup014" height="1em" width="1em" style="background: green"/> <mprescripts/> - <mspace id="sub015" height="1em" width="1em" mathbackground="magenta"/> - <mspace id="sup015" height="1em" width="1em" mathbackground="cyan"/> + <mspace id="sub015" height="1em" width="1em" style="background: magenta"/> + <mspace id="sup015" height="1em" width="1em" style="background: cyan"/> </mmultiscripts> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-1.html index 6e039b9d..d355f11 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-1.html
@@ -91,68 +91,68 @@ <body> <p> <math> - <mspace id="baseline" width="30px" height="2px" depth="0px" mathbackground="blue"/> + <mspace id="baseline" width="30px" height="2px" depth="0px" style="background: blue"/> <munder id="under0"> - <mspace id="under0base" width="30px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="under0under" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="under0base" width="30px" height="5px" depth="5px" style="background: black"/> + <mspace id="under0under" width="10px" height="5px" depth="5px" style="background: black"/> </munder> <munder id="under1"> - <mspace id="under1base" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="under1under" width="30px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="under1base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="under1under" width="30px" height="5px" depth="5px" style="background: black"/> </munder> <munder id="under2"> - <mspace id="under2base" width="10px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="under2under" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="under2base" width="10px" height="15px" depth="15px" style="background: black"/> + <mspace id="under2under" width="10px" height="5px" depth="5px" style="background: black"/> </munder> <munder id="under3"> - <mspace id="under3base" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="under3under" width="10px" height="15px" depth="15px" mathbackground="black"/> + <mspace id="under3base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="under3under" width="10px" height="15px" depth="15px" style="background: black"/> </munder> <mover id="over0"> - <mspace id="over0base" width="30px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="over0over" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="over0base" width="30px" height="5px" depth="5px" style="background: black"/> + <mspace id="over0over" width="10px" height="5px" depth="5px" style="background: black"/> </mover> <mover id="over1"> - <mspace id="over1base" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="over1over" width="30px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="over1base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="over1over" width="30px" height="5px" depth="5px" style="background: black"/> </mover> <mover id="over2"> - <mspace id="over2base" width="10px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="over2over" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="over2base" width="10px" height="15px" depth="15px" style="background: black"/> + <mspace id="over2over" width="10px" height="5px" depth="5px" style="background: black"/> </mover> <mover id="over3"> - <mspace id="over3base" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="over3over" width="10px" height="15px" depth="15px" mathbackground="black"/> + <mspace id="over3base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="over3over" width="10px" height="15px" depth="15px" style="background: black"/> </mover> <munderover id="underover0"> - <mspace id="underover0base" width="30px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="underover0under" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="underover0over" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="underover0base" width="30px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover0under" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover0over" width="10px" height="5px" depth="5px" style="background: black"/> </munderover> <munderover id="underover1"> - <mspace id="underover1base" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="underover1under" width="30px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="underover1over" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="underover1base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover1under" width="30px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover1over" width="10px" height="5px" depth="5px" style="background: black"/> </munderover> <munderover id="underover2"> - <mspace id="underover2base" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="underover2under" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="underover2over" width="30px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="underover2base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover2under" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover2over" width="30px" height="5px" depth="5px" style="background: black"/> </munderover> <munderover id="underover3"> - <mspace id="underover3base" width="10px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="underover3under" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="underover3over" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="underover3base" width="10px" height="15px" depth="15px" style="background: black"/> + <mspace id="underover3under" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover3over" width="10px" height="5px" depth="5px" style="background: black"/> </munderover> <munderover id="underover4"> - <mspace id="underover4base" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="underover4under" width="10px" height="15px" depth="15px" mathbackground="black"/> - <mspace id="underover4over" width="10px" height="5px" depth="5px" mathbackground="black"/> + <mspace id="underover4base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover4under" width="10px" height="15px" depth="15px" style="background: black"/> + <mspace id="underover4over" width="10px" height="5px" depth="5px" style="background: black"/> </munderover> <munderover id="underover5"> - <mspace id="underover5base" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="underover5under" width="10px" height="5px" depth="5px" mathbackground="black"/> - <mspace id="underover5over" width="10px" height="15px" depth="15px" mathbackground="black"/> + <mspace id="underover5base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover5under" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover5over" width="10px" height="15px" depth="15px" style="background: black"/> </munderover> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-1.html index 1e5a6606..bd6c5f1 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-1.html
@@ -82,60 +82,60 @@ <body> <p> <math style="font-family: lowerlimitbaselinedropmin3000;"> - <mspace id="ref0001" height="1em" width="3em" mathbackground="green"/> + <mspace id="ref0001" height="1em" width="3em" style="background: green"/> <munder> <mo movablelimits="false">∑</mo> - <mspace id="under00011" depth="1em" width="3em" mathbackground="blue"/> + <mspace id="under00011" depth="1em" width="3em" style="background: blue"/> </munder> <munderover> <mo movablelimits="false">∑</mo> - <mspace id="under00012" depth="1em" width="3em" mathbackground="blue"/> - <mspace height="1em" width="3em" mathbackground="black"/> + <mspace id="under00012" depth="1em" width="3em" style="background: blue"/> + <mspace height="1em" width="3em" style="background: black"/> </munderover> </math> </p> <hr/> <p> <math style="font-family: lowerlimitgapmin11000;"> - <mspace id="ref0002" height="1em" width="3em" mathbackground="green"/> + <mspace id="ref0002" height="1em" width="3em" style="background: green"/> <munder> <mo movablelimits="false">∑</mo> - <mspace id="under00021" depth="1em" width="3em" mathbackground="blue"/> + <mspace id="under00021" depth="1em" width="3em" style="background: blue"/> </munder> <munderover> <mo movablelimits="false">∑</mo> - <mspace id="under00022" depth="1em" width="3em" mathbackground="blue"/> - <mspace height="1em" width="3em" mathbackground="black"/> + <mspace id="under00022" depth="1em" width="3em" style="background: blue"/> + <mspace height="1em" width="3em" style="background: black"/> </munderover> </math> </p> <hr/> <p> <math style="font-family: upperlimitbaselinerisemin5000;"> - <mspace id="ref0003" height="1em" width="3em" mathbackground="green"/> + <mspace id="ref0003" height="1em" width="3em" style="background: green"/> <mover> <mo movablelimits="false">∑</mo> - <mspace id="over00031" height="1em" width="3em" mathbackground="blue"/> + <mspace id="over00031" height="1em" width="3em" style="background: blue"/> </mover> <munderover> <mo movablelimits="false">∑</mo> - <mspace height="1em" width="3em" mathbackground="black"/> - <mspace id="over00032" height="1em" width="3em" mathbackground="blue"/> + <mspace height="1em" width="3em" style="background: black"/> + <mspace id="over00032" height="1em" width="3em" style="background: blue"/> </munderover> </math> </p> <hr/> <p> <math style="font-family: upperlimitgapmin7000;"> - <mspace id="ref0004" height="1em" width="3em" mathbackground="green"/> + <mspace id="ref0004" height="1em" width="3em" style="background: green"/> <mover> <mo movablelimits="false">∑</mo> - <mspace id="over00041" depth="1em" width="3em" mathbackground="blue"/> + <mspace id="over00041" depth="1em" width="3em" style="background: blue"/> </mover> <munderover> <mo movablelimits="false">∑</mo> - <mspace height="1em" width="3em" mathbackground="black"/> - <mspace id="over00042" depth="1em" width="3em" mathbackground="blue"/> + <mspace height="1em" width="3em" style="background: black"/> + <mspace id="over00042" depth="1em" width="3em" style="background: blue"/> </munderover> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-2.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-2.html index c28f29c..73a7c5b 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-2.html
@@ -82,60 +82,60 @@ <body> <p> <math style="font-family: bottomshiftdown3000;"> - <mspace id="ref0001" height="1em" width="3em" mathbackground="green"/> + <mspace id="ref0001" height="1em" width="3em" style="background: green"/> <munder> <mo>→</mo> - <mspace id="under00011" depth="1em" width="3em" mathbackground="blue"/> + <mspace id="under00011" depth="1em" width="3em" style="background: blue"/> </munder> <munderover> <mo>→</mo> - <mspace id="under00012" depth="1em" width="3em" mathbackground="blue"/> - <mspace height="1em" width="3em" mathbackground="black"/> + <mspace id="under00012" depth="1em" width="3em" style="background: blue"/> + <mspace height="1em" width="3em" style="background: black"/> </munderover> </math> </p> <hr/> <p> <math style="font-family: gapbelowmin11000;"> - <mspace id="ref0002" height="1em" width="3em" mathbackground="green"/> + <mspace id="ref0002" height="1em" width="3em" style="background: green"/> <munder> <mo>→</mo> - <mspace id="under00021" depth="1em" width="3em" mathbackground="blue"/> + <mspace id="under00021" depth="1em" width="3em" style="background: blue"/> </munder> <munderover> <mo>→</mo> - <mspace id="under00022" depth="1em" width="3em" mathbackground="blue"/> - <mspace height="1em" width="3em" mathbackground="black"/> + <mspace id="under00022" depth="1em" width="3em" style="background: blue"/> + <mspace height="1em" width="3em" style="background: black"/> </munderover> </math> </p> <hr/> <p> <math style="font-family: topshiftup5000;"> - <mspace id="ref0003" height="1em" width="3em" mathbackground="green"/> + <mspace id="ref0003" height="1em" width="3em" style="background: green"/> <mover> <mo>→</mo> - <mspace id="over00031" height="1em" width="3em" mathbackground="blue"/> + <mspace id="over00031" height="1em" width="3em" style="background: blue"/> </mover> <munderover> <mo>→</mo> - <mspace height="1em" width="3em" mathbackground="black"/> - <mspace id="over00032" height="1em" width="3em" mathbackground="blue"/> + <mspace height="1em" width="3em" style="background: black"/> + <mspace id="over00032" height="1em" width="3em" style="background: blue"/> </munderover> </math> </p> <hr/> <p> <math style="font-family: gapabovemin7000;"> - <mspace id="ref0004" height="1em" width="3em" mathbackground="green"/> + <mspace id="ref0004" height="1em" width="3em" style="background: green"/> <mover> <mo>→</mo> - <mspace id="over00041" depth="1em" width="3em" mathbackground="blue"/> + <mspace id="over00041" depth="1em" width="3em" style="background: blue"/> </mover> <munderover> <mo>→</mo> - <mspace height="1em" width="3em" mathbackground="black"/> - <mspace id="over00042" depth="1em" width="3em" mathbackground="blue"/> + <mspace height="1em" width="3em" style="background: black"/> + <mspace id="over00042" depth="1em" width="3em" style="background: blue"/> </munderover> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-3.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-3.html index 0172ff1c..3fb57c0 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-3.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-3.html
@@ -189,132 +189,132 @@ <body> <p> <math style="font-family: accentbaseheight4000underbarextradescender5000;"> - <mspace id="ref001" height="1em" width="3em" mathbackground="green"/> - <munder mathbackground="cyan" id="el0011"> - <mspace id="base0011" height="3em" width="1em" mathbackground="black"/> - <mspace id="under0011" height="1em" width="3em" mathbackground="blue"/> + <mspace id="ref001" height="1em" width="3em" style="background: green"/> + <munder style="background: cyan" id="el0011"> + <mspace id="base0011" height="3em" width="1em" style="background: black"/> + <mspace id="under0011" height="1em" width="3em" style="background: blue"/> </munder> - <munder mathbackground="cyan" id="el0012" accentunder="true"> - <mspace id="base0012" height="5em" width="1em" mathbackground="black"/> - <mspace id="under0012" height="1em" width="3em" mathbackground="blue"/> + <munder style="background: cyan" id="el0012" accentunder="true"> + <mspace id="base0012" height="5em" width="1em" style="background: black"/> + <mspace id="under0012" height="1em" width="3em" style="background: blue"/> </munder> - <munder mathbackground="cyan" id="el0013" accentunder="true"> - <mspace id="base0013" height="3em" width="1em" mathbackground="black"/> - <mspace id="under0013" height="1em" width="3em" mathbackground="blue"/> + <munder style="background: cyan" id="el0013" accentunder="true"> + <mspace id="base0013" height="3em" width="1em" style="background: black"/> + <mspace id="under0013" height="1em" width="3em" style="background: blue"/> </munder> - <munderover mathbackground="cyan" id="el0014"> - <mspace id="base0014" height="3em" width="1em" mathbackground="black"/> - <mspace id="under0014" height="1em" width="3em" mathbackground="blue"/> - <mspace id="over0014" height="1em" width="3em" mathbackground="red"/> + <munderover style="background: cyan" id="el0014"> + <mspace id="base0014" height="3em" width="1em" style="background: black"/> + <mspace id="under0014" height="1em" width="3em" style="background: blue"/> + <mspace id="over0014" height="1em" width="3em" style="background: red"/> </munderover> - <munderover mathbackground="cyan" id="el0015" accent="true"> - <mspace id="base0015" height="5em" width="1em" mathbackground="black"/> - <mspace id="under0015" height="1em" width="3em" mathbackground="blue"/> - <mspace id="over0015" height="1em" width="3em" mathbackground="red"/> + <munderover style="background: cyan" id="el0015" accent="true"> + <mspace id="base0015" height="5em" width="1em" style="background: black"/> + <mspace id="under0015" height="1em" width="3em" style="background: blue"/> + <mspace id="over0015" height="1em" width="3em" style="background: red"/> </munderover> - <munderover mathbackground="cyan" id="el0016" accent="true"> - <mspace id="base0016" height="3em" width="1em" mathbackground="black"/> - <mspace id="under0016" height="1em" width="3em" mathbackground="blue"/> - <mspace id="over0016" height="1em" width="3em" mathbackground="red"/> + <munderover style="background: cyan" id="el0016" accent="true"> + <mspace id="base0016" height="3em" width="1em" style="background: black"/> + <mspace id="under0016" height="1em" width="3em" style="background: blue"/> + <mspace id="over0016" height="1em" width="3em" style="background: red"/> </munderover> </math> </p> <hr/> <p> <math style="font-family: accentbaseheight4000underbarverticalgap7000;"> - <mspace id="ref002" height="1em" width="3em" mathbackground="green"/> - <munder mathbackground="cyan" id="el0021"> - <mspace id="base0021" height="3em" width="1em" mathbackground="black"/> - <mspace id="under0021" height="1em" width="3em" mathbackground="blue"/> + <mspace id="ref002" height="1em" width="3em" style="background: green"/> + <munder style="background: cyan" id="el0021"> + <mspace id="base0021" height="3em" width="1em" style="background: black"/> + <mspace id="under0021" height="1em" width="3em" style="background: blue"/> </munder> - <munder mathbackground="cyan" id="el0022" accentunder="true"> - <mspace id="base0022" height="5em" width="1em" mathbackground="black"/> - <mspace id="under0022" height="1em" width="3em" mathbackground="blue"/> + <munder style="background: cyan" id="el0022" accentunder="true"> + <mspace id="base0022" height="5em" width="1em" style="background: black"/> + <mspace id="under0022" height="1em" width="3em" style="background: blue"/> </munder> - <munder mathbackground="cyan" id="el0023" accentunder="true"> - <mspace id="base0023" height="3em" width="1em" mathbackground="black"/> - <mspace id="under0023" height="1em" width="3em" mathbackground="blue"/> + <munder style="background: cyan" id="el0023" accentunder="true"> + <mspace id="base0023" height="3em" width="1em" style="background: black"/> + <mspace id="under0023" height="1em" width="3em" style="background: blue"/> </munder> - <munderover mathbackground="cyan" id="el0024"> - <mspace id="base0024" height="3em" width="1em" mathbackground="black"/> - <mspace id="under0024" height="1em" width="3em" mathbackground="blue"/> - <mspace id="over0024" height="1em" width="3em" mathbackground="red"/> + <munderover style="background: cyan" id="el0024"> + <mspace id="base0024" height="3em" width="1em" style="background: black"/> + <mspace id="under0024" height="1em" width="3em" style="background: blue"/> + <mspace id="over0024" height="1em" width="3em" style="background: red"/> </munderover> - <munderover mathbackground="cyan" id="el0025" accent="true"> - <mspace id="base0025" height="5em" width="1em" mathbackground="black"/> - <mspace id="under0025" height="1em" width="3em" mathbackground="blue"/> - <mspace id="over0025" height="1em" width="3em" mathbackground="red"/> + <munderover style="background: cyan" id="el0025" accent="true"> + <mspace id="base0025" height="5em" width="1em" style="background: black"/> + <mspace id="under0025" height="1em" width="3em" style="background: blue"/> + <mspace id="over0025" height="1em" width="3em" style="background: red"/> </munderover> - <munderover mathbackground="cyan" id="el0026" accent="true"> - <mspace id="base0026" height="3em" width="1em" mathbackground="black"/> - <mspace id="under0026" height="1em" width="3em" mathbackground="blue"/> - <mspace id="over0026" height="1em" width="3em" mathbackground="red"/> + <munderover style="background: cyan" id="el0026" accent="true"> + <mspace id="base0026" height="3em" width="1em" style="background: black"/> + <mspace id="under0026" height="1em" width="3em" style="background: blue"/> + <mspace id="over0026" height="1em" width="3em" style="background: red"/> </munderover> </math> </p> <hr/> <p> <math style="font-family: accentbaseheight4000overbarextraascender3000;"> - <mspace id="ref003" height="1em" width="3em" mathbackground="green"/> - <mover mathbackground="cyan" id="el0031"> - <mspace id="base0031" height="3em" width="1em" mathbackground="black"/> - <mspace id="over0031" height="1em" width="3em" mathbackground="red"/> + <mspace id="ref003" height="1em" width="3em" style="background: green"/> + <mover style="background: cyan" id="el0031"> + <mspace id="base0031" height="3em" width="1em" style="background: black"/> + <mspace id="over0031" height="1em" width="3em" style="background: red"/> </mover> - <mover mathbackground="cyan" id="el0032" accent="true"> - <mspace id="base0032" height="5em" width="1em" mathbackground="black"/> - <mspace id="over0032" height="1em" width="3em" mathbackground="red"/> + <mover style="background: cyan" id="el0032" accent="true"> + <mspace id="base0032" height="5em" width="1em" style="background: black"/> + <mspace id="over0032" height="1em" width="3em" style="background: red"/> </mover> - <mover mathbackground="cyan" id="el0033" accent="true"> - <mspace id="base0033" height="3em" width="1em" mathbackground="black"/> - <mspace id="over0033" height="1em" width="3em" mathbackground="red"/> + <mover style="background: cyan" id="el0033" accent="true"> + <mspace id="base0033" height="3em" width="1em" style="background: black"/> + <mspace id="over0033" height="1em" width="3em" style="background: red"/> </mover> - <munderover mathbackground="cyan" id="el0034"> - <mspace id="base0034" height="3em" width="1em" mathbackground="black"/> - <mspace id="under0034" height="1em" width="3em" mathbackground="blue"/> - <mspace id="over0034" height="1em" width="3em" mathbackground="red"/> + <munderover style="background: cyan" id="el0034"> + <mspace id="base0034" height="3em" width="1em" style="background: black"/> + <mspace id="under0034" height="1em" width="3em" style="background: blue"/> + <mspace id="over0034" height="1em" width="3em" style="background: red"/> </munderover> - <munderover mathbackground="cyan" id="el0035" accent="true"> - <mspace id="base0035" height="5em" width="1em" mathbackground="black"/> - <mspace id="under0035" height="1em" width="3em" mathbackground="blue"/> - <mspace id="over0035" height="1em" width="3em" mathbackground="red"/> + <munderover style="background: cyan" id="el0035" accent="true"> + <mspace id="base0035" height="5em" width="1em" style="background: black"/> + <mspace id="under0035" height="1em" width="3em" style="background: blue"/> + <mspace id="over0035" height="1em" width="3em" style="background: red"/> </munderover> - <munderover mathbackground="cyan" id="el0036" accent="true"> - <mspace id="base0036" height="3em" width="1em" mathbackground="black"/> - <mspace id="under0036" height="1em" width="3em" mathbackground="blue"/> - <mspace id="over0036" height="1em" width="3em" mathbackground="red"/> + <munderover style="background: cyan" id="el0036" accent="true"> + <mspace id="base0036" height="3em" width="1em" style="background: black"/> + <mspace id="under0036" height="1em" width="3em" style="background: blue"/> + <mspace id="over0036" height="1em" width="3em" style="background: red"/> </munderover> </math> </p> <hr/> <p> <math style="font-family: accentbaseheight4000overbarverticalgap11000;"> - <mspace id="ref004" height="1em" width="3em" mathbackground="green"/> - <mover mathbackground="cyan" id="el0041"> - <mspace id="base0041" height="3em" width="1em" mathbackground="black"/> - <mspace id="over0041" height="1em" width="3em" mathbackground="red"/> + <mspace id="ref004" height="1em" width="3em" style="background: green"/> + <mover style="background: cyan" id="el0041"> + <mspace id="base0041" height="3em" width="1em" style="background: black"/> + <mspace id="over0041" height="1em" width="3em" style="background: red"/> </mover> - <mover mathbackground="cyan" id="el0042" accent="true"> - <mspace id="base0042" height="5em" width="1em" mathbackground="black"/> - <mspace id="over0042" height="1em" width="3em" mathbackground="red"/> + <mover style="background: cyan" id="el0042" accent="true"> + <mspace id="base0042" height="5em" width="1em" style="background: black"/> + <mspace id="over0042" height="1em" width="3em" style="background: red"/> </mover> - <mover mathbackground="cyan" id="el0043" accent="true"> - <mspace id="base0043" height="3em" width="1em" mathbackground="black"/> - <mspace id="over0043" height="1em" width="3em" mathbackground="red"/> + <mover style="background: cyan" id="el0043" accent="true"> + <mspace id="base0043" height="3em" width="1em" style="background: black"/> + <mspace id="over0043" height="1em" width="3em" style="background: red"/> </mover> - <munderover mathbackground="cyan" id="el0044"> - <mspace id="base0044" height="3em" width="1em" mathbackground="black"/> - <mspace id="under0044" height="1em" width="3em" mathbackground="blue"/> - <mspace id="over0044" height="1em" width="3em" mathbackground="red"/> + <munderover style="background: cyan" id="el0044"> + <mspace id="base0044" height="3em" width="1em" style="background: black"/> + <mspace id="under0044" height="1em" width="3em" style="background: blue"/> + <mspace id="over0044" height="1em" width="3em" style="background: red"/> </munderover> - <munderover mathbackground="cyan" id="el0045" accent="true"> - <mspace id="base0045" height="5em" width="1em" mathbackground="black"/> - <mspace id="under0045" height="1em" width="3em" mathbackground="blue"/> - <mspace id="over0045" height="1em" width="3em" mathbackground="red"/> + <munderover style="background: cyan" id="el0045" accent="true"> + <mspace id="base0045" height="5em" width="1em" style="background: black"/> + <mspace id="under0045" height="1em" width="3em" style="background: blue"/> + <mspace id="over0045" height="1em" width="3em" style="background: red"/> </munderover> - <munderover mathbackground="cyan" id="el0046" accent="true"> - <mspace id="base0046" height="3em" width="1em" mathbackground="black"/> - <mspace id="under0046" height="1em" width="3em" mathbackground="blue"/> - <mspace id="over0046" height="1em" width="3em" mathbackground="red"/> + <munderover style="background: cyan" id="el0046" accent="true"> + <mspace id="base0046" height="3em" width="1em" style="background: black"/> + <mspace id="under0046" height="1em" width="3em" style="background: blue"/> + <mspace id="over0046" height="1em" width="3em" style="background: red"/> </munderover> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-4.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-4.html index 061cda79..6dee35ca 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-4.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-4.html
@@ -189,132 +189,132 @@ <body> <p> <math style="font-family: accentbaseheight4000underbarextradescender5000;"> - <mspace id="ref001" height="1em" width="3em" mathbackground="green"/> - <munder mathbackground="cyan" id="el0011"> - <mspace id="base0011" height="3em" width="1em" mathbackground="black"/> - <mo id="under0011" mathcolor="blue">°</mo> + <mspace id="ref001" height="1em" width="3em" style="background: green"/> + <munder style="background: cyan" id="el0011"> + <mspace id="base0011" height="3em" width="1em" style="background: black"/> + <mo id="under0011" style="color: blue">°</mo> </munder> - <munder mathbackground="cyan" id="el0012"> - <mspace id="base0012" height="5em" width="1em" mathbackground="black"/> - <mo id="under0012" mathcolor="blue">˘</mo> + <munder style="background: cyan" id="el0012"> + <mspace id="base0012" height="5em" width="1em" style="background: black"/> + <mo id="under0012" style="color: blue">˘</mo> </munder> - <munder mathbackground="cyan" id="el0013"> - <mspace id="base0013" height="3em" width="1em" mathbackground="black"/> - <mo id="under0013" mathcolor="blue">˘</mo> + <munder style="background: cyan" id="el0013"> + <mspace id="base0013" height="3em" width="1em" style="background: black"/> + <mo id="under0013" style="color: blue">˘</mo> </munder> - <munderover mathbackground="cyan" id="el0014"> - <mspace id="base0014" height="3em" width="1em" mathbackground="black"/> - <mo id="under0014" mathcolor="blue">°</mo> - <mo id="over0014" mathcolor="red">°</mo> + <munderover style="background: cyan" id="el0014"> + <mspace id="base0014" height="3em" width="1em" style="background: black"/> + <mo id="under0014" style="color: blue">°</mo> + <mo id="over0014" style="color: red">°</mo> </munderover> - <munderover mathbackground="cyan" id="el0015" accent="true"> - <mspace id="base0015" height="5em" width="1em" mathbackground="black"/> - <mo id="under0015" mathcolor="blue">˘</mo> - <mo id="over0015" mathcolor="red">˘</mo> + <munderover style="background: cyan" id="el0015" accent="true"> + <mspace id="base0015" height="5em" width="1em" style="background: black"/> + <mo id="under0015" style="color: blue">˘</mo> + <mo id="over0015" style="color: red">˘</mo> </munderover> - <munderover mathbackground="cyan" id="el0016" accent="true"> - <mspace id="base0016" height="3em" width="1em" mathbackground="black"/> - <mo id="under0016" mathcolor="blue">˘</mo> - <mo id="over0016" mathcolor="red">˘</mo> + <munderover style="background: cyan" id="el0016" accent="true"> + <mspace id="base0016" height="3em" width="1em" style="background: black"/> + <mo id="under0016" style="color: blue">˘</mo> + <mo id="over0016" style="color: red">˘</mo> </munderover> </math> </p> <hr/> <p> <math style="font-family: accentbaseheight4000underbarverticalgap7000;"> - <mspace id="ref002" height="1em" width="3em" mathbackground="green"/> - <munder mathbackground="cyan" id="el0021" accentunder="false"> - <mspace id="base0021" height="3em" width="1em" mathbackground="black"/> - <mo id="under0021" mathcolor="blue">˘</mo> + <mspace id="ref002" height="1em" width="3em" style="background: green"/> + <munder style="background: cyan" id="el0021" accentunder="false"> + <mspace id="base0021" height="3em" width="1em" style="background: black"/> + <mo id="under0021" style="color: blue">˘</mo> </munder> - <munder mathbackground="cyan" id="el0022"> - <mspace id="base0022" height="5em" width="1em" mathbackground="black"/> - <mo id="under0022" mathcolor="blue" accent="true">˘</mo> + <munder style="background: cyan" id="el0022"> + <mspace id="base0022" height="5em" width="1em" style="background: black"/> + <mo id="under0022" style="color: blue" accent="true">˘</mo> </munder> - <munder mathbackground="cyan" id="el0023"> - <mspace id="base0023" height="3em" width="1em" mathbackground="black"/> - <mo id="under0023" mathcolor="blue" accent="true">°</mo> + <munder style="background: cyan" id="el0023"> + <mspace id="base0023" height="3em" width="1em" style="background: black"/> + <mo id="under0023" style="color: blue" accent="true">°</mo> </munder> - <munderover mathbackground="cyan" id="el0024"> - <mspace id="base0024" height="3em" width="1em" mathbackground="black"/> - <mo id="under0024" mathcolor="blue" accent="false">˘</mo> - <mo id="over0024" mathcolor="red" accent="false">˘</mo> + <munderover style="background: cyan" id="el0024"> + <mspace id="base0024" height="3em" width="1em" style="background: black"/> + <mo id="under0024" style="color: blue" accent="false">˘</mo> + <mo id="over0024" style="color: red" accent="false">˘</mo> </munderover> - <munderover mathbackground="cyan" id="el0025"> - <mspace id="base0025" height="5em" width="1em" mathbackground="black"/> - <mo id="under0025" mathcolor="blue" accent="false">˘</mo> - <mo id="over0025" mathcolor="red">˘</mo> + <munderover style="background: cyan" id="el0025"> + <mspace id="base0025" height="5em" width="1em" style="background: black"/> + <mo id="under0025" style="color: blue" accent="false">˘</mo> + <mo id="over0025" style="color: red">˘</mo> </munderover> - <munderover mathbackground="cyan" id="el0026"> - <mspace id="base0026" height="3em" width="1em" mathbackground="black"/> - <mo id="under0026" mathcolor="blue" accent="false">˘</mo> - <mo id="over0026" mathcolor="red">˘</mo> + <munderover style="background: cyan" id="el0026"> + <mspace id="base0026" height="3em" width="1em" style="background: black"/> + <mo id="under0026" style="color: blue" accent="false">˘</mo> + <mo id="over0026" style="color: red">˘</mo> </munderover> </math> </p> <hr/> <p> <math style="font-family: accentbaseheight4000overbarextraascender3000;"> - <mspace id="ref003" height="1em" width="3em" mathbackground="green"/> - <mover mathbackground="cyan" id="el0031"> - <mspace id="base0031" height="3em" width="1em" mathbackground="black"/> - <mo id="over0031" mathcolor="red">°</mo> + <mspace id="ref003" height="1em" width="3em" style="background: green"/> + <mover style="background: cyan" id="el0031"> + <mspace id="base0031" height="3em" width="1em" style="background: black"/> + <mo id="over0031" style="color: red">°</mo> </mover> - <mover mathbackground="cyan" id="el0032" accent="true"> - <mspace id="base0032" height="5em" width="1em" mathbackground="black"/> - <mo id="over0032" mathcolor="red">°</mo> + <mover style="background: cyan" id="el0032" accent="true"> + <mspace id="base0032" height="5em" width="1em" style="background: black"/> + <mo id="over0032" style="color: red">°</mo> </mover> - <mover mathbackground="cyan" id="el0033"> - <mspace id="base0033" height="3em" width="1em" mathbackground="black"/> - <mo id="over0033" mathcolor="red">˘</mo> + <mover style="background: cyan" id="el0033"> + <mspace id="base0033" height="3em" width="1em" style="background: black"/> + <mo id="over0033" style="color: red">˘</mo> </mover> - <munderover mathbackground="cyan" id="el0034"> - <mspace id="base0034" height="3em" width="1em" mathbackground="black"/> - <mo id="under0034" mathcolor="blue">°</mo> - <mo id="over0034" mathcolor="red" accent="false">˘</mo> + <munderover style="background: cyan" id="el0034"> + <mspace id="base0034" height="3em" width="1em" style="background: black"/> + <mo id="under0034" style="color: blue">°</mo> + <mo id="over0034" style="color: red" accent="false">˘</mo> </munderover> - <munderover mathbackground="cyan" id="el0035" accent="true"> - <mspace id="base0035" height="5em" width="1em" mathbackground="black"/> - <mo id="under0035" mathcolor="blue">˘</mo> - <mo id="over0035" mathcolor="red">˘</mo> + <munderover style="background: cyan" id="el0035" accent="true"> + <mspace id="base0035" height="5em" width="1em" style="background: black"/> + <mo id="under0035" style="color: blue">˘</mo> + <mo id="over0035" style="color: red">˘</mo> </munderover> - <munderover mathbackground="cyan" id="el0036" accent="true"> - <mspace id="base0036" height="3em" width="1em" mathbackground="black"/> - <mo id="under0036" mathcolor="blue">˘</mo> - <mo id="over0036" mathcolor="red">˘</mo> + <munderover style="background: cyan" id="el0036" accent="true"> + <mspace id="base0036" height="3em" width="1em" style="background: black"/> + <mo id="under0036" style="color: blue">˘</mo> + <mo id="over0036" style="color: red">˘</mo> </munderover> </math> </p> <hr/> <p> <math style="font-family: accentbaseheight4000overbarverticalgap11000;"> - <mspace id="ref004" height="1em" width="3em" mathbackground="green"/> - <mover mathbackground="cyan" id="el0041"> - <mspace id="base0041" height="3em" width="1em" mathbackground="black"/> - <mo id="over0041" mathcolor="red">°</mo> + <mspace id="ref004" height="1em" width="3em" style="background: green"/> + <mover style="background: cyan" id="el0041"> + <mspace id="base0041" height="3em" width="1em" style="background: black"/> + <mo id="over0041" style="color: red">°</mo> </mover> - <mover mathbackground="cyan" id="el0042" accent="true"> - <mspace id="base0042" height="5em" width="1em" mathbackground="black"/> - <mo id="over0042" mathcolor="red">°</mo> + <mover style="background: cyan" id="el0042" accent="true"> + <mspace id="base0042" height="5em" width="1em" style="background: black"/> + <mo id="over0042" style="color: red">°</mo> </mover> - <mover mathbackground="cyan" id="el0043"> - <mspace id="base0043" height="3em" width="1em" mathbackground="black"/> - <mo id="over0043" mathcolor="red">˘</mo> + <mover style="background: cyan" id="el0043"> + <mspace id="base0043" height="3em" width="1em" style="background: black"/> + <mo id="over0043" style="color: red">˘</mo> </mover> - <munderover mathbackground="cyan" id="el0044"> - <mspace id="base0044" height="3em" width="1em" mathbackground="black"/> - <mo id="under0044" mathcolor="blue">°</mo> - <mo id="over0044" mathcolor="red" accent="false">˘</mo> + <munderover style="background: cyan" id="el0044"> + <mspace id="base0044" height="3em" width="1em" style="background: black"/> + <mo id="under0044" style="color: blue">°</mo> + <mo id="over0044" style="color: red" accent="false">˘</mo> </munderover> - <munderover mathbackground="cyan" id="el0045" accent="true"> - <mspace id="base0045" height="5em" width="1em" mathbackground="black"/> - <mo id="under0045" mathcolor="blue">˘</mo> - <mo id="over0045" mathcolor="red">˘</mo> + <munderover style="background: cyan" id="el0045" accent="true"> + <mspace id="base0045" height="5em" width="1em" style="background: black"/> + <mo id="under0045" style="color: blue">˘</mo> + <mo id="over0045" style="color: red">˘</mo> </munderover> - <munderover mathbackground="cyan" id="el0046" accent="true"> - <mspace id="base0046" height="3em" width="1em" mathbackground="black"/> - <mo id="under0046" mathcolor="blue">˘</mo> - <mo id="over0046" mathcolor="red">˘</mo> + <munderover style="background: cyan" id="el0046" accent="true"> + <mspace id="base0046" height="3em" width="1em" style="background: black"/> + <mo id="under0046" style="color: blue">˘</mo> + <mo id="over0046" style="color: red">˘</mo> </munderover> </math> </p>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-1.html index adb3637..dc2622d 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-1.html
@@ -81,9 +81,9 @@ <mspace id="depth0" depth="25px"/> <mspace id="depth1" depth="50px"/> <mspace id="depth2" depth="75px"/> - <mspace id="mspace0" width="25px" height="50px" depth="75px" mathbackground="green"/> - <mspace id="mspace1" width="50px" height="75px" depth="25px" mathbackground="blue"/> - <mspace id="mspace2" width="75px" height="25px" depth="50px" mathbackground="green"/> + <mspace id="mspace0" width="25px" height="50px" depth="75px" style="background: green"/> + <mspace id="mspace1" width="50px" height="75px" depth="25px" style="background: blue"/> + <mspace id="mspace2" width="75px" height="25px" depth="50px" style="background: green"/> </math> </p> <hr/>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-2.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-2.html index 544cfb1f..072f2bda 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-2.html
@@ -14,17 +14,17 @@ <div style="position: absolute; top: 0px; left: 0px; width: 200px; height: 200px;"> <math style="position: absolute; top: 0px; left: 0px"> - <mspace width="50px" height="100px" depth="100px" mathbackground="green"/> - <mspace width="50px" height="100px" depth="100px" mathbackground="green"/> - <mspace width="25px" depth="100px" mathbackground="green"/> - <mspace width="25px" depth="100px" mathbackground="green"/> - <mspace width="25px" height="100px" mathbackground="green"/> - <mspace width="25px" height="100px" mathbackground="green"/> + <mspace width="50px" height="100px" depth="100px" style="background: green"/> + <mspace width="50px" height="100px" depth="100px" style="background: green"/> + <mspace width="25px" depth="100px" style="background: green"/> + <mspace width="25px" depth="100px" style="background: green"/> + <mspace width="25px" height="100px" style="background: green"/> + <mspace width="25px" height="100px" style="background: green"/> </math> <math style="position: absolute; top: 0px; left: 0px"> - <mspace width="100px" height="20px" depth="20px" mathbackground="red"/> - <mspace width="50px" height="100px" mathbackground="red"/> - <mspace width="50px" depth="100px" mathbackground="red"/> + <mspace width="100px" height="20px" depth="20px" style="background: red"/> + <mspace width="50px" height="100px" style="background: red"/> + <mspace width="50px" depth="100px" style="background: red"/> </math> </div> <!-- These green divs should cover the red mspace elements -->
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/tables/table-axis-height.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/tables/table-axis-height.html index 50c3491..4d2b446 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/tables/table-axis-height.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/tables/table-axis-height.html
@@ -45,8 +45,8 @@ <body> <p> <math style="font-family: axisheight5000-verticalarrow14000"> - <mspace id="baseline" mathbackground="green" width="50px" height="1px"/> - <mtable id="table" mathbackground="blue"><mtr><mtd><mspace width="100px" height="1px"/></mtd></mtr></mtable> + <mspace id="baseline" style="background: green" width="50px" height="1px"/> + <mtable id="table" style="background: blue"><mtr><mtd><mspace width="100px" height="1px"/></mtd></mtr></mtable> </math> </p> </body>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/display-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/display-1.html index 551f640..a7d6277 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/display-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/display-1.html
@@ -10,7 +10,7 @@ <body> <p>Test passes if you see a green square.</p> <div style="background: green; color: red; width: 200px; height: 200px;"> - <math style="display: none;"><mspace width="200px" height="200px" mathbackground="red"/></math> + <math style="display: none;"><mspace width="200px" height="200px" style="background: red"/></math> </div> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-1.html index 80e4c75..6164346 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-1.html
@@ -22,12 +22,12 @@ <div style="width: 150px; height: 150px; overflow: hidden"> <math> <mrow id="link" href="#target"> - <mspace id="space" width="150px" height="150px" mathbackground="red"/> + <mspace id="space" width="150px" height="150px" style="background: red"/> </mrow> </math> <div style="height: 500px;"></div> <math id="target"> - <mspace width="150px" height="150px" mathbackground="green"/> + <mspace width="150px" height="150px" style="background: green"/> </math> </div>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-2.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-2.html index 1e41f77c..6e50493 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-2.html
@@ -24,14 +24,14 @@ <mrow href="#target"> <mrow> <mrow> - <mspace id="space" width="150px" height="150px" mathbackground="red"/> + <mspace id="space" width="150px" height="150px" style="background: red"/> </mrow> </mrow> </mrow> </math> <div style="height: 500px;"></div> <math id="target"> - <mspace width="150px" height="150px" mathbackground="green"/> + <mspace width="150px" height="150px" style="background: green"/> </math> </div>
diff --git a/third_party/blink/web_tests/external/wpt/mixed-content/imageset.https.sub.html b/third_party/blink/web_tests/external/wpt/mixed-content/imageset.https.sub.html index dd37156..1f3d047 100644 --- a/third_party/blink/web_tests/external/wpt/mixed-content/imageset.https.sub.html +++ b/third_party/blink/web_tests/external/wpt/mixed-content/imageset.https.sub.html
@@ -21,9 +21,9 @@ <img srcset="http://{{domains[]}}:{{ports[http][0]}}/images/smiley.png?img_srcset"> <script> window.addEventListener("load", t.step_func(function() { - verifyNumberOfDownloads("http://{{domains[]}}:{{ports[http][0]}}/images/smiley.png?img_src", 1); - verifyNumberOfDownloads("http://{{domains[]}}:{{ports[http][0]}}/images/smiley.png?picture", 0); - verifyNumberOfDownloads("http://{{domains[]}}:{{ports[http][0]}}/images/smiley.png?img_srcset", 0); + verifyNumberOfResourceTimingEntries("http://{{domains[]}}:{{ports[http][0]}}/images/smiley.png?img_src", 1); + verifyNumberOfResourceTimingEntries("http://{{domains[]}}:{{ports[http][0]}}/images/smiley.png?picture", 0); + verifyNumberOfResourceTimingEntries("http://{{domains[]}}:{{ports[http][0]}}/images/smiley.png?img_srcset", 0); t.done(); })); </script>
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-abort-method-manual.https.html b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-abort-method-manual.https.html new file mode 100644 index 0000000..a24bac86 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-abort-method-manual.https.html
@@ -0,0 +1,95 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Manual tests for PaymentRequest.abort() method</title> +<link rel="help" href="https://w3c.github.io/payment-request/#abort-method"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +"use strict"; +setup({ + explicit_done: true, + explicit_timeout: true, +}); +const basicCard = Object.freeze({ supportedMethods: "basic-card" }); +const applePay = Object.freeze({ + supportedMethods: "https://apple.com/apple-pay", + data: { + version: 3, + merchantIdentifier: "merchant.com.example", + countryCode: "US", + merchantCapabilities: ["supports3DS"], + supportedNetworks: ["visa"], + } +}); +const defaultMethods = Object.freeze([basicCard, applePay]); +const defaultDetails = Object.freeze({ + total: { + label: "Total", + amount: { + currency: "USD", + value: "1.00", + }, + }, +}); + +function testShowSameRequestMultipleTimes() { + promise_test(async t => { + const request = new PaymentRequest(defaultMethods, defaultDetails); + const acceptPromise = request.show() + try { + await request.abort(); + } catch (err) { + assert_unreached("Unexpected promise rejection: " + err.message); + } + await promise_rejects(t, "AbortError", acceptPromise); + // As request is now "closed", trying to show it will fail + await promise_rejects(t, "InvalidStateError", request.show()); + }, "The same request cannot be shown multiple times."); +} + +function testAbortBeforeShow() { + promise_test(async t => { + // request is in "created" state. + const request = new PaymentRequest(defaultMethods, defaultDetails); + await promise_rejects(t, "InvalidStateError", request.abort()); + // Call it again, for good measure. + await promise_rejects(t, "InvalidStateError", request.abort()); + // The request's state is "created", so let's show it + // which changes the state to "interactive.". + const acceptPromise = request.show() + // Let's set request the state to "closed" by calling .abort() + try { + await request.abort(); + } catch (err) { + assert_unreached("Unexpected promise rejection: " + err.message); + } + // The request is now "closed", so... + await promise_rejects(t, "InvalidStateError", request.abort()); + await promise_rejects(t, "AbortError", acceptPromise); + }, "Aborting a request before it is shown doesn't prevent it from being shown later."); +} +</script> +<h2>Manual tests for PaymentRequest.abort() method</h2> +<p> + Click on each button in sequence from top to bottom without refreshing the + page. Each button will bring up the Payment Request UI window and then will + close it automatically. (If a payment sheet stays open, the test has failed.) +</p> +<ol> + <li> + <button onclick="testShowSameRequestMultipleTimes()"> + The same request cannot be shown multiple times. + </button> + </li> + <li> + <button onclick="testAbortBeforeShow()"> + Aborting a request before it is shown doesn't prevent it from being shown + later. + </button> + </li> + <li><button onclick="done()">Done!</button></li> +</ol> +<small> + If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> + and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>. +</small>
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-abort-method.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-abort-method.https-expected.txt deleted file mode 100644 index 2f5a073..0000000 --- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-abort-method.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Test for PaymentRequest.abort() method Uncaught TypeError: Cannot set property 'click' of undefined -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-abort-method.https.html b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-abort-method.https.html index 75e39a01..cf16401 100644 --- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-abort-method.https.html +++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-abort-method.https.html
@@ -1,11 +1,11 @@ <!DOCTYPE html> <meta charset="utf-8"> <title>Test for PaymentRequest.abort() method</title> -<link rel="help" href="https://w3c.github.io/browser-payment-api/#abort-method"> +<link rel="help" href="https://w3c.github.io/payment-request/#abort-method"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src='/resources/testdriver-vendor.js'></script> <script src="/resources/testdriver.js"></script> +<script src='/resources/testdriver-vendor.js'></script> <script> "use strict"; setup({ @@ -44,45 +44,11 @@ promise_test(async t => { const request = new PaymentRequest(defaultMethods, defaultDetails); - const acceptPromise = test_driver.bless("show payment request", () => - request.show() - ); - try { - await request.abort(); - } catch (err) { - assert_unreached("Unexpected promise rejection: " + err.message); - } - await promise_rejects(t, "AbortError", acceptPromise); - // As request is now "closed", trying to show it will fail - await promise_rejects(t, "InvalidStateError", request.show()); -}, "The same request cannot be shown multiple times."); - -promise_test(async t => { - // request is in "created" state. - const request = new PaymentRequest(defaultMethods, defaultDetails); - await promise_rejects(t, "InvalidStateError", request.abort()); - // Call it again, for good measure. - await promise_rejects(t, "InvalidStateError", request.abort()); - // The request's state is "created", so let's show it - // which changes the state to "interactive.". - const acceptPromise = test_driver.bless("show payment request", () => - request.show() - ); - // Let's set request the state to "closed" by calling .abort() - try { - await request.abort(); - } catch (err) { - assert_unreached("Unexpected promise rejection: " + err.message); - } - // The request is now "closed", so... - await promise_rejects(t, "InvalidStateError", request.abort()); - await promise_rejects(t, "AbortError", acceptPromise); -}, "Aborting a request before it is shown doesn't prevent it from being shown later."); - -promise_test(async t => { - const request = new PaymentRequest(defaultMethods, defaultDetails); const promises = new Set([request.abort(), request.abort(), request.abort()]); assert_equals(promises.size, 3, "Must have three unique objects"); }, "Calling abort() multiple times is always a new object."); </script> - +<small> + If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> + and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>. +</small>
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method-manual.https.html b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method-manual.https.html new file mode 100644 index 0000000..fea45500 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method-manual.https.html
@@ -0,0 +1,105 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Manual tests for PaymentRequest.canMakePayment() method</title> +<link rel="help" href="https://w3c.github.io/payment-request/#canmakepayment-method"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +setup({ + explicit_done: true, + explicit_timeout: true, +}); + +const basicCard = Object.freeze({ supportedMethods: "basic-card" }); +const applePay = Object.freeze({ + supportedMethods: "https://apple.com/apple-pay", + data: { + version: 3, + merchantIdentifier: "merchant.com.example", + countryCode: "US", + merchantCapabilities: ["supports3DS"], + supportedNetworks: ["visa"], + } +}); +const defaultMethods = Object.freeze([basicCard, applePay]); +const defaultDetails = Object.freeze({ + total: { + label: "Total", + amount: { + currency: "USD", + value: "1.00", + }, + }, +}); + +function testInteractiveState() { + promise_test(async t => { + const request = new PaymentRequest(defaultMethods, defaultDetails); + const acceptPromise = request.show(); // Sets state to "interactive" + const canMakePaymentPromise = request.canMakePayment(); + try { + const result = await canMakePaymentPromise; + assert_true( + false, + `canMakePaymentPromise should have thrown InvalidStateError` + ); + } catch (err) { + await promise_rejects(t, "InvalidStateError", canMakePaymentPromise); + } finally { + await request.abort(); + await promise_rejects(t, "AbortError", acceptPromise); + } + // The state should be "closed" + await promise_rejects(t, "InvalidStateError", request.canMakePayment()); + }, 'If request.[[state]] is "interactive", then return a promise rejected with an "InvalidStateError" DOMException.'); +} + +function testClosedState() { + promise_test(async t => { + const request = new PaymentRequest(defaultMethods, defaultDetails); + const acceptPromise = request.show(); // Sets state to "interactive" + acceptPromise.catch(() => {}); // no-op, just to silence unhandled rejection in devtools. + await request.abort(); // The state is now "closed" + await promise_rejects(t, "InvalidStateError", request.canMakePayment()); + try { + const result = await request.canMakePayment(); + assert_true( + false, + `should have thrown InvalidStateError, but instead returned "${result}"` + ); + } catch (err) { + assert_equals( + err.name, + "InvalidStateError", + "must be an InvalidStateError." + ); + } + }, 'If request.[[state]] is "closed", then return a promise rejected with an "InvalidStateError" DOMException.'); +} +</script> + +<h2>Manual tests for PaymentRequest.canMakePayment() method</h2> +<p> + Click on each button in sequence from top to bottom without refreshing the + page. Each button will bring up the Payment Request UI window and then will + close it automatically. (If a payment sheet stays open, the test has failed.) +</p> +<ol> + <li> + <button onclick="testInteractiveState()"> + If request.[[state]] is "interactive", then return a promise rejected with + an "InvalidStateError" DOMException. + </button> + </li> + <li> + <button onclick="testClosedState()"> + If request.[[state]] is "closed", then return a promise rejected with an + "InvalidStateError" DOMException. + </button> + </li> + <li><button onclick="done()">Done!</button></li> +</ol> +<small> + If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> + and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>. +</small>
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method.https-expected.txt index 0f09114..29f5282d 100644 --- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method.https-expected.txt
@@ -1,4 +1,7 @@ This is a testharness.js-based test. -FAIL Tests for PaymentRequest.canMakePayment() method Uncaught TypeError: Cannot set property 'click' of undefined +FAIL If payment method identifier are supported, resolve promise with true. promise_test: Unhandled rejection with value: object "UnknownError: Request failed" +FAIL If request.[[state]] is "created", then return a promise that resolves to true for known method. assert_equals: if it throws, then it must be a NotAllowedError. expected "NotAllowedError" but got "UnknownError" +FAIL All methods are unsupported promise_test: Unhandled rejection with value: object "UnknownError: Request failed" +FAIL Mix of supported and unsupported methods, at least one method is supported. promise_test: Unhandled rejection with value: object "UnknownError: Request failed" Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method.https.html b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method.https.html index 672e5ce..cc8349a 100644 --- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method.https.html +++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method.https.html
@@ -1,11 +1,11 @@ <!DOCTYPE html> <meta charset="utf-8"> <title>Tests for PaymentRequest.canMakePayment() method</title> -<link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method"> +<link rel="help" href="https://w3c.github.io/payment-request/#canmakepayment-method"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src='/resources/testdriver-vendor.js'></script> <script src="/resources/testdriver.js"></script> +<script src='/resources/testdriver-vendor.js'></script> <script> const basicCard = Object.freeze({ supportedMethods: "basic-card" }); const applePay = Object.freeze({ @@ -44,51 +44,6 @@ promise_test(async t => { const request = new PaymentRequest(defaultMethods, defaultDetails); - const acceptPromise = test_driver.bless("show payment request", () => { - request.show(); // Sets state to "interactive" - }); - const canMakePaymentPromise = request.canMakePayment(); - try { - const result = await canMakePaymentPromise; - assert_true( - false, - `canMakePaymentPromise should have thrown InvalidStateError` - ); - } catch (err) { - await promise_rejects(t, "InvalidStateError", canMakePaymentPromise); - } finally { - await request.abort(); - await promise_rejects(t, "AbortError", acceptPromise); - } - // The state should be "closed" - await promise_rejects(t, "InvalidStateError", request.canMakePayment()); -}, 'If request.[[state]] is "interactive", then return a promise rejected with an "InvalidStateError" DOMException.'); - -promise_test(async t => { - const request = new PaymentRequest(defaultMethods, defaultDetails); - const acceptPromise = test_driver.bless("show payment request", () => { - request.show(); // Sets state to "interactive" - }); - acceptPromise.catch(() => {}); // no-op, just to silence unhandled rejection in devtools. - await request.abort(); // The state is now "closed" - await promise_rejects(t, "InvalidStateError", request.canMakePayment()); - try { - const result = await request.canMakePayment(); - assert_true( - false, - `should have thrown InvalidStateError, but instead returned "${result}"` - ); - } catch (err) { - assert_equals( - err.name, - "InvalidStateError", - "must be an InvalidStateError." - ); - } -}, 'If request.[[state]] is "closed", then return a promise rejected with an "InvalidStateError" DOMException.'); - -promise_test(async t => { - const request = new PaymentRequest(defaultMethods, defaultDetails); try { assert_true( await request.canMakePayment(),
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-multiple-show-manual.https.html b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-multiple-show-manual.https.html new file mode 100644 index 0000000..cc41217 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-multiple-show-manual.https.html
@@ -0,0 +1,66 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Manual test for multiple PaymentRequest.show()</title> +<link rel="help" href="https://w3c.github.io/payment-request/#show-method"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +"use strict"; +setup({ + allow_uncaught_exception: true, +}); +const defaultMethods = Object.freeze([ + { supportedMethods: "basic-card" }, + { + supportedMethods: "https://apple.com/apple-pay", + data: { + version: 3, + merchantIdentifier: "merchant.com.example", + countryCode: "US", + merchantCapabilities: ["supports3DS"], + supportedNetworks: ["visa"], + } + }, +]); + +const defaultDetails = Object.freeze({ + total: { + label: "Total", + amount: { + currency: "USD", + value: "1.00", + }, + }, +}); + +function testCallingShowMultipleTimes() { + promise_test(async t => { + const request = new PaymentRequest(defaultMethods, defaultDetails); + const p1 = request.show(); + const p2 = request.show(); + const p3 = request.show(); + const promises = new Set([p1, p2, p3]); + await request.abort(); + assert_equals(promises.size, 3, "Must have three unique objects"); + await promise_rejects(t, "AbortError", p1); + await promise_rejects(t, "InvalidStateError", p2); + await promise_rejects(t, "InvalidStateError", p3); + }, "Calling show() multiple times is always a new object."); +} +</script> +<h2>Manual test for multiple PaymentRequest.show()</h2> +<p> + Click on the button to bring up the Payment Request UI window and then will + close it automatically. (If a payment sheet stays open, the test has failed.) +</p> +<ul> + <li> + <button onclick="testCallingShowMultipleTimes()"> + Calling show() multiple times is always a new object. + </button> + </li> +</ul> +<small> + If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> + and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>. +</small>
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method-manual.https.html b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method-manual.https.html new file mode 100644 index 0000000..6ef98e8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method-manual.https.html
@@ -0,0 +1,97 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Manual tests for PaymentRequest.show() method</title> +<link rel="help" href="https://w3c.github.io/payment-request/#show-method"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +"use strict"; +setup({ + explicit_done: true, + explicit_timeout: true, +}); +const defaultMethods = Object.freeze([ + { supportedMethods: "basic-card" }, + { + supportedMethods: "https://apple.com/apple-pay", + data: { + version: 3, + merchantIdentifier: "merchant.com.example", + countryCode: "US", + merchantCapabilities: ["supports3DS"], + supportedNetworks: ["visa"], + } + }, +]); + +const defaultDetails = Object.freeze({ + total: { + label: "Total", + amount: { + currency: "USD", + value: "1.00", + }, + }, +}); + +function testThrowsIfStateIsNotCreated() { + promise_test(async t => { + const request = new PaymentRequest(defaultMethods, defaultDetails); + const acceptPromise = request.show(); // Sets state to "interactive" + await promise_rejects(t, "InvalidStateError", request.show()); + await request.abort(); + await promise_rejects(t, "AbortError", acceptPromise); + }, "Throws if the promise [[state]] is not 'created'."); +} + +function testPaymentRequestIsShowingBoolean() { + promise_test(async t => { + const request1 = new PaymentRequest(defaultMethods, defaultDetails); + const request2 = new PaymentRequest(defaultMethods, defaultDetails); + const acceptPromise1 = request1.show(); + const acceptPromise2 = request2.show(); + await promise_rejects(t, "AbortError", acceptPromise2); + await request1.abort(); + await promise_rejects(t, "AbortError", acceptPromise1); + }, `If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException.`); +} + +function testNotSupportedError() { + promise_test(async t => { + const request = new PaymentRequest( + [{ supportedMethods: "this-is-not-supported" }], + defaultDetails + ); + const acceptPromise = request.show(); + await promise_rejects(t, "NotSupportedError", acceptPromise); + }, `If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException.`); +} +</script> +<h2>Manual tests for PaymentRequest.show() method</h2> +<p> + Click on each button in sequence from top to bottom without refreshing the + page. Each button will bring up the Payment Request UI window and then will + close it automatically. (If a payment sheet stays open, the test has failed.) +</p> +<ol> + <li> + <button onclick="testThrowsIfStateIsNotCreated()"> + Throws if the promise [[state]] is not 'created'. + </button> + </li> + <li> + <button onclick="testPaymentRequestIsShowingBoolean()"> + If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException. + </button> + </li> + <li> + <button onclick="testNotSupportedError()"> + If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException. + </button> + </li> + <li><button onclick="done()">Done!</button></li> +</ol> +<small> + If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> + and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>. +</small>
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https-expected.txt new file mode 100644 index 0000000..cfe2e93 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Calling show() without being triggered by user interaction throws assert_throws: function "function() { throw e }" threw object "UnknownError: Request failed" that is not a DOMException SecurityError: property "code" is equal to 0, expected 18 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https.html b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https.html index 3d36259..dd049870 100644 --- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https.html +++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https.html
@@ -1,11 +1,9 @@ <!DOCTYPE html> <meta charset="utf-8"> <title>Test for PaymentRequest.show() method</title> -<link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method"> +<link rel="help" href="https://w3c.github.io/payment-request/#show-method"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="/resources/testdriver.js"></script> -<script src="/resources/testdriver-vendor.js"></script> <script> "use strict"; const defaultMethods = Object.freeze([ @@ -37,51 +35,6 @@ const acceptPromise = request.show(); await promise_rejects(t, "SecurityError", acceptPromise); }, `Calling show() without being triggered by user interaction throws`); - -promise_test(t => { - return test_driver.bless("show payment request", async () => { - const request = new PaymentRequest(defaultMethods, defaultDetails); - const acceptPromise = request.show(); // Sets state to "interactive" - await promise_rejects(t, "InvalidStateError", request.show()); - await request.abort(); - await promise_rejects(t, "AbortError", acceptPromise); - }); -}, "Throws if the promise [[state]] is not 'created'."); - -promise_test(t => { - return test_driver.bless("show payment request", async () => { - const request1 = new PaymentRequest(defaultMethods, defaultDetails); - const request2 = new PaymentRequest(defaultMethods, defaultDetails); - const acceptPromise1 = request1.show(); - const acceptPromise2 = request2.show(); - await promise_rejects(t, "AbortError", acceptPromise2); - await request1.abort(); - await promise_rejects(t, "AbortError", acceptPromise1); - }); -}, `If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException.`); - -promise_test(t => { - return test_driver.bless("show payment request", async () => { - const request = new PaymentRequest( - [{ supportedMethods: "this-is-not-supported" }], - defaultDetails - ); - const acceptPromise = request.show(); - await promise_rejects(t, "NotSupportedError", acceptPromise); - }); -}, `If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException.`); - -promise_test(t => { - return test_driver.bless("show payment request", async () => { - const request = new PaymentRequest( - [{ supportedMethods: "basic-card" }], - defaultDetails - ); - const promises = new Set([request.show(), request.show(), request.show()]); - await request.abort(); - assert_equals(promises.size, 3, "Must have three unique objects"); - }); -}, "Calling show() multiple times is always a new object."); </script> <small> If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
diff --git a/third_party/blink/web_tests/external/wpt/preload/avoid-delaying-onload-link-preload.html b/third_party/blink/web_tests/external/wpt/preload/avoid-delaying-onload-link-preload.html index 77838c3..a1b19c8 100644 --- a/third_party/blink/web_tests/external/wpt/preload/avoid-delaying-onload-link-preload.html +++ b/third_party/blink/web_tests/external/wpt/preload/avoid-delaying-onload-link-preload.html
@@ -9,7 +9,7 @@ <script> window.addEventListener("load", t.step_func(function() { verifyPreloadAndRTSupport(); - verifyNumberOfDownloads("/resources/dummy.js?pipe=trickle(d5)", 0); + verifyNumberOfResourceTimingEntries("/resources/dummy.js?pipe=trickle(d5)", 0); t.done(); })); </script>
diff --git a/third_party/blink/web_tests/external/wpt/preload/delaying-onload-link-preload-after-discovery.html b/third_party/blink/web_tests/external/wpt/preload/delaying-onload-link-preload-after-discovery.html index 095d89ad..1c856d16 100644 --- a/third_party/blink/web_tests/external/wpt/preload/delaying-onload-link-preload-after-discovery.html +++ b/third_party/blink/web_tests/external/wpt/preload/delaying-onload-link-preload-after-discovery.html
@@ -11,8 +11,8 @@ <script> window.addEventListener("load", t.step_func(function() { verifyPreloadAndRTSupport(); - verifyNumberOfDownloads("resources/dummy.js?pipe=trickle(d5)", 1); - verifyNumberOfDownloads("resources/square.png?pipe=trickle(d5)", 1); + verifyLoadedAndNoDoubleDownload("resources/dummy.js?pipe=trickle(d5)"); + verifyLoadedAndNoDoubleDownload("resources/square.png?pipe=trickle(d5)"); t.done(); })); var script = document.createElement("script");
diff --git a/third_party/blink/web_tests/external/wpt/preload/download-resources.html b/third_party/blink/web_tests/external/wpt/preload/download-resources.html index dc2b4693..510ebb4 100644 --- a/third_party/blink/web_tests/external/wpt/preload/download-resources.html +++ b/third_party/blink/web_tests/external/wpt/preload/download-resources.html
@@ -16,20 +16,21 @@ <link rel=preload href="resources/dummy.xml?novalue"> <link rel=preload href="resources/dummy.xml" as="fetch"> <body> -<script src="resources/dummy.js?pipe=trickle(d5)&download-resources"></script> <script> window.addEventListener("load", t.step_func(function() { - verifyPreloadAndRTSupport() - verifyNumberOfDownloads("resources/dummy.js", 1); - verifyNumberOfDownloads("resources/dummy.css", 1); - verifyNumberOfDownloads("/fonts/CanvasTest.ttf", 1); - verifyNumberOfDownloads("resources/white.mp4", 1); - verifyNumberOfDownloads("resources/sound_5.oga", 1); - verifyNumberOfDownloads("resources/foo.vtt", 1); - verifyNumberOfDownloads("resources/dummy.xml?foo=bar", 0); - verifyNumberOfDownloads("resources/dummy.xml?novalue", 0); - verifyNumberOfDownloads("resources/dummy.xml", 1); - t.done(); + t.step_timeout(function() { + verifyPreloadAndRTSupport() + verifyNumberOfResourceTimingEntries("resources/dummy.js", 1); + verifyNumberOfResourceTimingEntries("resources/dummy.css", 1); + verifyNumberOfResourceTimingEntries("/fonts/CanvasTest.ttf", 1); + verifyNumberOfResourceTimingEntries("resources/white.mp4", 1); + verifyNumberOfResourceTimingEntries("resources/sound_5.oga", 1); + verifyNumberOfResourceTimingEntries("resources/foo.vtt", 1); + verifyNumberOfResourceTimingEntries("resources/dummy.xml?foo=bar", 0); + verifyNumberOfResourceTimingEntries("resources/dummy.xml?novalue", 0); + verifyNumberOfResourceTimingEntries("resources/dummy.xml", 1); + t.done(); + }, 5000); })); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/preload/dynamic-adding-preload-imagesrcset.tentative.html b/third_party/blink/web_tests/external/wpt/preload/dynamic-adding-preload-imagesrcset.tentative.html index be8f0af..e1b8431 100644 --- a/third_party/blink/web_tests/external/wpt/preload/dynamic-adding-preload-imagesrcset.tentative.html +++ b/third_party/blink/web_tests/external/wpt/preload/dynamic-adding-preload-imagesrcset.tentative.html
@@ -17,15 +17,14 @@ link.imageSizes = "400px"; link.onload = t.step_func(function() { t.step_timeout(function() { - verifyNumberOfDownloads("resources/square.png?default", 0); - verifyNumberOfDownloads("resources/square.png?200", 0); - verifyNumberOfDownloads("resources/square.png?400", 1); - verifyNumberOfDownloads("resources/square.png?800", 0); + verifyNumberOfResourceTimingEntries("resources/square.png?default", 0); + verifyNumberOfResourceTimingEntries("resources/square.png?200", 0); + verifyNumberOfResourceTimingEntries("resources/square.png?400", 1); + verifyNumberOfResourceTimingEntries("resources/square.png?800", 0); t.done(); }, 0); }); document.body.appendChild(link); }); </script> -<script src="resources/dummy.js?pipe=trickle(d5)&dynamic-adding-preload"></script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/preload/dynamic-adding-preload-nonce.html b/third_party/blink/web_tests/external/wpt/preload/dynamic-adding-preload-nonce.html index 10dae6b9..19e09472e 100644 --- a/third_party/blink/web_tests/external/wpt/preload/dynamic-adding-preload-nonce.html +++ b/third_party/blink/web_tests/external/wpt/preload/dynamic-adding-preload-nonce.html
@@ -14,7 +14,7 @@ link.nonce = "abc"; link.onload = link.onerror = t.step_func(function() { t.step_timeout(function() { - verifyNumberOfDownloads("resources/dummy.js?with-nonce", 1); + verifyNumberOfResourceTimingEntries("resources/dummy.js?with-nonce", 1); t.done(); }, 0); }); @@ -29,7 +29,7 @@ link.href = "resources/dummy.js?without-nonce"; link.onload = link.onerror = t.step_func(function() { t.step_timeout(function() { - verifyNumberOfDownloads("resources/dummy.js?without-nonce", 0); + verifyNumberOfResourceTimingEntries("resources/dummy.js?without-nonce", 0); t.done(); }, 0); });
diff --git a/third_party/blink/web_tests/external/wpt/preload/dynamic-adding-preload.html b/third_party/blink/web_tests/external/wpt/preload/dynamic-adding-preload.html index 2a299bd..0cecc198 100644 --- a/third_party/blink/web_tests/external/wpt/preload/dynamic-adding-preload.html +++ b/third_party/blink/web_tests/external/wpt/preload/dynamic-adding-preload.html
@@ -15,12 +15,11 @@ link.href = "resources/dummy.js?dynamic-adding-preload"; link.onload = t.step_func(function() { t.step_timeout(function() { - verifyNumberOfDownloads("resources/dummy.js?dynamic-adding-preload", 1); + verifyNumberOfResourceTimingEntries("resources/dummy.js?dynamic-adding-preload", 1); t.done(); }, 0); }); document.body.appendChild(link); }); </script> -<script src="resources/dummy.js?pipe=trickle(d5)&dynamic-adding-preload"></script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/preload/link-header-on-subresource.html b/third_party/blink/web_tests/external/wpt/preload/link-header-on-subresource.html index a02bc7c..087a342 100644 --- a/third_party/blink/web_tests/external/wpt/preload/link-header-on-subresource.html +++ b/third_party/blink/web_tests/external/wpt/preload/link-header-on-subresource.html
@@ -6,12 +6,13 @@ var t = async_test('Makes sure that Link headers on subresources preload resources'); </script> <link rel=stylesheet href="resources/dummy-preloads-subresource.css?link-header-on-subresource"> -<script src="resources/dummy.js?pipe=trickle(d5)&link-header-on-subresources"></script> <script> window.addEventListener("load", t.step_func(function() { - verifyPreloadAndRTSupport(); - verifyNumberOfDownloads("/fonts/CanvasTest.ttf?link-header-on-subresource", 1); - t.done(); + t.step_timeout(function() { + verifyPreloadAndRTSupport(); + verifyNumberOfResourceTimingEntries("/fonts/CanvasTest.ttf?link-header-on-subresource", 1); + t.done(); + }, 5000); })); </script>
diff --git a/third_party/blink/web_tests/external/wpt/preload/link-header-preload-delay-onload.html b/third_party/blink/web_tests/external/wpt/preload/link-header-preload-delay-onload.html index 7f38f8c9..a445d80 100644 --- a/third_party/blink/web_tests/external/wpt/preload/link-header-preload-delay-onload.html +++ b/third_party/blink/web_tests/external/wpt/preload/link-header-preload-delay-onload.html
@@ -31,10 +31,10 @@ } } assert_true(found_background_first); - verifyNumberOfDownloads("resources/square.png?link-header-preload-delay-onload", 1); - verifyNumberOfDownloads("resources/square.png?background", 1); - verifyNumberOfDownloads("resources/dummy.js?link-header-preload-delay-onload", 1); - verifyNumberOfDownloads("resources/dummy.css?link-header-preload-delay-onload", 1); + verifyLoadedAndNoDoubleDownload("resources/square.png?link-header-preload-delay-onload"); + verifyLoadedAndNoDoubleDownload("resources/square.png?background"); + verifyLoadedAndNoDoubleDownload("resources/dummy.js?link-header-preload-delay-onload"); + verifyLoadedAndNoDoubleDownload("resources/dummy.css?link-header-preload-delay-onload"); t.done(); })); </script>
diff --git a/third_party/blink/web_tests/external/wpt/preload/link-header-preload-nonce.html b/third_party/blink/web_tests/external/wpt/preload/link-header-preload-nonce.html index 240d6f1..dc1ec10 100644 --- a/third_party/blink/web_tests/external/wpt/preload/link-header-preload-nonce.html +++ b/third_party/blink/web_tests/external/wpt/preload/link-header-preload-nonce.html
@@ -5,12 +5,13 @@ <script nonce="abc"> var t = async_test('Makes sure that Link headers preload resources with CSP nonce'); </script> -<script nonce="abc" src="resources/dummy.js?pipe=trickle(d5)&link-header-preload-nonce"></script> <script nonce="abc"> window.addEventListener('load', t.step_func(function() { - verifyPreloadAndRTSupport(); - verifyNumberOfResourceTimingEntries("resources/dummy.js?from-header&without-nonce", 0); - verifyNumberOfResourceTimingEntries("resources/dummy.js?from-header&with-nonce", 1); - t.done(); + t.step_timeout(function() { + verifyPreloadAndRTSupport(); + verifyNumberOfResourceTimingEntries("resources/dummy.js?from-header&without-nonce", 0); + verifyNumberOfResourceTimingEntries("resources/dummy.js?from-header&with-nonce", 1); + t.done(); + }, 5000); })); </script>
diff --git a/third_party/blink/web_tests/external/wpt/preload/link-header-preload-srcset.tentative.html b/third_party/blink/web_tests/external/wpt/preload/link-header-preload-srcset.tentative.html index 024da96..8d057549 100644 --- a/third_party/blink/web_tests/external/wpt/preload/link-header-preload-srcset.tentative.html +++ b/third_party/blink/web_tests/external/wpt/preload/link-header-preload-srcset.tentative.html
@@ -7,21 +7,22 @@ var t = async_test('Makes sure that Link headers preload images with (experimental) imagesrcset/imagesizes attributes.'); </script> <body> -<script src="resources/dummy.js?pipe=trickle(d3)&link-header-preload-srcset"></script> <script> window.addEventListener("load", t.step_func(function() { - verifyPreloadAndRTSupport(); - verifyNumberOfResourceTimingEntries('resources/square.png?from-header&1x', 1); - verifyNumberOfResourceTimingEntries('resources/square.png?from-header&2x', 0); - verifyNumberOfResourceTimingEntries('resources/square.png?from-header&3x', 0); - verifyNumberOfResourceTimingEntries('resources/square.png?from-header&base', 0); - verifyNumberOfResourceTimingEntries('resources/square.png?from-header&200', 0); - verifyNumberOfResourceTimingEntries('resources/square.png?from-header&400', 1); - verifyNumberOfResourceTimingEntries('resources/square.png?from-header&800', 0); - verifyNumberOfResourceTimingEntries('resources/square.png?from-header&150', 0); - verifyNumberOfResourceTimingEntries('resources/square.png?from-header&300', 1); - verifyNumberOfResourceTimingEntries('resources/square.png?from-header&600', 0); - t.done(); + t.step_timeout(function() { + verifyPreloadAndRTSupport(); + verifyNumberOfResourceTimingEntries('resources/square.png?from-header&1x', 1); + verifyNumberOfResourceTimingEntries('resources/square.png?from-header&2x', 0); + verifyNumberOfResourceTimingEntries('resources/square.png?from-header&3x', 0); + verifyNumberOfResourceTimingEntries('resources/square.png?from-header&base', 0); + verifyNumberOfResourceTimingEntries('resources/square.png?from-header&200', 0); + verifyNumberOfResourceTimingEntries('resources/square.png?from-header&400', 1); + verifyNumberOfResourceTimingEntries('resources/square.png?from-header&800', 0); + verifyNumberOfResourceTimingEntries('resources/square.png?from-header&150', 0); + verifyNumberOfResourceTimingEntries('resources/square.png?from-header&300', 1); + verifyNumberOfResourceTimingEntries('resources/square.png?from-header&600', 0); + t.done(); + }, 3000); })); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/preload/link-header-preload.html b/third_party/blink/web_tests/external/wpt/preload/link-header-preload.html index 94a731b..0ca364b 100644 --- a/third_party/blink/web_tests/external/wpt/preload/link-header-preload.html +++ b/third_party/blink/web_tests/external/wpt/preload/link-header-preload.html
@@ -6,14 +6,15 @@ var t = async_test('Makes sure that Link headers preload resources'); </script> <body> -<script src="resources/dummy.js?pipe=trickle(d5)&link-header-preload"></script> <script> window.addEventListener("load", t.step_func(function() { - verifyPreloadAndRTSupport(); - verifyNumberOfDownloads("resources/square.png?link-header-preload", 1); - verifyNumberOfDownloads("resources/dummy.js?link-header-preload", 1); - verifyNumberOfDownloads("resources/dummy.css?link-header-preload", 1); - t.done(); + t.step_timeout(function() { + verifyPreloadAndRTSupport(); + verifyNumberOfResourceTimingEntries("resources/square.png?link-header-preload", 1); + verifyNumberOfResourceTimingEntries("resources/dummy.js?link-header-preload", 1); + verifyNumberOfResourceTimingEntries("resources/dummy.css?link-header-preload", 1); + t.done(); + }, 5000); })); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/preload/onerror-event.html b/third_party/blink/web_tests/external/wpt/preload/onerror-event.html index 5fae70d..8190be87 100644 --- a/third_party/blink/web_tests/external/wpt/preload/onerror-event.html +++ b/third_party/blink/web_tests/external/wpt/preload/onerror-event.html
@@ -28,21 +28,22 @@ <link rel=preload href="non-existent/dummy.xml?foo" as=foobarxmlthing onerror="gibberishFailed = true;"> <link rel=preload href="non-existent/dummy.xml?fetch" as=fetch onerror="fetchFailed = true;"> <link rel=preload href="non-existent/dummy.xml?empty" onerror="emptyFailed = true;"> -<script src="resources/dummy.js?pipe=trickle(d5)&onerror-event"></script> <script> window.onload = t.step_func(function() { - verifyPreloadAndRTSupport(); - assert_true(styleFailed, "style triggered error event"); - assert_true(scriptFailed, "script triggered error event"); - assert_true(imageFailed, "image triggered error event"); - assert_true(fontFailed, "font triggered error event"); - assert_true(videoFailed, "video triggered error event"); - assert_true(audioFailed, "audio triggered error event"); - assert_true(trackFailed, "track triggered error event"); - assert_false(gibberishFailed, "gibberish as value did not trigger error event"); - assert_true(fetchFailed, "fetch as triggered error event"); - assert_false(emptyFailed, "empty as triggered error event"); - t.done(); + t.step_timeout(function() { + verifyPreloadAndRTSupport(); + assert_true(styleFailed, "style triggered error event"); + assert_true(scriptFailed, "script triggered error event"); + assert_true(imageFailed, "image triggered error event"); + assert_true(fontFailed, "font triggered error event"); + assert_true(videoFailed, "video triggered error event"); + assert_true(audioFailed, "audio triggered error event"); + assert_true(trackFailed, "track triggered error event"); + assert_false(gibberishFailed, "gibberish as value did not trigger error event"); + assert_true(fetchFailed, "fetch as triggered error event"); + assert_false(emptyFailed, "empty as triggered error event"); + t.done(); + }, 5000); }); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/preload/onload-event.html b/third_party/blink/web_tests/external/wpt/preload/onload-event.html index 6af2d64a..f9348b8c 100644 --- a/third_party/blink/web_tests/external/wpt/preload/onload-event.html +++ b/third_party/blink/web_tests/external/wpt/preload/onload-event.html
@@ -27,22 +27,23 @@ <link rel=preload href="resources/dummy.xml?fetch" as=fetch onload="fetchLoaded = true;"> <link rel=preload href="resources/dummy.xml" onload="noTypeLoaded = true;"> <body> -<script src="resources/dummy.js?pipe=trickle(d5)&onload-event"></script> <script> window.onload = t.step_func(function() { - verifyPreloadAndRTSupport(); - assert_true(styleLoaded, "style triggered load event"); - assert_true(scriptLoaded, "script triggered load event"); - assert_true(imageLoaded, "image triggered load event"); - assert_true(fontLoaded, "font triggered load event"); - assert_true(videoLoaded, "video triggered load event"); - assert_true(audioLoaded, "audio triggered load event"); - assert_true(trackLoaded, "track triggered load event"); - assert_false(gibberishLoaded, "gibberish as value triggered load event"); - assert_false(gibberishErrored, "gibberish as value triggered error event"); - assert_true(fetchLoaded, "fetch as value triggered load event"); - assert_false(noTypeLoaded, "empty as triggered load event"); - t.done(); + t.step_timeout(function() { + verifyPreloadAndRTSupport(); + assert_true(styleLoaded, "style triggered load event"); + assert_true(scriptLoaded, "script triggered load event"); + assert_true(imageLoaded, "image triggered load event"); + assert_true(fontLoaded, "font triggered load event"); + assert_true(videoLoaded, "video triggered load event"); + assert_true(audioLoaded, "audio triggered load event"); + assert_true(trackLoaded, "track triggered load event"); + assert_false(gibberishLoaded, "gibberish as value triggered load event"); + assert_false(gibberishErrored, "gibberish as value triggered error event"); + assert_true(fetchLoaded, "fetch as value triggered load event"); + assert_false(noTypeLoaded, "empty as triggered load event"); + t.done(); + }, 5000); }); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/preload/preload-csp.sub.html b/third_party/blink/web_tests/external/wpt/preload/preload-csp.sub.html index 8e5e45b..7fe06eb0 100644 --- a/third_party/blink/web_tests/external/wpt/preload/preload-csp.sub.html +++ b/third_party/blink/web_tests/external/wpt/preload/preload-csp.sub.html
@@ -16,19 +16,20 @@ <link rel=preload href="resources/dummy.xml?foo=bar" as=foobarxmlthing> <link rel=preload href="resources/dummy.xml"> <body> -<script src="resources/dummy.js?pipe=trickle(d5)&preload-csp"></script> <script> window.onload = t.step_func(function() { - verifyPreloadAndRTSupport(); - verifyNumberOfDownloads("{{host}}:{{ports[http][1]}}/preload/resources/dummy.js", 0); - verifyNumberOfDownloads("resources/dummy.css", 0); - verifyNumberOfDownloads("resources/square.png", 0); - verifyNumberOfDownloads("/fonts/CanvasTest.ttf", 0); - verifyNumberOfDownloads("resources/white.mp4", 0); - verifyNumberOfDownloads("resources/sound_5.oga", 0); - verifyNumberOfDownloads("resources/foo.vtt", 0); - verifyNumberOfDownloads("resources/dummy.xml", 0); - t.done(); + t.step_timeout(function() { + verifyPreloadAndRTSupport(); + verifyNumberOfResourceTimingEntries("{{host}}:{{ports[http][1]}}/preload/resources/dummy.js", 0); + verifyNumberOfResourceTimingEntries("resources/dummy.css", 0); + verifyNumberOfResourceTimingEntries("resources/square.png", 0); + verifyNumberOfResourceTimingEntries("/fonts/CanvasTest.ttf", 0); + verifyNumberOfResourceTimingEntries("resources/white.mp4", 0); + verifyNumberOfResourceTimingEntries("resources/sound_5.oga", 0); + verifyNumberOfResourceTimingEntries("resources/foo.vtt", 0); + verifyNumberOfResourceTimingEntries("resources/dummy.xml", 0); + t.done(); + }, 5000); }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/preload/preload-default-csp.sub.html b/third_party/blink/web_tests/external/wpt/preload/preload-default-csp.sub.html index cb080e6..7813e36 100644 --- a/third_party/blink/web_tests/external/wpt/preload/preload-default-csp.sub.html +++ b/third_party/blink/web_tests/external/wpt/preload/preload-default-csp.sub.html
@@ -16,19 +16,20 @@ <link rel=preload href="resources/dummy.xml?foo=bar" as=foobarxmlthing> <link rel=preload href="resources/dummy.xml"> <body> -<script src="resources/dummy.js?pipe=trickle(d5)&preload-default-csp"></script> <script> window.onload = t.step_func(function() { - verifyPreloadAndRTSupport(); - verifyNumberOfDownloads("{{host}}:{{ports[http][1]}}/preload/resources/dummy.js", 0); - verifyNumberOfDownloads("resources/dummy.css", 0); - verifyNumberOfDownloads("resources/square.png", 0); - verifyNumberOfDownloads("/fonts/CanvasTest.ttf", 0); - verifyNumberOfDownloads("resources/white.mp4", 0); - verifyNumberOfDownloads("resources/sound_5.oga", 0); - verifyNumberOfDownloads("resources/foo.vtt", 0); - verifyNumberOfDownloads("resources/dummy.xml", 0); - t.done(); + t.step_timeout(function() { + verifyPreloadAndRTSupport(); + verifyNumberOfResourceTimingEntries("{{host}}:{{ports[http][1]}}/preload/resources/dummy.js", 0); + verifyNumberOfResourceTimingEntries("resources/dummy.css", 0); + verifyNumberOfResourceTimingEntries("resources/square.png", 0); + verifyNumberOfResourceTimingEntries("/fonts/CanvasTest.ttf", 0); + verifyNumberOfResourceTimingEntries("resources/white.mp4", 0); + verifyNumberOfResourceTimingEntries("resources/sound_5.oga", 0); + verifyNumberOfResourceTimingEntries("resources/foo.vtt", 0); + verifyNumberOfResourceTimingEntries("resources/dummy.xml", 0); + t.done(); + }, 5000); }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/preload/preload-with-type.html b/third_party/blink/web_tests/external/wpt/preload/preload-with-type.html index 8578143..83eafc5 100644 --- a/third_party/blink/web_tests/external/wpt/preload/preload-with-type.html +++ b/third_party/blink/web_tests/external/wpt/preload/preload-with-type.html
@@ -47,19 +47,20 @@ </script> <link rel=preload href="resources/foo.vtt" as=track type="text/foobar" onload="gibberishLoaded++;"> <body> -<script src="resources/dummy.js?pipe=trickle(d5)&preload-with-type"></script> <script> window.onload = t.step_func(function() { - verifyPreloadAndRTSupport(); - assert_true(styleLoaded, "style triggered load event"); - assert_true(scriptLoaded, "script triggered load event"); - assert_true(imageLoaded, "image triggered load event"); - assert_true(fontLoaded, "font triggered load event"); - assert_true(videoLoaded, "video triggered load event"); - assert_true(audioLoaded, "audio triggered load event"); - assert_true(trackLoaded, "track triggered load event"); - assert_equals(gibberishLoaded, 0, "resources with gibberish type should not be loaded"); - t.done(); + t.step_timeout(function() { + verifyPreloadAndRTSupport(); + assert_true(styleLoaded, "style triggered load event"); + assert_true(scriptLoaded, "script triggered load event"); + assert_true(imageLoaded, "image triggered load event"); + assert_true(fontLoaded, "font triggered load event"); + assert_true(videoLoaded, "video triggered load event"); + assert_true(audioLoaded, "audio triggered load event"); + assert_true(trackLoaded, "track triggered load event"); + assert_equals(gibberishLoaded, 0, "resources with gibberish type should not be loaded"); + t.done(); + }, 5000); }); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/preload/resources/preload_helper.js b/third_party/blink/web_tests/external/wpt/preload/resources/preload_helper.js index b2cf832..f464908 100644 --- a/third_party/blink/web_tests/external/wpt/preload/resources/preload_helper.js +++ b/third_party/blink/web_tests/external/wpt/preload/resources/preload_helper.js
@@ -10,19 +10,32 @@ return new URL(url, location.href).href; } -function verifyNumberOfDownloads(url, number) -{ - var numDownloads = 0; - performance.getEntriesByName(getAbsoluteURL(url)).forEach(entry => { - if (entry.transferSize > 0) { - numDownloads++; - } - }); - assert_equals(numDownloads, number, url); -} - function verifyNumberOfResourceTimingEntries(url, number) { var numEntries = performance.getEntriesByName(getAbsoluteURL(url)).length; assert_equals(numEntries, number, url); } + +// Verifies that the resource is loaded, but not downloaded from network +// more than once. This can be used to verify that a preloaded resource is +// not downloaded again when used. +function verifyLoadedAndNoDoubleDownload(url) { + var entries = performance.getEntriesByName(getAbsoluteURL(url)); + // UA may create separate RT entries for preload and normal load, + // so we just check (entries.length > 0). + assert_greater_than(entries.length, 0, url + ' should be loaded'); + + var numDownloads = 0; + entries.forEach(entry => { + // transferSize is zero if the resource is loaded from cache. + if (entry.transferSize > 0) { + numDownloads++; + } + }); + // numDownloads can be zero if the resource was already cached before running + // the test (for example, when the test is running repeatedly without + // clearing cache between runs). + assert_less_than_equal( + numDownloads, 1, + url + ' should be downloaded from network at most once'); +}
diff --git a/third_party/blink/web_tests/external/wpt/preload/single-download-late-used-preload.html b/third_party/blink/web_tests/external/wpt/preload/single-download-late-used-preload.html index 5549cb8..51533ba 100644 --- a/third_party/blink/web_tests/external/wpt/preload/single-download-late-used-preload.html +++ b/third_party/blink/web_tests/external/wpt/preload/single-download-late-used-preload.html
@@ -9,11 +9,11 @@ assert_equals(link.as, "image"); link.addEventListener("load", () => { verifyPreloadAndRTSupport(); - verifyNumberOfDownloads("resources/square.png?pipe=trickle(d1)", 1); + verifyNumberOfResourceTimingEntries("resources/square.png?pipe=trickle(d1)", 1); var img = document.createElement("img"); img.src = "resources/square.png?pipe=trickle(d1)"; img.onload = () => { - verifyNumberOfDownloads("resources/square.png?pipe=trickle(d1)", 1); + verifyLoadedAndNoDoubleDownload("resources/square.png?pipe=trickle(d1)"); done(); }; document.body.appendChild(img);
diff --git a/third_party/blink/web_tests/external/wpt/preload/single-download-preload.html b/third_party/blink/web_tests/external/wpt/preload/single-download-preload.html index e8f2617..16d893c 100644 --- a/third_party/blink/web_tests/external/wpt/preload/single-download-preload.html +++ b/third_party/blink/web_tests/external/wpt/preload/single-download-preload.html
@@ -16,7 +16,6 @@ <link rel=preload href="resources/dummy.xml?foo=bar" as=foobarxmlthing> <link rel=preload href="resources/dummy.xml?single-download-preload"> <body> -<script src="resources/dummy.js?pipe=trickle(d3)&single-download-preload"></script> <style> #background { width: 200px; @@ -45,17 +44,17 @@ window.addEventListener("load", t.step_func(function() { verifyPreloadAndRTSupport(); setTimeout(t.step_func(function() { - verifyNumberOfDownloads("resources/dummy.js?single-download-preload", 1); - verifyNumberOfDownloads("resources/dummy.css?single-download-preload", 1); - verifyNumberOfDownloads("resources/square.png?single-download-preload", 1); - verifyNumberOfDownloads("resources/square.png?background&single-download-preload", 1); - verifyNumberOfDownloads("/fonts/CanvasTest.ttf?single-download-preload", 1); - verifyNumberOfDownloads("resources/dummy.xml?foobar", 0); - verifyNumberOfDownloads("resources/foo.vtt?single-download-preload", 1); - verifyNumberOfDownloads("resources/dummy.xml?single-download-preload", 1); + verifyLoadedAndNoDoubleDownload("resources/dummy.js?single-download-preload"); + verifyLoadedAndNoDoubleDownload("resources/dummy.css?single-download-preload"); + verifyLoadedAndNoDoubleDownload("resources/square.png?single-download-preload"); + verifyLoadedAndNoDoubleDownload("resources/square.png?background&single-download-preload"); + verifyLoadedAndNoDoubleDownload("/fonts/CanvasTest.ttf?single-download-preload"); + verifyNumberOfResourceTimingEntries("resources/dummy.xml?foobar", 0); + verifyLoadedAndNoDoubleDownload("resources/foo.vtt?single-download-preload"); + verifyLoadedAndNoDoubleDownload("resources/dummy.xml?single-download-preload"); // FIXME: We should verify for video and audio as well, but they seem to (flakily?) trigger multiple partial requests. t.done(); - }), 0); + }), 3000); })); </script> <span>PASS - this text is here just so that the browser will download the font.</span>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/resource-reload-TAO.sub.html b/third_party/blink/web_tests/external/wpt/resource-timing/resource-reload-TAO.sub.html new file mode 100644 index 0000000..48ab84b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/resource-timing/resource-reload-TAO.sub.html
@@ -0,0 +1,25 @@ +<!doctype html> +<html> +<head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</head> +<body> +<iframe src="resources/iframe-reload-TAO.sub.html"></iframe> +<script> +async_test(t => { + window.onmessage = t.step_func(e => { + const data = e.data; + assert_greater_than(data.domainLookupStart, 0, + "domainLookupStart should be greater than 0."); + assert_greater_than(data.domainLookupEnd, 0, + "domainLookupEnd should be greater than 0."); + assert_greater_than(data.connectStart, 0, + "connectStart should be greater than 0."); + assert_greater_than(data.connectEnd, 0, + "connectEnd should be greater than 0."); + t.done(); + }); +}, "Test that TAO headers are reused on reloads."); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/resources/cors-ahem.py b/third_party/blink/web_tests/external/wpt/resource-timing/resources/cors-ahem.py new file mode 100644 index 0000000..1998d47c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/resource-timing/resources/cors-ahem.py
@@ -0,0 +1,17 @@ +import os.path + +def main(request, response): + etag = "123abc" + if etag == request.headers.get("If-None-Match", None): + response.headers.set("X-HTTP-STATUS", 304) + response.status = (304, "Not Modified") + return "" + + response.headers.set("Cache-Control", "public, max-age=86400") + response.headers.set("Content-Type", "font/truetype") + response.headers.set("Access-Control-Allow-Origin", "*") + response.headers.set("Timing-Allow-Origin", "*") + response.headers.set("ETag", etag) + font = "../../fonts/Ahem.ttf" + path = os.path.join(os.path.dirname(__file__), font) + response.content = open(path, "rb").read()
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/resources/iframe-reload-TAO.sub.html b/third_party/blink/web_tests/external/wpt/resource-timing/resources/iframe-reload-TAO.sub.html new file mode 100644 index 0000000..577aff77 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/resource-timing/resources/iframe-reload-TAO.sub.html
@@ -0,0 +1,28 @@ +<style> +@font-face { + font-family: ahem; + src: url(http://{{domains[www]}}:{{ports[http][1]}}/resource-timing/resources/cors-ahem.py); +} +</style> +<div style="font-family: ahem;">This fetches ahem font.</div> +<script> + if (location.hash === '#check') { + document.fonts.ready.then(()=> { + const entries = performance.getEntriesByName('http://{{domains[www]}}:{{ports[http][1]}}/resource-timing/resources/cors-ahem.py'); + if (entries.length != 1) + return; + const entry = entries[0]; + window.parent.postMessage({ + "domainLookupStart": entry.domainLookupStart, + "domainLookupEnd": entry.domainLookupEnd, + "connectStart": entry.connectStart, + "connectEnd": entry.connectEnd + }, "*"); + }); + } else { + document.fonts.ready.then(() => { + location.hash = 'check'; + location.reload(); + }); + } +</script>
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/testcommon.js b/third_party/blink/web_tests/external/wpt/web-animations/testcommon.js index 5dbf6fd7..e6dad7c 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/testcommon.js +++ b/third_party/blink/web_tests/external/wpt/web-animations/testcommon.js
@@ -191,13 +191,13 @@ function waitForNextFrame() { const timeAtStart = document.timeline.currentTime; return new Promise(resolve => { - window.requestAnimationFrame(() => { - if (timeAtStart === document.timeline.currentTime) { - window.requestAnimationFrame(resolve); - } else { - resolve(); - } - }); + (function handleFrame() { + if (timeAtStart === document.timeline.currentTime) { + window.requestAnimationFrame(handleFrame); + } else { + resolve(); + } + }()); }); }
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCIceConnectionState-candidate-pair.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCIceConnectionState-candidate-pair.https.html new file mode 100644 index 0000000..7280d040 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCIceConnectionState-candidate-pair.https.html
@@ -0,0 +1,33 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<title>RTCIceConnectionState and RTCIceCandidatePair</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="RTCPeerConnection-helper.js"></script> +<script> +'use strict'; + +promise_test(async t => { + const caller = new RTCPeerConnection(); + t.add_cleanup(() => caller.close()); + const callee = new RTCPeerConnection(); + t.add_cleanup(() => callee.close()); + + const stream = await navigator.mediaDevices.getUserMedia({audio:true}); + const [track] = stream.getTracks(); + caller.addTrack(track, stream); + exchangeIceCandidates(caller, callee); + await doSignalingHandshake(caller, callee); + await listenToIceConnected(t, caller); + + const report = await caller.getStats(); + let succeededPairFound = false; + report.forEach(stats => { + if (stats.type == 'candidate-pair' && stats.state == 'succeeded') + succeededPairFound = true; + }); + assert_true(succeededPairFound, 'A succeeded candidate-pair should exist'); +}, 'On ICE connected, getStats() contains a connected candidate-pair'); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-helper.js b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-helper.js index d1056d90f3..1ff5f540 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-helper.js +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-helper.js
@@ -205,6 +205,55 @@ await localPc.setRemoteDescription(answer); } +// Returns a promise that resolves when |pc.iceConnectionState| is 'connected' +// or 'completed'. +function listenToIceConnected(pc) { + return new Promise((resolve) => { + function isConnected(pc) { + return pc.iceConnectionState == 'connected' || + pc.iceConnectionState == 'completed'; + } + if (isConnected(pc)) { + resolve(); + return; + } + pc.oniceconnectionstatechange = () => { + if (isConnected(pc)) + resolve(); + }; + }); +} + +// Returns a promise that resolves when |pc.connectionState| is 'connected'. +function listenToConnected(pc) { + return new Promise((resolve) => { + if (pc.connectionState == 'connected') { + resolve(); + return; + } + pc.onconnectionstatechange = () => { + if (pc.connectionState == 'connected') + resolve(); + }; + }); +} + +// Resolves when RTP packets have been received. +function listenForSSRCs(t, receiver) { + return new Promise((resolve) => { + function listen() { + const ssrcs = receiver.getSynchronizationSources(); + assert_true(ssrcs != undefined); + if (ssrcs.length > 0) { + resolve(ssrcs); + return; + } + t.step_timeout(listen, 0); + }; + listen(); + }); +} + // Helper function to create a pair of connected data channel. // On success the promise resolves to an array with two data channels. // It does the heavy lifting of performing signaling handshake,
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html similarity index 91% rename from third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.html rename to third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html index b647b3d3..8acabf4 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.html +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html
@@ -182,6 +182,26 @@ }, 'connection with one data channel should eventually ' + 'have connected connection state'); + promise_test(async t => { + const caller = new RTCPeerConnection(); + t.add_cleanup(() => caller.close()); + const callee = new RTCPeerConnection(); + t.add_cleanup(() => callee.close()); + + caller.addTransceiver('audio', {direction:'recvonly'}); + const stream = await navigator.mediaDevices.getUserMedia({audio:true}); + const [track] = stream.getTracks(); + callee.addTrack(track, stream); + exchangeIceCandidates(caller, callee); + await doSignalingHandshake(caller, callee); + + assert_equals(caller.getTransceivers().length, 1); + const [transceiver] = caller.getTransceivers(); + assert_equals(transceiver.currentDirection, 'recvonly'); + + await listenToIceConnected(caller); + }, 'ICE can connect in a recvonly usecase'); + /* TODO 4.4.4 RTCIceConnectionState Enum
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-track-stats.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-track-stats.https.html index 2d45c34..e394e63e 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-track-stats.https.html +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-track-stats.https.html
@@ -404,7 +404,7 @@ callee.addTrack(tracks[1], streams[1]); exchangeIceCandidates(caller, callee); await doSignalingHandshake(caller, callee); - await onIceConnectionStateCompleted(caller); + await listenToConnected(caller); let receiver = caller.getReceivers()[0]; // Obtain inbound and outbound RTP stream stats on a full stats report. @@ -452,7 +452,7 @@ callee.addTrack(tracks[1], streams[1]); exchangeIceCandidates(caller, callee); await doSignalingHandshake(caller, callee); - await onIceConnectionStateCompleted(caller); + await listenToConnected(caller); let receiver = caller.getReceivers()[0]; // Obtain inbound and outbound RTP stream stats on a full stats report. @@ -500,7 +500,7 @@ callee.addTrack(tracks[1], streams[1]); exchangeIceCandidates(caller, callee); await doSignalingHandshake(caller, callee); - await onIceConnectionStateCompleted(caller); + await listenToIceConnected(caller); // Wait until RTCP has arrived so that it can not arrive between // the two get stats calls. @@ -531,7 +531,7 @@ callee.addTrack(tracks[1], streams[1]); exchangeIceCandidates(caller, callee); await doSignalingHandshake(caller, callee); - await onIceConnectionStateCompleted(caller); + await listenToIceConnected(caller); let receiver = caller.getReceivers()[0]; // Wait until RTCP has arrived so that it can not arrive between @@ -603,24 +603,6 @@ return stats; } - // Returns a promise that is resolved when pc.iceConnectionState reaches the - // 'connected' or 'completed' state. This is when transport stats can be - // expected to have its selectedCandidatePairId defined. - async function onIceConnectionStateCompleted(pc) { - if (pc.iceConnectionState == 'connected' || - pc.iceConnectionState == 'completed') { - return Promise.resolve(); - } - let resolver = new Resolver(); - pc.oniceconnectionstatechange = e => { - if (pc.iceConnectionState == 'connected' || - pc.iceConnectionState == 'completed') { - resolver.resolve(); - } - }; - return resolver; - } - // Explores the stats graph starting from |stat|, validating each stat // (validateRtcStats) and asserting that all stats of the report were visited. function validateStatsGraph(report, stat) {
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-getSynchronizationSources.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-getSynchronizationSources.https.html index 36460b4..82ce3bd 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-getSynchronizationSources.https.html +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-getSynchronizationSources.https.html
@@ -26,21 +26,6 @@ return trackEvent.receiver; } -function listenForSSRCs(t, receiver) { - return new Promise((resolve) => { - function listen() { - const ssrcs = receiver.getSynchronizationSources(); - assert_true(ssrcs != undefined); - if (ssrcs.length > 0) { - resolve(ssrcs); - return; - } - t.step_timeout(listen, 0); - }; - listen(); - }); -} - for (const kind of ['audio', 'video']) { promise_test(async t => { const receiver = await initiateSingleTrackCallAndReturnReceiver(t, kind);
diff --git a/third_party/blink/web_tests/fast/scroll-behavior/wheel-and-touch-scroll-use-count.html b/third_party/blink/web_tests/fast/scroll-behavior/wheel-and-touch-scroll-use-count.html index c7ea5f2..0418a97 100644 --- a/third_party/blink/web_tests/fast/scroll-behavior/wheel-and-touch-scroll-use-count.html +++ b/third_party/blink/web_tests/fast/scroll-behavior/wheel-and-touch-scroll-use-count.html
@@ -38,14 +38,20 @@ async function scrollDown(pixels_to_scroll, gesture_source_type) { const precise_deltas = true; - const previous_scroll_offset = scrollable.scrollTop; await waitForCompositorCommit(); - + const previous_scroll_offset = scrollable.scrollTop; + await smoothScroll(pixels_to_scroll, start_x, start_y, gesture_source_type, 'down', SPEED_INSTANT, precise_deltas); await waitFor(() => { - return scrollable.scrollTop - previous_scroll_offset >= pixels_to_scroll; - }, "Didn't scroll by expected amount: " + pixels_to_scroll); + // To avoid test flakiness, instead of expecting to scroll by + // pixels_to_scroll precisely, up to 3 pixels error is also accepted. + // TODO(bokan): Change to precise expectation once https://crbug.com/897520 + // fixed. + return approx_equals(scrollable.scrollTop - previous_scroll_offset, + pixels_to_scroll, + 3 /* pixels */); + }, "Didn't scroll by approximately expected amount: " + pixels_to_scroll); await waitForCompositorCommit(); } @@ -54,7 +60,7 @@ promise_test(async () => { await scrollDown(50, GestureSourceType.MOUSE_INPUT); - await waitFor(() => { + await waitFor(() => { return internals.isUseCounted(document, SCROLL_BY_WHEEL_COUNTER); }, "Didn't record wheel use count"); }, "Scrolling by wheel on main/compositor should update usecounters.");
diff --git a/third_party/blink/web_tests/http/tests/css/resource-timing-details-for-revalidation.html b/third_party/blink/web_tests/http/tests/css/resource-timing-details-for-revalidation.html deleted file mode 100644 index 7200c91..0000000 --- a/third_party/blink/web_tests/http/tests/css/resource-timing-details-for-revalidation.html +++ /dev/null
@@ -1,34 +0,0 @@ -<!DOCTYPE html> -<script src="/js-test-resources/js-test.js"></script> -<style> -@font-face { - font-family: ahem; - src: url(http://localhost:8080/css/resources/cors-ahem.php); -} -</style> - -<div style="font-family: ahem;">This fetches ahem font.<div> - -<script> -if (window.testRunner) - testRunner.waitUntilDone(); - -var entry; -if (location.hash == '#check') { - document.fonts.ready.then(function() { - setTimeout(function() { - entry = performance.getEntriesByName('http://localhost:8080/css/resources/cors-ahem.php')[0]; - shouldBeTrue('entry.domainLookupStart > 0'); - if (window.testRunner) - testRunner.notifyDone(); - }, 10); - }); -} else { - document.fonts.ready.then(function() { - setTimeout(function() { - location.hash = 'check'; - location.reload(); - }, 10); - }); -} -</script>
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-8-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-8-expected.txt new file mode 100644 index 0000000..77506623 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-8-expected.txt
@@ -0,0 +1,105 @@ +This is a testharness.js-based test. +Found 101 tests; 61 PASS, 40 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS load nested browsing context <frame src> +PASS load nested browsing context <iframe src> +PASS load nested browsing context <object data> +PASS load nested browsing context <embed src> +PASS loading css <link> +PASS loading js <script> +PASS loading image <img src> +FAIL loading image <embed src> assert_equals: expected substring %C3%A5 got default intrinsic width expected 2 but got 300 +FAIL loading image <object data> assert_equals: expected substring %C3%A5 got default intrinsic width expected 2 but got 300 +PASS loading image <input src> +PASS loading image <video poster> +FAIL loading video <video> assert_equals: expected substring %C3%A5 got %E5 expected 5 but got 3 +FAIL loading video <video><source> assert_equals: expected substring %C3%A5 got %E5 expected 5 but got 3 +FAIL loading video <audio> assert_equals: expected substring %C3%A5 got %E5 expected 5 but got 3 +FAIL loading video <audio><source> assert_equals: expected substring %C3%A5 got %E5 expected 5 but got 3 +PASS loading webvtt <track> +PASS submit form <form action> +PASS submit form <input formaction> +PASS submit form <button formaction> +PASS <base href> +PASS Worker constructor +PASS SharedWorker constructor +PASS EventSource constructor +PASS EventSource#url +FAIL XMLDocument#load() doc.load is not a function +PASS window.open() +PASS <a>.search +PASS <area>.search +FAIL history.pushState assert_equals: url was resolved against the iframe's URL instead of the settings object's API base URL expected -1 but got 84 +FAIL history.replaceState assert_equals: url was resolved against the iframe's URL instead of the settings object's API base URL expected -1 but got 84 +PASS SVG <a> +FAIL SVG <feImage> poll_for_stash is not defined +FAIL SVG <image> poll_for_stash is not defined +FAIL SVG <use> poll_for_stash is not defined +PASS XMLHttpRequest#open() +PASS importScripts() in a dedicated worker +PASS Worker() in a dedicated worker +FAIL SharedWorker() in a dedicated worker assert_equals: expected "%C3%A5" but got "ReferenceError: SharedWorker is not defined" +FAIL importScripts() in a shared worker assert_equals: expected "%C3%A5" but got "importScripts failed to run" +FAIL Worker() in a shared worker assert_equals: expected "%C3%A5" but got "ReferenceError: Worker is not defined" +FAIL SharedWorker() in a shared worker assert_equals: expected "%C3%A5" but got "ReferenceError: SharedWorker is not defined" +PASS WebSocket constructor +PASS WebSocket#url +FAIL Parsing cache manifest (CACHE) poll_for_stash is not defined +FAIL Parsing cache manifest (FALLBACK) poll_for_stash is not defined +FAIL Parsing cache manifest (NETWORK) poll_for_stash is not defined +FAIL CSS <link> (utf-8) #<id> { background-image:<url> } poll_for_stash is not defined +FAIL CSS <link> (windows-1252) #<id> { background-image:<url> } poll_for_stash is not defined +FAIL CSS <style> #<id> { background-image:<url> } poll_for_stash is not defined +FAIL CSS <link> (utf-8) #<id> { border-image-source:<url> } poll_for_stash is not defined +FAIL CSS <link> (windows-1252) #<id> { border-image-source:<url> } poll_for_stash is not defined +FAIL CSS <style> #<id> { border-image-source:<url> } poll_for_stash is not defined +FAIL CSS <link> (utf-8) #<id>::before { content:<url> } poll_for_stash is not defined +FAIL CSS <link> (windows-1252) #<id>::before { content:<url> } poll_for_stash is not defined +FAIL CSS <style> #<id>::before { content:<url> } poll_for_stash is not defined +FAIL CSS <link> (utf-8) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } poll_for_stash is not defined +FAIL CSS <link> (windows-1252) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } poll_for_stash is not defined +FAIL CSS <style> @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } poll_for_stash is not defined +FAIL CSS <link> (utf-8) #<id> { display:list-item; list-style-image:<url> } poll_for_stash is not defined +FAIL CSS <link> (windows-1252) #<id> { display:list-item; list-style-image:<url> } poll_for_stash is not defined +FAIL CSS <style> #<id> { display:list-item; list-style-image:<url> } poll_for_stash is not defined +FAIL CSS <link> (utf-8) @import <url>; poll_for_stash is not defined +FAIL CSS <link> (windows-1252) @import <url>; poll_for_stash is not defined +FAIL CSS <style> @import <url>; poll_for_stash is not defined +FAIL CSS <link> (utf-8) #<id> { cursor:<url>, pointer } poll_for_stash is not defined +FAIL CSS <link> (windows-1252) #<id> { cursor:<url>, pointer } poll_for_stash is not defined +FAIL CSS <style> #<id> { cursor:<url>, pointer } poll_for_stash is not defined +PASS <?xml-stylesheet?> (CSS) +PASS URL constructor, url +PASS URL constructor, base +PASS Scheme ftp (getting <a>.href) +PASS Scheme file (getting <a>.href) +PASS Scheme gopher (getting <a>.href) +PASS Scheme http (getting <a>.href) +PASS Scheme https (getting <a>.href) +PASS Scheme ws (getting <a>.href) +PASS Scheme wss (getting <a>.href) +PASS Scheme mailto (getting <a>.href) +PASS Scheme data (getting <a>.href) +PASS Scheme javascript (getting <a>.href) +PASS Scheme ftps (getting <a>.href) +PASS Scheme httpbogus (getting <a>.href) +PASS Scheme bitcoin (getting <a>.href) +PASS Scheme geo (getting <a>.href) +PASS Scheme im (getting <a>.href) +PASS Scheme irc (getting <a>.href) +PASS Scheme ircs (getting <a>.href) +PASS Scheme magnet (getting <a>.href) +PASS Scheme mms (getting <a>.href) +PASS Scheme news (getting <a>.href) +PASS Scheme nntp (getting <a>.href) +PASS Scheme sip (getting <a>.href) +PASS Scheme sms (getting <a>.href) +PASS Scheme smsto (getting <a>.href) +PASS Scheme ssh (getting <a>.href) +PASS Scheme tel (getting <a>.href) +PASS Scheme urn (getting <a>.href) +PASS Scheme webcal (getting <a>.href) +PASS Scheme wtai (getting <a>.href) +PASS Scheme xmpp (getting <a>.href) +PASS Scheme web+http (getting <a>.href) +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251-expected.txt new file mode 100644 index 0000000..4de5bd1 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251-expected.txt
@@ -0,0 +1,105 @@ +This is a testharness.js-based test. +Found 101 tests; 51 PASS, 50 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS load nested browsing context <frame src> +PASS load nested browsing context <iframe src> +PASS load nested browsing context <object data> +PASS load nested browsing context <embed src> +PASS loading css <link> +PASS loading js <script> +FAIL loading image <img src> assert_equals: expected substring %26%23229%3B got unknown query expected (undefined) undefined but got (number) 256 +FAIL loading image <embed src> assert_equals: expected substring %26%23229%3B got default intrinsic width expected (undefined) undefined but got (number) 300 +FAIL loading image <object data> assert_equals: expected substring %26%23229%3B got default intrinsic width expected (undefined) undefined but got (number) 300 +FAIL loading image <input src> assert_equals: expected substring %26%23229%3B got unknown query expected (undefined) undefined but got (number) 256 +FAIL loading image <video poster> assert_equals: expected substring %26%23229%3B got unknown query expected (undefined) undefined but got (number) 256 +FAIL loading video <video> assert_equals: expected substring %26%23229%3B got undefined expected (undefined) undefined but got (number) 614 +FAIL loading video <video><source> assert_equals: expected substring %26%23229%3B got undefined expected (undefined) undefined but got (number) 614 +FAIL loading video <audio> assert_equals: expected substring %26%23229%3B got undefined expected (undefined) undefined but got (number) 614 +FAIL loading video <audio><source> assert_equals: expected substring %26%23229%3B got undefined expected (undefined) undefined but got (number) 614 +PASS loading webvtt <track> +PASS submit form <form action> +PASS submit form <input formaction> +PASS submit form <button formaction> +FAIL <base href> assert_true: expected substring %26%23229%3B got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resource.py?q=%C3%A5&encoding=windows-1251&type= expected true got false +PASS Worker constructor +PASS SharedWorker constructor +PASS EventSource constructor +PASS EventSource#url +FAIL XMLDocument#load() doc.load is not a function +PASS window.open() +FAIL <a>.search assert_true: href content attribute expected substring %26%23229%3B got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resource.py?q=%C3%A5&encoding=windows-1251&type=html expected true got false +FAIL <area>.search assert_true: href content attribute expected substring %26%23229%3B got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resource.py?q=%C3%A5&encoding=windows-1251&type=html expected true got false +FAIL history.pushState assert_true: expected substring %26%23229%3B got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resources/resource.py?q=%C3%A5&encoding=windows-1251&type=html expected true got false +FAIL history.replaceState assert_true: expected substring %26%23229%3B got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resources/resource.py?q=%C3%A5&encoding=windows-1251&type=html expected true got false +PASS SVG <a> +FAIL SVG <feImage> poll_for_stash is not defined +FAIL SVG <image> poll_for_stash is not defined +FAIL SVG <use> poll_for_stash is not defined +FAIL XMLHttpRequest#open() assert_equals: expected "%C3%A5" but got "%26%23229%3B" +PASS importScripts() in a dedicated worker +PASS Worker() in a dedicated worker +FAIL SharedWorker() in a dedicated worker assert_equals: expected "%C3%A5" but got "ReferenceError: SharedWorker is not defined" +FAIL importScripts() in a shared worker assert_equals: expected "%C3%A5" but got "importScripts failed to run" +FAIL Worker() in a shared worker assert_equals: expected "%C3%A5" but got "ReferenceError: Worker is not defined" +FAIL SharedWorker() in a shared worker assert_equals: expected "%C3%A5" but got "ReferenceError: SharedWorker is not defined" +PASS WebSocket constructor +PASS WebSocket#url +FAIL Parsing cache manifest (CACHE) poll_for_stash is not defined +FAIL Parsing cache manifest (FALLBACK) poll_for_stash is not defined +FAIL Parsing cache manifest (NETWORK) poll_for_stash is not defined +FAIL CSS <link> (windows-1251) #<id> { background-image:<url> } poll_for_stash is not defined +FAIL CSS <link> (utf-8) #<id> { background-image:<url> } poll_for_stash is not defined +FAIL CSS <style> #<id> { background-image:<url> } poll_for_stash is not defined +FAIL CSS <link> (windows-1251) #<id> { border-image-source:<url> } poll_for_stash is not defined +FAIL CSS <link> (utf-8) #<id> { border-image-source:<url> } poll_for_stash is not defined +FAIL CSS <style> #<id> { border-image-source:<url> } poll_for_stash is not defined +FAIL CSS <link> (windows-1251) #<id>::before { content:<url> } poll_for_stash is not defined +FAIL CSS <link> (utf-8) #<id>::before { content:<url> } poll_for_stash is not defined +FAIL CSS <style> #<id>::before { content:<url> } poll_for_stash is not defined +FAIL CSS <link> (windows-1251) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } poll_for_stash is not defined +FAIL CSS <link> (utf-8) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } poll_for_stash is not defined +FAIL CSS <style> @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } poll_for_stash is not defined +FAIL CSS <link> (windows-1251) #<id> { display:list-item; list-style-image:<url> } poll_for_stash is not defined +FAIL CSS <link> (utf-8) #<id> { display:list-item; list-style-image:<url> } poll_for_stash is not defined +FAIL CSS <style> #<id> { display:list-item; list-style-image:<url> } poll_for_stash is not defined +FAIL CSS <link> (windows-1251) @import <url>; poll_for_stash is not defined +FAIL CSS <link> (utf-8) @import <url>; poll_for_stash is not defined +FAIL CSS <style> @import <url>; poll_for_stash is not defined +FAIL CSS <link> (windows-1251) #<id> { cursor:<url>, pointer } poll_for_stash is not defined +FAIL CSS <link> (utf-8) #<id> { cursor:<url>, pointer } poll_for_stash is not defined +FAIL CSS <style> #<id> { cursor:<url>, pointer } poll_for_stash is not defined +FAIL <?xml-stylesheet?> (CSS) assert_equals: expected "\"%C3%A5\"" but got "\"%26%23229%3B\"" +PASS URL constructor, url +PASS URL constructor, base +PASS Scheme ftp (getting <a>.href) +PASS Scheme file (getting <a>.href) +PASS Scheme gopher (getting <a>.href) +PASS Scheme http (getting <a>.href) +PASS Scheme https (getting <a>.href) +FAIL Scheme ws (getting <a>.href) assert_true: expected substring %C3%A5 got ws://example.invalid/?x=%26%23229%3B expected true got false +FAIL Scheme wss (getting <a>.href) assert_true: expected substring %C3%A5 got wss://example.invalid/?x=%26%23229%3B expected true got false +PASS Scheme mailto (getting <a>.href) +PASS Scheme data (getting <a>.href) +PASS Scheme javascript (getting <a>.href) +PASS Scheme ftps (getting <a>.href) +PASS Scheme httpbogus (getting <a>.href) +PASS Scheme bitcoin (getting <a>.href) +PASS Scheme geo (getting <a>.href) +PASS Scheme im (getting <a>.href) +PASS Scheme irc (getting <a>.href) +PASS Scheme ircs (getting <a>.href) +PASS Scheme magnet (getting <a>.href) +PASS Scheme mms (getting <a>.href) +PASS Scheme news (getting <a>.href) +PASS Scheme nntp (getting <a>.href) +PASS Scheme sip (getting <a>.href) +PASS Scheme sms (getting <a>.href) +PASS Scheme smsto (getting <a>.href) +PASS Scheme ssh (getting <a>.href) +PASS Scheme tel (getting <a>.href) +PASS Scheme urn (getting <a>.href) +PASS Scheme webcal (getting <a>.href) +PASS Scheme wtai (getting <a>.href) +PASS Scheme xmpp (getting <a>.href) +PASS Scheme web+http (getting <a>.href) +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252-expected.txt similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252-expected.txt rename to third_party/blink/web_tests/platform/linux/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252-expected.txt
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252-expected.txt new file mode 100644 index 0000000..63cac4e --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252-expected.txt
@@ -0,0 +1,105 @@ +This is a testharness.js-based test. +Found 101 tests; 67 PASS, 32 FAIL, 2 TIMEOUT, 0 NOTRUN. +PASS load nested browsing context <frame src> +PASS load nested browsing context <iframe src> +PASS load nested browsing context <object data> +PASS load nested browsing context <embed src> +PASS loading css <link> +PASS loading js <script> +PASS loading image <img src> +FAIL loading image <embed src> assert_equals: expected substring %E5 got default intrinsic width expected 1 but got 300 +FAIL loading image <object data> assert_equals: expected substring %E5 got default intrinsic width expected 1 but got 300 +PASS loading image <input src> +PASS loading image <video poster> +FAIL loading video <video> assert_equals: expected substring %E5 got Infinity expected 3 but got Infinity +FAIL loading video <video><source> assert_equals: expected substring %E5 got Infinity expected 3 but got Infinity +FAIL loading video <audio> assert_equals: expected substring %E5 got Infinity expected 3 but got Infinity +FAIL loading video <audio><source> assert_equals: expected substring %E5 got Infinity expected 3 but got Infinity +PASS loading webvtt <track> +PASS submit form <form action> +PASS submit form <input formaction> +PASS submit form <button formaction> +FAIL <base href> assert_true: expected substring %E5 got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resource.py?q=%C3%A5&encoding=windows-1252&type= expected true got false +PASS Worker constructor +PASS SharedWorker constructor +PASS EventSource constructor +PASS EventSource#url +FAIL XMLDocument#load() doc.load is not a function +PASS window.open() +FAIL <a>.search assert_true: href content attribute expected substring %E5 got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resource.py?q=%C3%A5&encoding=windows-1252&type=html expected true got false +FAIL <area>.search assert_true: href content attribute expected substring %E5 got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resource.py?q=%C3%A5&encoding=windows-1252&type=html expected true got false +FAIL history.pushState assert_true: expected substring %E5 got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resources/resource.py?q=%C3%A5&encoding=windows-1252&type=html expected true got false +FAIL history.replaceState assert_true: expected substring %E5 got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resources/resource.py?q=%C3%A5&encoding=windows-1252&type=html expected true got false +PASS SVG <a> +PASS SVG <feImage> +PASS SVG <image> +PASS SVG <use> +FAIL XMLHttpRequest#open() assert_equals: expected "%C3%A5" but got "%E5" +PASS importScripts() in a dedicated worker +PASS Worker() in a dedicated worker +FAIL SharedWorker() in a dedicated worker assert_equals: expected "%C3%A5" but got "ReferenceError: SharedWorker is not defined" +FAIL importScripts() in a shared worker assert_equals: expected "%C3%A5" but got "importScripts failed to run" +FAIL Worker() in a shared worker assert_equals: expected "%C3%A5" but got "ReferenceError: Worker is not defined" +FAIL SharedWorker() in a shared worker assert_equals: expected "%C3%A5" but got "ReferenceError: SharedWorker is not defined" +PASS WebSocket constructor +PASS WebSocket#url +TIMEOUT Parsing cache manifest (CACHE) Test timed out +TIMEOUT Parsing cache manifest (FALLBACK) Test timed out +PASS Parsing cache manifest (NETWORK) +FAIL CSS <link> (windows-1252) #<id> { background-image:<url> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <link> (utf-8) #<id> { background-image:<url> } +FAIL CSS <style> #<id> { background-image:<url> } assert_equals: expected "%C3%A5" but got "%E5" +FAIL CSS <link> (windows-1252) #<id> { border-image-source:<url> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <link> (utf-8) #<id> { border-image-source:<url> } +FAIL CSS <style> #<id> { border-image-source:<url> } assert_equals: expected "%C3%A5" but got "%E5" +FAIL CSS <link> (windows-1252) #<id>::before { content:<url> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <link> (utf-8) #<id>::before { content:<url> } +FAIL CSS <style> #<id>::before { content:<url> } assert_equals: expected "%C3%A5" but got "%E5" +FAIL CSS <link> (windows-1252) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <link> (utf-8) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } +FAIL CSS <style> @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } assert_equals: expected "%C3%A5" but got "%E5" +FAIL CSS <link> (windows-1252) #<id> { display:list-item; list-style-image:<url> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <link> (utf-8) #<id> { display:list-item; list-style-image:<url> } +FAIL CSS <style> #<id> { display:list-item; list-style-image:<url> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <link> (windows-1252) @import <url>; +PASS CSS <link> (utf-8) @import <url>; +PASS CSS <style> @import <url>; +FAIL CSS <link> (windows-1252) #<id> { cursor:<url>, pointer } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <link> (utf-8) #<id> { cursor:<url>, pointer } +FAIL CSS <style> #<id> { cursor:<url>, pointer } assert_equals: expected "%C3%A5" but got "%E5" +FAIL <?xml-stylesheet?> (CSS) assert_equals: expected "\"%C3%A5\"" but got "\"%E5\"" +PASS URL constructor, url +PASS URL constructor, base +PASS Scheme ftp (getting <a>.href) +PASS Scheme file (getting <a>.href) +PASS Scheme gopher (getting <a>.href) +PASS Scheme http (getting <a>.href) +PASS Scheme https (getting <a>.href) +FAIL Scheme ws (getting <a>.href) assert_true: expected substring %C3%A5 got ws://example.invalid/?x=%E5 expected true got false +FAIL Scheme wss (getting <a>.href) assert_true: expected substring %C3%A5 got wss://example.invalid/?x=%E5 expected true got false +PASS Scheme mailto (getting <a>.href) +PASS Scheme data (getting <a>.href) +PASS Scheme javascript (getting <a>.href) +PASS Scheme ftps (getting <a>.href) +PASS Scheme httpbogus (getting <a>.href) +PASS Scheme bitcoin (getting <a>.href) +PASS Scheme geo (getting <a>.href) +PASS Scheme im (getting <a>.href) +PASS Scheme irc (getting <a>.href) +PASS Scheme ircs (getting <a>.href) +PASS Scheme magnet (getting <a>.href) +PASS Scheme mms (getting <a>.href) +PASS Scheme news (getting <a>.href) +PASS Scheme nntp (getting <a>.href) +PASS Scheme sip (getting <a>.href) +PASS Scheme sms (getting <a>.href) +PASS Scheme smsto (getting <a>.href) +PASS Scheme ssh (getting <a>.href) +PASS Scheme tel (getting <a>.href) +PASS Scheme urn (getting <a>.href) +PASS Scheme webcal (getting <a>.href) +PASS Scheme wtai (getting <a>.href) +PASS Scheme xmpp (getting <a>.href) +PASS Scheme web+http (getting <a>.href) +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252-expected.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252-expected.txt
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-8-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-8-expected.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-8-expected.txt
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251-expected.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251-expected.txt
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252-expected.txt new file mode 100644 index 0000000..63cac4e --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252-expected.txt
@@ -0,0 +1,105 @@ +This is a testharness.js-based test. +Found 101 tests; 67 PASS, 32 FAIL, 2 TIMEOUT, 0 NOTRUN. +PASS load nested browsing context <frame src> +PASS load nested browsing context <iframe src> +PASS load nested browsing context <object data> +PASS load nested browsing context <embed src> +PASS loading css <link> +PASS loading js <script> +PASS loading image <img src> +FAIL loading image <embed src> assert_equals: expected substring %E5 got default intrinsic width expected 1 but got 300 +FAIL loading image <object data> assert_equals: expected substring %E5 got default intrinsic width expected 1 but got 300 +PASS loading image <input src> +PASS loading image <video poster> +FAIL loading video <video> assert_equals: expected substring %E5 got Infinity expected 3 but got Infinity +FAIL loading video <video><source> assert_equals: expected substring %E5 got Infinity expected 3 but got Infinity +FAIL loading video <audio> assert_equals: expected substring %E5 got Infinity expected 3 but got Infinity +FAIL loading video <audio><source> assert_equals: expected substring %E5 got Infinity expected 3 but got Infinity +PASS loading webvtt <track> +PASS submit form <form action> +PASS submit form <input formaction> +PASS submit form <button formaction> +FAIL <base href> assert_true: expected substring %E5 got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resource.py?q=%C3%A5&encoding=windows-1252&type= expected true got false +PASS Worker constructor +PASS SharedWorker constructor +PASS EventSource constructor +PASS EventSource#url +FAIL XMLDocument#load() doc.load is not a function +PASS window.open() +FAIL <a>.search assert_true: href content attribute expected substring %E5 got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resource.py?q=%C3%A5&encoding=windows-1252&type=html expected true got false +FAIL <area>.search assert_true: href content attribute expected substring %E5 got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resource.py?q=%C3%A5&encoding=windows-1252&type=html expected true got false +FAIL history.pushState assert_true: expected substring %E5 got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resources/resource.py?q=%C3%A5&encoding=windows-1252&type=html expected true got false +FAIL history.replaceState assert_true: expected substring %E5 got http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/resources/resources/resource.py?q=%C3%A5&encoding=windows-1252&type=html expected true got false +PASS SVG <a> +PASS SVG <feImage> +PASS SVG <image> +PASS SVG <use> +FAIL XMLHttpRequest#open() assert_equals: expected "%C3%A5" but got "%E5" +PASS importScripts() in a dedicated worker +PASS Worker() in a dedicated worker +FAIL SharedWorker() in a dedicated worker assert_equals: expected "%C3%A5" but got "ReferenceError: SharedWorker is not defined" +FAIL importScripts() in a shared worker assert_equals: expected "%C3%A5" but got "importScripts failed to run" +FAIL Worker() in a shared worker assert_equals: expected "%C3%A5" but got "ReferenceError: Worker is not defined" +FAIL SharedWorker() in a shared worker assert_equals: expected "%C3%A5" but got "ReferenceError: SharedWorker is not defined" +PASS WebSocket constructor +PASS WebSocket#url +TIMEOUT Parsing cache manifest (CACHE) Test timed out +TIMEOUT Parsing cache manifest (FALLBACK) Test timed out +PASS Parsing cache manifest (NETWORK) +FAIL CSS <link> (windows-1252) #<id> { background-image:<url> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <link> (utf-8) #<id> { background-image:<url> } +FAIL CSS <style> #<id> { background-image:<url> } assert_equals: expected "%C3%A5" but got "%E5" +FAIL CSS <link> (windows-1252) #<id> { border-image-source:<url> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <link> (utf-8) #<id> { border-image-source:<url> } +FAIL CSS <style> #<id> { border-image-source:<url> } assert_equals: expected "%C3%A5" but got "%E5" +FAIL CSS <link> (windows-1252) #<id>::before { content:<url> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <link> (utf-8) #<id>::before { content:<url> } +FAIL CSS <style> #<id>::before { content:<url> } assert_equals: expected "%C3%A5" but got "%E5" +FAIL CSS <link> (windows-1252) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <link> (utf-8) @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } +FAIL CSS <style> @font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> } assert_equals: expected "%C3%A5" but got "%E5" +FAIL CSS <link> (windows-1252) #<id> { display:list-item; list-style-image:<url> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <link> (utf-8) #<id> { display:list-item; list-style-image:<url> } +FAIL CSS <style> #<id> { display:list-item; list-style-image:<url> } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <link> (windows-1252) @import <url>; +PASS CSS <link> (utf-8) @import <url>; +PASS CSS <style> @import <url>; +FAIL CSS <link> (windows-1252) #<id> { cursor:<url>, pointer } assert_equals: expected "%C3%A5" but got "%E5" +PASS CSS <link> (utf-8) #<id> { cursor:<url>, pointer } +FAIL CSS <style> #<id> { cursor:<url>, pointer } assert_equals: expected "%C3%A5" but got "%E5" +FAIL <?xml-stylesheet?> (CSS) assert_equals: expected "\"%C3%A5\"" but got "\"%E5\"" +PASS URL constructor, url +PASS URL constructor, base +PASS Scheme ftp (getting <a>.href) +PASS Scheme file (getting <a>.href) +PASS Scheme gopher (getting <a>.href) +PASS Scheme http (getting <a>.href) +PASS Scheme https (getting <a>.href) +FAIL Scheme ws (getting <a>.href) assert_true: expected substring %C3%A5 got ws://example.invalid/?x=%E5 expected true got false +FAIL Scheme wss (getting <a>.href) assert_true: expected substring %C3%A5 got wss://example.invalid/?x=%E5 expected true got false +PASS Scheme mailto (getting <a>.href) +PASS Scheme data (getting <a>.href) +PASS Scheme javascript (getting <a>.href) +PASS Scheme ftps (getting <a>.href) +PASS Scheme httpbogus (getting <a>.href) +PASS Scheme bitcoin (getting <a>.href) +PASS Scheme geo (getting <a>.href) +PASS Scheme im (getting <a>.href) +PASS Scheme irc (getting <a>.href) +PASS Scheme ircs (getting <a>.href) +PASS Scheme magnet (getting <a>.href) +PASS Scheme mms (getting <a>.href) +PASS Scheme news (getting <a>.href) +PASS Scheme nntp (getting <a>.href) +PASS Scheme sip (getting <a>.href) +PASS Scheme sms (getting <a>.href) +PASS Scheme smsto (getting <a>.href) +PASS Scheme ssh (getting <a>.href) +PASS Scheme tel (getting <a>.href) +PASS Scheme urn (getting <a>.href) +PASS Scheme webcal (getting <a>.href) +PASS Scheme wtai (getting <a>.href) +PASS Scheme xmpp (getting <a>.href) +PASS Scheme web+http (getting <a>.href) +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/webrtc/RTCPeerConnection-track-stats.https-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/webrtc/RTCPeerConnection-track-stats.https-expected.txt deleted file mode 100644 index 1a6478f..0000000 --- a/third_party/blink/web_tests/platform/win7/external/wpt/webrtc/RTCPeerConnection-track-stats.https-expected.txt +++ /dev/null
@@ -1,21 +0,0 @@ -This is a testharness.js-based test. -PASS addTrack() without setLocalDescription() yields track stats -PASS addTrack() without setLocalDescription() yields media stream stats -PASS addTrack() with setLocalDescription() yields track stats -PASS addTrack() with setLocalDescription() yields media stream stats -PASS addTrack(): Media stream stats references track stats -PASS Media stream stats references track stats -PASS O/A exchange yields outbound RTP stream stats for sending track -PASS O/A exchange yields inbound RTP stream stats for receiving track -PASS replaceTrack() before offer: new track attachment stats present -PASS replaceTrack() after offer, before answer: new track attachment stats present -PASS replaceTrack() after answer: new track attachment stats present -FAIL replaceTrack(): original track attachment stats present after replacing assert_true: Has stats for original track expected true got false -PASS RTCRtpSender.getStats() contains only outbound-rtp and related stats -FAIL RTCRtpReceiver.getStats() contains only inbound-rtp and related stats assert_equals: receiverReport should contain candidate-pair stats expected 1 but got 0 -PASS RTCPeerConnection.getStats(sendingTrack) is the same as RTCRtpSender.getStats() -PASS RTCPeerConnection.getStats(receivingTrack) is the same as RTCRtpReceiver.getStats() -PASS RTCPeerConnection.getStats(track) throws InvalidAccessError when there are zero senders or receivers for the track -PASS RTCPeerConnection.getStats(track) throws InvalidAccessError when there are multiple senders for the track -Harness: the test ran to completion. -
diff --git a/third_party/webxr_test_pages/bucket_index.html b/third_party/webxr_test_pages/bucket_index.html new file mode 100644 index 0000000..6159f9a --- /dev/null +++ b/third_party/webxr_test_pages/bucket_index.html
@@ -0,0 +1,16 @@ +<!doctype html> +<html> + <body> + <h1>Test revisions</h1> + <ul> + {% for item in items %} + <li> + {{ item.text }} + {% for link in item.links %} + <a href="{{ link.href }}">{{ link.anchor }}</a> + {% endfor %} + </li> + {% endfor %} + </ul> + </body> +</html>
diff --git a/third_party/webxr_test_pages/update_bucket.py b/third_party/webxr_test_pages/update_bucket.py new file mode 100755 index 0000000..21b0e2b --- /dev/null +++ b/third_party/webxr_test_pages/update_bucket.py
@@ -0,0 +1,199 @@ +#!/usr/bin/env python +# Copyright 2019 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. + +from __future__ import print_function + +import argparse +import logging +import os +import re +import subprocess +import sys +import tempfile + +# Add third_party directory to the Python import path +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +import jinja2 + +# Oldest version of this directory that works for serving. Used to limit git +# history searches. +FIRST_REVISION = '08a37e09f110ab9cb2af3180f054f26a2fd274d6' +TEST_SUBDIR = 'webxr-samples' +INDEX_TEMPLATE = 'bucket_index.html' + +# Google Cloud storage bucket destination. +BUCKET = 'gs://chromium-webxr-test' + +# URL templates used for creating the index page. +LINK_OMAHAPROXY = ('https://storage.googleapis.com/' + 'chromium-find-releases-static/index.html#%s') +LINK_CRREV = 'https://crrev.com/%s' + +CR_POSITION_RE = re.compile(r'^Cr-Commit-Position:.*\#(\d+)') +BUCKET_COPY_RE = re.compile(r'^r(\d+)') + +g_flags = None + +def run_command(*args): + """Runs a shell command and returns output.""" + logging.debug('Executing: %s', args) + return subprocess.check_output(args) + +def run_readonly(*args): + """Runs command expected to have no side effects, safe for dry runs.""" + return run_command(*args) + +def run_modify(*args): + """Runs command with side effects, skipped for dry runs.""" + if g_flags.dry_run: + print('Dry-Run:', *args) + return + return run_command(*args) + +def get_cr_positions(): + """Retrieves list of Cr-Commit-Position entries for local commits""" + revs = run_readonly('git', 'log', '--format=%H', FIRST_REVISION+'^..', '--', + TEST_SUBDIR) + cr_positions = [] + for rev in revs.splitlines(): + cr_position = None + msg = run_readonly('git', 'show', '-s', '--format=%B', rev) + for line in msg.splitlines(): + m = CR_POSITION_RE.match(line) + if m: + cr_position = m.group(1) + cr_positions.append(cr_position) + return cr_positions + +def get_bucket_copies(): + """Retrieves list of test subdirectories from Cloud Storage""" + copies = [] + dirs = run_readonly('gsutil', 'ls', '-d', BUCKET) + strip_len = len(BUCKET) + 1 + for rev in dirs.splitlines(): + pos = rev[strip_len:] + m = BUCKET_COPY_RE.search(pos) + if m: + copies.append(m.group(1)) + return copies + +def is_working_dir_clean(): + """Checks if the git working directory has unsaved changes""" + status = run_readonly('git', 'status', '--porcelain', '--untracked-files=no') + return status.strip() == '' + +def write_to_bucket(cr_position): + """Copies the test directory to Cloud Storage""" + destination = BUCKET + '/r' + cr_position + run_modify('gsutil', '-m', 'rsync', '-x', 'media', '-r', './' + TEST_SUBDIR, + destination) + +def write_index(): + """Updates Cloud Storage index.html based on available test copies""" + cr_positions = get_bucket_copies() + cr_positions.sort(key=int, reverse=True) + logging.debug('Index: %s', cr_positions) + + items = [] + + for pos in cr_positions: + rev = 'r' + pos + links = [] + links.append({'href': '%s/index.html' % rev, + 'anchor': 'index.html'}) + links.append({'href': LINK_CRREV % pos, + 'anchor': '[crrev]'}) + links.append({'href': LINK_OMAHAPROXY % rev, + 'anchor': '[find in releases]'}) + items.append({'text': rev, 'links': links}) + + template = jinja2.Template(open(INDEX_TEMPLATE).read()) + content = template.render({'items': items}) + logging.debug('index.html content:\n%s', content) + + with tempfile.NamedTemporaryFile(suffix='.html') as temp: + temp.write(content) + temp.seek(0) + run_modify('gsutil', 'cp', temp.name, BUCKET + '/index.html') + +def update_test_copies(): + """Uploads a new test copy if available""" + + if not is_working_dir_clean() and not g_flags.ignore_unclean_status: + raise Exception('Working directory is not clean, check "git status"') + + cr_positions = get_cr_positions() + logging.debug('Found git commit positions: %s', cr_positions) + if not cr_positions: + raise Exception('No commit positions found') + + latest_cr_position = cr_positions[0] + if latest_cr_position is None and not g_flags.force_destination_cr_position: + raise Exception('Top commit has no Cr-Commit-Position. Sync to master?') + + existing_copies = get_bucket_copies() + logging.debug('Found bucket copies: %s', existing_copies) + + out_cr_position = g_flags.force_destination_cr_position or latest_cr_position + + need_index_update = False + if out_cr_position in existing_copies: + logging.info('Destination "r%s" already exists, skipping write', + out_cr_position) + else: + write_to_bucket(out_cr_position) + need_index_update = True + + return need_index_update + +def main(): + parser = argparse.ArgumentParser(description=""" +Copies the current '%s' content to a Google Cloud Storage bucket +subdirectory named after the Cr-Commit-Position, and writes an index.html file +linking to the known test directories.""" % TEST_SUBDIR) + + parser.add_argument('-v', '--verbose', action="store_true", + help="Print debugging info") + parser.add_argument('-n', '--dry-run', action="store_true", + help="Don't run state-changing commands") + parser.add_argument('--update-index-only', action="store_true", + help=("Generate a new index.html file based on already " + "existing directories, ignoring local changes")) + parser.add_argument('--ignore-unclean-status', action="store_true", + help=("Proceed with copy even if there are uncommitted " + "local changes in the git working directory")) + parser.add_argument('--force-destination-cr-position', + help=("Force writing current content to the specified " + "destination CR position instead of determining " + "the name based on local git history, bypassing " + "history sanity checks")) + parser.add_argument('--bucket', default=BUCKET, + help=("Destination Cloud Storage location, including " + "'gs://' prefix")) + + global g_flags + g_flags = parser.parse_args() + + if g_flags.verbose: + logging.basicConfig(level=logging.DEBUG) + + if not os.path.isdir(TEST_SUBDIR): + raise Exception('Must be run from webxr_test_pages directory') + + need_index_update = False + if g_flags.update_index_only: + need_index_update = True + else: + need_index_update = update_test_copies() + + # Create an index.html file covering all found test copies. + if need_index_update: + write_index() + else: + logging.info('No changes, skipping index update.') + + +if __name__ == '__main__': + main()
diff --git a/tools/android/checkxmlstyle/checkxmlstyle.py b/tools/android/checkxmlstyle/checkxmlstyle.py index 931f020..2c4d28f5 100644 --- a/tools/android/checkxmlstyle/checkxmlstyle.py +++ b/tools/android/checkxmlstyle/checkxmlstyle.py
@@ -93,7 +93,8 @@ """Checks no (A)RGB values are defined outside colors.xml.""" errors = [] for f in IncludedFiles(input_api): - if f.LocalPath().endswith('/colors.xml'): + if (f.LocalPath().endswith('/colors.xml') or + f.LocalPath().endswith('/color_palette.xml')): continue # Ingnore vector drawable xmls contents = input_api.ReadFile(f) @@ -123,7 +124,8 @@ """Checks colors defined by (A)RGB values in colors.xml are unique.""" errors = [] for f in IncludedFiles(input_api): - if not f.LocalPath().endswith('/colors.xml'): + if not (f.LocalPath().endswith('/colors.xml') + or f.LocalPath().endswith('/color_palette.xml')): continue colors = defaultdict(int) contents = input_api.ReadFile(f)
diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids index bcce629..6f7cfef 100644 --- a/tools/gritsettings/resource_ids +++ b/tools/gritsettings/resource_ids
@@ -191,16 +191,16 @@ "messages": [15100], }, "components/policy/resources/policy_templates.grd": { - "structures": [17000], - }, - "components/resources/components_resources.grd": { - "includes": [17010], - }, - "components/resources/components_scaled_resources.grd": { "structures": [17200], }, + "components/resources/components_resources.grd": { + "includes": [17210], + }, + "components/resources/components_scaled_resources.grd": { + "structures": [17400], + }, "components/embedder_suppport/android/java/strings/web_contents_delegate_android_strings.grd": { - "messages": [17400], + "messages": [17600], }, # END components/ section.
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 3d67c80a..34369c27 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -20037,6 +20037,13 @@ <description>Please enter the description of this user action.</description> </action> +<action name="Tablet.WindowDrag.OpenedOverview"> + <owner>minch@chromium.org</owner> + <description> + User dragged a window from top in tablet mode and opened overview behind. + </description> +</action> + <action name="Tablet_BackButton"> <owner>sammiequon@chromium.org</owner> <description>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 21c5014..cf63c57 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -1706,6 +1706,12 @@ <int value="1" label="Panel"/> </enum> +<enum name="AppWindowDragEndWindowState"> + <int value="0" label="Maximized or Fullscreen"/> + <int value="1" label="In Overview"/> + <int value="2" label="In Splitview"/> +</enum> + <enum name="ArcAuthAccountCheckStatus"> <int value="0" label="Account is up to date"/> <int value="1" label="New account"/> @@ -35334,7 +35340,7 @@ <int value="2" label="File creation error"/> <int value="3" label="File writing error"/> <int value="4" label="Frame no longer exists"/> - <int value="5" label="Main frame serialization forbidden"/> + <int value="5" label="DEPRECATED"/> <int value="6" label="Render process no longer exists"/> </enum> @@ -44404,7 +44410,7 @@ <enum name="ProximityAuth_BleWeaveConnectionResult"> <int value="0" label="Closed normally"/> - <int value="1" label="Timeout: Setting connection latency"/> + <int value="1" label="(Deprecated) Timeout: Setting connection latency"/> <int value="2" label="Timeout: Creating GATT connection"/> <int value="3" label="Timeout: Starting notify session"/> <int value="4" label="Timeout: Finding GATT characteristics"/> @@ -51670,6 +51676,11 @@ label="Discarded a tab playing audio (included in the previous one)"/> </enum> +<enum name="TabDragType"> + <int value="0" label="Source Browser Window"/> + <int value="1" label="Tab In The Browser Window."/> +</enum> + <enum name="TabForegroundState"> <int value="0" label="Foreground (app in foreground)"/> <int value="1" label="Background (app in foreground)"/> @@ -54250,6 +54261,17 @@ <int value="14" label="kWinMediaFoundationGetBufferByIndexReturnedNull"/> <int value="15" label="kBufferPoolMaxBufferCountExceeded"/> <int value="16" label="kBufferPoolBufferAllocationFailed"/> + <int value="17" label="kVideoCaptureImplNotInStartedState"/> + <int value="18" label="kVideoCaptureImplFailedToWrapDataAsMediaVideoFrame"/> + <int value="19" label="kVideoTrackAdapterHasNoResolutionAdapters"/> + <int value="20" label="kResolutionAdapterFrameIsNotValid"/> + <int value="21" label="kResolutionAdapterWrappingFrameForCroppingFailed"/> + <int value="22" label="kResolutionAdapterTimestampTooCloseToPrevious"/> + <int value="23" label="kResolutionAdapterFrameRateIsHigherThanRequested"/> + <int value="24" label="kResolutionAdapterHasNoCallbacks"/> + <int value="25" + label="kVideoTrackFrameDelivererNotEnabledReplacingWithBlackFrame"/> + <int value="26" label="kRendererSinkFrameDelivererIsNotStarted"/> </enum> <enum name="VideoCaptureServiceEvent"> @@ -56415,6 +56437,12 @@ <int value="3" label="Desktop Aura"/> </enum> +<enum name="WindowDragEndEventType"> + <int value="0" label="Drag ends with normal end event."/> + <int value="1" label="Drag has been reverted."/> + <int value="2" label="Drag ends with fling."/> +</enum> + <enum name="WindowOcclusionState"> <int value="0" label="Unknown"/> <int value="1" label="Visible"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 69c14d44..a185bd8 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -82028,6 +82028,15 @@ </summary> </histogram> +<histogram name="PasswordProtection.VisualFeatureExtractionDuration" units="ms"> + <owner>chrome-safebrowsing-alerts@google.com</owner> + <summary> + The time it takes to extract the visual features of a login page before + sending a PasswordProtectionRequest. Logged every time visual features are + extracted (when an SBER user sends an On Focus ping). + </summary> +</histogram> + <histogram name="PaymentRequest.CanMakePayment.NotUsed.WithShowEffectOnCompletion" enum="PaymentRequestFlowCompletionStatus"> @@ -114373,13 +114382,27 @@ </histogram> <histogram name="Sync.DeviceCount"> - <owner>skym@chromium.org</owner> + <obsolete> + Deprecated in M74. + </obsolete> + <owner>mastiz@chromium.org</owner> + <owner>jkrcal@chromium.org</owner> <summary> The largest number of active syncing devices known to any profile. May be 0 when there are no signed in/syncing profiles open. </summary> </histogram> +<histogram name="Sync.DeviceCount2"> + <owner>mastiz@chromium.org</owner> + <owner>jkrcal@chromium.org</owner> + <summary> + The largest number of active and concurrently syncing devices known to any + profile. May be 0 when there are no signed in/syncing profiles open. Logged + with every UMA log. + </summary> +</histogram> + <histogram name="Sync.DeviceIdMismatchDetails" enum="DeviceIdMismatch"> <obsolete> Deprecated in M53. @@ -116898,6 +116921,90 @@ </summary> </histogram> +<histogram name="Tablet.AppDrag.EndWindowState" + enum="AppWindowDragEndWindowState" expires_after="2019-12-20"> + <owner>minch@chromium.org</owner> + <owner>omrilio@chromium.org</owner> + <summary> + Drag an app window from top in tablet mode will result in different window + states. Logged when the app drag ended to record the window end state. + </summary> +</histogram> + +<histogram name="Tablet.AppWindowDrag.CountOfPerUserSession" units="times" + expires_after="2019-12-20"> + <owner>minch@chromium.org</owner> + <owner>omrilio@chromium.org</owner> + <summary> + The number of the action that drag an app window from top in tablet mode. + Logged when the TabletModeController is destructed, which means the user + session is ended. + </summary> +</histogram> + +<histogram name="Tablet.AppWindowDrag.InSplitView.CountOfPerUserSession" + units="times" expires_after="2019-12-20"> + <owner>minch@chromium.org</owner> + <owner>omrilio@chromium.org</owner> + <summary> + The number of the action that drag an app window from top in tablet mode + when splitview is active. Logged when the TabletModeController is + destructed, which means the user session is ended. + </summary> +</histogram> + +<histogram name="Tablet.TabDrag.CountOfPerUserSession" units="times" + expires_after="2019-12-20"> + <owner>minch@chromium.org</owner> + <owner>omrilio@chromium.org</owner> + <summary> + The number of the action that drag a tab of the browser window in tablet + mode. Logged when the TabletModeController is destructed, which means the + user session is ended. + </summary> +</histogram> + +<histogram name="Tablet.TabDrag.DragType" enum="TabDragType" + expires_after="2019-12-20"> + <owner>minch@chromium.org</owner> + <owner>omrilio@chromium.org</owner> + <summary> + The type of a tab drag done in tablet mode. Logged when start to drag a tab + of the browser window in tablet mode. + </summary> +</histogram> + +<histogram name="Tablet.TabDrag.InSplitView.CountOfPerUserSession" + units="times" expires_after="2019-12-20"> + <owner>minch@chromium.org</owner> + <owner>omrilio@chromium.org</owner> + <summary> + The number of the action that drag a tab of the browser window in tablet + mode when splitview is active. Logged when the TabletModeController is + destructed, which means the user session is ended. + </summary> +</histogram> + +<histogram name="Tablet.WindowDrag.DragEndEventType" + enum="WindowDragEndEventType" expires_after="2019-12-20"> + <owner>minch@chromium.org</owner> + <owner>omrilio@chromium.org</owner> + <summary> + The type of the window (app window or tab strip) drag end event in tablet + mode. Logged when the window drag in tablet mode ended. + </summary> +</histogram> + +<histogram name="Tablet.WindowDrag.OpenedWindowsNumber" units="numbers" + expires_after="2019-12-20"> + <owner>minch@chromium.org</owner> + <owner>omrilio@chromium.org</owner> + <summary> + The number of windows in overview when dragging a window from top in tablet + mode. Logged when start the window drag and overview has been opened behind. + </summary> +</histogram> + <histogram name="TabManager.BackgroundTabOpening.ForegroundTab.ExpectedTaskQueueingDuration" units="ms"> @@ -126157,6 +126264,19 @@ </summary> </histogram> +<histogram + name="WebCore.HTMLDocumentParser.PreloadScannerAppCacheDelayTime.MainFrame" + units="microseconds" expires_after="2019-06-30"> + <owner>yoavweiss@chromium.org</owner> + <owner>csharrison@chromium.org</owner> + <summary> + Time in which requests have been delayed after being discovered by the + HTMLPreloadScanner, due to document element not being yet available, which + is required for AppCache support. Recorded per document, but applies only to + main frames. + </summary> +</histogram> + <histogram name="WebCore.IndexedDB.BackingStore.ConsistencyError" enum="IDBLevelDBBackingStoreInternalErrorType"> <owner>dgrogan@chromium.org</owner> @@ -144422,7 +144542,11 @@ <histogram_suffixes name="TaskSchedulerWorkerPool" separator="."> <suffix name="BackgroundBlockingPool" - label="Applies to the BackgroundBlocking worker pool."/> + label="Applies to the BackgroundBlocking worker pool."> + <obsolete> + Deprecated January 2019 as the pool no longer exists. + </obsolete> + </suffix> <suffix name="BackgroundFileIOPool" label="Applies to the BackgroundFileIO worker pool."> <obsolete> @@ -144431,7 +144555,11 @@ </suffix> <suffix name="BackgroundPool" label="Applies to the Background worker pool."/> <suffix name="ForegroundBlockingPool" - label="Applies to the ForegroundBlocking worker pool."/> + label="Applies to the ForegroundBlocking worker pool."> + <obsolete> + Deprecated January 2019 as the pool no longer exists. + </obsolete> + </suffix> <suffix name="ForegroundFileIOPool" label="Applies to the ForegroundFileIO worker pool."> <obsolete>
diff --git a/tools/perf/scripts_smoke_unittest.py b/tools/perf/scripts_smoke_unittest.py index 09ca602..80927b4 100644 --- a/tools/perf/scripts_smoke_unittest.py +++ b/tools/perf/scripts_smoke_unittest.py
@@ -13,6 +13,11 @@ from telemetry import decorators from telemetry.testing import options_for_unittests +RUNNER_SCRIPTS_DIR = os.path.join(os.path.dirname(__file__), + '..', '..', 'testing', 'scripts') +sys.path.append(RUNNER_SCRIPTS_DIR) +import run_performance_tests # pylint: disable=wrong-import-position,import-error + class ScriptsSmokeTest(unittest.TestCase): @@ -59,7 +64,7 @@ self.assertIn('kraken', stdout) @decorators.Disabled('chromeos') # crbug.com/754913 - def testRunTelemetryBenchmarkAsGoogletest(self): + def testRunPerformanceTestsTelemetry_end2end(self): options = options_for_unittests.GetCopy() browser_type = options.browser_type tempdir = tempfile.mkdtemp() @@ -93,3 +98,68 @@ finally: shutil.rmtree(tempdir) + @decorators.Disabled('win') # ".exe" is auto-added which breaks Windows. + def testRunPerformanceTestsGtest_end2end(self): + tempdir = tempfile.mkdtemp() + benchmark = 'dummy_gtest' + return_code, stdout = self.RunPerfScript( + '../../testing/scripts/run_performance_tests.py ' + + os.path.join('..', '..', 'tools', 'perf', 'testdata', 'dummy_gtest') + + ' --non-telemetry=true ' + '--this-arg=passthrough ' + '--gtest-benchmark-name dummy_gtest ' + '--isolated-script-test-output=/x/y/z/output.json ' + '--isolated-script-test-output=%s' % ( + os.path.join(tempdir, 'output.json') + )) + self.assertEquals(return_code, 0, stdout) + try: + # By design, run_performance_tests.py does not output test results + # to the location passed in by --isolated-script-test-output. Instead + # it uses the directory of that file and puts stuff in its own + # subdirectories for the purposes of merging later. + with open(os.path.join(tempdir, benchmark, 'test_results.json')) as f: + test_results = json.load(f) + self.assertIsNotNone( + test_results, 'json_test_results should be populated: ' + stdout) + with open(os.path.join(tempdir, benchmark, 'perf_results.json')) as f: + perf_results = json.load(f) + self.assertIsNotNone( + perf_results, 'json perf results should be populated: ' + stdout) + except IOError as e: + self.fail('json_test_results should be populated: ' + stdout + str(e)) + finally: + shutil.rmtree(tempdir) + + def testRunPerformanceTestsTelemetryArgsParser(self): + options = run_performance_tests.parse_arguments([ + '../../tools/perf/run_benchmark', '-v', '--browser=release_x64', + '--upload-results', '--run-ref-build', + '--test-shard-map-filename=win-10-perf_map.json', + '--assert-gpu-compositing', + r'--isolated-script-test-output=c:\a\b\c\output.json', + r'--isolated-script-test-perf-output=c:\a\b\c\perftest-output.json', + '--passthrough-arg=--a=b', + ]) + self.assertIn('--assert-gpu-compositing', options.passthrough_args) + self.assertIn('--browser=release_x64', options.passthrough_args) + self.assertIn('-v', options.passthrough_args) + self.assertIn('--a=b', options.passthrough_args) + self.assertEqual(options.executable, '../../tools/perf/run_benchmark') + self.assertEqual(options.isolated_script_test_output, + r'c:\a\b\c\output.json') + + def testRunPerformanceTestsGtestArgsParser(self): + options = run_performance_tests.parse_arguments([ + 'media_perftests', '--non-telemetry=true', '--single-process-tests', + '--test-launcher-retry-limit=0', + '--isolated-script-test-filter=*::-*_unoptimized::*_unaligned::' + '*unoptimized_aligned', + '--gtest-benchmark-name', 'media_perftests', + '--isolated-script-test-output=/x/y/z/output.json', + ]) + self.assertIn('--single-process-tests', options.passthrough_args) + self.assertIn('--test-launcher-retry-limit=0', options.passthrough_args) + self.assertEqual(options.executable, 'media_perftests') + self.assertEqual(options.isolated_script_test_output, + r'/x/y/z/output.json')
diff --git a/tools/perf/testdata/dummy_gtest b/tools/perf/testdata/dummy_gtest new file mode 100755 index 0000000..044ed7f --- /dev/null +++ b/tools/perf/testdata/dummy_gtest
@@ -0,0 +1,12 @@ +#!/usr/bin/env vpython +# Copyright 2019 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. + +"""This is a fake version of a non-Telemetry performance test (gtest_perf_test). + +It is used by ../scripts_smoke_unittest.py. +""" + +# This is just a random line of output that can be converted into graph_json. +print r"*RESULT clockless_video_playback_vp8: bear_silent.webm= 53.406108056578425 runs/s"
diff --git a/ui/accessibility/ax_event_generator.cc b/ui/accessibility/ax_event_generator.cc index ffc70534..f368dca 100644 --- a/ui/accessibility/ax_event_generator.cc +++ b/ui/accessibility/ax_event_generator.cc
@@ -208,6 +208,10 @@ node->data().role != ax::mojom::Role::kAlert) AddEvent(node, Event::LIVE_REGION_CREATED); break; + case ax::mojom::StringAttribute::kAutoComplete: + LOG(ERROR) << "auto!"; + AddEvent(node, Event::AUTO_COMPLETE_CHANGED); + break; default: AddEvent(node, Event::OTHER_ATTRIBUTE_CHANGED); break;
diff --git a/ui/accessibility/ax_event_generator.h b/ui/accessibility/ax_event_generator.h index 268dd3fa..0c355d6 100644 --- a/ui/accessibility/ax_event_generator.h +++ b/ui/accessibility/ax_event_generator.h
@@ -24,6 +24,7 @@ enum class Event : int32_t { ACTIVE_DESCENDANT_CHANGED, ALERT, + AUTO_COMPLETE_CHANGED, CHECKED_STATE_CHANGED, CHILDREN_CHANGED, COLLAPSED,
diff --git a/ui/android/java/res/color/chip_background_color.xml b/ui/android/java/res/color/chip_background_color.xml index f905a15..219cc303 100644 --- a/ui/android/java/res/color/chip_background_color.xml +++ b/ui/android/java/res/color/chip_background_color.xml
@@ -6,7 +6,7 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:alpha="@dimen/default_disabled_alpha" - android:color="@color/modern_grey_100" + android:color="@color/modern_secondary_color" android:state_enabled="false" /> <item android:alpha="@dimen/chip_background_selected_focused_alpha" android:color="@color/modern_blue_600" @@ -18,5 +18,5 @@ <item android:alpha="@dimen/default_focused_alpha" android:color="@color/modern_grey_800" android:state_focused="true" /> - <item android:color="@android:color/white" /> + <item android:color="@color/modern_primary_color" /> </selector>
diff --git a/ui/android/java/res/drawable-v21/popup_bg_tinted.xml b/ui/android/java/res/drawable-v21/popup_bg_tinted.xml new file mode 100644 index 0000000..19be5b61 --- /dev/null +++ b/ui/android/java/res/drawable-v21/popup_bg_tinted.xml
@@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2019 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. --> + +<nine-patch xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/popup_bg" + android:tint="@color/modern_primary_color" + android:tintMode="multiply"/> \ No newline at end of file
diff --git a/ui/android/java/res/drawable/popup_bg_tinted.xml b/ui/android/java/res/drawable/popup_bg_tinted.xml new file mode 100644 index 0000000..8552a8f --- /dev/null +++ b/ui/android/java/res/drawable/popup_bg_tinted.xml
@@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2019 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. --> + +<layer-list xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + tools:ignore="UnusedResources"> + <item android:drawable="@drawable/popup_bg" /> + <item> + <shape> + <corners android:radius="4dp" /> + <solid android:color="@color/modern_primary_color" /> + </shape> + </item> +</layer-list>
diff --git a/ui/android/java/res/values-v17/styles.xml b/ui/android/java/res/values-v17/styles.xml index edb3d3d7..a1b3491 100644 --- a/ui/android/java/res/values-v17/styles.xml +++ b/ui/android/java/res/values-v17/styles.xml
@@ -8,7 +8,7 @@ <resources xmlns:tools="http://schemas.android.com/tools"> <style name="DropdownPopupWindow" parent="@android:style/Widget.ListPopupWindow"> - <item name="android:popupBackground">@drawable/popup_bg</item> + <item name="android:popupBackground">@drawable/popup_bg_tinted</item> </style> <!-- Buttons --> @@ -87,7 +87,6 @@ </style> <!-- Used by Chrome and Content --> - <!-- TODO(huayinz): Update prefixes for text appearance styles in ui/android. --> <style name="TextAppearance" parent="android:TextAppearance" tools:ignore="UnusedResources" /> <style name="TextAppearance.RobotoMediumStyle"> <item name="android:fontFamily">sans-serif</item>
diff --git a/ui/android/java/res/values/color_palette.xml b/ui/android/java/res/values/color_palette.xml new file mode 100644 index 0000000..60d71e7 --- /dev/null +++ b/ui/android/java/res/values/color_palette.xml
@@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources xmlns:tools="http://schemas.android.com/tools"> + <!-- Modern color palette --> + <color name="modern_blue_300">#8AB4F8</color> + <color name="modern_blue_600">#1A73E8</color> + <color name="modern_grey_50" tools:ignore="UnusedResources">#F8F9FA</color> + <color name="modern_grey_100" tools:ignore="UnusedResources">#F1F3F4</color> + <color name="modern_grey_200" tools:ignore="UnusedResources">#E8EAED</color> + <color name="modern_grey_200_alpha_38" tools:ignore="UnusedResources">#61E8EAED</color> + <color name="modern_grey_300" tools:ignore="UnusedResources">#DADCE0</color> + <color name="modern_grey_400" tools:ignore="UnusedResources">#BDC1C6</color> + <color name="modern_grey_500" tools:ignore="UnusedResources">#9AA0A6</color> + <color name="modern_grey_600" tools:ignore="UnusedResources">#80868B</color> + <color name="modern_grey_700">#5F6368</color> + <color name="modern_grey_800" tools:ignore="UnusedResources">#3C4043</color> + <color name="modern_grey_900">#202124</color> + + <color name="black_alpha_38">#61000000</color> + + <color name="white_alpha_10" tools:ignore="UnusedResources">#1AFFFFFF</color> + <color name="white_alpha_50" tools:ignore="UnusedResources">#80FFFFFF</color> + <color name="white_alpha_70">#B3FFFFFF</color> +</resources> \ No newline at end of file
diff --git a/ui/android/java/res/values/colors.xml b/ui/android/java/res/values/colors.xml index 347ab27..fc3bd06 100644 --- a/ui/android/java/res/values/colors.xml +++ b/ui/android/java/res/values/colors.xml
@@ -21,24 +21,11 @@ <color name="default_icon_color_white" tools:ignore="UnusedResources"> @android:color/white </color> - <color name="hairline_stroke_color" tools:ignore="UnusedResources">@color/modern_grey_300</color> + <color name="hairline_stroke_color">@color/modern_grey_300</color> - <!-- Modern color palette --> - <color name="modern_blue_300">#8AB4F8</color> - <color name="modern_blue_600">#1A73E8</color> - <color name="modern_grey_50" tools:ignore="UnusedResources">#F8F9FA</color> - <color name="modern_grey_100" tools:ignore="UnusedResources">#F1F3F4</color> - <color name="modern_grey_200" tools:ignore="UnusedResources">#E8EAED</color> - <color name="modern_grey_300" tools:ignore="UnusedResources">#DADCE0</color> - <color name="modern_grey_400" tools:ignore="UnusedResources">#BDC1C6</color> - <color name="modern_grey_500" tools:ignore="UnusedResources">#9AA0A6</color> - <color name="modern_grey_600" tools:ignore="UnusedResources">#80868B</color> - <color name="modern_grey_700">#5F6368</color> - <color name="modern_grey_800" tools:ignore="UnusedResources">#3C4043</color> - <color name="modern_grey_900">#202124</color> - - <color name="black_alpha_38">#61000000</color> - <color name="white_alpha_70">#B3FFFFFF</color> + <!-- Common background and branding color. --> + <color name="modern_primary_color">@android:color/white</color> + <color name="modern_secondary_color">@color/modern_grey_100</color> <color name="dropdown_divider_color">#E5E5E5</color> <color name="dropdown_dark_divider_color">#C0C0C0</color>
diff --git a/ui/android/java/res_night/values-night/colors.xml b/ui/android/java/res_night/values-night/colors.xml index 8a868ef..d03127fa 100644 --- a/ui/android/java/res_night/values-night/colors.xml +++ b/ui/android/java/res_night/values-night/colors.xml
@@ -4,7 +4,18 @@ found in the LICENSE file. --> <resources> - <!-- TODO(huayinz): Change the colors. --> - <color name="default_text_color">@android:color/holo_green_dark</color> - <color name="default_text_color_secondary">@android:color/holo_green_light</color> + <!-- Common text colors --> + <color name="default_text_color">@color/modern_grey_200</color> + <color name="default_text_color_secondary">@color/modern_grey_500</color> + <color name="default_text_color_link">@color/modern_blue_300</color> + <color name="disabled_text_color">@color/modern_grey_200_alpha_38</color> + + <!-- Common icon colors for drawables. --> + <color name="default_icon_color">@color/modern_grey_200</color> + <color name="default_icon_color_blue">@color/modern_blue_300</color> + <color name="hairline_stroke_color">@color/white_alpha_10</color> + + <!-- Common background and branding color. --> + <color name="modern_primary_color">@color/modern_grey_900</color> + <color name="modern_secondary_color">@color/modern_grey_800</color> </resources> \ No newline at end of file
diff --git a/ui/android/java/src/org/chromium/ui/DropdownPopupWindowImpl.java b/ui/android/java/src/org/chromium/ui/DropdownPopupWindowImpl.java index 7d1f995d1..b65dd316 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownPopupWindowImpl.java +++ b/ui/android/java/src/org/chromium/ui/DropdownPopupWindowImpl.java
@@ -82,8 +82,8 @@ ViewRectProvider rectProvider = new ViewRectProvider(mAnchorView); rectProvider.setIncludePadding(true); - mBackground = - ApiCompatibilityUtils.getDrawable(context.getResources(), R.drawable.popup_bg); + mBackground = ApiCompatibilityUtils.getDrawable( + context.getResources(), R.drawable.popup_bg_tinted); mAnchoredPopupWindow = new AnchoredPopupWindow( context, mAnchorView, mBackground, mContentView, rectProvider); mAnchoredPopupWindow.addOnDismissListener(onDismissLitener); @@ -117,8 +117,8 @@ public void onPreLayoutChange( boolean positionBelow, int x, int y, int width, int height, Rect anchorRect) { mBackground.setBounds(anchorRect); - mAnchoredPopupWindow.setBackgroundDrawable( - ApiCompatibilityUtils.getDrawable(mContext.getResources(), R.drawable.popup_bg)); + mAnchoredPopupWindow.setBackgroundDrawable(ApiCompatibilityUtils.getDrawable( + mContext.getResources(), R.drawable.popup_bg_tinted)); } /**
diff --git a/ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java b/ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java index 8457f4be..8b61553 100644 --- a/ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java +++ b/ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java
@@ -192,22 +192,6 @@ mObservers.remove(observer); } - /** - * Toggle the accurate mode if it wasn't already doing so. The backend will - * keep track of the number of times this has been called. - */ - public static void startAccurateListening() { - getManager().startAccurateListening(); - } - - /** - * Request to stop the accurate mode. It will effectively be stopped only if - * this method is called as many times as startAccurateListening(). - */ - public static void stopAccurateListening() { - getManager().stopAccurateListening(); - } - protected DisplayAndroid(int displayId) { mDisplayId = displayId; mObservers = new WeakHashMap<>();
diff --git a/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java b/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java index 4f6e994..e2e2396 100644 --- a/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java +++ b/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java
@@ -5,12 +5,9 @@ package org.chromium.ui.display; import android.annotation.SuppressLint; -import android.content.ComponentCallbacks; import android.content.Context; -import android.content.res.Configuration; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; -import android.os.Build; import android.util.SparseArray; import android.view.Display; import android.view.WindowManager; @@ -28,125 +25,14 @@ @MainDex public class DisplayAndroidManager { /** - * DisplayListenerBackend is an interface that abstract the mechanism used for the actual - * display update listening. The reason being that from Android API Level 17 DisplayListener - * will be used. Before that, an unreliable solution based on onConfigurationChanged has to be - * used. + * DisplayListenerBackend is used to handle the actual listening of display changes. It handles + * it via the Android DisplayListener API. */ - private interface DisplayListenerBackend { - - /** - * Starts to listen for display changes. This will be called - * when the first observer is added. - */ - void startListening(); - - /** - * Toggle the accurate mode if it wasn't already doing so. The backend - * will keep track of the number of times this has been called. - */ - void startAccurateListening(); - - /** - * Request to stop the accurate mode. It will effectively be stopped - * only if this method is called as many times as - * startAccurateListening(). - */ - void stopAccurateListening(); - } - - /** - * DisplayListenerAPI16 implements DisplayListenerBackend - * to use ComponentCallbacks in order to listen for display - * changes. - * - * This method is known to not correctly detect 180 degrees changes but it - * is the only method that will work before API Level 17 (excluding polling). - * When toggleAccurateMode() is called, it will start polling in order to - * find out if the display has changed. - */ - private class DisplayListenerAPI16 - implements DisplayListenerBackend, ComponentCallbacks { - - private static final long POLLING_DELAY = 500; - - private int mAccurateCount; - - // DisplayListenerBackend implementation: - - @Override - public void startListening() { - getContext().registerComponentCallbacks(this); - } - - @Override - public void startAccurateListening() { - ++mAccurateCount; - - if (mAccurateCount > 1) return; - - // Start polling if we went from 0 to 1. The polling will - // automatically stop when mAccurateCount reaches 0. - final DisplayListenerAPI16 self = this; - ThreadUtils.postOnUiThreadDelayed(new Runnable() { - @Override - public void run() { - self.onConfigurationChanged(null); - - if (self.mAccurateCount < 1) return; - - ThreadUtils.postOnUiThreadDelayed(this, - DisplayListenerAPI16.POLLING_DELAY); - } - }, POLLING_DELAY); - } - - @Override - public void stopAccurateListening() { - --mAccurateCount; - assert mAccurateCount >= 0; - } - - // ComponentCallbacks implementation: - - @Override - public void onConfigurationChanged(Configuration newConfig) { - ((PhysicalDisplayAndroid) mIdMap.get(mMainSdkDisplayId)).updateFromDisplay( - getDefaultDisplayForContext(getContext())); - } - - @Override - public void onLowMemory() { - } - } - - /** - * DisplayListenerBackendImpl implements DisplayListenerBackend - * to use DisplayListener in order to listen for display changes. - * - * This method is reliable but DisplayListener is only available for API Level 17+. - */ - @SuppressLint("NewApi") - private class DisplayListenerBackendImpl - implements DisplayListenerBackend, DisplayListener { - - // DisplayListenerBackend implementation: - - @Override + private class DisplayListenerBackend implements DisplayListener { public void startListening() { getDisplayManager().registerDisplayListener(this, null); } - @Override - public void startAccurateListening() { - // Always accurate. Do nothing. - } - - @Override - public void stopAccurateListening() { - // Always accurate. Do nothing. - } - // DisplayListener implementation: @Override @@ -191,7 +77,7 @@ private long mNativePointer; private int mMainSdkDisplayId; private final SparseArray<DisplayAndroid> mIdMap = new SparseArray<>(); - private DisplayListenerBackend mBackend; + private DisplayListenerBackend mBackend = new DisplayListenerBackend(); private int mNextVirtualDisplayId = VIRTUAL_DISPLAY_ID_BEGIN; /* package */ static DisplayAndroidManager getInstance() { @@ -234,20 +120,15 @@ private void initialize() { Display display; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - mBackend = new DisplayListenerBackendImpl(); - // Make sure the display map contains the built-in primary display. - // The primary display is never removed. - display = getDisplayManager().getDisplay(Display.DEFAULT_DISPLAY); - // Android documentation on Display.DEFAULT_DISPLAY suggests that the above - // method might return null. In that case we retrieve the default display - // from the application context and take it as the primary display. - if (display == null) display = getDefaultDisplayForContext(getContext()); - } else { - mBackend = new DisplayListenerAPI16(); - display = getDefaultDisplayForContext(getContext()); - } + // Make sure the display map contains the built-in primary display. + // The primary display is never removed. + display = getDisplayManager().getDisplay(Display.DEFAULT_DISPLAY); + + // Android documentation on Display.DEFAULT_DISPLAY suggests that the above + // method might return null. In that case we retrieve the default display + // from the application context and take it as the primary display. + if (display == null) display = getDefaultDisplayForContext(getContext()); mMainSdkDisplayId = display.getDisplayId(); addDisplay(display); // Note this display is never removed. @@ -273,14 +154,6 @@ return displayAndroid; } - /* package */ void startAccurateListening() { - mBackend.startAccurateListening(); - } - - /* package */ void stopAccurateListening() { - mBackend.stopAccurateListening(); - } - private DisplayAndroid addDisplay(Display display) { int sdkDisplayId = display.getDisplayId(); PhysicalDisplayAndroid displayAndroid = new PhysicalDisplayAndroid(display);
diff --git a/ui/aura/mus/embed_root.cc b/ui/aura/mus/embed_root.cc index e0262c58..341fae7a 100644 --- a/ui/aura/mus/embed_root.cc +++ b/ui/aura/mus/embed_root.cc
@@ -136,7 +136,6 @@ focus_client_ = std::make_unique<EmbeddedFocusClient>(window_tree_host->window()); window_tree_host_ = std::move(window_tree_host); - window_tree_host_->Show(); delegate_->OnEmbed(window()); }
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc index 3b35c8f..91cf66a 100644 --- a/ui/aura/mus/window_tree_client.cc +++ b/ui/aura/mus/window_tree_client.cc
@@ -496,10 +496,8 @@ window_tree_host->InitHost(); SetLocalPropertiesFromServerProperties( WindowMus::Get(window_tree_host->window()), window_data); - if (window_data.visible) { - SetWindowVisibleFromServer(WindowMus::Get(window_tree_host->window()), - true); - } + SetWindowVisibleFromServer(WindowMus::Get(window_tree_host->window()), + window_data.visible); WindowMus* window = WindowMus::Get(window_tree_host->window()); SetWindowBoundsFromServer(window, window_data.bounds, /* from_server */ true,
diff --git a/ui/aura/mus/window_tree_client_unittest.cc b/ui/aura/mus/window_tree_client_unittest.cc index ec61619..47e01db6 100644 --- a/ui/aura/mus/window_tree_client_unittest.cc +++ b/ui/aura/mus/window_tree_client_unittest.cc
@@ -2626,6 +2626,22 @@ window_tree_client()->OnWindowFocused(server_id(embed_root->window())); } +// Verifies visibility from server is applied properly when an embed root is +// created. +TEST_F(WindowTreeClientTest, EmbedRootVisibility) { + for (bool visible : {true, false}) { + TestEmbedRootDelegate embed_root_delegate; + std::unique_ptr<EmbedRoot> embed_root = + window_tree_client_impl()->CreateEmbedRoot(&embed_root_delegate); + WindowTreeClientTestApi(window_tree_client_impl()) + .CallOnEmbedFromToken(embed_root.get(), visible); + ASSERT_TRUE(embed_root->window()); + EXPECT_EQ(visible, embed_root->window()->TargetVisibility()); + EXPECT_EQ(visible, + embed_root->window()->GetHost()->compositor()->IsVisible()); + } +} + TEST_F(WindowTreeClientTest, PerformWindowMove) { int call_count = 0; bool last_result = false;
diff --git a/ui/aura/test/mus/test_window_tree.cc b/ui/aura/test/mus/test_window_tree.cc index 193606d3..e034fd22 100644 --- a/ui/aura/test/mus/test_window_tree.cc +++ b/ui/aura/test/mus/test_window_tree.cc
@@ -60,6 +60,7 @@ embedder_window_data->window_id = (kFakeEmbedderClientId << 32) | kFakeEmbedderWindowId; embedder_window_data->bounds = gfx::Rect(320, 240); + embedder_window_data->visible = true; viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator; parent_local_surface_id_allocator.GenerateId();
diff --git a/ui/aura/test/mus/window_tree_client_test_api.cc b/ui/aura/test/mus/window_tree_client_test_api.cc index 5e2b50a..b60c563 100644 --- a/ui/aura/test/mus/window_tree_client_test_api.cc +++ b/ui/aura/test/mus/window_tree_client_test_api.cc
@@ -58,13 +58,14 @@ old_capture ? WindowPortMus::Get(old_capture)->server_id() : 0); } -void WindowTreeClientTestApi::CallOnEmbedFromToken(EmbedRoot* embed_root) { +void WindowTreeClientTestApi::CallOnEmbedFromToken(EmbedRoot* embed_root, + bool visible) { embed_root->OnScheduledEmbedForExistingClient( base::UnguessableToken::Create()); viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator; parent_local_surface_id_allocator.GenerateId(); tree_client_impl_->OnEmbedFromToken( - embed_root->token(), CreateWindowDataForEmbed(), kDisplayId, + embed_root->token(), CreateWindowDataForEmbed(visible), kDisplayId, parent_local_surface_id_allocator.GetCurrentLocalSurfaceIdAllocation()); } @@ -106,7 +107,8 @@ return false; } -ws::mojom::WindowDataPtr WindowTreeClientTestApi::CreateWindowDataForEmbed() { +ws::mojom::WindowDataPtr WindowTreeClientTestApi::CreateWindowDataForEmbed( + bool visible) { ws::mojom::WindowDataPtr root_data(ws::mojom::WindowData::New()); root_data->parent_id = 0; // OnEmbed() is passed windows the client doesn't own. Use a |client_id| of 1 @@ -116,7 +118,7 @@ const ws::Id client_id = 1; root_data->window_id = (client_id << 32) | tree_client_impl_->GetRoots().size(); - root_data->visible = true; + root_data->visible = visible; return root_data; }
diff --git a/ui/aura/test/mus/window_tree_client_test_api.h b/ui/aura/test/mus/window_tree_client_test_api.h index 329a6d38..f253120 100644 --- a/ui/aura/test/mus/window_tree_client_test_api.h +++ b/ui/aura/test/mus/window_tree_client_test_api.h
@@ -55,8 +55,9 @@ void CallOnCaptureChanged(Window* new_capture, Window* old_capture); // Simulates the EmbedRoot receiving the token from the WindowTree and then - // the WindowTree calling OnEmbedFromToken(). - void CallOnEmbedFromToken(EmbedRoot* embed_root); + // the WindowTree calling OnEmbedFromToken(). |visible| is the initial value + // to supply from the server for the visibility. + void CallOnEmbedFromToken(EmbedRoot* embed_root, bool visible = true); // Sets the WindowTree. This calls WindowTreeConnectionEstablished(), which // means it should only be called once, during setup. @@ -83,7 +84,8 @@ #endif friend void test::WaitForAllChangesToComplete(WindowTreeClient* client); - ws::mojom::WindowDataPtr CreateWindowDataForEmbed(); + // |visible| whether the window is visible. + ws::mojom::WindowDataPtr CreateWindowDataForEmbed(bool visible = true); // This is private as WaitForAllChangesToComplete() (in // change_completion_waiter) should be used instead.
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js index 63cc452..f2a98ac 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js
@@ -9,12 +9,55 @@ /** * File table list. - * @constructor - * @struct - * @extends {cr.ui.table.TableList} */ -function FileTableList() { - throw new Error('Designed to decorate elements'); +class FileTableList extends cr.ui.table.TableList { + constructor() { + // To silence closure compiler. + super(); + /* + * @type {?function(number, number)} + */ + this.onMergeItems_ = null; + + throw new Error('Designed to decorate elements'); + } + + /** + * @param {function(number, number)} onMergeItems callback called from + * |mergeItems| with the parameters |beginIndex| and |endIndex|. + */ + setOnMergeItems(onMergeItems) { + assert(!this.onMergeItems_); + this.onMergeItems_ = onMergeItems; + } + + /** @override */ + mergeItems(beginIndex, endIndex) { + cr.ui.table.TableList.prototype.mergeItems.call(this, beginIndex, endIndex); + + // Make sure that list item's selected attribute is updated just after the + // mergeItems operation is done. This prevents checkmarks on selected items + // from being animated unintentionally by redraw. + for (let i = beginIndex; i < endIndex; i++) { + const item = this.getListItemByIndex(i); + if (!item) { + continue; + } + const isSelected = this.selectionModel.getIndexSelected(i); + if (item.selected != isSelected) { + item.selected = isSelected; + } + } + + if (this.onMergeItems_) { + this.onMergeItems_(beginIndex, endIndex); + } + } + + /** @override */ + createSelectionController(sm) { + return new FileListSelectionController(assert(sm)); + } } /** @@ -23,107 +66,62 @@ */ FileTableList.decorate = self => { self.__proto__ = FileTableList.prototype; -}; - -FileTableList.prototype.__proto__ = cr.ui.table.TableList.prototype; - -/** - * @type {?function(number, number)} - */ -FileTableList.prototype.onMergeItems_ = null; - -/** - * @param {function(number, number)} onMergeItems callback called from - * |mergeItems| with the parameters |beginIndex| and |endIndex|. - */ -FileTableList.prototype.setOnMergeItems = function(onMergeItems) { - assert(!this.onMergeItems_); - this.onMergeItems_ = onMergeItems; -}; - -/** @override */ -FileTableList.prototype.mergeItems = function(beginIndex, endIndex) { - cr.ui.table.TableList.prototype.mergeItems.call(this, beginIndex, endIndex); - - // Make sure that list item's selected attribute is updated just after the - // mergeItems operation is done. This prevents checkmarks on selected items - // from being animated unintentionally by redraw. - for (let i = beginIndex; i < endIndex; i++) { - const item = this.getListItemByIndex(i); - if (!item) { - continue; - } - const isSelected = this.selectionModel.getIndexSelected(i); - if (item.selected != isSelected) { - item.selected = isSelected; - } - } - - if (this.onMergeItems_) { - this.onMergeItems_(beginIndex, endIndex); - } -}; - -/** @override */ -FileTableList.prototype.createSelectionController = function(sm) { - return new FileListSelectionController(assert(sm)); + self.onMergeItems_ = null; }; /** * Selection controller for the file table list. - * @param {!cr.ui.ListSelectionModel} selectionModel The selection model to - * interact with. - * @constructor - * @extends {cr.ui.ListSelectionController} - * @struct */ -function FileListSelectionController(selectionModel) { - cr.ui.ListSelectionController.call(this, selectionModel); - +class FileListSelectionController extends cr.ui.ListSelectionController { /** - * Whether to allow touch-specific interaction. - * @type {boolean} + * @param {!cr.ui.ListSelectionModel} selectionModel The selection model to + * interact with. */ - this.enableTouchMode_ = false; - util.isTouchModeEnabled().then(enabled => { - this.enableTouchMode_ = enabled; - }); + constructor(selectionModel) { + super(selectionModel); + //cr.ui.ListSelectionController.call(this, selectionModel); - /** - * @type {!FileTapHandler} - * @const - */ - this.tapHandler_ = new FileTapHandler(); + /** + * Whether to allow touch-specific interaction. + * @type {boolean} + */ + this.enableTouchMode_ = false; + util.isTouchModeEnabled().then(enabled => { + this.enableTouchMode_ = enabled; + }); + + /** + * @type {!FileTapHandler} + * @const + */ + this.tapHandler_ = new FileTapHandler(); + } + + /** @override */ + handlePointerDownUp(e, index) { + filelist.handlePointerDownUp.call(this, e, index); + } + + /** @override */ + handleTouchEvents(e, index) { + if (!this.enableTouchMode_) { + return; + } + if (this.tapHandler_.handleTouchEvents( + e, index, filelist.handleTap.bind(this))) { + // If a tap event is processed, FileTapHandler cancels the event to prevent + // triggering click events. Then it results not moving the focus to the + // list. So we do that here explicitly. + filelist.focusParentList(e); + } + } + + /** @override */ + handleKeyDown(e) { + filelist.handleKeyDown.call(this, e); + } } -FileListSelectionController.prototype = /** @struct */ { - __proto__: cr.ui.ListSelectionController.prototype -}; - -/** @override */ -FileListSelectionController.prototype.handlePointerDownUp = function(e, index) { - filelist.handlePointerDownUp.call(this, e, index); -}; - -/** @override */ -FileListSelectionController.prototype.handleTouchEvents = function(e, index) { - if (!this.enableTouchMode_) { - return; - } - if (this.tapHandler_.handleTouchEvents( - e, index, filelist.handleTap.bind(this))) { - // If a tap event is processed, FileTapHandler cancels the event to prevent - // triggering click events. Then it results not moving the focus to the - // list. So we do that here explicitly. - filelist.focusParentList(e); - } -}; - -/** @override */ -FileListSelectionController.prototype.handleKeyDown = function(e) { - filelist.handleKeyDown.call(this, e); -}; - /** * Common item decoration for table's and grid's items. * @param {cr.ui.ListItem} li List item.
diff --git a/ui/ozone/platform/wayland/wayland_pointer.cc b/ui/ozone/platform/wayland/wayland_pointer.cc index 4e7940cd..9063900 100644 --- a/ui/ozone/platform/wayland/wayland_pointer.cc +++ b/ui/ozone/platform/wayland/wayland_pointer.cc
@@ -61,11 +61,10 @@ WaylandPointer* pointer = static_cast<WaylandPointer*>(data); pointer->location_.SetPoint(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y)); - if (surface) { - WaylandWindow* window = WaylandWindow::FromSurface(surface); - window->set_pointer_focus(true); - pointer->window_with_pointer_focus_ = window; - } + pointer->FocusWindow(surface); + MouseEvent event(ET_MOUSE_ENTERED, pointer->location_, pointer->location_, + EventTimeForNow(), pointer->flags_, 0); + pointer->callback_.Run(&event); } // static @@ -77,12 +76,7 @@ MouseEvent event(ET_MOUSE_EXITED, gfx::Point(), gfx::Point(), EventTimeForNow(), pointer->flags_, 0); pointer->callback_.Run(&event); - if (surface) { - WaylandWindow* window = WaylandWindow::FromSurface(surface); - window->set_pointer_focus(false); - window->set_has_implicit_grab(false); - pointer->window_with_pointer_focus_ = nullptr; - } + pointer->UnfocusWindow(surface); } // static @@ -218,4 +212,21 @@ keyboard_modifiers_ = 0; } +void WaylandPointer::FocusWindow(wl_surface* surface) { + if (surface) { + WaylandWindow* window = WaylandWindow::FromSurface(surface); + window->set_pointer_focus(true); + window_with_pointer_focus_ = window; + } +} + +void WaylandPointer::UnfocusWindow(wl_surface* surface) { + if (surface) { + WaylandWindow* window = WaylandWindow::FromSurface(surface); + window->set_pointer_focus(false); + window->set_has_implicit_grab(false); + window_with_pointer_focus_ = nullptr; + } +} + } // namespace ui
diff --git a/ui/ozone/platform/wayland/wayland_pointer.h b/ui/ozone/platform/wayland/wayland_pointer.h index 0c398d1..1af7b970 100644 --- a/ui/ozone/platform/wayland/wayland_pointer.h +++ b/ui/ozone/platform/wayland/wayland_pointer.h
@@ -65,6 +65,8 @@ wl_fixed_t value); void MaybeSetOrResetImplicitGrab(); + void FocusWindow(wl_surface* surface); + void UnfocusWindow(wl_surface* surface); WaylandConnection* connection_ = nullptr; std::unique_ptr<WaylandCursor> cursor_;
diff --git a/ui/ozone/platform/wayland/wayland_pointer_unittest.cc b/ui/ozone/platform/wayland/wayland_pointer_unittest.cc index 24233ba1..1242433 100644 --- a/ui/ozone/platform/wayland/wayland_pointer_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_pointer_unittest.cc
@@ -44,6 +44,27 @@ DISALLOW_COPY_AND_ASSIGN(WaylandPointerTest); }; +ACTION_P(CloneEvent, ptr) { + *ptr = Event::Clone(*arg0); +} + +TEST_P(WaylandPointerTest, Enter) { + wl_pointer_send_enter(pointer_->resource(), 1, surface_->resource(), 0, 0); + + std::unique_ptr<Event> event; + EXPECT_CALL(delegate_, DispatchEvent(_)).WillOnce(CloneEvent(&event)); + + Sync(); + + ASSERT_TRUE(event); + ASSERT_TRUE(event->IsMouseEvent()); + auto* mouse_event = event->AsMouseEvent(); + EXPECT_EQ(ET_MOUSE_ENTERED, mouse_event->type()); + EXPECT_EQ(0, mouse_event->button_flags()); + EXPECT_EQ(0, mouse_event->changed_button_flags()); + EXPECT_EQ(gfx::PointF(0, 0), mouse_event->location_f()); +} + TEST_P(WaylandPointerTest, Leave) { MockPlatformWindowDelegate other_delegate; WaylandWindow other_window(&other_delegate, connection_.get()); @@ -68,17 +89,13 @@ 0); wl_pointer_send_button(pointer_->resource(), 4, 1004, BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED); - EXPECT_CALL(delegate_, DispatchEvent(_)).Times(1); + EXPECT_CALL(delegate_, DispatchEvent(_)).Times(2); // Do an extra Sync() here so that we process the second enter event before we // destroy |other_window|. Sync(); } -ACTION_P(CloneEvent, ptr) { - *ptr = Event::Clone(*arg0); -} - ACTION_P3(CloneEventAndCheckCapture, window, result, ptr) { ASSERT_TRUE(window->HasCapture() == result); *ptr = Event::Clone(*arg0); @@ -86,6 +103,9 @@ TEST_P(WaylandPointerTest, Motion) { wl_pointer_send_enter(pointer_->resource(), 1, surface_->resource(), 0, 0); + Sync(); // We're interested in checking Motion event in this test case, so + // skip Enter event here. + wl_pointer_send_motion(pointer_->resource(), 1002, wl_fixed_from_double(10.75), wl_fixed_from_double(20.375));
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd index f530c8b8..c87bd42 100644 --- a/ui/strings/ui_strings.grd +++ b/ui/strings/ui_strings.grd
@@ -837,7 +837,7 @@ Remove this suggestion? </message> <message name="IDS_REMOVE_ZERO_STATE_SUGGESTION_DETAILS" desc="Detailed explanation message for removing zero state suggestion"> - Hiding this suggestion will not show it again from your account across all your devices. + Removing this suggestion will hide it from your account across all your devices. </message> <message name="IDS_REMOVE_SUGGESTION_BUTTON_LABEL" desc="Remove suggestion button label"> Remove
diff --git a/ui/views/accessibility/view_accessibility.cc b/ui/views/accessibility/view_accessibility.cc index e1281a9c..bd82fee 100644 --- a/ui/views/accessibility/view_accessibility.cc +++ b/ui/views/accessibility/view_accessibility.cc
@@ -153,6 +153,16 @@ ax::mojom::StringAttribute::kDescription)); } + static const ax::mojom::IntAttribute kOverridableIntAttributes[]{ + ax::mojom::IntAttribute::kPosInSet, + ax::mojom::IntAttribute::kSetSize, + }; + + for (auto attribute : kOverridableIntAttributes) { + if (custom_data_.HasIntAttribute(attribute)) + data->AddIntAttribute(attribute, custom_data_.GetIntAttribute(attribute)); + } + if (!data->HasStringAttribute(ax::mojom::StringAttribute::kDescription)) { base::string16 tooltip; view_->GetTooltipText(gfx::Point(), &tooltip); @@ -226,6 +236,11 @@ custom_data_.relative_bounds.bounds = bounds; } +void ViewAccessibility::OverridePosInSet(int pos_in_set, int set_size) { + custom_data_.AddIntAttribute(ax::mojom::IntAttribute::kPosInSet, pos_in_set); + custom_data_.AddIntAttribute(ax::mojom::IntAttribute::kSetSize, set_size); +} + gfx::NativeViewAccessible ViewAccessibility::GetNativeObject() { return nullptr; }
diff --git a/ui/views/accessibility/view_accessibility.h b/ui/views/accessibility/view_accessibility.h index 26da24f..ebccb37 100644 --- a/ui/views/accessibility/view_accessibility.h +++ b/ui/views/accessibility/view_accessibility.h
@@ -7,6 +7,7 @@ #include <memory> #include <string> +#include <vector> #include "base/macros.h" #include "base/strings/string16.h" @@ -65,6 +66,13 @@ void OverrideIsIgnored(bool value); void OverrideBounds(const gfx::RectF& bounds); + // Override indexes used by some screen readers when describing elements in a + // menu, list, etc. If not specified, a view's index in its parent and its + // parent's number of children provide the values for these. + // + // Note: |pos_in_set| is 1-indexed. + void OverridePosInSet(int pos_in_set, int set_size); + virtual gfx::NativeViewAccessible GetNativeObject(); virtual void NotifyAccessibilityEvent(ax::mojom::Event event_type) {} #if defined(OS_MACOSX)
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index 573f1d4..2164c84 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc
@@ -27,6 +27,7 @@ #include "ui/gfx/image/image_skia_rep.h" #include "ui/gfx/native_widget_types.h" #include "ui/native_theme/native_theme.h" +#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/controls/button/menu_button.h" #include "ui/views/controls/menu/menu_config.h" #include "ui/views/controls/menu/menu_controller_delegate.h" @@ -1992,6 +1993,9 @@ item->GetSubmenu()->GetWidget()->SetNativeWindowProperty( TooltipManager::kGroupingPropertyKey, reinterpret_cast<void*>(kGroupingId)); + + // Set the selection indices for this menu level based on traversal order. + SetSelectionIndices(item); } else { item->GetSubmenu()->Reposition(bounds); } @@ -2480,6 +2484,37 @@ } } +void MenuController::SetSelectionIndices(MenuItemView* parent) { + std::vector<View*> ordering; + SubmenuView* const submenu = parent->GetSubmenu(); + + for (int i = 0; i < submenu->GetMenuItemCount(); ++i) { + MenuItemView* const item = submenu->GetMenuItemAt(i); + if (!item->visible() || !item->enabled()) + continue; + + bool found_focusable = false; + if (item->has_children()) { + for (View* child = GetInitialFocusableView(item, true); child; + child = GetNextFocusableView(item, child, true)) { + ordering.push_back(child); + found_focusable = true; + } + } + if (!found_focusable) + ordering.push_back(item); + } + + if (ordering.empty()) + return; + + const int set_size = ordering.size(); + for (int i = 0; i < set_size; ++i) { + const int set_pos = i + 1; // 1-indexed + ordering[i]->GetViewAccessibility().OverridePosInSet(set_pos, set_size); + } +} + void MenuController::MoveSelectionToFirstOrLastItem( SelectionIncrementDirectionType direction) { MenuItemView* item = pending_state_.item;
diff --git a/ui/views/controls/menu/menu_controller.h b/ui/views/controls/menu/menu_controller.h index f6a40f6..5353a55 100644 --- a/ui/views/controls/menu/menu_controller.h +++ b/ui/views/controls/menu/menu_controller.h
@@ -494,6 +494,14 @@ // Selects the next or previous (depending on |direction|) menu item. void IncrementSelection(SelectionIncrementDirectionType direction); + // Sets up accessible indices for menu items based on up/down arrow selection + // logic, to be used by screen readers to give accurate "item X of Y" + // information (and to be consistent with accessible keyboard use). + // + // This only sets one level of menu, so it must be called when submenus are + // opened as well. + void SetSelectionIndices(MenuItemView* parent); + // Selects the first or last (depending on |direction|) menu item. void MoveSelectionToFirstOrLastItem( SelectionIncrementDirectionType direction);
diff --git a/ui/views/controls/menu/menu_controller_unittest.cc b/ui/views/controls/menu/menu_controller_unittest.cc index 305d043..a746afb9 100644 --- a/ui/views/controls/menu/menu_controller_unittest.cc +++ b/ui/views/controls/menu/menu_controller_unittest.cc
@@ -14,6 +14,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" +#include "ui/accessibility/ax_node_data.h" #include "ui/events/event.h" #include "ui/events/event_constants.h" #include "ui/events/event_handler.h" @@ -21,6 +22,7 @@ #include "ui/events/test/event_generator.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" +#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/controls/menu/menu_controller_delegate.h" #include "ui/views/controls/menu/menu_delegate.h" #include "ui/views/controls/menu/menu_host.h" @@ -712,6 +714,10 @@ return MenuConfig::instance().arrow_key_selection_wraps; } + void OpenMenu(MenuItemView* parent) { + menu_controller_->OpenMenuImpl(parent, true); + } + private: void Init() { owner_ = std::make_unique<GestureTestWidget>(); @@ -2122,5 +2128,186 @@ sub_menu->Close(); } +TEST_F(MenuControllerTest, SetSelectionIndices_MenuItemsOnly) { + MenuItemView* const item1 = menu_item()->GetSubmenu()->GetMenuItemAt(0); + MenuItemView* const item2 = menu_item()->GetSubmenu()->GetMenuItemAt(1); + MenuItemView* const item3 = menu_item()->GetSubmenu()->GetMenuItemAt(2); + MenuItemView* const item4 = menu_item()->GetSubmenu()->GetMenuItemAt(3); + OpenMenu(menu_item()); + + ui::AXNodeData data; + item1->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(1, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(4, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + item2->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(2, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(4, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + item3->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(3, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(4, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + item4->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(4, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(4, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); +} + +TEST_F(MenuControllerTest, + SetSelectionIndices_MenuItemsOnly_SkipHiddenAndDisabled) { + MenuItemView* const item1 = menu_item()->GetSubmenu()->GetMenuItemAt(0); + item1->SetEnabled(false); + MenuItemView* const item2 = menu_item()->GetSubmenu()->GetMenuItemAt(1); + MenuItemView* const item3 = menu_item()->GetSubmenu()->GetMenuItemAt(2); + item3->SetVisible(false); + MenuItemView* const item4 = menu_item()->GetSubmenu()->GetMenuItemAt(3); + OpenMenu(menu_item()); + + ui::AXNodeData data; + item2->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(1, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(2, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + item4->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(2, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(2, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); +} + +TEST_F(MenuControllerTest, SetSelectionIndices_Buttons) { + AddButtonMenuItems(); + MenuItemView* const item1 = menu_item()->GetSubmenu()->GetMenuItemAt(0); + MenuItemView* const item2 = menu_item()->GetSubmenu()->GetMenuItemAt(1); + MenuItemView* const item3 = menu_item()->GetSubmenu()->GetMenuItemAt(2); + MenuItemView* const item4 = menu_item()->GetSubmenu()->GetMenuItemAt(3); + MenuItemView* const item5 = menu_item()->GetSubmenu()->GetMenuItemAt(4); + Button* const button1 = Button::AsButton(item5->child_at(0)); + Button* const button2 = Button::AsButton(item5->child_at(1)); + Button* const button3 = Button::AsButton(item5->child_at(2)); + OpenMenu(menu_item()); + + ui::AXNodeData data; + item1->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(1, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(7, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + item2->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(2, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(7, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + item3->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(3, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(7, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + item4->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(4, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(7, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + button1->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(5, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(7, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + button2->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(6, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(7, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + button3->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(7, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(7, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); +} + +TEST_F(MenuControllerTest, SetSelectionIndices_Buttons_SkipHiddenAndDisabled) { + AddButtonMenuItems(); + MenuItemView* const item1 = menu_item()->GetSubmenu()->GetMenuItemAt(0); + MenuItemView* const item2 = menu_item()->GetSubmenu()->GetMenuItemAt(1); + MenuItemView* const item3 = menu_item()->GetSubmenu()->GetMenuItemAt(2); + MenuItemView* const item4 = menu_item()->GetSubmenu()->GetMenuItemAt(3); + MenuItemView* const item5 = menu_item()->GetSubmenu()->GetMenuItemAt(4); + Button* const button1 = Button::AsButton(item5->child_at(0)); + button1->SetEnabled(false); + Button* const button2 = Button::AsButton(item5->child_at(1)); + button2->SetVisible(false); + Button* const button3 = Button::AsButton(item5->child_at(2)); + OpenMenu(menu_item()); + + ui::AXNodeData data; + item1->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(1, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(5, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + item2->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(2, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(5, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + item3->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(3, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(5, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + item4->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(4, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(5, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + button3->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(5, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(5, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); +} + +TEST_F(MenuControllerTest, SetSelectionIndices_NestedButtons) { + class DummyButtonListener : public ButtonListener { + public: + ~DummyButtonListener() override = default; + void ButtonPressed(Button* sender, const ui::Event& event) override {} + }; + + MenuItemView* const item1 = menu_item()->GetSubmenu()->GetMenuItemAt(0); + MenuItemView* const item2 = menu_item()->GetSubmenu()->GetMenuItemAt(1); + MenuItemView* const item3 = menu_item()->GetSubmenu()->GetMenuItemAt(2); + MenuItemView* const item4 = menu_item()->GetSubmenu()->GetMenuItemAt(3); + + // This simulates how buttons are nested in views in the main app menu. + View* const container_view = new View(); + container_view->GetViewAccessibility().OverrideRole(ax::mojom::Role::kMenu); + item4->AddChildView(container_view); + + // There's usually a label before the traversable elements. + container_view->AddChildView(new Label()); + + // Add two focusable buttons (buttons in menus are always focusable). + Button* const button1 = + new LabelButton(new DummyButtonListener(), base::string16()); + button1->SetFocusBehavior(View::FocusBehavior::ALWAYS); + button1->GetViewAccessibility().OverrideRole(ax::mojom::Role::kMenuItem); + container_view->AddChildView(button1); + Button* const button2 = + new LabelButton(new DummyButtonListener(), base::string16()); + button2->GetViewAccessibility().OverrideRole(ax::mojom::Role::kMenuItem); + button2->SetFocusBehavior(View::FocusBehavior::ALWAYS); + container_view->AddChildView(button2); + + OpenMenu(menu_item()); + + ui::AXNodeData data; + item1->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(1, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(5, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + item2->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(2, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(5, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + item3->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(3, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(5, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + data = ui::AXNodeData(); + button1->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(4, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(5, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + data = ui::AXNodeData(); + button2->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(5, data.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(5, data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); +} + } // namespace test } // namespace views