diff --git a/DEPS b/DEPS index 5ffe680..e5a9c15 100644 --- a/DEPS +++ b/DEPS
@@ -195,11 +195,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': '578215be44d00af16d431bc277b0d0d429fbf53d', + 'skia_revision': '8025507f746b2b95a840684ce6746aae55cecbfd', # 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': 'bccf9d557196688f8cc91c00db6526f8f493124c', + 'v8_revision': '70f0b007689faeba4c5edb01018c40b2f203f2f9', # 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. @@ -266,7 +266,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '5a8fc1fe06a281f2ece82031d9e91281a71c9805', + 'devtools_frontend_revision': 'b8ae5a73f8754a47acc50f4c1d7461e8a6fd5e26', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -875,7 +875,7 @@ # Build tools for Chrome OS. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'ac74b9c703be054e6f7ce1360ef02dbcd3e8b1a4', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '7f786caa5d60e1feec3af7913f47e632440b07da', 'condition': 'checkout_chromeos', }, @@ -1248,7 +1248,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'cd8de1d295b4bedf5b0b00a6655575881df8696a', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '41db2fb64914bb8c4cd2261f8ecedf1ef3b28942', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1470,7 +1470,7 @@ }, 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'd37b0ec2bb0c4cbf8e9b196f75795d7106b57ad3', + Var('webrtc_git') + '/src.git' + '@' + '59230836579a7ce0386faebb07c73ac23f31a2b4', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1542,7 +1542,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@25e9f126d8c331c5a72893d07c11f95a23acae3b', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@65f9045b37a9f02731008b8f71d86bb9db4f0444', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index a06c44f..932d731 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -53,6 +53,19 @@ standalone_system_webview_apk_tmpl("system_webview_no_weblayer_apk") { exclude_weblayer_java = true apk_name = "SystemWebViewNoWebLayer" + + # Adding deps on recycler view in the base WebView APK will end up keeping the + # Java in the base APK instead of the WebLayer DFM, even though it is not + # needed in the base APK. + # + # If you hit this check and are adding a dep to //ui/android:ui_java, use + # //ui/android:ui_no_recycler_view instead. If you hit this check because you + # are adding //third_party/android_deps:android_support_*, use the androidx + # version of the dep instead. + # TODO(b/165810905): Use per-feature -keep rules in R8 once supported, then + # this can be removed. + assert_no_deps = + [ "//third_party/android_deps:androidx_recyclerview_recyclerview_java" ] } if (enable_webview_bundles) { @@ -571,7 +584,7 @@ "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/blink/public:blink_headers_java", - "//ui/android:ui_java", + "//ui/android:ui_no_recycler_view_java", "//url:gurl_java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
diff --git a/android_webview/glue/BUILD.gn b/android_webview/glue/BUILD.gn index 10bf86b2..3508bce4 100644 --- a/android_webview/glue/BUILD.gn +++ b/android_webview/glue/BUILD.gn
@@ -24,7 +24,7 @@ "//content/public/android:content_java", "//net/android:net_java", "//third_party/android_deps:androidx_annotation_annotation_java", - "//ui/android:ui_java", + "//ui/android:ui_no_recycler_view_java", "//url:gurl_java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index 3dd9051..53f5dc3 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -1716,6 +1716,8 @@ mContentsClient.getVisitedHistory(callback); } + private static final Pattern BAD_HEADER_CHAR = Pattern.compile("[\u0000\r\n]"); + /** * WebView.loadUrl. */ @@ -1740,6 +1742,15 @@ LoadUrlParams params = new LoadUrlParams(url, PageTransition.TYPED); if (additionalHttpHeaders != null) { + boolean valid = true; + for (Map.Entry<String, String> header : additionalHttpHeaders.entrySet()) { + if (BAD_HEADER_CHAR.matcher(header.getKey()).find() + || BAD_HEADER_CHAR.matcher(header.getValue()).find()) { + valid = false; + break; + } + } + RecordHistogram.recordBooleanHistogram("Android.WebView.ExtraHeaders.Valid", valid); params.setExtraHeaders(new HashMap<String, String>(additionalHttpHeaders)); }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwSettings.java b/android_webview/java/src/org/chromium/android_webview/AwSettings.java index 8b2219ef..107ee18 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwSettings.java +++ b/android_webview/java/src/org/chromium/android_webview/AwSettings.java
@@ -26,6 +26,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.content_public.browser.WebContents; import java.lang.annotation.Retention; @@ -642,6 +643,66 @@ < Build.VERSION_CODES.P; } + // Used to record the UMA histogram Android.WebView.UserAgent.Valid. Since these values + // are persisted to logs, they should never be renumbered or reused. + @IntDef({UserAgentType.VALID, UserAgentType.HAS_NULL, UserAgentType.EXTRA_HEADERS, + UserAgentType.EXTRA_HEADERS_SLOPPY_LINEEND, UserAgentType.HEADER_TERMINATION, + UserAgentType.UNKNOWN_INVALID}) + @interface UserAgentType { + int VALID = 0; + int HAS_NULL = 1; + int EXTRA_HEADERS = 2; + int EXTRA_HEADERS_SLOPPY_LINEEND = 3; + int HEADER_TERMINATION = 4; + int UNKNOWN_INVALID = 5; + int COUNT = 6; + } + + // Regex fragments used in checkUserAgentValueValidity. + private static final String HEADER_NAME = "[^\r\n:]+"; + private static final String HEADER_VALUE = "[^\r\n]+"; + private static final String HEADER = HEADER_NAME + ":" + HEADER_VALUE; + private static final String STRICT_LINEEND = "\r\n"; + private static final String SLOPPY_LINEEND = "(?:\r\n|\r|\n)"; + + private static @UserAgentType int checkUserAgentValueValidity(String ua) { + boolean hasLineEnds = false; + for (int i = 0; i < ua.length(); ++i) { + char c = ua.charAt(i); + if (c == '\u0000') { + // An embedded null is never going to be valid. + return UserAgentType.HAS_NULL; + } + if (c == '\r' || c == '\n') { + hasLineEnds = true; + break; + } + } + + if (!hasLineEnds) { + // If we had no nulls and no CR or LF, it's good enough to pass + // net::HttpUtil::IsValidHeaderValue(). + return UserAgentType.VALID; + } + + // If it has CR/LFs in it, it might be trying to insert extra headers or other "creative" + // uses; check if there's a plausible interpretation. We already established there are no + // nulls above. + if (ua.matches(HEADER_VALUE + "(?:" + STRICT_LINEEND + HEADER + ")+")) { + // Looks like a working attempt to insert additional headers, using CRLF as per spec. + return UserAgentType.EXTRA_HEADERS; + } else if (ua.matches(HEADER_VALUE + "(?:" + SLOPPY_LINEEND + HEADER + ")+")) { + // Looks like an attempt to insert additional headers, but wrong line endings. + return UserAgentType.EXTRA_HEADERS_SLOPPY_LINEEND; + } else if (ua.matches(".*" + SLOPPY_LINEEND + SLOPPY_LINEEND + ".*")) { + // Possibly an attempt to terminate headers and push the rest into the request body? + return UserAgentType.HEADER_TERMINATION; + } else { + // Maybe just random garbage, or some more weird/subtle usage. + return UserAgentType.UNKNOWN_INVALID; + } + } + /** * See {@link android.webkit.WebSettings#setUserAgentString}. */ @@ -655,6 +716,13 @@ mUserAgent = ua; } if (!oldUserAgent.equals(mUserAgent)) { + if (ua != null && ua.length() > 0) { + // If we're using the passed-in string (not the default), and we've actually + // changed the UA since the last call, then check whether it's a valid header + // value so we can log metrics. + RecordHistogram.recordEnumeratedHistogram("Android.WebView.UserAgent.Valid", + checkUserAgentValueValidity(ua), UserAgentType.COUNT); + } mEventHandler.runOnUiThreadBlockingAndLocked(() -> { if (mNativeAwSettings != 0) { AwSettingsJni.get().updateUserAgentLocked(
diff --git a/android_webview/lib/aw_main_delegate.cc b/android_webview/lib/aw_main_delegate.cc index fd25a45..6007355 100644 --- a/android_webview/lib/aw_main_delegate.cc +++ b/android_webview/lib/aw_main_delegate.cc
@@ -248,6 +248,8 @@ features.EnableIfNotSet( metrics::UnsentLogStoreMetrics::kRecordLastUnsentLogMetadataMetrics); + + features.DisableIfNotSet(::features::kPeriodicBackgroundSync); } android_webview::RegisterPathProvider();
diff --git a/android_webview/nonembedded/BUILD.gn b/android_webview/nonembedded/BUILD.gn index 618fb9f..e9792e0d 100644 --- a/android_webview/nonembedded/BUILD.gn +++ b/android_webview/nonembedded/BUILD.gn
@@ -33,7 +33,7 @@ "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:com_google_code_findbugs_jsr305_java", "//third_party/android_deps:protobuf_lite_runtime_java", - "//ui/android:ui_java", + "//ui/android:ui_no_recycler_view_java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] } @@ -72,7 +72,7 @@ "//third_party/android_deps:androidx_lifecycle_lifecycle_common_java", "//third_party/android_deps:androidx_lifecycle_lifecycle_viewmodel_java", "//third_party/android_deps:androidx_savedstate_savedstate_java", - "//ui/android:ui_java", + "//ui/android:ui_no_recycler_view_java", ] resources_package = "org.chromium.android_webview.devui" }
diff --git a/ash/accelerators/accelerator_confirmation_dialog.cc b/ash/accelerators/accelerator_confirmation_dialog.cc index dfbaf82..9e6aa14 100644 --- a/ash/accelerators/accelerator_confirmation_dialog.cc +++ b/ash/accelerators/accelerator_confirmation_dialog.cc
@@ -27,6 +27,7 @@ int dialog_text_id, base::OnceClosure on_accept_callback, base::OnceClosure on_cancel_callback) { + SetModalType(ui::MODAL_TYPE_SYSTEM); SetTitle(l10n_util::GetStringUTF16(window_title_text_id)); SetButtonLabel(ui::DIALOG_BUTTON_OK, l10n_util::GetStringUTF16(IDS_ASH_CONTINUE_BUTTON)); @@ -59,10 +60,6 @@ AcceleratorConfirmationDialog::~AcceleratorConfirmationDialog() = default; -ui::ModalType AcceleratorConfirmationDialog::GetModalType() const { - return ui::MODAL_TYPE_SYSTEM; -} - base::WeakPtr<AcceleratorConfirmationDialog> AcceleratorConfirmationDialog::GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr();
diff --git a/ash/accelerators/accelerator_confirmation_dialog.h b/ash/accelerators/accelerator_confirmation_dialog.h index 51770af..e378b7a 100644 --- a/ash/accelerators/accelerator_confirmation_dialog.h +++ b/ash/accelerators/accelerator_confirmation_dialog.h
@@ -23,9 +23,6 @@ base::OnceClosure on_cancel_callback); ~AcceleratorConfirmationDialog() override; - // views::DialogDelegateView: - ui::ModalType GetModalType() const override; - base::WeakPtr<AcceleratorConfirmationDialog> GetWeakPtr(); private:
diff --git a/ash/app_list/views/privacy_info_view.cc b/ash/app_list/views/privacy_info_view.cc index 44547d1..ca7133d 100644 --- a/ash/app_list/views/privacy_info_view.cc +++ b/ash/app_list/views/privacy_info_view.cc
@@ -245,11 +245,12 @@ size_t offset; const base::string16 text = l10n_util::GetStringFUTF16(info_string_id_, link, &offset); - auto text_view = std::make_unique<views::StyledLabel>(text, this); + text_view_ = AddChildView(std::make_unique<views::StyledLabel>(this)); + text_view_->SetText(text); views::StyledLabel::RangeStyleInfo style; style.override_color = gfx::kGoogleGrey900; - text_view->AddStyleRange(gfx::Range(0, offset), style); + text_view_->AddStyleRange(gfx::Range(0, offset), style); // TODO(crbug.com/1114628): Remove the custom view once RangeStyleInfo // supports selected links. @@ -259,13 +260,12 @@ custom_view->SetEnabledColor(gfx::kGoogleBlue700); link_style.custom_view = custom_view.get(); link_view_ = custom_view.get(); - text_view->AddCustomView(std::move(custom_view)); - text_view->AddStyleRange(gfx::Range(offset, offset + link.length()), - link_style); + text_view_->AddCustomView(std::move(custom_view)); + text_view_->AddStyleRange(gfx::Range(offset, offset + link.length()), + link_style); - text_view->SetFocusBehavior(FocusBehavior::ALWAYS); - text_view->SetAutoColorReadabilityEnabled(false); - text_view_ = AddChildView(std::move(text_view)); + text_view_->SetFocusBehavior(FocusBehavior::ALWAYS); + text_view_->SetAutoColorReadabilityEnabled(false); } void PrivacyInfoView::InitCloseButton() {
diff --git a/ash/app_list/views/remove_query_confirmation_dialog.cc b/ash/app_list/views/remove_query_confirmation_dialog.cc index 8a2d3558..a23f7258 100644 --- a/ash/app_list/views/remove_query_confirmation_dialog.cc +++ b/ash/app_list/views/remove_query_confirmation_dialog.cc
@@ -27,6 +27,7 @@ const base::string16& query, RemovalConfirmationCallback confirm_callback) : confirm_callback_(std::move(confirm_callback)) { + SetModalType(ui::MODAL_TYPE_WINDOW); SetTitle(l10n_util::GetStringUTF16(IDS_REMOVE_ZERO_STATE_SUGGESTION_TITLE)); SetShowCloseButton(false); @@ -67,8 +68,4 @@ return gfx::Size(default_width, GetHeightForWidth(default_width)); } -ui::ModalType RemoveQueryConfirmationDialog::GetModalType() const { - return ui::MODAL_TYPE_WINDOW; -} - } // namespace ash
diff --git a/ash/app_list/views/remove_query_confirmation_dialog.h b/ash/app_list/views/remove_query_confirmation_dialog.h index 21c156a7..ce623c5 100644 --- a/ash/app_list/views/remove_query_confirmation_dialog.h +++ b/ash/app_list/views/remove_query_confirmation_dialog.h
@@ -29,9 +29,6 @@ const char* GetClassName() const override; gfx::Size CalculatePreferredSize() const override; - // views::WidgetDelegate: - ui::ModalType GetModalType() const override; - private: RemovalConfirmationCallback confirm_callback_;
diff --git a/ash/assistant/ui/main_stage/assistant_opt_in_view.cc b/ash/assistant/ui/main_stage/assistant_opt_in_view.cc index 889bb4b3..e1619ed 100644 --- a/ash/assistant/ui/main_stage/assistant_opt_in_view.cc +++ b/ash/assistant/ui/main_stage/assistant_opt_in_view.cc
@@ -143,8 +143,7 @@ views::BoxLayout::CrossAxisAlignment::kCenter); // Label. - label_ = container_->AddChildView(std::make_unique<views::StyledLabel>( - base::string16(), /*listener=*/nullptr)); + label_ = container_->AddChildView(std::make_unique<views::StyledLabel>()); label_->SetAutoColorReadabilityEnabled(false); label_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_CENTER);
diff --git a/ash/assistant/ui/main_stage/assistant_query_view.cc b/ash/assistant/ui/main_stage/assistant_query_view.cc index a272abd..9ba8bdc 100644 --- a/ash/assistant/ui/main_stage/assistant_query_view.cc +++ b/ash/assistant/ui/main_stage/assistant_query_view.cc
@@ -80,8 +80,7 @@ views::BoxLayout::CrossAxisAlignment::kStretch); // Label. - label_ = AddChildView(std::make_unique<views::StyledLabel>( - base::string16(), /*listener=*/nullptr)); + label_ = AddChildView(std::make_unique<views::StyledLabel>()); label_->SetAutoColorReadabilityEnabled(false); label_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_CENTER); label_->SetLineHeight(kLineHeightDip);
diff --git a/ash/display/display_change_dialog.cc b/ash/display/display_change_dialog.cc index b21fc439..a4e907dd 100644 --- a/ash/display/display_change_dialog.cc +++ b/ash/display/display_change_dialog.cc
@@ -48,6 +48,7 @@ base::Unretained(this))); SetCancelCallback(base::BindOnce(&DisplayChangeDialog::OnCancelButtonClicked, base::Unretained(this))); + SetModalType(ui::MODAL_TYPE_SYSTEM); SetLayoutManager(std::make_unique<views::FillLayout>()); SetBorder(views::CreateEmptyBorder( @@ -82,10 +83,6 @@ RecordDisplayChangeDialogHistogram(/*accepted=*/false); } -ui::ModalType DisplayChangeDialog::GetModalType() const { - return ui::MODAL_TYPE_SYSTEM; -} - gfx::Size DisplayChangeDialog::CalculatePreferredSize() const { return gfx::Size(350, 100); }
diff --git a/ash/display/display_change_dialog.h b/ash/display/display_change_dialog.h index 1ebb17c9..c2ac34b 100644 --- a/ash/display/display_change_dialog.h +++ b/ash/display/display_change_dialog.h
@@ -33,8 +33,6 @@ DisplayChangeDialog(const DisplayChangeDialog&) = delete; DisplayChangeDialog& operator=(const DisplayChangeDialog&) = delete; - ui::ModalType GetModalType() const override; - // views::View: gfx::Size CalculatePreferredSize() const override;
diff --git a/ash/extended_desktop_unittest.cc b/ash/extended_desktop_unittest.cc index 35023dccb..ef34d3a 100644 --- a/ash/extended_desktop_unittest.cc +++ b/ash/extended_desktop_unittest.cc
@@ -47,18 +47,6 @@ std::move(layout)); } -class ModalWidgetDelegate : public views::WidgetDelegateView { - public: - ModalWidgetDelegate() = default; - ~ModalWidgetDelegate() override = default; - - // Overridden from views::WidgetDelegate: - ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_SYSTEM; } - - private: - DISALLOW_COPY_AND_ASSIGN(ModalWidgetDelegate); -}; - // An event handler which moves the target window to the secondary root window // at pre-handle phase of a mouse release event. class MoveWindowByClickEventHandler : public ui::EventHandler { @@ -234,8 +222,10 @@ EXPECT_EQ(root_windows[0], Shell::GetRootWindowForNewWindows()); // Open system modal. Make sure it's on 2nd root window and active. + auto delegate = std::make_unique<views::WidgetDelegateView>(); + delegate->SetModalType(ui::MODAL_TYPE_SYSTEM); views::Widget* modal_widget = views::Widget::CreateWindowWithContext( - new ModalWidgetDelegate(), GetContext(), gfx::Rect(1200, 100, 100, 100)); + delegate.release(), GetContext(), gfx::Rect(1200, 100, 100, 100)); modal_widget->Show(); EXPECT_TRUE(wm::IsActiveWindow(modal_widget->GetNativeView())); EXPECT_EQ(root_windows[1], modal_widget->GetNativeView()->GetRootWindow());
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc index f86e3ed1..6b62e88 100644 --- a/ash/login/ui/lock_contents_view.cc +++ b/ash/login/ui/lock_contents_view.cc
@@ -1979,7 +1979,8 @@ *bold_start += shortcut_offset_in_string; } - auto label = std::make_unique<views::StyledLabel>(error_text, this); + auto label = std::make_unique<views::StyledLabel>(this); + label->SetText(error_text); MakeSectionBold(label.get(), error_text, bold_start, bold_length); label->SetAutoColorReadabilityEnabled(false);
diff --git a/ash/login/ui/login_expanded_public_account_view.cc b/ash/login/ui/login_expanded_public_account_view.cc index 95c95668..8a191e0f 100644 --- a/ash/login/ui/login_expanded_public_account_view.cc +++ b/ash/login/ui/login_expanded_public_account_view.cc
@@ -320,7 +320,9 @@ size_t offset; const base::string16 text = l10n_util::GetStringFUTF16( IDS_ASH_LOGIN_PUBLIC_ACCOUNT_SIGNOUT_REMINDER, link, &offset); - learn_more_label_ = new views::StyledLabel(text, this); + learn_more_label_ = + labels_view_->AddChildView(std::make_unique<views::StyledLabel>(this)); + learn_more_label_->SetText(text); views::StyledLabel::RangeStyleInfo style; style.custom_font = learn_more_label_->GetFontList().Derive( @@ -335,8 +337,6 @@ link_style); learn_more_label_->SetAutoColorReadabilityEnabled(false); - labels_view_->AddChildView(learn_more_label_); - // Create button to show/hide advanced view. advanced_view_button_ = new SelectionButtonView( l10n_util::GetStringUTF16(
diff --git a/ash/login/ui/pin_request_view.cc b/ash/login/ui/pin_request_view.cc index 0ec91e3..fde7b78 100644 --- a/ash/login/ui/pin_request_view.cc +++ b/ash/login/ui/pin_request_view.cc
@@ -182,6 +182,12 @@ default_accessible_title_(request.accessible_title.empty() ? request.title : request.accessible_title) { + // MODAL_TYPE_SYSTEM is used to get a semi-transparent background behind the + // pin request view, when it is used directly on a widget. The overlay + // consumes all the inputs from the user, so that they can only interact with + // the pin request view while it is visible. + SetModalType(ui::MODAL_TYPE_SYSTEM); + // Main view contains all other views aligned vertically and centered. auto layout = std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical, @@ -407,14 +413,6 @@ return GetPinRequestViewSize(); } -ui::ModalType PinRequestView::GetModalType() const { - // MODAL_TYPE_SYSTEM is used to get a semi-transparent background behind the - // pin request view, when it is used directly on a widget. The overlay - // consumes all the inputs from the user, so that they can only interact with - // the pin request view while it is visible. - return ui::MODAL_TYPE_SYSTEM; -} - views::View* PinRequestView::GetInitiallyFocusedView() { return access_code_view_; }
diff --git a/ash/login/ui/pin_request_view.h b/ash/login/ui/pin_request_view.h index fd3fbc2..f2adefe 100644 --- a/ash/login/ui/pin_request_view.h +++ b/ash/login/ui/pin_request_view.h
@@ -130,7 +130,6 @@ void GetAccessibleNodeData(ui::AXNodeData* node_data) override; // views::DialogDelegateView: - ui::ModalType GetModalType() const override; views::View* GetInitiallyFocusedView() override; base::string16 GetAccessibleWindowTitle() const override;
diff --git a/ash/login/ui/public_account_warning_dialog.cc b/ash/login/ui/public_account_warning_dialog.cc index cd91cd0..34f5c4c 100644 --- a/ash/login/ui/public_account_warning_dialog.cc +++ b/ash/login/ui/public_account_warning_dialog.cc
@@ -62,6 +62,7 @@ PublicAccountWarningDialog::PublicAccountWarningDialog( base::WeakPtr<LoginExpandedPublicAccountView> controller) : controller_(controller) { + SetModalType(ui::MODAL_TYPE_SYSTEM); SetButtons(ui::DIALOG_BUTTON_NONE); SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical, gfx::Insets(), @@ -130,10 +131,6 @@ frame_view->SetTitleView(std::move(title_label)); } -ui::ModalType PublicAccountWarningDialog::GetModalType() const { - return ui::MODAL_TYPE_SYSTEM; -} - gfx::Size PublicAccountWarningDialog::CalculatePreferredSize() const { return gfx::Size(kDialogWidthDp, kDialogHeightDp); }
diff --git a/ash/login/ui/public_account_warning_dialog.h b/ash/login/ui/public_account_warning_dialog.h index c6721679..189d3461 100644 --- a/ash/login/ui/public_account_warning_dialog.h +++ b/ash/login/ui/public_account_warning_dialog.h
@@ -27,9 +27,6 @@ // views::DialogDelegate: void AddedToWidget() override; - // views::WidgetDelegate: - ui::ModalType GetModalType() const override; - // views::View: gfx::Size CalculatePreferredSize() const override;
diff --git a/ash/public/cpp/presentation_time_recorder.cc b/ash/public/cpp/presentation_time_recorder.cc index f59f13f..f55459c 100644 --- a/ash/public/cpp/presentation_time_recorder.cc +++ b/ash/public/cpp/presentation_time_recorder.cc
@@ -143,6 +143,7 @@ if (report_immediately_for_test) { state_ = COMMITTED; gfx::PresentationFeedback feedback; + feedback.timestamp = now; OnPresented(request_count_++, now, feedback); return true; } @@ -170,7 +171,20 @@ << ", flags=" << ToFlagString(feedback.flags); return; } + if (feedback.timestamp.is_null()) { + // TODO(b/165951963): ideally feedback.timestamp should not be null. + // Consider replacing this by DCHECK or CHECK. + LOG(ERROR) << "Invalid feedback timestamp (" << count << "):" + << " timestamp is not set"; + return; + } const base::TimeDelta delta = feedback.timestamp - requested_time; + if (delta.InMilliseconds() < 0) { + LOG(ERROR) << "Invalid timestamp for presentation feedback (" << count + << "): requested_time=" << requested_time + << " feedback.timestamp=" << feedback.timestamp; + return; + } if (delta.InMilliseconds() > max_latency_ms_) max_latency_ms_ = delta.InMilliseconds();
diff --git a/ash/root_window_controller_unittest.cc b/ash/root_window_controller_unittest.cc index 8953c2d0..39c59e4d 100644 --- a/ash/root_window_controller_unittest.cc +++ b/ash/root_window_controller_unittest.cc
@@ -51,22 +51,6 @@ namespace ash { namespace { -class TestDelegate : public views::WidgetDelegateView { - public: - explicit TestDelegate(bool system_modal) : system_modal_(system_modal) {} - ~TestDelegate() override = default; - - // Overridden from views::WidgetDelegate: - ui::ModalType GetModalType() const override { - return system_modal_ ? ui::MODAL_TYPE_SYSTEM : ui::MODAL_TYPE_NONE; - } - - private: - bool system_modal_; - - DISALLOW_COPY_AND_ASSIGN(TestDelegate); -}; - class DeleteOnBlurDelegate : public aura::test::TestWindowDelegate, public aura::client::FocusChangeObserver { public: @@ -115,9 +99,15 @@ return widget; } + views::WidgetDelegate* CreateModalWidgetDelegate() { + auto delegate = std::make_unique<views::WidgetDelegateView>(); + delegate->SetModalType(ui::MODAL_TYPE_SYSTEM); + return delegate.release(); + } + views::Widget* CreateModalWidget(const gfx::Rect& bounds) { views::Widget* widget = views::Widget::CreateWindowWithContext( - new TestDelegate(true), GetContext()); + CreateModalWidgetDelegate(), GetContext()); // See the above comment. widget->SetBounds(bounds); widget->Show(); @@ -126,8 +116,8 @@ views::Widget* CreateModalWidgetWithParent(const gfx::Rect& bounds, aura::Window* parent) { - views::Widget* widget = - views::Widget::CreateWindowWithParent(new TestDelegate(true), parent); + views::Widget* widget = views::Widget::CreateWindowWithParent( + CreateModalWidgetDelegate(), parent); // See the above comment. widget->SetBounds(bounds); widget->Show();
diff --git a/ash/session/multiprofiles_intro_dialog.cc b/ash/session/multiprofiles_intro_dialog.cc index 16479e9..7aede6eb 100644 --- a/ash/session/multiprofiles_intro_dialog.cc +++ b/ash/session/multiprofiles_intro_dialog.cc
@@ -37,10 +37,6 @@ widget->Show(); } -ui::ModalType MultiprofilesIntroDialog::GetModalType() const { - return ui::MODAL_TYPE_SYSTEM; -} - gfx::Size MultiprofilesIntroDialog::CalculatePreferredSize() const { return gfx::Size( kDefaultWidth, @@ -52,6 +48,7 @@ l10n_util::GetStringUTF16(IDS_ASH_DIALOG_DONT_SHOW_AGAIN))), on_accept_(std::move(on_accept)) { never_show_again_checkbox_->SetChecked(true); + SetModalType(ui::MODAL_TYPE_SYSTEM); SetTitle(l10n_util::GetStringUTF16(IDS_ASH_MULTIPROFILES_INTRO_HEADLINE)); SetShowCloseButton(false); SetAcceptCallback(base::BindOnce(
diff --git a/ash/session/multiprofiles_intro_dialog.h b/ash/session/multiprofiles_intro_dialog.h index 8a6f7a77..bb5af9fc 100644 --- a/ash/session/multiprofiles_intro_dialog.h +++ b/ash/session/multiprofiles_intro_dialog.h
@@ -23,9 +23,6 @@ static void Show(OnAcceptCallback on_accept); - // views::WidgetDelegate overrides. - ui::ModalType GetModalType() const override; - // views::View overrides. gfx::Size CalculatePreferredSize() const override;
diff --git a/ash/session/session_aborted_dialog.cc b/ash/session/session_aborted_dialog.cc index 405a6ef7..bff4fe2 100644 --- a/ash/session/session_aborted_dialog.cc +++ b/ash/session/session_aborted_dialog.cc
@@ -49,10 +49,6 @@ } } -ui::ModalType SessionAbortedDialog::GetModalType() const { - return ui::MODAL_TYPE_SYSTEM; -} - gfx::Size SessionAbortedDialog::CalculatePreferredSize() const { return gfx::Size( kDefaultWidth, @@ -60,6 +56,7 @@ } SessionAbortedDialog::SessionAbortedDialog() { + SetModalType(ui::MODAL_TYPE_SYSTEM); SetTitle( l10n_util::GetStringUTF16(IDS_ASH_MULTIPROFILES_SESSION_ABORT_HEADLINE)); SetShowCloseButton(false);
diff --git a/ash/session/session_aborted_dialog.h b/ash/session/session_aborted_dialog.h index be2173fb..db74931 100644 --- a/ash/session/session_aborted_dialog.h +++ b/ash/session/session_aborted_dialog.h
@@ -18,9 +18,6 @@ public: static void Show(const std::string& user_email); - // views::WidgetDelegate overrides. - ui::ModalType GetModalType() const override; - // views::View overrides. gfx::Size CalculatePreferredSize() const override;
diff --git a/ash/session/teleport_warning_dialog.cc b/ash/session/teleport_warning_dialog.cc index 48cec03..a9476e2 100644 --- a/ash/session/teleport_warning_dialog.cc +++ b/ash/session/teleport_warning_dialog.cc
@@ -31,6 +31,7 @@ on_accept_(std::move(callback)) { never_show_again_checkbox_->SetChecked(true); SetShowCloseButton(false); + SetModalType(ui::MODAL_TYPE_SYSTEM); SetTitle(l10n_util::GetStringUTF16(IDS_ASH_TELEPORT_WARNING_TITLE)); SetAcceptCallback(base::BindOnce( [](TeleportWarningDialog* dialog) { @@ -59,10 +60,6 @@ widget->Show(); } -ui::ModalType TeleportWarningDialog::GetModalType() const { - return ui::MODAL_TYPE_SYSTEM; -} - gfx::Size TeleportWarningDialog::CalculatePreferredSize() const { return gfx::Size( kDefaultWidth,
diff --git a/ash/session/teleport_warning_dialog.h b/ash/session/teleport_warning_dialog.h index 18b5459..f1c5cb7 100644 --- a/ash/session/teleport_warning_dialog.h +++ b/ash/session/teleport_warning_dialog.h
@@ -27,9 +27,6 @@ static void Show(OnAcceptCallback callback); - // views::WidgetDelegate overrides. - ui::ModalType GetModalType() const override; - // views::View overrides. gfx::Size CalculatePreferredSize() const override;
diff --git a/ash/shell_unittest.cc b/ash/shell_unittest.cc index 8d9671b5..7990c46 100644 --- a/ash/shell_unittest.cc +++ b/ash/shell_unittest.cc
@@ -130,32 +130,13 @@ EXPECT_FALSE(Shell::GetContainer(root_window, kShellWindowId_PhantomWindow)); } -class ModalWindow : public views::WidgetDelegateView { - public: - ModalWindow() { SetTitle(base::ASCIIToUTF16("Modal Window")); } - ~ModalWindow() override = default; - - // Overridden from views::WidgetDelegate: - bool CanResize() const override { return true; } - ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_SYSTEM; } - - private: - DISALLOW_COPY_AND_ASSIGN(ModalWindow); -}; - -class WindowWithPreferredSize : public views::WidgetDelegateView { - public: - WindowWithPreferredSize() = default; - ~WindowWithPreferredSize() override = default; - - // views::WidgetDelegate: - gfx::Size CalculatePreferredSize() const override { - return gfx::Size(400, 300); - } - - private: - DISALLOW_COPY_AND_ASSIGN(WindowWithPreferredSize); -}; +views::WidgetDelegateView* CreateModalWidgetDelegate() { + auto delegate = std::make_unique<views::WidgetDelegateView>(); + delegate->SetCanResize(true); + delegate->SetModalType(ui::MODAL_TYPE_SYSTEM); + delegate->SetTitle(base::ASCIIToUTF16("Modal Window")); + return delegate.release(); +} class SimpleMenuDelegate : public ui::SimpleMenuModel::Delegate { public: @@ -264,7 +245,11 @@ views::Widget::InitParams params; params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; // Don't specify bounds, parent or context. - params.delegate = new WindowWithPreferredSize; + { + auto delegate = std::make_unique<views::WidgetDelegateView>(); + delegate->SetPreferredSize(gfx::Size(400, 300)); + params.delegate = delegate.release(); + } views::Widget widget; params.context = GetContext(); widget.Init(std::move(params)); @@ -321,7 +306,7 @@ // Create a modal window. views::Widget* modal_widget = views::Widget::CreateWindowWithParent( - new ModalWindow(), widget->GetNativeView()); + CreateModalWidgetDelegate(), widget->GetNativeView()); modal_widget->Show(); // It should be in modal container. @@ -370,7 +355,7 @@ // Create a modal window with a lock window as parent. views::Widget* lock_modal_widget = views::Widget::CreateWindowWithParent( - new ModalWindow(), lock_widget->GetNativeView()); + CreateModalWidgetDelegate(), lock_widget->GetNativeView()); lock_modal_widget->Show(); EXPECT_TRUE(lock_modal_widget->GetNativeView()->HasFocus()); @@ -383,7 +368,7 @@ // Create a modal window with a normal window as parent. views::Widget* modal_widget = views::Widget::CreateWindowWithParent( - new ModalWindow(), widget->GetNativeView()); + CreateModalWidgetDelegate(), widget->GetNativeView()); modal_widget->Show(); // Window on lock screen shouldn't lost focus. EXPECT_FALSE(modal_widget->GetNativeView()->HasFocus());
diff --git a/ash/shortcut_viewer/views/keyboard_shortcut_item_view.cc b/ash/shortcut_viewer/views/keyboard_shortcut_item_view.cc index 758d81a7..8421d6f 100644 --- a/ash/shortcut_viewer/views/keyboard_shortcut_item_view.cc +++ b/ash/shortcut_viewer/views/keyboard_shortcut_item_view.cc
@@ -58,8 +58,10 @@ const KeyboardShortcutItem& item, ShortcutCategory category) : shortcut_item_(&item), category_(category) { - description_label_view_ = AddChildView(std::make_unique<views::StyledLabel>( - l10n_util::GetStringUTF16(item.description_message_id), nullptr)); + description_label_view_ = + AddChildView(std::make_unique<views::StyledLabel>()); + description_label_view_->SetText( + l10n_util::GetStringUTF16(item.description_message_id)); // StyledLabel will flip the alignment if UI layout is right-to-left. // Flip the alignment here in order to make |description_label_view_| always // align to left. @@ -111,8 +113,8 @@ accessible_string = l10n_util::GetStringFUTF16( item.shortcut_message_id, accessible_names, /*offsets=*/nullptr); } - shortcut_label_view_ = AddChildView( - std::make_unique<views::StyledLabel>(shortcut_string, nullptr)); + shortcut_label_view_ = AddChildView(std::make_unique<views::StyledLabel>()); + shortcut_label_view_->SetText(shortcut_string); // StyledLabel will flip the alignment if UI layout is right-to-left. // Flip the alignment here in order to make |shortcut_label_view_| always // align to right.
diff --git a/ash/system/accessibility/accessibility_feature_disable_dialog.cc b/ash/system/accessibility/accessibility_feature_disable_dialog.cc index 9a695f8b..7b9b58d8 100644 --- a/ash/system/accessibility/accessibility_feature_disable_dialog.cc +++ b/ash/system/accessibility/accessibility_feature_disable_dialog.cc
@@ -27,6 +27,7 @@ base::OnceClosure on_accept_callback, base::OnceClosure on_cancel_callback) : on_cancel_callback_(std::move(on_cancel_callback)) { + SetModalType(ui::MODAL_TYPE_SYSTEM); SetTitle(l10n_util::GetStringUTF16(window_title_text_id)); SetButtonLabel(ui::DIALOG_BUTTON_OK, l10n_util::GetStringUTF16(IDS_ASH_YES_BUTTON)); @@ -67,10 +68,6 @@ AccessibilityFeatureDisableDialog::~AccessibilityFeatureDisableDialog() = default; -ui::ModalType AccessibilityFeatureDisableDialog::GetModalType() const { - return ui::MODAL_TYPE_SYSTEM; -} - base::WeakPtr<AccessibilityFeatureDisableDialog> AccessibilityFeatureDisableDialog::GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr();
diff --git a/ash/system/accessibility/accessibility_feature_disable_dialog.h b/ash/system/accessibility/accessibility_feature_disable_dialog.h index bb630f8..442b4a5 100644 --- a/ash/system/accessibility/accessibility_feature_disable_dialog.h +++ b/ash/system/accessibility/accessibility_feature_disable_dialog.h
@@ -25,9 +25,6 @@ base::OnceClosure on_cancel_callback); ~AccessibilityFeatureDisableDialog() override; - // views::DialogDelegateView: - ui::ModalType GetModalType() const override; - base::WeakPtr<AccessibilityFeatureDisableDialog> GetWeakPtr(); // views::View:
diff --git a/ash/system/message_center/stacked_notification_bar.cc b/ash/system/message_center/stacked_notification_bar.cc index e92d217..68f0703 100644 --- a/ash/system/message_center/stacked_notification_bar.cc +++ b/ash/system/message_center/stacked_notification_bar.cc
@@ -284,6 +284,8 @@ expand_all_button_->SetVisible(false); AddChildView(expand_all_button_); + + SetPaintToLayer(); } StackedNotificationBar::~StackedNotificationBar() {
diff --git a/ash/system/session/logout_confirmation_dialog.cc b/ash/system/session/logout_confirmation_dialog.cc index c74dd894..e3d711b4 100644 --- a/ash/system/session/logout_confirmation_dialog.cc +++ b/ash/system/session/logout_confirmation_dialog.cc
@@ -37,6 +37,7 @@ LogoutConfirmationController* controller, base::TimeTicks logout_time) : controller_(controller), logout_time_(logout_time) { + SetModalType(ui::MODAL_TYPE_SYSTEM); SetTitle(l10n_util::GetStringUTF16(IDS_ASH_LOGOUT_CONFIRMATION_TITLE)); SetShowCloseButton(false); @@ -82,10 +83,6 @@ GetWidget()->Close(); } -ui::ModalType LogoutConfirmationDialog::GetModalType() const { - return ui::MODAL_TYPE_SYSTEM; -} - void LogoutConfirmationDialog::WindowClosing() { update_timer_.Stop(); if (controller_)
diff --git a/ash/system/session/logout_confirmation_dialog.h b/ash/system/session/logout_confirmation_dialog.h index d117ca1..ada175a 100644 --- a/ash/system/session/logout_confirmation_dialog.h +++ b/ash/system/session/logout_confirmation_dialog.h
@@ -33,7 +33,6 @@ void ControllerGone(); // views::WidgetDelegate: - ui::ModalType GetModalType() const override; void WindowClosing() override; // views::View:
diff --git a/ash/system/session/shutdown_confirmation_dialog.cc b/ash/system/session/shutdown_confirmation_dialog.cc index e1ec587..b76586c 100644 --- a/ash/system/session/shutdown_confirmation_dialog.cc +++ b/ash/system/session/shutdown_confirmation_dialog.cc
@@ -35,6 +35,7 @@ base::OnceClosure on_cancel_callback) { SetTitle(l10n_util::GetStringUTF16(window_title_text_id)); SetShowCloseButton(false); + SetModalType(ui::MODAL_TYPE_SYSTEM); SetButtonLabel( ui::DIALOG_BUTTON_OK, @@ -66,10 +67,6 @@ ShutdownConfirmationDialog::~ShutdownConfirmationDialog() = default; -ui::ModalType ShutdownConfirmationDialog::GetModalType() const { - return ui::MODAL_TYPE_SYSTEM; -} - gfx::Size ShutdownConfirmationDialog::CalculatePreferredSize() const { return gfx::Size( kDefaultWidth,
diff --git a/ash/system/session/shutdown_confirmation_dialog.h b/ash/system/session/shutdown_confirmation_dialog.h index 6d2aa1c..acda4b18 100644 --- a/ash/system/session/shutdown_confirmation_dialog.h +++ b/ash/system/session/shutdown_confirmation_dialog.h
@@ -26,9 +26,6 @@ base::OnceClosure on_cancel_callback); ~ShutdownConfirmationDialog() override; - // views::WidgetDelegate: - ui::ModalType GetModalType() const override; - // views::View: gfx::Size CalculatePreferredSize() const override;
diff --git a/ash/wm/drag_window_controller.cc b/ash/wm/drag_window_controller.cc index 7d5dc01..ce46aac 100644 --- a/ash/wm/drag_window_controller.cc +++ b/ash/wm/drag_window_controller.cc
@@ -96,10 +96,6 @@ window->parent(), &bounds); window->SetBounds(bounds); window->SetTransform(original_window->transform()); - window->layer()->SetClipRect(original_window->layer()->clip_rect()); - window->layer()->SetRoundedCornerRadius( - original_window->layer()->rounded_corner_radii()); - window->layer()->SetIsFastRoundedCorner(true); widget_->SetOpacity(opacity); }
diff --git a/ash/wm/mru_window_tracker_unittest.cc b/ash/wm/mru_window_tracker_unittest.cc index 1077ebe..4bed2d8 100644 --- a/ash/wm/mru_window_tracker_unittest.cc +++ b/ash/wm/mru_window_tracker_unittest.cc
@@ -81,19 +81,6 @@ } }; -namespace { - -class TestDelegate : public views::WidgetDelegateView { - public: - TestDelegate() = default; - ~TestDelegate() override = default; - - // views::WidgetDelegateView: - ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_SYSTEM; } -}; - -} // namespace - // Test basic functionalities of MruWindowTracker. TEST_P(MruWindowTrackerOrderTest, Basic) { std::unique_ptr<aura::Window> w1(CreateTestWindow()); @@ -142,8 +129,10 @@ EXPECT_EQ(w5.get(), window_list[3]); EXPECT_EQ(w6.get(), window_list[4]); + auto delegate = std::make_unique<views::WidgetDelegateView>(); + delegate->SetModalType(ui::MODAL_TYPE_SYSTEM); std::unique_ptr<views::Widget> modal = - CreateTestWidget(new TestDelegate(), kShellWindowId_Invalid); + CreateTestWidget(delegate.release(), kShellWindowId_Invalid); EXPECT_EQ(modal.get()->GetNativeView()->parent()->id(), kShellWindowId_SystemModalContainer);
diff --git a/ash/wm/system_modal_container_layout_manager_unittest.cc b/ash/wm/system_modal_container_layout_manager_unittest.cc index fb21b5f..9c9b7cc 100644 --- a/ash/wm/system_modal_container_layout_manager_unittest.cc +++ b/ash/wm/system_modal_container_layout_manager_unittest.cc
@@ -68,7 +68,10 @@ class TestWindow : public views::WidgetDelegateView { public: - explicit TestWindow(bool modal) : modal_(modal) {} + explicit TestWindow(bool modal) { + SetModalType(modal ? ui::MODAL_TYPE_SYSTEM : ui::MODAL_TYPE_NONE); + SetPreferredSize(gfx::Size(50, 50)); + } ~TestWindow() override = default; // The window needs be closed from widget in order for @@ -77,19 +80,7 @@ views::Widget::GetWidgetForNativeWindow(window)->Close(); } - // Overridden from views::View: - gfx::Size CalculatePreferredSize() const override { - return gfx::Size(50, 50); - } - - // Overridden from views::WidgetDelegate: - ui::ModalType GetModalType() const override { - return modal_ ? ui::MODAL_TYPE_SYSTEM : ui::MODAL_TYPE_NONE; - } - private: - bool modal_; - DISALLOW_COPY_AND_ASSIGN(TestWindow); };
diff --git a/ash/wm/test_child_modal_parent.cc b/ash/wm/test_child_modal_parent.cc index 13101c1..c364ac0 100644 --- a/ash/wm/test_child_modal_parent.cc +++ b/ash/wm/test_child_modal_parent.cc
@@ -43,34 +43,23 @@ const SkColor kModalParentColor = SK_ColorBLUE; const SkColor kChildColor = SK_ColorWHITE; +views::WidgetDelegateView* CreateChildModalWindow() { + auto child = std::make_unique<views::WidgetDelegateView>(); + child->SetModalType(ui::MODAL_TYPE_CHILD); + child->SetTitle(base::ASCIIToUTF16("Examples: Child Modal Window")); + child->SetBackground(views::CreateSolidBackground(kChildColor)); + child->SetPreferredSize(gfx::Size(kChildWindowWidth, kChildWindowHeight)); + + auto textfield = std::make_unique<views::Textfield>(); + textfield->SetBounds(kTextfieldLeft, kTextfieldTop, kTextfieldWidth, + kTextfieldHeight); + textfield->SetPlaceholderText(base::ASCIIToUTF16("modal child window")); + child->AddChildView(std::move(textfield)); + return child.release(); +} + } // namespace -class ChildModalWindow : public views::WidgetDelegateView { - public: - ChildModalWindow() { - SetTitle(base::ASCIIToUTF16("Examples: Child Modal Window")); - SetBackground(views::CreateSolidBackground(kChildColor)); - views::Textfield* modal_child_textfield = new views::Textfield; - AddChildView(modal_child_textfield); - modal_child_textfield->SetBounds(kTextfieldLeft, kTextfieldTop, - kTextfieldWidth, kTextfieldHeight); - modal_child_textfield->SetPlaceholderText( - base::ASCIIToUTF16("modal child window")); - } - ~ChildModalWindow() override = default; - - private: - // Overridden from View: - gfx::Size CalculatePreferredSize() const override { - return gfx::Size(kChildWindowWidth, kChildWindowHeight); - } - - // Overridden from WidgetDelegate: - ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_CHILD; } - - DISALLOW_COPY_AND_ASSIGN(ChildModalWindow); -}; - // static TestChildModalParent* TestChildModalParent::Show(aura::Window* context) { auto* test_child_modal_parent = new TestChildModalParent(context); @@ -119,7 +108,7 @@ aura::Window* TestChildModalParent::ShowModalChild() { DCHECK(!modal_child_); - modal_child_ = Widget::CreateWindowWithParent(new ChildModalWindow(), + modal_child_ = Widget::CreateWindowWithParent(CreateChildModalWindow(), GetWidget()->GetNativeView()); wm::SetModalParent(modal_child_->GetNativeView(), modal_parent_->GetNativeView());
diff --git a/base/BUILD.gn b/base/BUILD.gn index 19928b7..293a4a0 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -3483,7 +3483,6 @@ deps = [ ":jni_java", - "//third_party/android_deps:android_support_v4_java", "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_collection_collection_java", "//third_party/android_deps:androidx_core_core_java",
diff --git a/base/allocator/partition_allocator/page_allocator_internals_posix.h b/base/allocator/partition_allocator/page_allocator_internals_posix.h index d796bf5..d8a21bc 100644 --- a/base/allocator/partition_allocator/page_allocator_internals_posix.h +++ b/base/allocator/partition_allocator/page_allocator_internals_posix.h
@@ -24,7 +24,7 @@ #if defined(OS_ANDROID) #include <sys/prctl.h> #endif -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #include <sys/resource.h> #include <algorithm>
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc index 56c094c..a83950e 100644 --- a/base/allocator/partition_allocator/partition_alloc_unittest.cc +++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -330,7 +330,7 @@ } } -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) bool CheckPageInCore(void* ptr, bool in_core) { unsigned char ret = 0; EXPECT_EQ(0, mincore(ptr, kSystemPageSize, &ret)); @@ -341,7 +341,7 @@ EXPECT_TRUE(CheckPageInCore(ptr, in_core)) #else #define CHECK_PAGE_IN_CORE(ptr, in_core) (void)(0) -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) class MockPartitionStatsDumper : public PartitionStatsDumper { public:
diff --git a/build/android/gyp/lint.py b/build/android/gyp/lint.py index 78628c6..1b10be0 100755 --- a/build/android/gyp/lint.py +++ b/build/android/gyp/lint.py
@@ -25,6 +25,7 @@ # These checks are not useful for chromium. _DISABLED_ALWAYS = [ + "AppCompatResource", # Lint does not correctly detect our appcompat lib. "Assert", # R8 --force-enable-assertions is used to enable java asserts. "LintBaseline", # Don't warn about using baseline.xml files. "MissingApplicationIcon", # False positive for non-production targets.
diff --git a/build/android/gyp/proguard.py b/build/android/gyp/proguard.py index 3ba4f819..3199073 100755 --- a/build/android/gyp/proguard.py +++ b/build/android/gyp/proguard.py
@@ -253,6 +253,7 @@ cmd = build_utils.JavaCmd(options.warnings_as_errors) + [ '-Dcom.android.tools.r8.allowTestProguardOptions=1', + '-Dcom.android.tools.r8.enableVerticalClassMerging=1', ] if options.disable_outlining: cmd += ['-Dcom.android.tools.r8.disableOutlining=1']
diff --git a/build/config/linux/pangocairo/pangocairo.gni b/build/config/linux/pangocairo/pangocairo.gni index 0449105..395a1c0 100644 --- a/build/config/linux/pangocairo/pangocairo.gni +++ b/build/config/linux/pangocairo/pangocairo.gni
@@ -2,8 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//build/config/ui.gni") declare_args() { - use_pangocairo = is_linux && !is_chromeos && !is_chromecast + use_pangocairo = + is_linux && !is_chromeos && !is_chromecast && !chromeos_is_browser_only }
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 9fcd918..bff53f91 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20200825.0.1 +0.20200825.1.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 9fcd918..bff53f91 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20200825.0.1 +0.20200825.1.1
diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh index 6310137..b437309d 100755 --- a/build/install-build-deps.sh +++ b/build/install-build-deps.sh
@@ -225,6 +225,15 @@ # 64-bit systems need a minimum set of 32-bit compat packages for the pre-built # NaCl binaries. if file -L /sbin/init | grep -q 'ELF 64-bit'; then + dev_list="${dev_list} libc6-i386 lib32stdc++6" + + # lib32gcc-s1 used to be called lib32gcc1 in older distros. + if package_exists lib32gcc-s1; then + dev_list="${dev_list} lib32gcc-s1" + elif package_exists lib32gcc1; then + dev_list="${dev_list} lib32gcc1" + fi + dev_list="${dev_list} libc6-i386 lib32gcc-s1 lib32stdc++6" fi
diff --git a/cc/mojo_embedder/async_layer_tree_frame_sink.cc b/cc/mojo_embedder/async_layer_tree_frame_sink.cc index b37945a..bc859573 100644 --- a/cc/mojo_embedder/async_layer_tree_frame_sink.cc +++ b/cc/mojo_embedder/async_layer_tree_frame_sink.cc
@@ -356,8 +356,9 @@ void AsyncLayerTreeFrameSink::OnMojoConnectionError( uint32_t custom_reason, const std::string& description) { + // TODO(sgilhuly): Use DLOG(FATAL) once crbug.com/1043899 is resolved. if (custom_reason) - DLOG(FATAL) << description; + DLOG(ERROR) << description; if (client_) client_->DidLoseLayerTreeFrameSink(); }
diff --git a/chrome/android/expectations/lint-baseline.xml b/chrome/android/expectations/lint-baseline.xml index 8d93a63..421c798 100644 --- a/chrome/android/expectations/lint-baseline.xml +++ b/chrome/android/expectations/lint-baseline.xml
@@ -255,380 +255,6 @@ </issue> <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/bookmark_action_bar_menu.xml" - line="15" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/bookmark_action_bar_menu.xml" - line="22" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/bookmark_action_bar_menu.xml" - line="28" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/bookmark_action_bar_menu.xml" - line="38" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/bookmark_action_bar_menu.xml" - line="44" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/bookmark_action_bar_menu.xml" - line="50" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="never" />" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/bookmark_action_bar_menu.xml" - line="55" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="never" />" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/bookmark_action_bar_menu.xml" - line="59" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/browser/download/android/java/res/menu/download_manager_menu.xml" - line="16" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/browser/download/android/java/res/menu/download_manager_menu.xml" - line="23" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/browser/download/android/java/res/menu/download_manager_menu.xml" - line="29" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/browser/download/android/java/res/menu/download_manager_menu.xml" - line="39" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/browser/download/android/java/res/menu/download_manager_menu.xml" - line="45" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom" />" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/history_manager_menu.xml" - line="16" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/history_manager_menu.xml" - line="22" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/history_manager_menu.xml" - line="28" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/history_manager_menu.xml" - line="38" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="never" />" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/history_manager_menu.xml" - line="43" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="never" />" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/history_manager_menu.xml" - line="47" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="never" />" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/history_manager_menu.xml" - line="51" - column="13"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="always"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/languages_action_bar_menu.xml" - line="12" - column="9"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:actionViewClass` when not using the appcompat library" - errorLine1=" app:actionViewClass="androidx.appcompat.widget.SearchView"/>" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/languages_action_bar_menu.xml" - line="13" - column="9"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="always"/>" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/browser/password_check/android/java/res/menu/password_check_editor_action_bar_menu.xml" - line="12" - column="9"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="always"/>" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/password_entry_editor_action_bar_menu.xml" - line="12" - column="9"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"/>" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/password_entry_viewer_action_bar_menu.xml" - line="15" - column="9"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"/>" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/password_entry_viewer_action_bar_menu.xml" - line="23" - column="9"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/prefeditor_editor_menu.xml" - line="13" - column="9"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom" />" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/prefeditor_editor_menu.xml" - line="20" - column="9"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="always"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/save_password_preferences_action_bar_menu.xml" - line="13" - column="9"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:actionViewClass` when not using the appcompat library" - errorLine1=" app:actionViewClass="androidx.appcompat.widget.SearchView" />" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/save_password_preferences_action_bar_menu.xml" - line="14" - column="9"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="ifRoom"/>" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/save_password_preferences_action_bar_menu.xml" - line="20" - column="9"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="never"/>" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/res/menu/save_password_preferences_action_bar_menu.xml" - line="26" - column="9"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:showAsAction` when not using the appcompat library" - errorLine1=" app:showAsAction="always"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../components/browser_ui/site_settings/android/java/res/menu/website_preferences_menu.xml" - line="10" - column="11"/> - </issue> - - <issue - id="AppCompatResource" - message="Should use `android:actionViewClass` when not using the appcompat library" - errorLine1=" app:actionViewClass="androidx.appcompat.widget.SearchView" />" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../components/browser_ui/site_settings/android/java/res/menu/website_preferences_menu.xml" - line="11" - column="11"/> - </issue> - - <issue id="VisibleForTests" message="This method should only be accessed from tests or within private scope" errorLine1=" if (AccountUtils.GOOGLE_ACCOUNT_TYPE.equals(desc.type)) return true;"
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantClient.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantClient.java index ca92f80..d41e826a 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantClient.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantClient.java
@@ -191,7 +191,7 @@ * * @param actionId id of the action * @param experimentIds comma-separated set of experiments to use while running the flow - * @param arguments report these as autobot parameters while performing this specific action + * @param arguments report these as script parameters while performing this specific action * @param onboardingCoordinator if non-null, reuse existing UI elements, usually created to show * onboarding. * @return true if the action was found started, false otherwise. The action can still fail
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java index 120ff7c..17019095 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java
@@ -4,7 +4,7 @@ package org.chromium.chrome.browser.customtabs; -import static org.chromium.components.content_settings.PrefNames.BLOCK_THIRD_PARTY_COOKIES; +import static org.chromium.components.content_settings.PrefNames.COOKIE_CONTROLS_MODE; import android.content.ComponentName; import android.content.Context; @@ -40,6 +40,7 @@ import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; +import org.chromium.components.content_settings.CookieControlsMode; import org.chromium.components.embedder_support.util.Origin; import org.chromium.components.prefs.PrefService; import org.chromium.components.safe_browsing.SafeBrowsingApiBridge; @@ -371,8 +372,9 @@ mServer = EmbeddedTestServer.createAndStartHTTPSServer(mContext, ServerCertificate.CERT_OK); TestThreadUtils.runOnUiThreadBlocking(() -> { PrefService prefs = UserPrefs.get(Profile.getLastUsedRegularProfile()); - Assert.assertFalse(prefs.getBoolean(BLOCK_THIRD_PARTY_COOKIES)); - prefs.setBoolean(BLOCK_THIRD_PARTY_COOKIES, true); + Assert.assertEquals( + prefs.getInteger(COOKIE_CONTROLS_MODE), CookieControlsMode.INCOGNITO_ONLY); + prefs.setInteger(COOKIE_CONTROLS_MODE, CookieControlsMode.BLOCK_THIRD_PARTY); }); final Uri url = Uri.parse(mServer.getURL("/set-cookie?acookie;SameSite=none;Secure")); TestThreadUtils.runOnUiThreadBlocking(() -> { @@ -405,7 +407,8 @@ // This isn't blocking third-party cookies by preferences. TestThreadUtils.runOnUiThreadBlocking(() -> { PrefService prefs = UserPrefs.get(Profile.getLastUsedRegularProfile()); - Assert.assertFalse(prefs.getBoolean(BLOCK_THIRD_PARTY_COOKIES)); + Assert.assertEquals( + prefs.getInteger(COOKIE_CONTROLS_MODE), CookieControlsMode.INCOGNITO_ONLY); }); // Of the three cookies, only one that's both SameSite=None and Secure @@ -435,8 +438,9 @@ mServer = EmbeddedTestServer.createAndStartServer(mContext); TestThreadUtils.runOnUiThreadBlocking(() -> { PrefService prefs = UserPrefs.get(Profile.getLastUsedRegularProfile()); - Assert.assertFalse(prefs.getBoolean(BLOCK_THIRD_PARTY_COOKIES)); - prefs.setBoolean(BLOCK_THIRD_PARTY_COOKIES, true); + Assert.assertEquals( + prefs.getInteger(COOKIE_CONTROLS_MODE), CookieControlsMode.INCOGNITO_ONLY); + prefs.setInteger(COOKIE_CONTROLS_MODE, CookieControlsMode.BLOCK_THIRD_PARTY); }); final Uri url = Uri.parse(mServer.getURL("/set-cookie?acookie")); final Uri origin = Uri.parse(Origin.create(url).toString());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/ReaderModeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/ReaderModeTest.java index bb7c26b..cd29d51 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/ReaderModeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/ReaderModeTest.java
@@ -26,6 +26,7 @@ import static org.chromium.chrome.browser.dom_distiller.ReaderModeManager.DOM_DISTILLER_SCHEME; import android.app.Activity; +import android.os.Build.VERSION_CODES; import android.support.test.InstrumentationRegistry; import androidx.annotation.NonNull; @@ -46,6 +47,7 @@ import org.chromium.base.ApplicationStatus; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeTabbedActivity; @@ -256,6 +258,8 @@ @Test @MediumTest @DisableFeatures(ChromeFeatureList.READER_MODE_IN_CCT) + @DisableIf.Build(sdk_is_less_than = VERSION_CODES.M, + message = "Failing on Lollipop Phone Tester. https://crbug.com/1120830") public void testPreferenceInTab() throws TimeoutException { mDownloadTestRule.loadUrl( DomDistillerUrlUtils.getDistillerViewUrlFromUrl(DOM_DISTILLER_SCHEME, mURL, TITLE));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewRenderTest.java index 958b16f..cce7b63 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewRenderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewRenderTest.java
@@ -110,7 +110,7 @@ public void testRender_TitleAndTitleIcon() throws IOException { setUpViews(R.style.Theme_Chromium_ModalDialog_TextPrimaryButton); final Drawable icon = UiUtils.getTintedDrawable( - getActivity(), R.drawable.ic_add, R.color.default_icon_color); + getActivity(), org.chromium.chrome.R.drawable.ic_add, R.color.default_icon_color); createModel(mModelBuilder.with(ModalDialogProperties.TITLE, mResources, R.string.title) .with(ModalDialogProperties.TITLE_ICON, icon)); mRenderTestRule.render(mModalDialogView, "title_and_title_icon");
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java index a9e850d6..c9b4524 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java
@@ -10,7 +10,7 @@ import static org.junit.Assert.assertNotNull; -import static org.chromium.components.content_settings.PrefNames.BLOCK_THIRD_PARTY_COOKIES; +import static org.chromium.components.content_settings.PrefNames.COOKIE_CONTROLS_MODE; import android.os.Build; import android.view.View; @@ -37,6 +37,7 @@ import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge; import org.chromium.components.content_settings.ContentSettingValues; import org.chromium.components.content_settings.ContentSettingsType; +import org.chromium.components.content_settings.CookieControlsMode; import org.chromium.components.location.LocationUtils; import org.chromium.components.page_info.PageInfoController; import org.chromium.components.page_info.PageInfoFeatureList; @@ -97,10 +98,10 @@ return view; } - private void setThirdPartyCookieBlocking(boolean value) { + private void setThirdPartyCookieBlocking(@CookieControlsMode int value) { TestThreadUtils.runOnUiThreadBlocking(() -> { UserPrefs.get(Profile.getLastUsedRegularProfile()) - .setBoolean(BLOCK_THIRD_PARTY_COOKIES, value); + .setInteger(COOKIE_CONTROLS_MODE, value); }); } @@ -214,7 +215,7 @@ @MediumTest @Feature({"RenderTest"}) public void testShowWithCookieBlocking() throws IOException { - setThirdPartyCookieBlocking(true); + setThirdPartyCookieBlocking(CookieControlsMode.BLOCK_THIRD_PARTY); loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath)); mRenderTestRule.render(getPageInfoView(), "PageInfo_CookieBlocking"); } @@ -227,7 +228,7 @@ @Feature({"RenderTest"}) public void testShowWithPermissionsAndCookieBlocking() throws IOException { addSomePermissions(mTestServerRule.getServer().getURL("/")); - setThirdPartyCookieBlocking(true); + setThirdPartyCookieBlocking(CookieControlsMode.BLOCK_THIRD_PARTY); loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath)); mRenderTestRule.render(getPageInfoView(), "PageInfo_PermissionsAndCookieBlocking"); } @@ -292,7 +293,7 @@ @Feature({"RenderTest"}) @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2) public void testShowCookiesSubpage() throws IOException { - setThirdPartyCookieBlocking(true); + setThirdPartyCookieBlocking(CookieControlsMode.BLOCK_THIRD_PARTY); loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath)); View dialog = (View) getPageInfoView().getParent(); onView(withId(R.id.page_info_cookies_row)).perform(click());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java index 55bfd6a..795cc977 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
@@ -5,7 +5,7 @@ package org.chromium.chrome.browser.site_settings; import static org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge.SITE_WILDCARD; -import static org.chromium.components.content_settings.PrefNames.BLOCK_THIRD_PARTY_COOKIES; +import static org.chromium.components.content_settings.PrefNames.COOKIE_CONTROLS_MODE; import android.content.Context; import android.content.Intent; @@ -252,7 +252,7 @@ Assert.assertEquals( "Third Party Cookie Blocking should be " + (expected ? "managed" : "unmanaged"), UserPrefs.get(Profile.getLastUsedRegularProfile()) - .isManagedPreference(BLOCK_THIRD_PARTY_COOKIES), + .isManagedPreference(COOKIE_CONTROLS_MODE), expected); }); }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index d585800..3963363 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -5652,6 +5652,20 @@ </message> </if> + <!-- Star View menu --> + <message name="IDS_STAR_VIEW_MENU_ADD_BOOKMARK" desc="The item label of the menu triggered from the star icon in the location bar for adding a bookmark."> + Add Bookmark + </message> + <message name="IDS_STAR_VIEW_MENU_EDIT_BOOKMARK" desc="The item label of the menu triggered from the star icon in the location bar for editing a bookmark."> + Edit Bookmark + </message> + <message name="IDS_STAR_VIEW_MENU_MOVE_TO_READ_LATER" desc="The item label of the menu triggered from the star icon in the location bar for moving the current tab to read later."> + Add to Read later + </message> + <message name="IDS_STAR_VIEW_MENU_MARK_AS_READ" desc="The item label of the menu triggered from the star icon in the location bar for marking the current tab's read later entry as read."> + Mark as Read + </message> + <!--Tooltip strings--> <message name="IDS_TOOLTIP_BACK" desc="The tooltip for back button"> Click to go back, hold to see history
diff --git a/chrome/app/generated_resources_grd/IDS_STAR_VIEW_MENU_ADD_BOOKMARK.png.sha1 b/chrome/app/generated_resources_grd/IDS_STAR_VIEW_MENU_ADD_BOOKMARK.png.sha1 new file mode 100644 index 0000000..7d33700f --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_STAR_VIEW_MENU_ADD_BOOKMARK.png.sha1
@@ -0,0 +1 @@ +cd19bd38c1c505428e1b952dff29ea2dcc23a749 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_STAR_VIEW_MENU_EDIT_BOOKMARK.png.sha1 b/chrome/app/generated_resources_grd/IDS_STAR_VIEW_MENU_EDIT_BOOKMARK.png.sha1 new file mode 100644 index 0000000..5140577 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_STAR_VIEW_MENU_EDIT_BOOKMARK.png.sha1
@@ -0,0 +1 @@ +ca95daa02a7ba6b6dcc742fa2359f58058ac8025 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_STAR_VIEW_MENU_MARK_AS_READ.png.sha1 b/chrome/app/generated_resources_grd/IDS_STAR_VIEW_MENU_MARK_AS_READ.png.sha1 new file mode 100644 index 0000000..5140577 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_STAR_VIEW_MENU_MARK_AS_READ.png.sha1
@@ -0,0 +1 @@ +ca95daa02a7ba6b6dcc742fa2359f58058ac8025 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_STAR_VIEW_MENU_MOVE_TO_READ_LATER.png.sha1 b/chrome/app/generated_resources_grd/IDS_STAR_VIEW_MENU_MOVE_TO_READ_LATER.png.sha1 new file mode 100644 index 0000000..7d33700f --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_STAR_VIEW_MENU_MOVE_TO_READ_LATER.png.sha1
@@ -0,0 +1 @@ +cd19bd38c1c505428e1b952dff29ea2dcc23a749 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 8f4fdf5..b0b97aef 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -2197,6 +2197,21 @@ <message name="IDS_SETTINGS_MULTIDEVICE_PHONE_HUB_TASK_CONTINUATION_SECTION_TITLE" translateable="false" desc="The title of the Phone Hub Task Continuation section on the settings page."> Task Continuation </message> + <message name="IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_ACK_TITLE" translateable="false" desc="The title of the dialog containing the Phone Hub notification opt-in flow shown when the Phone Hub 'Notifications' toggle is switched on."> + Turn on notifications on Android phone + </message> + <message name="IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_CONNECTING_TITLE" translateable="false" desc="The title of the dialog containing the Phone Hub notification opt-in flow shown when the user has confirmed to enable the feature that will mirror phone notifications to their Chromebook."> + Connecting to your Phone + </message> + <message name="IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_INSTRUCTIONS" translateable="false" desc="The body text of the dialog containing the Phone Hub notification opt-in flow when the Phone Hub 'Notifications' toggle is switched on, and when the user has confirmed to turn on the feature."> + Make sure your phone is nearby, unlocked and has Bluetooth and Wi-Fi turned on. Turn on notifications toggle under Google Play Services>Chromebook Phone Hub from your phone. + </message> + <message name="IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_COMPLETED_TITLE" translateable="false" desc="The title of the dialog containing the Phone Hub notification opt-in flow when the feature is successfully turned on and notifications on their phone will now be mirrored to their Chromebook."> + Notifications turned on + </message> + <message name="IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_COMPLETED_SUMMARY" translateable="false" desc="The body text of the dialog containing the Phone Hub notification opt-in flow when the feature is successfully turned on and notifications on their phone will now be mirrored to their Chromebook."> + You will receive your phone notifications on your Chromebook + </message> <!-- Lock Screen Page (OS settings) --> <message name="IDS_ASH_SETTINGS_LOCK_SCREEN_NOTIFICATION_TITLE" desc="The title of options to change the behavior of notifications on the lock screen.">
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 2c2d794..8b278d6 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -776,14 +776,14 @@ "metrics/chrome_browser_main_extra_parts_metrics.h", "metrics/chrome_feature_list_creator.cc", "metrics/chrome_feature_list_creator.h", + "metrics/chrome_metrics_extensions_helper.cc", + "metrics/chrome_metrics_extensions_helper.h", "metrics/chrome_metrics_service_accessor.cc", "metrics/chrome_metrics_service_accessor.h", "metrics/chrome_metrics_service_client.cc", "metrics/chrome_metrics_service_client.h", "metrics/chrome_metrics_services_manager_client.cc", "metrics/chrome_metrics_services_manager_client.h", - "metrics/chrome_stability_metrics_provider.cc", - "metrics/chrome_stability_metrics_provider.h", "metrics/https_engagement_metrics_provider.cc", "metrics/https_engagement_metrics_provider.h", "metrics/incognito_observer.cc", @@ -1415,6 +1415,8 @@ "push_messaging/push_messaging_service_factory.h", "push_messaging/push_messaging_service_impl.cc", "push_messaging/push_messaging_service_impl.h", + "push_messaging/push_messaging_utils.cc", + "push_messaging/push_messaging_utils.h", "query_tiles/tile_background_task.cc", "query_tiles/tile_background_task.h", "query_tiles/tile_service_factory.cc",
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc index 91edd4c..f9f4832 100644 --- a/chrome/browser/chrome_browser_interface_binders.cc +++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -126,6 +126,7 @@ #include "chrome/browser/ui/webui/tab_search/tab_search_ui.h" #include "chrome/common/caption.mojom.h" #include "chrome/common/webui_url_constants.h" +#include "media/base/media_switches.h" #include "media/mojo/mojom/speech_recognition_service.mojom.h" #endif @@ -372,7 +373,8 @@ Profile* profile = Profile::FromBrowserContext( frame_host->GetProcess()->GetBrowserContext()); PrefService* profile_prefs = profile->GetPrefs(); - if (profile_prefs->GetBoolean(prefs::kLiveCaptionEnabled)) { + if (profile_prefs->GetBoolean(prefs::kLiveCaptionEnabled) && + base::FeatureList::IsEnabled(media::kLiveCaption)) { SpeechRecognitionServiceFactory::GetForProfile(profile)->Create( std::move(receiver)); } @@ -384,7 +386,8 @@ Profile* profile = Profile::FromBrowserContext( frame_host->GetProcess()->GetBrowserContext()); PrefService* profile_prefs = profile->GetPrefs(); - if (profile_prefs->GetBoolean(prefs::kLiveCaptionEnabled)) { + if (profile_prefs->GetBoolean(prefs::kLiveCaptionEnabled) && + base::FeatureList::IsEnabled(media::kLiveCaption)) { captions::CaptionHostImpl::Create(frame_host, std::move(receiver)); } }
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 814294f..c481dd9 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -353,6 +353,7 @@ #include "storage/browser/file_system/external_mount_points.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "third_party/blink/public/common/loader/url_loader_throttle.h" #include "third_party/blink/public/common/switches.h" #include "third_party/blink/public/mojom/renderer_preferences.mojom.h" @@ -2168,7 +2169,7 @@ kDinosaurEasterEggSwitches, base::size(kDinosaurEasterEggSwitches)); - if (content::Referrer::ShouldForceLegacyDefaultReferrerPolicy()) + if (blink::ReferrerUtils::ShouldForceLegacyDefaultReferrerPolicy()) command_line->AppendSwitch( blink::switches::kForceLegacyDefaultReferrerPolicy);
diff --git a/chrome/browser/chrome_service_worker_browsertest.cc b/chrome/browser/chrome_service_worker_browsertest.cc index 2399b571..0bc4890d 100644 --- a/chrome/browser/chrome_service_worker_browsertest.cc +++ b/chrome/browser/chrome_service_worker_browsertest.cc
@@ -28,6 +28,7 @@ #include "chrome/test/base/test_chrome_web_ui_controller_factory.h" #include "chrome/test/base/ui_test_utils.h" #include "components/content_settings/browser/page_specific_content_settings.h" +#include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/pref_names.h" #include "components/favicon/content/content_favicon_driver.h" @@ -875,8 +876,9 @@ IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerNavigationPreloadTest, TopFrameWithThirdPartyBlocking) { // Enable third-party cookie blocking. - browser()->profile()->GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, - true); + browser()->profile()->GetPrefs()->SetInteger( + prefs::kCookieControlsMode, + static_cast<int>(content_settings::CookieControlsMode::kBlockThirdParty)); // Load a page that registers a service worker. ui_test_utils::NavigateToURL( @@ -908,8 +910,9 @@ IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerNavigationPreloadTest, SubFrameWithThirdPartyBlocking) { // Enable third-party cookie blocking. - browser()->profile()->GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, - true); + browser()->profile()->GetPrefs()->SetInteger( + prefs::kCookieControlsMode, + static_cast<int>(content_settings::CookieControlsMode::kBlockThirdParty)); // Load a page that registers a service worker. ui_test_utils::NavigateToURL(
diff --git a/chrome/browser/chrome_worker_browsertest.cc b/chrome/browser/chrome_worker_browsertest.cc index b00e12ce..3123805 100644 --- a/chrome/browser/chrome_worker_browsertest.cc +++ b/chrome/browser/chrome_worker_browsertest.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/common/pref_names.h" #include "components/prefs/pref_service.h" #include "content/public/browser/browser_context.h" @@ -20,8 +21,6 @@ #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" -enum class EnableThirdPartyCookieBlocking { kEnable, kDisable }; - // A simple fixture used for testing dedicated workers and shared workers. The // fixture stashes the HTTP request to the worker script for inspecting the // headers. @@ -47,15 +46,13 @@ // third-party cookie blocking configuration. // This is the regression test for https://crbug.com/933287. void TestWorkerScriptFetchWithThirdPartyCookieBlocking( - EnableThirdPartyCookieBlocking enable_third_party_cookie_blocking, + content_settings::CookieControlsMode cookie_controls_mode, const std::string& test_url) { const std::string kCookie = "foo=bar"; // Set up third-party cookie blocking. - browser()->profile()->GetPrefs()->SetBoolean( - prefs::kBlockThirdPartyCookies, - enable_third_party_cookie_blocking == - EnableThirdPartyCookieBlocking::kEnable); + browser()->profile()->GetPrefs()->SetInteger( + prefs::kCookieControlsMode, static_cast<int>(cookie_controls_mode)); // Make sure cookies are not set. ASSERT_TRUE( @@ -112,27 +109,27 @@ IN_PROC_BROWSER_TEST_F(ChromeWorkerBrowserTest, DedicatedWorkerScriptFetchWithThirdPartyBlocking) { TestWorkerScriptFetchWithThirdPartyCookieBlocking( - EnableThirdPartyCookieBlocking::kEnable, + content_settings::CookieControlsMode::kBlockThirdParty, "/workers/create_dedicated_worker.html?worker_url=/capture"); } IN_PROC_BROWSER_TEST_F(ChromeWorkerBrowserTest, DedicatedWorkerScriptFetchWithoutThirdPartyBlocking) { TestWorkerScriptFetchWithThirdPartyCookieBlocking( - EnableThirdPartyCookieBlocking::kDisable, + content_settings::CookieControlsMode::kOff, "/workers/create_dedicated_worker.html?worker_url=/capture"); } IN_PROC_BROWSER_TEST_F(ChromeWorkerBrowserTest, SharedWorkerScriptFetchWithThirdPartyBlocking) { TestWorkerScriptFetchWithThirdPartyCookieBlocking( - EnableThirdPartyCookieBlocking::kEnable, + content_settings::CookieControlsMode::kBlockThirdParty, "/workers/create_shared_worker.html?worker_url=/capture"); } IN_PROC_BROWSER_TEST_F(ChromeWorkerBrowserTest, SharedWorkerScriptFetchWithoutThirdPartyBlocking) { TestWorkerScriptFetchWithThirdPartyCookieBlocking( - EnableThirdPartyCookieBlocking::kDisable, + content_settings::CookieControlsMode::kOff, "/workers/create_shared_worker.html?worker_url=/capture"); }
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index a245944..bac93a6 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -122,6 +122,7 @@ "//chromeos/components/quick_answers/public/cpp:prefs", "//chromeos/components/remote_apps/mojom", "//chromeos/components/scanning", + "//chromeos/components/scanning/mojom", "//chromeos/components/smbfs", "//chromeos/components/smbfs/mojom", "//chromeos/components/string_matching", @@ -1103,6 +1104,7 @@ "extensions/extensions_permissions_tracker.h", "extensions/external_cache.cc", "extensions/external_cache.h", + "extensions/external_cache_delegate.cc", "extensions/external_cache_delegate.h", "extensions/external_cache_impl.cc", "extensions/external_cache_impl.h", @@ -2439,6 +2441,10 @@ "scanning/lorgnette_scanner_manager_factory.h", "scanning/lorgnette_scanner_manager_util.cc", "scanning/lorgnette_scanner_manager_util.h", + "scanning/scan_service.cc", + "scanning/scan_service.h", + "scanning/scan_service_factory.cc", + "scanning/scan_service_factory.h", "scanning/scanner_detector.h", "scanning/zeroconf_scanner_detector.cc", "scanning/zeroconf_scanner_detector.h", @@ -3497,6 +3503,7 @@ "scanning/fake_lorgnette_scanner_manager.h", "scanning/lorgnette_scanner_manager_unittest.cc", "scanning/lorgnette_scanner_manager_util_unittest.cc", + "scanning/scan_service_unittest.cc", "scanning/zeroconf_scanner_detector_unittest.cc", "scheduler_configuration_manager_unittest.cc", "session_length_limiter_unittest.cc",
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc index b9a4af6..b86055b3 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
@@ -809,11 +809,8 @@ external_cache_->UpdateExtensionsList(std::move(prefs)); } -void KioskAppManager::OnExtensionListsUpdated( - const base::DictionaryValue* prefs) { -} - -void KioskAppManager::OnExtensionLoadedInCache(const std::string& id) { +void KioskAppManager::OnExtensionLoadedInCache( + const extensions::ExtensionId& id) { KioskAppData* app_data = GetAppDataMutable(id); if (!app_data) return; @@ -827,7 +824,8 @@ observer.OnKioskExtensionLoadedInCache(id); } -void KioskAppManager::OnExtensionDownloadFailed(const std::string& id) { +void KioskAppManager::OnExtensionDownloadFailed( + const extensions::ExtensionId& id) { KioskAppData* app_data = GetAppDataMutable(id); if (!app_data) return; @@ -835,11 +833,6 @@ observer.OnKioskExtensionDownloadFailed(id); } -std::string KioskAppManager::GetInstalledExtensionVersion( - const std::string& id) { - return std::string(); -} - KioskAppManager::AutoLoginState KioskAppManager::GetAutoLoginState() const { PrefService* prefs = g_browser_process->local_state(); const base::DictionaryValue* dict =
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h index 3e89ba8b..fc181dd 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h +++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
@@ -21,6 +21,7 @@ #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chromeos/tpm/install_attributes.h" #include "components/account_id/account_id.h" +#include "extensions/common/extension_id.h" class GURL; class PrefRegistrySimple; @@ -278,10 +279,8 @@ void UpdateExternalCachePrefs(); // ExternalCacheDelegate: - void OnExtensionListsUpdated(const base::DictionaryValue* prefs) override; - void OnExtensionLoadedInCache(const std::string& id) override; - void OnExtensionDownloadFailed(const std::string& id) override; - std::string GetInstalledExtensionVersion(const std::string& id) override; + void OnExtensionLoadedInCache(const extensions::ExtensionId& id) override; + void OnExtensionDownloadFailed(const extensions::ExtensionId& id) override; // Callback for InstallAttributes::LockDevice() during // EnableConsumerModeKiosk() call.
diff --git a/chrome/browser/chromeos/arc/intent_helper/open_with_menu.cc b/chrome/browser/chromeos/arc/intent_helper/open_with_menu.cc index 36fc749..0375bd3 100644 --- a/chrome/browser/chromeos/arc/intent_helper/open_with_menu.cc +++ b/chrome/browser/chromeos/arc/intent_helper/open_with_menu.cc
@@ -13,6 +13,7 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/context_menu_params.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/models/image_model.h" namespace arc { @@ -101,7 +102,8 @@ IDS_CONTENT_CONTEXT_OPEN_WITH_APP, it->second.name); proxy_->UpdateMenuItem(command_id, true, false, label); if (!it->second.icon.IsEmpty()) - proxy_->UpdateMenuIcon(command_id, it->second.icon); + proxy_->UpdateMenuIcon(command_id, + ui::ImageModel::FromImage(it->second.icon)); } } }
diff --git a/chrome/browser/chromeos/arc/intent_helper/start_smart_selection_action_menu.cc b/chrome/browser/chromeos/arc/intent_helper/start_smart_selection_action_menu.cc index df24ce1..cf2282c 100644 --- a/chrome/browser/chromeos/arc/intent_helper/start_smart_selection_action_menu.cc +++ b/chrome/browser/chromeos/arc/intent_helper/start_smart_selection_action_menu.cc
@@ -25,6 +25,7 @@ #include "components/arc/session/arc_bridge_service.h" #include "components/renderer_context_menu/render_view_context_menu_proxy.h" #include "content/public/browser/context_menu_params.h" +#include "ui/base/models/image_model.h" #include "ui/gfx/image/image_skia_operations.h" namespace arc { @@ -179,7 +180,7 @@ void StartSmartSelectionActionMenu::SetMenuIcon(int command_id, const gfx::ImageSkia& image) { - proxy_->UpdateMenuIcon(command_id, gfx::Image(image)); + proxy_->UpdateMenuIcon(command_id, ui::ImageModel::FromImageSkia(image)); } } // namespace arc
diff --git a/chrome/browser/chromeos/crosapi/browser_manager.cc b/chrome/browser/chromeos/crosapi/browser_manager.cc index dff0173..5422ea5 100644 --- a/chrome/browser/chromeos/crosapi/browser_manager.cc +++ b/chrome/browser/chromeos/crosapi/browser_manager.cc
@@ -196,6 +196,10 @@ "--enable-crashpad", "--breakpad-dump-location=" + crash_dir}; + // CrAS is the default audio server in Chrome OS. + if (base::SysInfo::IsRunningOnChromeOS()) + argv.push_back("--use-cras"); + std::string additional_flags = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( chromeos::switches::kLacrosChromeAdditionalArgs); @@ -206,14 +210,9 @@ argv.push_back(flag); } - // We assume that if there's a custom chrome path, that this is a developer - // and they want to enable logging. - bool custom_chrome_path = base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kLacrosChromePath); - if (custom_chrome_path) { - argv.push_back("--enable-logging"); - argv.push_back("--log-file=" + LacrosLogPath().value()); - } + // Always enable logging. + argv.push_back("--enable-logging"); + argv.push_back("--log-file=" + LacrosLogPath().value()); // Set up Mojo channel. base::CommandLine command_line(argv);
diff --git a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.cc b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.cc index 0075cccc..2c98156 100644 --- a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.cc +++ b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.cc
@@ -91,18 +91,6 @@ LoadFinished(std::move(prefs_)); } -void DeviceLocalAccountExternalPolicyLoader::OnExtensionLoadedInCache( - const std::string& id) {} - -void DeviceLocalAccountExternalPolicyLoader::OnExtensionDownloadFailed( - const std::string& id) {} - -std::string -DeviceLocalAccountExternalPolicyLoader::GetInstalledExtensionVersion( - const std::string& id) { - return std::string(); -} - ExternalCache* DeviceLocalAccountExternalPolicyLoader::GetExternalCacheForTesting() { return external_cache_.get();
diff --git a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.h b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.h index 23ff108..df8831d 100644 --- a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.h +++ b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.h
@@ -60,9 +60,6 @@ // ExternalCacheDelegate: void OnExtensionListsUpdated(const base::DictionaryValue* prefs) override; - void OnExtensionLoadedInCache(const std::string& id) override; - void OnExtensionDownloadFailed(const std::string& id) override; - std::string GetInstalledExtensionVersion(const std::string& id) override; ExternalCache* GetExternalCacheForTesting();
diff --git a/chrome/browser/chromeos/extensions/external_cache_delegate.cc b/chrome/browser/chromeos/extensions/external_cache_delegate.cc new file mode 100644 index 0000000..0ac759a --- /dev/null +++ b/chrome/browser/chromeos/extensions/external_cache_delegate.cc
@@ -0,0 +1,23 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/extensions/external_cache_delegate.h" + +namespace chromeos { + +void ExternalCacheDelegate::OnExtensionListsUpdated( + const base::DictionaryValue* prefs) {} + +void ExternalCacheDelegate::OnExtensionLoadedInCache( + const extensions::ExtensionId& id) {} + +void ExternalCacheDelegate::OnExtensionDownloadFailed( + const extensions::ExtensionId& id) {} + +std::string ExternalCacheDelegate::GetInstalledExtensionVersion( + const extensions::ExtensionId& id) { + return std::string(); +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/external_cache_delegate.h b/chrome/browser/chromeos/extensions/external_cache_delegate.h index fcd983f..c1d88084 100644 --- a/chrome/browser/chromeos/extensions/external_cache_delegate.h +++ b/chrome/browser/chromeos/extensions/external_cache_delegate.h
@@ -7,6 +7,8 @@ #include <string> +#include "extensions/common/extension_id.h" + namespace base { class DictionaryValue; } @@ -18,18 +20,19 @@ virtual ~ExternalCacheDelegate() = default; // Caller owns |prefs|. - virtual void OnExtensionListsUpdated(const base::DictionaryValue* prefs) = 0; + virtual void OnExtensionListsUpdated(const base::DictionaryValue* prefs); // Called after extension with |id| is loaded in cache. - virtual void OnExtensionLoadedInCache(const std::string& id) = 0; + virtual void OnExtensionLoadedInCache(const extensions::ExtensionId& id); // Called when extension with |id| fails to load due to a download error. - virtual void OnExtensionDownloadFailed(const std::string& id) = 0; + virtual void OnExtensionDownloadFailed(const extensions::ExtensionId& id); // Cache needs to provide already installed extensions otherwise they // will be removed. Cache calls this function to get version of installed // extension or empty string if not installed. - virtual std::string GetInstalledExtensionVersion(const std::string& id) = 0; + virtual std::string GetInstalledExtensionVersion( + const extensions::ExtensionId& id); }; } // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/external_cache_impl_unittest.cc b/chrome/browser/chromeos/extensions/external_cache_impl_unittest.cc index 35b2966..9def4250 100644 --- a/chrome/browser/chromeos/extensions/external_cache_impl_unittest.cc +++ b/chrome/browser/chromeos/extensions/external_cache_impl_unittest.cc
@@ -63,9 +63,8 @@ void OnExtensionListsUpdated(const base::DictionaryValue* prefs) override { prefs_.reset(prefs->DeepCopy()); } - void OnExtensionLoadedInCache(const std::string& id) override {} - void OnExtensionDownloadFailed(const std::string& id) override {} - std::string GetInstalledExtensionVersion(const std::string& id) override { + std::string GetInstalledExtensionVersion( + const extensions::ExtensionId& id) override { std::map<std::string, std::string>::iterator it = installed_extensions_.find(id); return it != installed_extensions_.end() ? it->second : std::string();
diff --git a/chrome/browser/chromeos/extensions/signin_screen_extensions_external_loader.cc b/chrome/browser/chromeos/extensions/signin_screen_extensions_external_loader.cc index 1801c937..c60d1df 100644 --- a/chrome/browser/chromeos/extensions/signin_screen_extensions_external_loader.cc +++ b/chrome/browser/chromeos/extensions/signin_screen_extensions_external_loader.cc
@@ -85,17 +85,6 @@ LoadFinished(prefs->CreateDeepCopy()); } -void SigninScreenExtensionsExternalLoader::OnExtensionLoadedInCache( - const std::string& id) {} - -void SigninScreenExtensionsExternalLoader::OnExtensionDownloadFailed( - const std::string& id) {} - -std::string SigninScreenExtensionsExternalLoader::GetInstalledExtensionVersion( - const std::string& id) { - return std::string(); -} - SigninScreenExtensionsExternalLoader::~SigninScreenExtensionsExternalLoader() = default;
diff --git a/chrome/browser/chromeos/extensions/signin_screen_extensions_external_loader.h b/chrome/browser/chromeos/extensions/signin_screen_extensions_external_loader.h index f2502f9..cdf66e9 100644 --- a/chrome/browser/chromeos/extensions/signin_screen_extensions_external_loader.h +++ b/chrome/browser/chromeos/extensions/signin_screen_extensions_external_loader.h
@@ -39,9 +39,6 @@ // ExternalCacheDelegate: void OnExtensionListsUpdated(const base::DictionaryValue* prefs) override; - void OnExtensionLoadedInCache(const std::string& id) override; - void OnExtensionDownloadFailed(const std::string& id) override; - std::string GetInstalledExtensionVersion(const std::string& id) override; private: friend class base::RefCounted<SigninScreenExtensionsExternalLoader>;
diff --git a/chrome/browser/chromeos/input_method/ui/suggestion_view.cc b/chrome/browser/chromeos/input_method/ui/suggestion_view.cc index 91eebd5..1b37247 100644 --- a/chrome/browser/chromeos/input_method/ui/suggestion_view.cc +++ b/chrome/browser/chromeos/input_method/ui/suggestion_view.cc
@@ -47,9 +47,7 @@ // Creates the suggestion label, and returns it (never returns nullptr). // The label text is not set in this function. std::unique_ptr<views::StyledLabel> CreateSuggestionLabel() { - std::unique_ptr<views::StyledLabel> suggestion_label = - std::make_unique<views::StyledLabel>(base::EmptyString16(), - /*listener=*/nullptr); + auto suggestion_label = std::make_unique<views::StyledLabel>(); suggestion_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); suggestion_label->SetBorder( views::CreateEmptyBorder(gfx::Insets(kPadding / 2, 0)));
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_extensions_external_loader.cc b/chrome/browser/chromeos/login/demo_mode/demo_extensions_external_loader.cc index de9078b..05030c5 100644 --- a/chrome/browser/chromeos/login/demo_mode/demo_extensions_external_loader.cc +++ b/chrome/browser/chromeos/login/demo_mode/demo_extensions_external_loader.cc
@@ -121,17 +121,6 @@ LoadFinished(prefs->CreateDeepCopy()); } -void DemoExtensionsExternalLoader::OnExtensionLoadedInCache( - const std::string& id) {} - -void DemoExtensionsExternalLoader::OnExtensionDownloadFailed( - const std::string& id) {} - -std::string DemoExtensionsExternalLoader::GetInstalledExtensionVersion( - const std::string& id) { - return std::string(); -} - void DemoExtensionsExternalLoader::StartLoadingFromOfflineDemoResources() { DemoSession* demo_session = DemoSession::Get(); DCHECK(demo_session->resources()->loaded());
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_extensions_external_loader.h b/chrome/browser/chromeos/login/demo_mode/demo_extensions_external_loader.h index df48cef..dd7a489b 100644 --- a/chrome/browser/chromeos/login/demo_mode/demo_extensions_external_loader.h +++ b/chrome/browser/chromeos/login/demo_mode/demo_extensions_external_loader.h
@@ -50,9 +50,6 @@ // ExternalCacheDelegate: void OnExtensionListsUpdated(const base::DictionaryValue* prefs) override; - void OnExtensionLoadedInCache(const std::string& id) override; - void OnExtensionDownloadFailed(const std::string& id) override; - std::string GetInstalledExtensionVersion(const std::string& id) override; protected: ~DemoExtensionsExternalLoader() override;
diff --git a/chrome/browser/chromeos/scanning/scan_service.cc b/chrome/browser/chromeos/scanning/scan_service.cc new file mode 100644 index 0000000..dd2b5fd --- /dev/null +++ b/chrome/browser/chromeos/scanning/scan_service.cc
@@ -0,0 +1,59 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/scanning/scan_service.h" + +#include <utility> + +#include "base/bind.h" +#include "base/check.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/chromeos/scanning/lorgnette_scanner_manager.h" + +namespace chromeos { + +namespace { + +namespace mojo_ipc = scanning::mojom; + +} // namespace + +ScanService::ScanService(LorgnetteScannerManager* lorgnette_scanner_manager) + : lorgnette_scanner_manager_(lorgnette_scanner_manager) { + DCHECK(lorgnette_scanner_manager_); +} + +ScanService::~ScanService() = default; + +void ScanService::GetScanners(GetScannersCallback callback) { + lorgnette_scanner_manager_->GetScannerNames( + base::BindOnce(&ScanService::OnScannerNamesReceived, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} + +void ScanService::BindInterface( + mojo::PendingReceiver<mojo_ipc::ScanService> pending_receiver) { + receiver_.Bind(std::move(pending_receiver)); +} + +void ScanService::Shutdown() { + lorgnette_scanner_manager_ = nullptr; + receiver_.reset(); + weak_ptr_factory_.InvalidateWeakPtrs(); +} + +void ScanService::OnScannerNamesReceived( + GetScannersCallback callback, + std::vector<std::string> scanner_names) { + std::vector<mojo_ipc::ScannerPtr> scanners; + scanners.reserve(scanner_names.size()); + for (const auto& name : scanner_names) { + base::UnguessableToken id = base::UnguessableToken::Create(); + scanners.push_back(mojo_ipc::Scanner::New(id, base::UTF8ToUTF16(name))); + } + + std::move(callback).Run(std::move(scanners)); +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/scanning/scan_service.h b/chrome/browser/chromeos/scanning/scan_service.h new file mode 100644 index 0000000..17477fc --- /dev/null +++ b/chrome/browser/chromeos/scanning/scan_service.h
@@ -0,0 +1,60 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_SCANNING_SCAN_SERVICE_H_ +#define CHROME_BROWSER_CHROMEOS_SCANNING_SCAN_SERVICE_H_ + +#include <string> +#include <vector> + +#include "base/memory/weak_ptr.h" +#include "base/unguessable_token.h" +#include "chromeos/components/scanning/mojom/scanning.mojom.h" +#include "components/keyed_service/core/keyed_service.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver.h" + +namespace chromeos { + +class LorgnetteScannerManager; + +// Implementation of the chromeos::scanning::mojom::ScanService interface. Used +// by the scanning WebUI (chrome://scanning) to get connected scanners, obtain +// scanner capabilities, and perform scans. +class ScanService : public scanning::mojom::ScanService, public KeyedService { + public: + explicit ScanService(LorgnetteScannerManager* lorgnette_scanner_manager); + ~ScanService() override; + + ScanService(const ScanService&) = delete; + ScanService& operator=(const ScanService&) = delete; + + // scanning::mojom::ScanService: + void GetScanners(GetScannersCallback callback) override; + + // Binds receiver_ by consuming |pending_receiver|. + void BindInterface( + mojo::PendingReceiver<scanning::mojom::ScanService> pending_receiver); + + private: + // KeyedService: + void Shutdown() override; + + // Processes the result of calling LorgnetteScannerManager::GetScannerNames(). + void OnScannerNamesReceived(GetScannersCallback callback, + std::vector<std::string> scanner_names); + + // Receives and dispatches method calls to this implementation of the + // chromeos::scanning::mojom::ScanService interface. + mojo::Receiver<scanning::mojom::ScanService> receiver_{this}; + + // Unowned. Used to get scanner information and perform scans. + LorgnetteScannerManager* lorgnette_scanner_manager_; + + base::WeakPtrFactory<ScanService> weak_ptr_factory_{this}; +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_SCANNING_SCAN_SERVICE_H_
diff --git a/chrome/browser/chromeos/scanning/scan_service_factory.cc b/chrome/browser/chromeos/scanning/scan_service_factory.cc new file mode 100644 index 0000000..f1ad3185 --- /dev/null +++ b/chrome/browser/chromeos/scanning/scan_service_factory.cc
@@ -0,0 +1,60 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/scanning/scan_service_factory.h" + +#include "base/memory/singleton.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/chromeos/scanning/lorgnette_scanner_manager_factory.h" +#include "chrome/browser/chromeos/scanning/scan_service.h" +#include "chrome/browser/profiles/profile.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "content/public/browser/browser_context.h" + +namespace chromeos { + +// static +ScanService* ScanServiceFactory::GetForBrowserContext( + content::BrowserContext* context) { + return static_cast<ScanService*>( + ScanServiceFactory::GetInstance()->GetServiceForBrowserContext( + context, /*create=*/true)); +} + +// static +ScanServiceFactory* ScanServiceFactory::GetInstance() { + return base::Singleton<ScanServiceFactory>::get(); +} + +ScanServiceFactory::ScanServiceFactory() + : BrowserContextKeyedServiceFactory( + "ScanService", + BrowserContextDependencyManager::GetInstance()) { + DependsOn(LorgnetteScannerManagerFactory::GetInstance()); +} + +ScanServiceFactory::~ScanServiceFactory() = default; + +KeyedService* ScanServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + // Prevent an instance of ScanService from being created on the lock screen. + Profile* profile = Profile::FromBrowserContext(context); + if (ProfileHelper::IsLockScreenAppProfile(profile) || + ProfileHelper::IsSigninProfile(profile)) { + return nullptr; + } + + return new ScanService( + LorgnetteScannerManagerFactory::GetForBrowserContext(context)); +} + +bool ScanServiceFactory::ServiceIsCreatedWithBrowserContext() const { + return true; +} + +bool ScanServiceFactory::ServiceIsNULLWhileTesting() const { + return true; +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/scanning/scan_service_factory.h b/chrome/browser/chromeos/scanning/scan_service_factory.h new file mode 100644 index 0000000..b36c953 --- /dev/null +++ b/chrome/browser/chromeos/scanning/scan_service_factory.h
@@ -0,0 +1,47 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_SCANNING_SCAN_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_CHROMEOS_SCANNING_SCAN_SERVICE_FACTORY_H_ + +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace base { +template <typename T> +struct DefaultSingletonTraits; +} // namespace base + +namespace content { +class BrowserContext; +} // namespace content + +namespace chromeos { + +class ScanService; + +// Factory for ScanService. +class ScanServiceFactory : public BrowserContextKeyedServiceFactory { + public: + static ScanService* GetForBrowserContext(content::BrowserContext* context); + static ScanServiceFactory* GetInstance(); + + private: + friend struct base::DefaultSingletonTraits<ScanServiceFactory>; + + ScanServiceFactory(); + ~ScanServiceFactory() override; + + ScanServiceFactory(const ScanServiceFactory&) = delete; + ScanServiceFactory& operator=(const ScanServiceFactory&) = delete; + + // BrowserContextKeyedServiceFactory: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + bool ServiceIsCreatedWithBrowserContext() const override; + bool ServiceIsNULLWhileTesting() const override; +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_SCANNING_SCAN_SERVICE_FACTORY_H_
diff --git a/chrome/browser/chromeos/scanning/scan_service_unittest.cc b/chrome/browser/chromeos/scanning/scan_service_unittest.cc new file mode 100644 index 0000000..db2d99a --- /dev/null +++ b/chrome/browser/chromeos/scanning/scan_service_unittest.cc
@@ -0,0 +1,85 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/scanning/scan_service.h" + +#include <vector> + +#include "base/strings/utf_string_conversions.h" +#include "base/test/task_environment.h" +#include "chrome/browser/chromeos/scanning/fake_lorgnette_scanner_manager.h" +#include "chromeos/components/scanning/mojom/scanning.mojom-test-utils.h" +#include "chromeos/components/scanning/mojom/scanning.mojom.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { + +namespace { + +namespace mojo_ipc = scanning::mojom; + +// Scanner names used for tests. +constexpr char kFirstTestScannerName[] = "Test Scanner 1"; +constexpr char kSecondTestScannerName[] = "Test Scanner 2"; + +} // namespace + +class ScanServiceTest : public testing::Test { + public: + ScanServiceTest() = default; + + void SetUp() override { + scan_service_.BindInterface( + scan_service_remote_.BindNewPipeAndPassReceiver()); + } + + // Gets scanners by calling ScanService::GetScanners() via the mojo::Remote. + std::vector<mojo_ipc::ScannerPtr> GetScanners() { + std::vector<mojo_ipc::ScannerPtr> scanners; + mojo_ipc::ScanServiceAsyncWaiter(scan_service_remote_.get()) + .GetScanners(&scanners); + return scanners; + } + + protected: + FakeLorgnetteScannerManager fake_lorgnette_scanner_manager_; + + private: + base::test::TaskEnvironment task_environment_; + ScanService scan_service_{&fake_lorgnette_scanner_manager_}; + mojo::Remote<mojo_ipc::ScanService> scan_service_remote_; +}; + +// Test that no scanners are returned when there are no scanner names. +TEST_F(ScanServiceTest, NoScannerNames) { + fake_lorgnette_scanner_manager_.SetGetScannerNamesResponse({}); + auto scanners = GetScanners(); + EXPECT_TRUE(scanners.empty()); +} + +// Test that a scanner is returned with the correct display name. +TEST_F(ScanServiceTest, GetScanners) { + fake_lorgnette_scanner_manager_.SetGetScannerNamesResponse( + {kFirstTestScannerName}); + auto scanners = GetScanners(); + ASSERT_EQ(scanners.size(), 1u); + EXPECT_EQ(scanners[0]->display_name, + base::UTF8ToUTF16(kFirstTestScannerName)); +} + +// Test that two returned scanners have unique IDs. +TEST_F(ScanServiceTest, UniqueScannerIds) { + fake_lorgnette_scanner_manager_.SetGetScannerNamesResponse( + {kFirstTestScannerName, kSecondTestScannerName}); + auto scanners = GetScanners(); + ASSERT_EQ(scanners.size(), 2u); + EXPECT_EQ(scanners[0]->display_name, + base::UTF8ToUTF16(kFirstTestScannerName)); + EXPECT_EQ(scanners[1]->display_name, + base::UTF8ToUTF16(kSecondTestScannerName)); + EXPECT_NE(scanners[0]->id, scanners[1]->id); +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/ui/echo_dialog_view.cc b/chrome/browser/chromeos/ui/echo_dialog_view.cc index e57488b5..17cccf1 100644 --- a/chrome/browser/chromeos/ui/echo_dialog_view.cc +++ b/chrome/browser/chromeos/ui/echo_dialog_view.cc
@@ -83,7 +83,8 @@ base::string16 text = l10n_util::GetStringFUTF16(IDS_ECHO_CONSENT_DIALOG_TEXT, service_name, &offset); - auto label = std::make_unique<views::StyledLabel>(text, nullptr); + auto label = std::make_unique<views::StyledLabel>(); + label->SetText(text); views::StyledLabel::RangeStyleInfo service_name_style; gfx::FontList font_list = label->GetFontList();
diff --git a/chrome/browser/component_updater/soda_component_installer.cc b/chrome/browser/component_updater/soda_component_installer.cc index 7c0a4e68..59f7835 100644 --- a/chrome/browser/component_updater/soda_component_installer.cc +++ b/chrome/browser/component_updater/soda_component_installer.cc
@@ -19,6 +19,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "crypto/sha2.h" +#include "media/base/media_switches.h" using content::BrowserThread; @@ -133,17 +134,18 @@ PrefService* prefs, base::OnceClosure callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (!base::FeatureList::IsEnabled(media::kLiveCaption)) + return; + #if BUILDFLAG(ENABLE_SODA) auto installer = base::MakeRefCounted<ComponentInstaller>( std::make_unique<SODAComponentInstallerPolicy>(base::BindRepeating( [](ComponentUpdateService* cus, PrefService* prefs, const base::FilePath& install_dir) { - if (prefs->GetBoolean(prefs::kLiveCaptionEnabled)) { content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT}) ->PostTask(FROM_HERE, base::BindOnce(&UpdateSODAInstallDirPref, prefs, install_dir)); - } }, cus, prefs)));
diff --git a/chrome/browser/component_updater/soda_en_us_component_installer.cc b/chrome/browser/component_updater/soda_en_us_component_installer.cc index b54f8628..b4950cb 100644 --- a/chrome/browser/component_updater/soda_en_us_component_installer.cc +++ b/chrome/browser/component_updater/soda_en_us_component_installer.cc
@@ -17,6 +17,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "crypto/sha2.h" +#include "media/base/media_switches.h" using content::BrowserThread; @@ -137,19 +138,19 @@ base::OnceClosure callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); #if BUILDFLAG(ENABLE_SODA) - if (!prefs->GetBoolean(prefs::kLiveCaptionEnabled)) + if (!prefs->GetBoolean(prefs::kLiveCaptionEnabled) || + !base::FeatureList::IsEnabled(media::kLiveCaption)) { return; + } auto installer = base::MakeRefCounted<ComponentInstaller>( std::make_unique<SodaEnUsComponentInstallerPolicy>(base::BindRepeating( [](ComponentUpdateService* cus, PrefService* prefs, const base::FilePath& install_dir) { - if (prefs->GetBoolean(prefs::kLiveCaptionEnabled)) { content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT}) ->PostTask(FROM_HERE, base::BindOnce(&UpdateSodaEnUsInstallDirPref, prefs, install_dir)); - } }, cus, prefs)));
diff --git a/chrome/browser/component_updater/soda_ja_jp_component_installer.cc b/chrome/browser/component_updater/soda_ja_jp_component_installer.cc index 4096ea92..c819e181 100644 --- a/chrome/browser/component_updater/soda_ja_jp_component_installer.cc +++ b/chrome/browser/component_updater/soda_ja_jp_component_installer.cc
@@ -17,6 +17,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "crypto/sha2.h" +#include "media/base/media_switches.h" using content::BrowserThread; @@ -137,19 +138,19 @@ base::OnceClosure callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); #if BUILDFLAG(ENABLE_SODA) - if (!prefs->GetBoolean(prefs::kLiveCaptionEnabled)) + if (!prefs->GetBoolean(prefs::kLiveCaptionEnabled) || + !base::FeatureList::IsEnabled(media::kLiveCaption)) { return; + } auto installer = base::MakeRefCounted<ComponentInstaller>( std::make_unique<SodaJaJpComponentInstallerPolicy>(base::BindRepeating( [](ComponentUpdateService* cus, PrefService* prefs, const base::FilePath& install_dir) { - if (prefs->GetBoolean(prefs::kLiveCaptionEnabled)) { content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT}) ->PostTask(FROM_HERE, base::BindOnce(&UpdateSodaJaJpInstallDirPref, prefs, install_dir)); - } }, cus, prefs)));
diff --git a/chrome/browser/content_settings/cookie_settings_factory.cc b/chrome/browser/content_settings/cookie_settings_factory.cc index 19238e6c..cc9cfc12 100644 --- a/chrome/browser/content_settings/cookie_settings_factory.cc +++ b/chrome/browser/content_settings/cookie_settings_factory.cc
@@ -60,22 +60,14 @@ Profile* profile = Profile::FromBrowserContext(context); PrefService* prefs = profile->GetPrefs(); - // Migrate BlockThirdPartyCookies to CookieControlsMode pref. - if (prefs->IsUserModifiablePreference(prefs::kBlockThirdPartyCookies) && - prefs->GetBoolean(prefs::kBlockThirdPartyCookies) && - prefs->GetInteger(prefs::kCookieControlsMode) != - static_cast<int>(CookieControlsMode::kBlockThirdParty)) { - prefs->SetInteger(prefs::kCookieControlsMode, - static_cast<int>(CookieControlsMode::kBlockThirdParty)); - } - // Record cookie setting histograms. - base::UmaHistogramBoolean("Privacy.ThirdPartyCookieBlockingSetting", - prefs->GetBoolean(prefs::kBlockThirdPartyCookies)); - base::UmaHistogramEnumeration( - "Privacy.CookieControlsSetting", - static_cast<CookieControlsMode>( - prefs->GetInteger(prefs::kCookieControlsMode))); + auto cookie_controls_mode = static_cast<CookieControlsMode>( + prefs->GetInteger(prefs::kCookieControlsMode)); + base::UmaHistogramBoolean( + "Privacy.ThirdPartyCookieBlockingSetting", + cookie_controls_mode == CookieControlsMode::kBlockThirdParty); + base::UmaHistogramEnumeration("Privacy.CookieControlsSetting", + cookie_controls_mode); // The DNT setting is only vaguely cookie-related. However, there is currently // no DNT-related code that is executed once per Profile lifetime, and // creating a new BrowserContextKeyedService to record this metric would be
diff --git a/chrome/browser/content_settings/cookie_settings_factory_unittest.cc b/chrome/browser/content_settings/cookie_settings_factory_unittest.cc index e7373726..60aa78a 100644 --- a/chrome/browser/content_settings/cookie_settings_factory_unittest.cc +++ b/chrome/browser/content_settings/cookie_settings_factory_unittest.cc
@@ -86,8 +86,7 @@ // Android does not have guest profiles. #if !defined(OS_ANDROID) -// Tests that improved cookie controls are not available by default for guest -// profiles. +// Tests that cookie blocking is not enabled by default for guest profiles. TEST_F(CookieSettingsFactoryTest, GuestProfile) { TestingProfile::Builder guest_profile_builder; guest_profile_builder.SetGuestSession(); @@ -96,12 +95,12 @@ EXPECT_TRUE(otr_guest_profile->IsOffTheRecord()); scoped_refptr<content_settings::CookieSettings> guest_settings = CookieSettingsFactory::GetForProfile(otr_guest_profile); - EXPECT_FALSE(guest_settings->IsCookieControlsEnabled()); + EXPECT_FALSE(guest_settings->ShouldBlockThirdPartyCookies()); - // OTOH, improved controls are available by default for an incognito profile. + // OTOH, cookie blocking is default for an incognito profile. EXPECT_TRUE( CookieSettingsFactory::GetForProfile(profile_.GetPrimaryOTRProfile()) - ->IsCookieControlsEnabled()); + ->ShouldBlockThirdPartyCookies()); } #endif
diff --git a/chrome/browser/download/download_shelf_context_menu.cc b/chrome/browser/download/download_shelf_context_menu.cc index 62d24dd..8ef7463 100644 --- a/chrome/browser/download/download_shelf_context_menu.cc +++ b/chrome/browser/download/download_shelf_context_menu.cc
@@ -413,7 +413,8 @@ DownloadCommands::ALWAYS_OPEN_TYPE, GetLabelForCommandId(DownloadCommands::ALWAYS_OPEN_TYPE), ui::ImageModel::FromVectorIcon(vector_icons::kBusinessIcon, - gfx::kChromeIconGrey, 16)); + gfx::kChromeIconGrey, + ui::SimpleMenuModel::kDefaultIconSize)); } else { menu->AddCheckItem( DownloadCommands::ALWAYS_OPEN_TYPE,
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index af74217c..e0cc4ef 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -690,10 +690,6 @@ "updater/extension_updater.h", "updater/extension_updater_switches.cc", "updater/extension_updater_switches.h", - "updater/fetched_crx_file.cc", - "updater/fetched_crx_file.h", - "updater/parallel_unpacker.cc", - "updater/parallel_unpacker.h", "user_script_listener.cc", "user_script_listener.h", "warning_badge_service.cc",
diff --git a/chrome/browser/extensions/api/passwords_private/password_check_delegate.cc b/chrome/browser/extensions/api/passwords_private/password_check_delegate.cc index 825d3bc1..9f1ff907 100644 --- a/chrome/browser/extensions/api/passwords_private/password_check_delegate.cc +++ b/chrome/browser/extensions/api/passwords_private/password_check_delegate.cc
@@ -224,8 +224,8 @@ profile, ServiceAccessType::EXPLICIT_ACCESS)), saved_passwords_presenter_(password_store_), - compromised_credentials_manager_(password_store_, - &saved_passwords_presenter_), + compromised_credentials_manager_(&saved_passwords_presenter_, + password_store_), bulk_leak_check_service_adapter_( &saved_passwords_presenter_, BulkLeakCheckServiceFactory::GetForProfile(profile_),
diff --git a/chrome/browser/extensions/updater/extension_updater.cc b/chrome/browser/extensions/updater/extension_updater.cc index 248c0f9..f85479b 100644 --- a/chrome/browser/extensions/updater/extension_updater.cc +++ b/chrome/browser/extensions/updater/extension_updater.cc
@@ -106,6 +106,27 @@ ExtensionUpdater::CheckParams& ExtensionUpdater::CheckParams::operator=( ExtensionUpdater::CheckParams&& other) = default; +ExtensionUpdater::FetchedCRXFile::FetchedCRXFile( + const CRXFileInfo& file, + bool file_ownership_passed, + const std::set<int>& request_ids, + InstallCallback callback) + : info(file), + file_ownership_passed(file_ownership_passed), + request_ids(request_ids), + callback(std::move(callback)) {} + +ExtensionUpdater::FetchedCRXFile::FetchedCRXFile() + : file_ownership_passed(true) {} + +ExtensionUpdater::FetchedCRXFile::FetchedCRXFile(FetchedCRXFile&& other) = + default; + +ExtensionUpdater::FetchedCRXFile& ExtensionUpdater::FetchedCRXFile::operator=( + FetchedCRXFile&& other) = default; + +ExtensionUpdater::FetchedCRXFile::~FetchedCRXFile() = default; + ExtensionUpdater::InProgressCheck::InProgressCheck() = default; ExtensionUpdater::InProgressCheck::~InProgressCheck() = default;
diff --git a/chrome/browser/extensions/updater/extension_updater.h b/chrome/browser/extensions/updater/extension_updater.h index a65bb43..a4b125e5 100644 --- a/chrome/browser/extensions/updater/extension_updater.h +++ b/chrome/browser/extensions/updater/extension_updater.h
@@ -16,7 +16,6 @@ #include "base/files/file_path.h" #include "base/memory/weak_ptr.h" #include "base/scoped_observer.h" -#include "chrome/browser/extensions/updater/fetched_crx_file.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "extensions/browser/extension_registry_observer.h" @@ -155,6 +154,25 @@ friend class ExtensionUpdaterTest; friend class ExtensionUpdaterFileHandler; + // FetchedCRXFile holds information about a CRX file we fetched to disk, + // but have not yet installed. + struct FetchedCRXFile { + FetchedCRXFile(); + FetchedCRXFile(const CRXFileInfo& file, + bool file_ownership_passed, + const std::set<int>& request_ids, + InstallCallback callback); + FetchedCRXFile(FetchedCRXFile&& other); + FetchedCRXFile& operator=(FetchedCRXFile&& other); + ~FetchedCRXFile(); + + CRXFileInfo info; + GURL download_url; + bool file_ownership_passed; + std::set<int> request_ids; + InstallCallback callback; + }; + struct InProgressCheck { InProgressCheck(); InProgressCheck(const InProgressCheck&) = delete;
diff --git a/chrome/browser/extensions/updater/fetched_crx_file.cc b/chrome/browser/extensions/updater/fetched_crx_file.cc deleted file mode 100644 index f0a0d00..0000000 --- a/chrome/browser/extensions/updater/fetched_crx_file.cc +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/extensions/updater/fetched_crx_file.h" - -namespace extensions { - -FetchedCRXFile::FetchedCRXFile( - const CRXFileInfo& file, - bool file_ownership_passed, - const std::set<int>& request_ids, - ExtensionDownloaderDelegate::InstallCallback callback) - : info(file), - file_ownership_passed(file_ownership_passed), - request_ids(request_ids), - callback(std::move(callback)) {} - -FetchedCRXFile::FetchedCRXFile() = default; - -FetchedCRXFile::FetchedCRXFile(FetchedCRXFile&&) = default; -FetchedCRXFile& FetchedCRXFile::operator=(FetchedCRXFile&&) = default; - -FetchedCRXFile::~FetchedCRXFile() = default; - -} // namespace extensions
diff --git a/chrome/browser/extensions/updater/fetched_crx_file.h b/chrome/browser/extensions/updater/fetched_crx_file.h deleted file mode 100644 index fc02ad33..0000000 --- a/chrome/browser/extensions/updater/fetched_crx_file.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_EXTENSIONS_UPDATER_FETCHED_CRX_FILE_H_ -#define CHROME_BROWSER_EXTENSIONS_UPDATER_FETCHED_CRX_FILE_H_ - -#include <set> - -#include "extensions/browser/crx_file_info.h" -#include "extensions/browser/updater/extension_downloader_delegate.h" - -namespace extensions { - -// FetchedCRXFile holds information about a CRX file we fetched to disk, -// but have not yet unpacked or installed. -struct FetchedCRXFile { - FetchedCRXFile(); - FetchedCRXFile(const CRXFileInfo& file, - bool file_ownership_passed, - const std::set<int>& request_ids, - ExtensionDownloaderDelegate::InstallCallback callback); - FetchedCRXFile(FetchedCRXFile&& other); - FetchedCRXFile& operator=(FetchedCRXFile&&); - ~FetchedCRXFile(); - - FetchedCRXFile(const FetchedCRXFile&) = delete; - FetchedCRXFile& operator=(const FetchedCRXFile&) = delete; - - CRXFileInfo info; - GURL download_url; - bool file_ownership_passed = true; - std::set<int> request_ids; - ExtensionDownloaderDelegate::InstallCallback callback; -}; - -} // namespace extensions - -#endif // CHROME_BROWSER_EXTENSIONS_UPDATER_FETCHED_CRX_FILE_H_
diff --git a/chrome/browser/extensions/updater/parallel_unpacker.cc b/chrome/browser/extensions/updater/parallel_unpacker.cc deleted file mode 100644 index cfb0342..0000000 --- a/chrome/browser/extensions/updater/parallel_unpacker.cc +++ /dev/null
@@ -1,151 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/extensions/updater/parallel_unpacker.h" - -#include "base/task/post_task.h" -#include "base/values.h" -#include "chrome/browser/extensions/pending_extension_info.h" -#include "chrome/browser/profiles/profile.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "extensions/browser/content_verifier.h" -#include "extensions/browser/extension_file_task_runner.h" -#include "extensions/browser/extension_system.h" -#include "extensions/common/extension.h" -#include "third_party/skia/include/core/SkBitmap.h" - -namespace extensions { - -ParallelUnpacker::UnpackedExtension::UnpackedExtension() = default; -ParallelUnpacker::UnpackedExtension::UnpackedExtension( - FetchedCRXFile fetch_info, - const base::FilePath& temp_dir, - const base::FilePath& extension_root, - std::unique_ptr<base::DictionaryValue> original_manifest, - scoped_refptr<const Extension> extension, - const SkBitmap& install_icon, - declarative_net_request::RulesetInstallPrefs ruleset_install_prefs) - : fetch_info(std::move(fetch_info)), - temp_dir(temp_dir), - extension_root(extension_root), - original_manifest(std::move(original_manifest)), - extension(extension), - install_icon(install_icon), - ruleset_install_prefs(std::move(ruleset_install_prefs)) {} - -ParallelUnpacker::UnpackedExtension::UnpackedExtension(UnpackedExtension&&) = - default; - -ParallelUnpacker::UnpackedExtension& -ParallelUnpacker::UnpackedExtension::operator=(UnpackedExtension&&) = default; - -ParallelUnpacker::UnpackedExtension::~UnpackedExtension() = default; - -ParallelUnpacker::ParallelUnpacker(Delegate* delegate, Profile* profile) - : delegate_(delegate), profile_(profile) {} - -ParallelUnpacker::~ParallelUnpacker() = default; - -void ParallelUnpacker::Unpack( - FetchedCRXFile fetch_info, - const PendingExtensionInfo* pending_extension_info, - const Extension* extension, - const base::FilePath& install_directory) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(pending_extension_info || extension); - - auto install_source = pending_extension_info - ? pending_extension_info->install_source() - : extension->location(); - auto creation_flags = pending_extension_info - ? pending_extension_info->creation_flags() - : Extension::NO_FLAGS; - auto io_task_runner = GetExtensionFileTaskRunner(); - auto client = base::MakeRefCounted<Client>( - weak_ptr_factory_.GetWeakPtr(), std::move(fetch_info), io_task_runner); - - auto unpacker = base::MakeRefCounted<SandboxedUnpacker>( - install_source, creation_flags, install_directory, io_task_runner, - client.get()); - if (!io_task_runner->PostTask( - FROM_HERE, base::BindOnce(&SandboxedUnpacker::StartWithCrx, unpacker, - client->fetch_info().info))) { - NOTREACHED(); - } -} - -ParallelUnpacker::Client::Client( - base::WeakPtr<ParallelUnpacker> unpacker, - FetchedCRXFile fetch_info, - scoped_refptr<base::SequencedTaskRunner> io_task_runner) - : unpacker_(unpacker), - fetch_info_(std::move(fetch_info)), - io_task_runner_(io_task_runner) {} -ParallelUnpacker::Client::~Client() = default; - -void ParallelUnpacker::Client::ShouldComputeHashesForOffWebstoreExtension( - scoped_refptr<const Extension> extension, - base::OnceCallback<void(bool)> callback) { - DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&ParallelUnpacker::Client::ShouldComputeHashesOnUIThread, - this, extension, std::move(callback))); -} - -void ParallelUnpacker::Client::ShouldComputeHashesOnUIThread( - scoped_refptr<const Extension> extension, - base::OnceCallback<void(bool)> callback) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!unpacker_) { - // |ExtensionUpdater| isn't running, e.g. Stop() was called. Drop the refs - // in |callback|. - return; - } - auto* content_verifier = - ExtensionSystem::Get(unpacker_->profile_)->content_verifier(); - bool result = content_verifier && - content_verifier->ShouldComputeHashesOnInstall(*extension); - io_task_runner_->PostTask(FROM_HERE, - base::BindOnce(std::move(callback), result)); -} - -void ParallelUnpacker::Client::OnUnpackSuccess( - const base::FilePath& temp_dir, - const base::FilePath& extension_root, - std::unique_ptr<base::DictionaryValue> original_manifest, - const Extension* extension, - const SkBitmap& install_icon, - declarative_net_request::RulesetInstallPrefs ruleset_install_prefs) { - DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); - UnpackedExtension unpacked_extension( - std::move(fetch_info_), temp_dir, extension_root, - std::move(original_manifest), extension, install_icon, - std::move(ruleset_install_prefs)); - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&ParallelUnpacker::ReportSuccessOnUIThread, - unpacker_, std::move(unpacked_extension))); -} - -void ParallelUnpacker::Client::OnUnpackFailure(const CrxInstallError& error) { - DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&ParallelUnpacker::ReportFailureOnUIThread, - unpacker_, std::move(fetch_info_), error)); -} - -void ParallelUnpacker::ReportSuccessOnUIThread( - UnpackedExtension unpacked_extension) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - delegate_->OnParallelUnpackSuccess(std::move(unpacked_extension)); -} - -void ParallelUnpacker::ReportFailureOnUIThread(FetchedCRXFile fetch_info, - CrxInstallError error) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - delegate_->OnParallelUnpackFailure(std::move(fetch_info), std::move(error)); -} - -} // namespace extensions
diff --git a/chrome/browser/extensions/updater/parallel_unpacker.h b/chrome/browser/extensions/updater/parallel_unpacker.h deleted file mode 100644 index 39f23ffb..0000000 --- a/chrome/browser/extensions/updater/parallel_unpacker.h +++ /dev/null
@@ -1,153 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_EXTENSIONS_UPDATER_PARALLEL_UNPACKER_H_ -#define CHROME_BROWSER_EXTENSIONS_UPDATER_PARALLEL_UNPACKER_H_ - -#include <memory> -#include <set> - -#include "base/files/file_path.h" -#include "base/memory/scoped_refptr.h" -#include "chrome/browser/extensions/updater/fetched_crx_file.h" -#include "extensions/browser/api/declarative_net_request/ruleset_install_pref.h" -#include "extensions/browser/crx_file_info.h" -#include "extensions/browser/install/crx_install_error.h" -#include "extensions/browser/sandboxed_unpacker.h" -#include "extensions/browser/updater/extension_downloader_delegate.h" - -namespace base { -class DictionaryValue; -} // namespace base - -class Profile; - -namespace extensions { - -class PendingExtensionInfo; - -// Unpacks multiple extensions in parallel, and notifies |updater| when an -// extension has finished unpacking. -class ParallelUnpacker { - public: - // UnpackedExtension holds information about a CRX file we fetched and - // unpacked. - struct UnpackedExtension { - UnpackedExtension(); - UnpackedExtension( - FetchedCRXFile fetch_info, - const base::FilePath& temp_dir, - const base::FilePath& extension_root, - std::unique_ptr<base::DictionaryValue> original_manifest, - scoped_refptr<const Extension> extension, - const SkBitmap& install_icon, - declarative_net_request::RulesetInstallPrefs ruleset_install_prefs); - UnpackedExtension(UnpackedExtension&& other); - UnpackedExtension& operator=(UnpackedExtension&&); - ~UnpackedExtension(); - - UnpackedExtension(const UnpackedExtension&) = delete; - UnpackedExtension& operator=(const UnpackedExtension&) = delete; - - // Information about the fetched CRX file, including CRXFileInfo and a - // callback. - FetchedCRXFile fetch_info; - - // The fields below are the result of - // SandboxedUnpackerClient::OnUnpackSuccess(). - - // Temporary directory with results of unpacking. It should be deleted once - // we don't need it anymore. - base::FilePath temp_dir; - // The path to the extension root inside of temp_dir. - base::FilePath extension_root; - // The parsed but unmodified version of the manifest, with no modifications - // such as localization, etc. - std::unique_ptr<base::DictionaryValue> original_manifest; - // The extension that was unpacked. - scoped_refptr<const Extension> extension; - // The icon we will display in the installation UI, if any. - SkBitmap install_icon; - // Install prefs needed for the Declarative Net Request API. - declarative_net_request::RulesetInstallPrefs ruleset_install_prefs; - }; - - class Delegate { - public: - virtual void OnParallelUnpackSuccess( - UnpackedExtension unpacked_extension) = 0; - virtual void OnParallelUnpackFailure(FetchedCRXFile fetch_info, - CrxInstallError error) = 0; - }; - - // |delegate| must outlive this object. - ParallelUnpacker(Delegate* delegate, Profile* profile); - ~ParallelUnpacker(); - - ParallelUnpacker(const ParallelUnpacker&) = delete; - ParallelUnpacker& operator=(const ParallelUnpacker&) = delete; - - // Starts unpacking |crx_file|. Either |pending_extension_info| or |extension| - // must be non-null. When done unpacking, calls - // OnParallelUnpackSuccess/Failure() on this object's delegate. - // - // May be called multiple times in a row to unpack multiple extensions in - // parallel. - void Unpack(FetchedCRXFile crx_file, - const PendingExtensionInfo* pending_extension_info, - const Extension* extension, - const base::FilePath& install_directory); - - private: - // Listens for a single SandboxedUnpacker's events. Routes - // OnUnpackSuccess/Failure() back to the ParallelUnpacker via - // ReportSuccess/FailureOnUIThread(). - class Client : public SandboxedUnpackerClient { - public: - Client(base::WeakPtr<ParallelUnpacker> unpacker, - FetchedCRXFile fetch_info, - scoped_refptr<base::SequencedTaskRunner> io_task_runner); - - // SandboxedUnpackerClient: - void ShouldComputeHashesForOffWebstoreExtension( - scoped_refptr<const Extension> extension, - base::OnceCallback<void(bool)> callback) override; - void OnUnpackSuccess( - const base::FilePath& temp_dir, - const base::FilePath& extension_root, - std::unique_ptr<base::DictionaryValue> original_manifest, - const Extension* extension, - const SkBitmap& install_icon, - declarative_net_request::RulesetInstallPrefs ruleset_install_prefs) - override; - void OnUnpackFailure(const CrxInstallError& error) override; - - FetchedCRXFile& fetch_info() { return fetch_info_; } - - private: - ~Client() override; - - // To check whether we need to compute hashes or not, we have to make a - // query to ContentVerifier, and that should be done on the UI thread. - void ShouldComputeHashesOnUIThread(scoped_refptr<const Extension> extension, - base::OnceCallback<void(bool)> callback); - - base::WeakPtr<ParallelUnpacker> unpacker_; - FetchedCRXFile fetch_info_; - scoped_refptr<base::SequencedTaskRunner> io_task_runner_; - }; - - void ReportSuccessOnUIThread(UnpackedExtension unpacked_extension); - void ReportFailureOnUIThread(FetchedCRXFile fetch_info, - CrxInstallError error); - - Delegate* const delegate_; - Profile* const profile_; - - base::WeakPtrFactory<ParallelUnpacker> weak_ptr_factory_{this}; -}; - -} // namespace extensions - -#endif // CHROME_BROWSER_EXTENSIONS_UPDATER_PARALLEL_UNPACKER_H_
diff --git a/chrome/browser/extensions/updater/parallel_unpacker_unittest.cc b/chrome/browser/extensions/updater/parallel_unpacker_unittest.cc deleted file mode 100644 index 9aa028ed..0000000 --- a/chrome/browser/extensions/updater/parallel_unpacker_unittest.cc +++ /dev/null
@@ -1,126 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/extensions/updater/parallel_unpacker.h" - -#include "base/files/file_util.h" -#include "base/path_service.h" -#include "chrome/browser/extensions/pending_extension_info.h" -#include "chrome/test/base/testing_profile.h" -#include "content/public/test/test_utils.h" -#include "extensions/browser/extensions_test.h" -#include "extensions/common/extension_paths.h" -#include "extensions/common/verifier_formats.h" -#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" - -namespace extensions { - -class ParallelUnpackerTest : public testing::Test, - public ParallelUnpacker::Delegate { - public: - ParallelUnpackerTest() - : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP) {} - - void SetUp() override { - ASSERT_TRUE(extensions_dir_.CreateUniqueTempDir()); - in_process_utility_thread_helper_.reset( - new content::InProcessUtilityThreadHelper); - parallel_unpacker_ = std::make_unique<ParallelUnpacker>(this, &profile_); - } - - void TearDown() override { - in_process_utility_thread_helper_.reset(); - parallel_unpacker_.reset(); - } - - base::FilePath GetCrxFullPath(const std::string& crx_name) { - base::FilePath full_path; - EXPECT_TRUE(base::PathService::Get(extensions::DIR_TEST_DATA, &full_path)); - full_path = full_path.AppendASCII("unpacker").AppendASCII(crx_name); - EXPECT_TRUE(base::PathExists(full_path)) << full_path.value(); - return full_path; - } - - void Unpack(const std::string& crx_name) { - base::FilePath crx_path = GetCrxFullPath(crx_name); - extensions::CRXFileInfo crx_info(crx_path, GetTestVerifierFormat()); - extensions::FetchedCRXFile fetch_info(crx_info, false, std::set<int>(), - base::BindOnce([](bool) {})); - extensions::PendingExtensionInfo pending_extension_info( - "", "", GURL(), base::Version(), [](const Extension*) { return true; }, - false, Manifest::INTERNAL, Extension::NO_FLAGS, true, false); - - parallel_unpacker_->Unpack(std::move(fetch_info), &pending_extension_info, - nullptr, extensions_dir_.GetPath()); - in_progress_count_++; - } - - // ParallelUnpacker::Delegate: - void OnParallelUnpackSuccess( - ParallelUnpacker::UnpackedExtension unpacked_extension) override { - std::string file_name = - unpacked_extension.fetch_info.info.path.BaseName().MaybeAsASCII(); - successful_unpacks_.emplace(file_name, std::move(unpacked_extension)); - if (--in_progress_count_ == 0) - std::move(quit_closure_).Run(); - } - void OnParallelUnpackFailure(FetchedCRXFile fetch_info, - CrxInstallError error) override { - std::string file_name = fetch_info.info.path.BaseName().MaybeAsASCII(); - failed_unpacks_.emplace(file_name, std::move(error)); - if (--in_progress_count_ == 0) - std::move(quit_closure_).Run(); - } - - void WaitForAllComplete() { - base::RunLoop run_loop; - quit_closure_ = run_loop.QuitClosure(); - run_loop.Run(); - } - - protected: - std::map<std::string, ParallelUnpacker::UnpackedExtension> - successful_unpacks_; - std::map<std::string, CrxInstallError> failed_unpacks_; - - private: - content::BrowserTaskEnvironment task_environment_; - TestingProfile profile_; - base::ScopedTempDir extensions_dir_; - - std::unique_ptr<content::InProcessUtilityThreadHelper> - in_process_utility_thread_helper_; - data_decoder::test::InProcessDataDecoder in_process_data_decoder_; - - std::unique_ptr<ParallelUnpacker> parallel_unpacker_; - base::OnceClosure quit_closure_; - int in_progress_count_ = 0; -}; - -TEST_F(ParallelUnpackerTest, OneGood) { - Unpack("good_package.crx"); - WaitForAllComplete(); - EXPECT_EQ(successful_unpacks_.size(), 1u); - EXPECT_EQ(failed_unpacks_.size(), 0u); -} - -TEST_F(ParallelUnpackerTest, TwoGoodInParallel) { - Unpack("good_package.crx"); - Unpack("good_l10n.crx"); - WaitForAllComplete(); - EXPECT_EQ(successful_unpacks_.size(), 2u); - EXPECT_EQ(failed_unpacks_.size(), 0u); -} - -TEST_F(ParallelUnpackerTest, OneGoodAndOneBadInParallel) { - Unpack("good_package.crx"); - Unpack("missing_default_data.crx"); - WaitForAllComplete(); - EXPECT_EQ(successful_unpacks_.size(), 1u); - EXPECT_EQ(failed_unpacks_.size(), 1u); - EXPECT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE, - failed_unpacks_.find("missing_default_data.crx")->second.type()); -} - -} // namespace extensions
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 7574e36..d726ec9 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -4235,18 +4235,18 @@ }, { "name": "tab-groups", - "owners": [ "chrome-desktop-ui-seattle@google.com", "bsep" ], - "expiry_milestone": 86 + "owners": [ "chrome-desktop-ui-seattle@google.com", "connily" ], + "expiry_milestone": 88 }, { "name": "tab-groups-collapse", "owners": [ "chrome-desktop-ui-seattle@google.com", "xialinyan" ], - "expiry_milestone": 86 + "expiry_milestone": 89 }, { "name": "tab-groups-collapse-freezing", "owners": [ "chrome-desktop-ui-seattle@google.com", "xialinyan" ], - "expiry_milestone": 87 + "expiry_milestone": 89 }, { "name": "tab-groups-feedback",
diff --git a/chrome/browser/metrics/chrome_metrics_extensions_helper.cc b/chrome/browser/metrics/chrome_metrics_extensions_helper.cc new file mode 100644 index 0000000..9baeb68 --- /dev/null +++ b/chrome/browser/metrics/chrome_metrics_extensions_helper.cc
@@ -0,0 +1,25 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/metrics/chrome_metrics_extensions_helper.h" + +#include "content/public/browser/render_process_host.h" +#include "extensions/buildflags/buildflags.h" + +#if BUILDFLAG(ENABLE_EXTENSIONS) +#include "extensions/browser/process_map.h" +#endif + +ChromeMetricsExtensionsHelper::ChromeMetricsExtensionsHelper() = default; +ChromeMetricsExtensionsHelper::~ChromeMetricsExtensionsHelper() = default; + +bool ChromeMetricsExtensionsHelper::IsExtensionProcess( + content::RenderProcessHost* render_process_host) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return extensions::ProcessMap::Get(render_process_host->GetBrowserContext()) + ->Contains(render_process_host->GetID()); +#else + return false; +#endif +}
diff --git a/chrome/browser/metrics/chrome_metrics_extensions_helper.h b/chrome/browser/metrics/chrome_metrics_extensions_helper.h new file mode 100644 index 0000000..a73ad75 --- /dev/null +++ b/chrome/browser/metrics/chrome_metrics_extensions_helper.h
@@ -0,0 +1,23 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_METRICS_CHROME_METRICS_EXTENSIONS_HELPER_H_ +#define CHROME_BROWSER_METRICS_CHROME_METRICS_EXTENSIONS_HELPER_H_ + +#include "components/metrics/content/extensions_helper.h" + +class ChromeMetricsExtensionsHelper : public metrics::ExtensionsHelper { + public: + ChromeMetricsExtensionsHelper(); + ChromeMetricsExtensionsHelper(const ChromeMetricsExtensionsHelper&) = delete; + ChromeMetricsExtensionsHelper& operator=( + const ChromeMetricsExtensionsHelper&) = delete; + ~ChromeMetricsExtensionsHelper() override; + + // metrics::ExtensionsHelper: + bool IsExtensionProcess( + content::RenderProcessHost* render_process_host) override; +}; + +#endif // CHROME_BROWSER_METRICS_CHROME_METRICS_EXTENSIONS_HELPER_H_
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc index 88df467..867b30a 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.cc +++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -42,8 +42,8 @@ #include "chrome/browser/google/google_brand.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/metrics/cached_metrics_profile.h" +#include "chrome/browser/metrics/chrome_metrics_extensions_helper.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" -#include "chrome/browser/metrics/chrome_stability_metrics_provider.h" #include "chrome/browser/metrics/desktop_platform_features_metrics_provider.h" #include "chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service_factory.h" #include "chrome/browser/metrics/https_engagement_metrics_provider.h" @@ -68,6 +68,7 @@ #include "components/history/core/browser/history_service.h" #include "components/metrics/call_stack_profile_metrics_provider.h" #include "components/metrics/component_metrics_provider.h" +#include "components/metrics/content/content_stability_metrics_provider.h" #include "components/metrics/content/gpu_metrics_provider.h" #include "components/metrics/content/rendering_perf_metrics_provider.h" #include "components/metrics/content/subprocess_metrics_provider.h" @@ -627,7 +628,8 @@ std::make_unique<OmniboxMetricsProvider>()); metrics_service_->RegisterMetricsProvider( - std::make_unique<ChromeStabilityMetricsProvider>(local_state)); + std::make_unique<metrics::ContentStabilityMetricsProvider>( + local_state, std::make_unique<ChromeMetricsExtensionsHelper>())); metrics_service_->RegisterMetricsProvider( std::make_unique<metrics::GPUMetricsProvider>());
diff --git a/chrome/browser/metrics/chrome_stability_metrics_provider.h b/chrome/browser/metrics/chrome_stability_metrics_provider.h deleted file mode 100644 index ae996e9e..0000000 --- a/chrome/browser/metrics/chrome_stability_metrics_provider.h +++ /dev/null
@@ -1,84 +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 CHROME_BROWSER_METRICS_CHROME_STABILITY_METRICS_PROVIDER_H_ -#define CHROME_BROWSER_METRICS_CHROME_STABILITY_METRICS_PROVIDER_H_ - -#include "base/gtest_prod_util.h" -#include "base/macros.h" -#include "base/scoped_observer.h" -#include "build/build_config.h" -#include "components/metrics/metrics_provider.h" -#include "components/metrics/stability_metrics_helper.h" -#include "content/public/browser/browser_child_process_observer.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" - -#if defined(OS_ANDROID) -#include "components/crash/content/browser/crash_metrics_reporter_android.h" -#endif // defined(OS_ANDROID) - -class PrefService; - -// ChromeStabilityMetricsProvider gathers and logs Chrome-specific stability- -// related metrics. -class ChromeStabilityMetricsProvider - : public metrics::MetricsProvider, - public content::BrowserChildProcessObserver, -#if defined(OS_ANDROID) - public crash_reporter::CrashMetricsReporter::Observer, -#endif - public content::NotificationObserver { - public: - explicit ChromeStabilityMetricsProvider(PrefService* local_state); - ~ChromeStabilityMetricsProvider() override; - - // metrics::MetricsDataProvider: - void OnRecordingEnabled() override; - void OnRecordingDisabled() override; - void ProvideStabilityMetrics( - metrics::SystemProfileProto* system_profile_proto) override; - void ClearSavedStabilityMetrics() override; - - private: - FRIEND_TEST_ALL_PREFIXES(ChromeStabilityMetricsProviderTest, - BrowserChildProcessObserverGpu); - FRIEND_TEST_ALL_PREFIXES(ChromeStabilityMetricsProviderTest, - BrowserChildProcessObserverUtility); - FRIEND_TEST_ALL_PREFIXES(ChromeStabilityMetricsProviderTest, - NotificationObserver); - - // content::NotificationObserver: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - - // content::BrowserChildProcessObserver: - void BrowserChildProcessCrashed( - const content::ChildProcessData& data, - const content::ChildProcessTerminationInfo& info) override; - void BrowserChildProcessLaunchedAndConnected( - const content::ChildProcessData& data) override; - -#if defined(OS_ANDROID) - // crash_reporter::CrashMetricsReporter::Observer: - void OnCrashDumpProcessed( - int rph_id, - const crash_reporter::CrashMetricsReporter::ReportedCrashTypeSet& - reported_counts) override; - - ScopedObserver<crash_reporter::CrashMetricsReporter, - crash_reporter::CrashMetricsReporter::Observer> - scoped_observer_; -#endif // defined(OS_ANDROID) - - metrics::StabilityMetricsHelper helper_; - - // Registrar for receiving stability-related notifications. - content::NotificationRegistrar registrar_; - - DISALLOW_COPY_AND_ASSIGN(ChromeStabilityMetricsProvider); -}; - -#endif // CHROME_BROWSER_METRICS_CHROME_STABILITY_METRICS_PROVIDER_H_
diff --git a/chrome/browser/metrics/chrome_stability_metrics_provider_unittest.cc b/chrome/browser/metrics/chrome_stability_metrics_provider_unittest.cc index 3bb5f9e..f6a423b 100644 --- a/chrome/browser/metrics/chrome_stability_metrics_provider_unittest.cc +++ b/chrome/browser/metrics/chrome_stability_metrics_provider_unittest.cc
@@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/metrics/chrome_stability_metrics_provider.h" +#include "components/metrics/content/content_stability_metrics_provider.h" #include "base/macros.h" #include "base/test/metrics/histogram_tester.h" #include "build/build_config.h" +#include "chrome/browser/metrics/chrome_metrics_extensions_helper.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" @@ -38,6 +39,8 @@ const char kTestGpuProcessName[] = "content_gpu"; const char kTestUtilityProcessName[] = "test_utility_process"; +} // namespace + class ChromeStabilityMetricsProviderTest : public testing::Test { protected: ChromeStabilityMetricsProviderTest() : prefs_(new TestingPrefServiceSimple) { @@ -53,11 +56,9 @@ DISALLOW_COPY_AND_ASSIGN(ChromeStabilityMetricsProviderTest); }; -} // namespace - TEST_F(ChromeStabilityMetricsProviderTest, BrowserChildProcessObserverGpu) { base::HistogramTester histogram_tester; - ChromeStabilityMetricsProvider provider(prefs()); + metrics::ContentStabilityMetricsProvider provider(prefs(), nullptr); content::ChildProcessData child_process_data(content::PROCESS_TYPE_GPU); child_process_data.metrics_name = kTestGpuProcessName; @@ -89,7 +90,7 @@ TEST_F(ChromeStabilityMetricsProviderTest, BrowserChildProcessObserverUtility) { base::HistogramTester histogram_tester; - ChromeStabilityMetricsProvider provider(prefs()); + metrics::ContentStabilityMetricsProvider provider(prefs(), nullptr); content::ChildProcessData child_process_data(content::PROCESS_TYPE_UTILITY); child_process_data.metrics_name = kTestUtilityProcessName; @@ -131,7 +132,8 @@ TEST_F(ChromeStabilityMetricsProviderTest, NotificationObserver) { base::HistogramTester histogram_tester; - ChromeStabilityMetricsProvider provider(prefs()); + metrics::ContentStabilityMetricsProvider provider( + prefs(), std::make_unique<ChromeMetricsExtensionsHelper>()); std::unique_ptr<TestingProfileManager> profile_manager( new TestingProfileManager(TestingBrowserProcess::GetGlobal())); EXPECT_TRUE(profile_manager->SetUp());
diff --git a/chrome/browser/nearby_sharing/constants.h b/chrome/browser/nearby_sharing/constants.h index 5c4bd38..3606742 100644 --- a/chrome/browser/nearby_sharing/constants.h +++ b/chrome/browser/nearby_sharing/constants.h
@@ -11,6 +11,10 @@ constexpr base::TimeDelta kReadResponseFrameTimeout = base::TimeDelta::FromSeconds(60); +// Timeout for initiating a connection to a remote device. +constexpr base::TimeDelta kInitiateNearbyConnectionTimeout = + base::TimeDelta::FromSeconds(60); + // The delay before the receiver will disconnect from the sender after rejecting // an incoming file. The sender is expected to disconnect immediately after // reading the rejection frame.
diff --git a/chrome/browser/nearby_sharing/nearby_connections_manager_impl.cc b/chrome/browser/nearby_sharing/nearby_connections_manager_impl.cc index 233550c0..ad3437db 100644 --- a/chrome/browser/nearby_sharing/nearby_connections_manager_impl.cc +++ b/chrome/browser/nearby_sharing/nearby_connections_manager_impl.cc
@@ -8,6 +8,7 @@ #include "base/strings/string_number_conversions.h" #include "base/task/post_task.h" #include "base/unguessable_token.h" +#include "chrome/browser/nearby_sharing/constants.h" #include "chrome/browser/nearby_sharing/logging/logging.h" #include "chrome/services/sharing/public/mojom/nearby_connections_types.mojom.h" #include "crypto/random.h" @@ -152,7 +153,6 @@ base::Optional<std::vector<uint8_t>> bluetooth_mac_address, DataUsage data_usage, NearbyConnectionCallback callback) { - // TOOD(crbug/1076008): Implement. if (!nearby_connections_) { std::move(callback).Run(nullptr); return; @@ -162,38 +162,43 @@ connection_lifecycle_listeners_.Add( this, lifecycle_listener.InitWithNewPipeAndPassReceiver()); + auto result = + pending_outgoing_connections_.emplace(endpoint_id, std::move(callback)); + DCHECK(result.second); + + auto timeout_timer = std::make_unique<base::OneShotTimer>(); + timeout_timer->Start( + FROM_HERE, kInitiateNearbyConnectionTimeout, + base::BindOnce(&NearbyConnectionsManagerImpl::OnConnectionTimedOut, + weak_ptr_factory_.GetWeakPtr(), endpoint_id)); + connect_timeout_timers_.emplace(endpoint_id, std::move(timeout_timer)); + // TODO(crbug/10706008): Add MediumSelector and bluetooth_mac_address. nearby_connections_->RequestConnection( endpoint_info, endpoint_id, std::move(lifecycle_listener), base::BindOnce(&NearbyConnectionsManagerImpl::OnConnectionRequested, - weak_ptr_factory_.GetWeakPtr(), endpoint_id, - std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), endpoint_id)); +} + +void NearbyConnectionsManagerImpl::OnConnectionTimedOut( + const std::string& endpoint_id) { + NS_LOG(ERROR) << "Failed to connect to the remote shareTarget: Timed out."; + Disconnect(endpoint_id); } void NearbyConnectionsManagerImpl::OnConnectionRequested( const std::string& endpoint_id, - NearbyConnectionCallback callback, ConnectionsStatus status) { + auto it = pending_outgoing_connections_.find(endpoint_id); + if (it == pending_outgoing_connections_.end()) + return; + if (status != ConnectionsStatus::kSuccess) { NS_LOG(ERROR) << "Failed to connect to the remote shareTarget: " << status; - nearby_connections_->DisconnectFromEndpoint( - endpoint_id, - base::BindOnce( - [](const std::string& endpoint_id, ConnectionsStatus status) { - NS_LOG(VERBOSE) - << __func__ << ": Disconnecting from endpoint " << endpoint_id - << " attempted over Nearby Connections with result " - << status; - }, - endpoint_id)); - std::move(callback).Run(nullptr); + Disconnect(endpoint_id); return; } - auto result = - pending_outgoing_connections_.emplace(endpoint_id, std::move(callback)); - DCHECK(result.second); - // TODO(crbug/1111458): Support TransferManager. } @@ -450,6 +455,7 @@ DCHECK(result.second); std::move(it->second).Run(result.first->second.get()); pending_outgoing_connections_.erase(it); + connect_timeout_timers_.erase(endpoint_id); } } @@ -462,6 +468,7 @@ if (it != pending_outgoing_connections_.end()) { std::move(it->second).Run(nullptr); pending_outgoing_connections_.erase(it); + connect_timeout_timers_.erase(endpoint_id); } // TODO(crbug/1111458): Support TransferManager. @@ -475,6 +482,7 @@ if (it != pending_outgoing_connections_.end()) { std::move(it->second).Run(nullptr); pending_outgoing_connections_.erase(it); + connect_timeout_timers_.erase(endpoint_id); } connections_.erase(endpoint_id); @@ -562,7 +570,6 @@ } nearby_connections_ = nullptr; discovered_endpoints_.clear(); - pending_outgoing_connections_.clear(); payload_status_listeners_.clear(); ClearIncomingPayloads(); connections_.clear(); @@ -570,4 +577,10 @@ discovery_listener_ = nullptr; incoming_connection_listener_ = nullptr; endpoint_discovery_listener_.reset(); + connect_timeout_timers_.clear(); + + for (auto& entry : pending_outgoing_connections_) + std::move(entry.second).Run(/*connection=*/nullptr); + + pending_outgoing_connections_.clear(); }
diff --git a/chrome/browser/nearby_sharing/nearby_connections_manager_impl.h b/chrome/browser/nearby_sharing/nearby_connections_manager_impl.h index 7ecd1b7..0348d6b 100644 --- a/chrome/browser/nearby_sharing/nearby_connections_manager_impl.h +++ b/chrome/browser/nearby_sharing/nearby_connections_manager_impl.h
@@ -12,6 +12,7 @@ #include "base/files/file.h" #include "base/gtest_prod_util.h" #include "base/memory/weak_ptr.h" +#include "base/timer/timer.h" #include "chrome/browser/nearby_sharing/nearby_connection_impl.h" #include "chrome/browser/nearby_sharing/nearby_file_handler.h" #include "chrome/browser/nearby_sharing/nearby_process_manager.h" @@ -122,8 +123,8 @@ void OnPayloadTransferUpdate(const std::string& endpoint_id, PayloadTransferUpdatePtr update) override; + void OnConnectionTimedOut(const std::string& endpoint_id); void OnConnectionRequested(const std::string& endpoint_id, - NearbyConnectionCallback callback, ConnectionsStatus status); bool BindNearbyConnections(); void Reset(); @@ -146,6 +147,9 @@ // A map of endpoint_id to NearbyConnection. base::flat_map<std::string, std::unique_ptr<NearbyConnectionImpl>> connections_; + // A map of endpoint_id to timers that timeout a connection request. + base::flat_map<std::string, std::unique_ptr<base::OneShotTimer>> + connect_timeout_timers_; // A map of payload_id to PayloadStatusListener*. base::flat_map<int64_t, PayloadStatusListener*> payload_status_listeners_; // A map of payload_id to PayloadPtr.
diff --git a/chrome/browser/nearby_sharing/nearby_connections_manager_impl_unittest.cc b/chrome/browser/nearby_sharing/nearby_connections_manager_impl_unittest.cc index 005898b..95945f8 100644 --- a/chrome/browser/nearby_sharing/nearby_connections_manager_impl_unittest.cc +++ b/chrome/browser/nearby_sharing/nearby_connections_manager_impl_unittest.cc
@@ -11,6 +11,7 @@ #include "base/run_loop.h" #include "base/test/bind_test_util.h" #include "base/test/mock_callback.h" +#include "chrome/browser/nearby_sharing/constants.h" #include "chrome/browser/nearby_sharing/mock_nearby_connections.h" #include "chrome/browser/nearby_sharing/mock_nearby_process_manager.h" #include "chrome/browser/nearby_sharing/nearby_connection_impl.h" @@ -339,7 +340,8 @@ run_loop.Run(); } - content::BrowserTaskEnvironment task_environment_; + content::BrowserTaskEnvironment task_environment_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; TestingProfile profile_; std::unique_ptr<net::test::MockNetworkChangeNotifier> network_notifier_ = net::test::MockNetworkChangeNotifier::Create(); @@ -803,6 +805,60 @@ cancel_run_loop.Run(); } +TEST_F(NearbyConnectionsManagerImplTest, ConnectTimeout) { + mojo::Remote<EndpointDiscoveryListener> discovery_listener_remote; + testing::NiceMock<MockDiscoveryListener> discovery_listener; + StartDiscovery(discovery_listener_remote, discovery_listener); + + // RequestConnection will time out. + const std::vector<uint8_t> local_endpoint_info(std::begin(kEndpointInfo), + std::end(kEndpointInfo)); + + mojo::Remote<ConnectionLifecycleListener> connection_listener_remote; + NearbyConnectionsMojom::RequestConnectionCallback connect_callback; + EXPECT_CALL(nearby_connections_, RequestConnection) + .WillOnce( + [&](const std::vector<uint8_t>& endpoint_info, + const std::string& endpoint_id, + mojo::PendingRemote<ConnectionLifecycleListener> listener, + NearbyConnectionsMojom::RequestConnectionCallback callback) { + EXPECT_EQ(local_endpoint_info, endpoint_info); + EXPECT_EQ(kRemoteEndpointId, endpoint_id); + + connection_listener_remote.Bind(std::move(listener)); + // Do not call callback until connection timed out. + connect_callback = std::move(callback); + }); + + // Timing out should call disconnect. + EXPECT_CALL(nearby_connections_, DisconnectFromEndpoint) + .WillOnce( + [&](const std::string& endpoint_id, + NearbyConnectionsMojom::DisconnectFromEndpointCallback callback) { + EXPECT_EQ(kRemoteEndpointId, endpoint_id); + std::move(callback).Run(Status::kSuccess); + }); + + base::RunLoop run_loop; + NearbyConnection* nearby_connection = nullptr; + nearby_connections_manager_.Connect( + local_endpoint_info, kRemoteEndpointId, + /*bluetooth_mac_address=*/base::nullopt, DataUsage::kOffline, + base::BindLambdaForTesting([&](NearbyConnection* connection) { + nearby_connection = connection; + run_loop.Quit(); + })); + // Simulate time passing until timeout is reached. + task_environment_.FastForwardBy(kInitiateNearbyConnectionTimeout); + run_loop.Run(); + + // Expect callback to be called with null connection. + EXPECT_FALSE(nearby_connection); + + // Resolving the connect callback after timeout should do nothing. + std::move(connect_callback).Run(Status::kSuccess); +} + TEST_F(NearbyConnectionsManagerImplTest, StartAdvertising) { mojo::Remote<ConnectionLifecycleListener> connection_listener_remote; testing::NiceMock<MockIncomingConnectionListener>
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc index ea7b9ee..2db699f 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
@@ -767,7 +767,6 @@ NS_LOG(VERBOSE) << __func__ << ": Nearby sharing disabled!"; StopAdvertising(); StopScanning(); - // TODO(crbug/1085067): Stop discovery. nearby_connections_manager_->Shutdown(); } InvalidateSurfaceState(); @@ -1520,7 +1519,6 @@ settings_.GetDataUsage(), share_target); // TODO(crbug.com/1111458): Add preferred transfer type. - // TODO(crbug.com/1085067): Add timeout nearby_connections_manager_->Connect( std::move(endpoint_info), *info->endpoint_id(), std::move(bluetooth_mac_address), adjusted_data_usage,
diff --git a/chrome/browser/net/cookie_policy_browsertest.cc b/chrome/browser/net/cookie_policy_browsertest.cc index de6dc9d..f780fba 100644 --- a/chrome/browser/net/cookie_policy_browsertest.cc +++ b/chrome/browser/net/cookie_policy_browsertest.cc
@@ -62,8 +62,11 @@ } void SetBlockThirdPartyCookies(bool value) { - browser()->profile()->GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, - value); + browser()->profile()->GetPrefs()->SetInteger( + prefs::kCookieControlsMode, + static_cast<int>( + value ? content_settings::CookieControlsMode::kBlockThirdParty + : content_settings::CookieControlsMode::kOff)); } void NavigateToPageWithFrame(const std::string& host) {
diff --git a/chrome/browser/net/network_context_configuration_browsertest.cc b/chrome/browser/net/network_context_configuration_browsertest.cc index ef22656..1968782c 100644 --- a/chrome/browser/net/network_context_configuration_browsertest.cc +++ b/chrome/browser/net/network_context_configuration_browsertest.cc
@@ -795,8 +795,12 @@ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); net::test_server::RegisterDefaultHandlers(&https_server); ASSERT_TRUE(https_server.Start()); - if (GetPrefService()->FindPreference(prefs::kBlockThirdPartyCookies)) - GetPrefService()->SetBoolean(prefs::kBlockThirdPartyCookies, true); + if (GetPrefService()->FindPreference(prefs::kCookieControlsMode)) { + GetPrefService()->SetInteger( + prefs::kCookieControlsMode, + static_cast<int>( + content_settings::CookieControlsMode::kBlockThirdParty)); + } SetCookie(CookieType::kFirstParty, CookiePersistenceType::kPersistent, embedded_test_server()); @@ -849,7 +853,9 @@ test_server.RegisterRequestHandler(base::BindRepeating(&EchoCookieHeader)); ASSERT_TRUE(test_server.Start()); - GetPrefService()->SetBoolean(prefs::kBlockThirdPartyCookies, true); + GetPrefService()->SetInteger( + prefs::kCookieControlsMode, + static_cast<int>(content_settings::CookieControlsMode::kBlockThirdParty)); SetCookie(CookieType::kFirstParty, CookiePersistenceType::kPersistent, embedded_test_server()); @@ -1565,7 +1571,9 @@ if (system) return; - GetPrefService()->SetBoolean(prefs::kBlockThirdPartyCookies, true); + GetPrefService()->SetInteger( + prefs::kCookieControlsMode, + static_cast<int>(content_settings::CookieControlsMode::kBlockThirdParty)); SetCookie(CookieType::kThirdParty, CookiePersistenceType::kSession, https_server()); @@ -1584,33 +1592,19 @@ if (system) return; - // The preference is expected to be reset in incognito mode. - if (is_incognito()) { - EXPECT_FALSE(GetPrefService()->GetBoolean(prefs::kBlockThirdPartyCookies)); - EXPECT_EQ( - static_cast<int>(content_settings::CookieControlsMode::kIncognitoOnly), - GetPrefService()->GetInteger(prefs::kCookieControlsMode)); - return; - } - - // For regular sessions, the kBlockThirdpartyCookies preference gets migrated - // to kCookieControlsMode. Reset it so it doesn't interfere with the test. + // The third-party cookies pref should carry over to the next session. EXPECT_EQ( static_cast<int>(content_settings::CookieControlsMode::kBlockThirdParty), GetPrefService()->GetInteger(prefs::kCookieControlsMode)); - GetPrefService()->SetInteger( - prefs::kCookieControlsMode, - static_cast<int>(content_settings::CookieControlsMode::kIncognitoOnly)); - - // The kBlockThirdPartyCookies pref should carry over to the next session. - EXPECT_TRUE(GetPrefService()->GetBoolean(prefs::kBlockThirdPartyCookies)); SetCookie(CookieType::kThirdParty, CookiePersistenceType::kSession, https_server()); EXPECT_TRUE(GetCookies(https_server()->base_url()).empty()); // Set pref to false, third party cookies should be allowed now. - GetPrefService()->SetBoolean(prefs::kBlockThirdPartyCookies, false); + GetPrefService()->SetInteger( + prefs::kCookieControlsMode, + static_cast<int>(content_settings::CookieControlsMode::kOff)); // Set a third-party cookie. It should actually get set this time. SetCookie(CookieType::kThirdParty, CookiePersistenceType::kSession, https_server());
diff --git a/chrome/browser/net/referrer_policy_policy_browsertest.cc b/chrome/browser/net/referrer_policy_policy_browsertest.cc index 1c6a4af..28f4694 100644 --- a/chrome/browser/net/referrer_policy_policy_browsertest.cc +++ b/chrome/browser/net/referrer_policy_policy_browsertest.cc
@@ -12,10 +12,10 @@ #include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_types.h" #include "components/policy/policy_constants.h" -#include "content/public/common/referrer.h" #include "content/public/test/browser_test.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" namespace policy { @@ -37,7 +37,7 @@ IN_PROC_BROWSER_TEST_F(ForceLegacyDefaultReferrerPolicy, UpdatesDynamically) { // When the policy's unset, we shouldn't be forcing the legacy default // referrer policy. - EXPECT_FALSE(content::Referrer::ShouldForceLegacyDefaultReferrerPolicy()); + EXPECT_FALSE(blink::ReferrerUtils::ShouldForceLegacyDefaultReferrerPolicy()); policy::PolicyMap values; values.Set(key::kForceLegacyDefaultReferrerPolicy, POLICY_LEVEL_RECOMMENDED, @@ -46,7 +46,7 @@ policy_provider_.UpdateChromePolicy(values); base::RunLoop().RunUntilIdle(); // When the policy's true, we should have flipped the global to true. - EXPECT_TRUE(content::Referrer::ShouldForceLegacyDefaultReferrerPolicy()); + EXPECT_TRUE(blink::ReferrerUtils::ShouldForceLegacyDefaultReferrerPolicy()); values.Set(key::kForceLegacyDefaultReferrerPolicy, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, base::Value(false), @@ -54,7 +54,7 @@ policy_provider_.UpdateChromePolicy(values); base::RunLoop().RunUntilIdle(); // When the policy's false, we should have flipped the global back to false. - EXPECT_FALSE(content::Referrer::ShouldForceLegacyDefaultReferrerPolicy()); + EXPECT_FALSE(blink::ReferrerUtils::ShouldForceLegacyDefaultReferrerPolicy()); } } // namespace policy
diff --git a/chrome/browser/net/referrer_policy_policy_handler.cc b/chrome/browser/net/referrer_policy_policy_handler.cc index 0ee95754..1ba71d2 100644 --- a/chrome/browser/net/referrer_policy_policy_handler.cc +++ b/chrome/browser/net/referrer_policy_policy_handler.cc
@@ -8,7 +8,7 @@ #include "components/policy/core/common/policy_map.h" #include "components/policy/policy_constants.h" #include "components/prefs/pref_value_map.h" -#include "content/public/common/referrer.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" namespace policy { @@ -24,7 +24,7 @@ policies.GetValue(key::kForceLegacyDefaultReferrerPolicy); if (value) { DCHECK(value->is_bool()); - content::Referrer::SetForceLegacyDefaultReferrerPolicy(value->GetBool()); + blink::ReferrerUtils::SetForceLegacyDefaultReferrerPolicy(value->GetBool()); } }
diff --git a/chrome/browser/net/referrer_policy_policy_handler_unittest.cc b/chrome/browser/net/referrer_policy_policy_handler_unittest.cc index 6003561..812268e9 100644 --- a/chrome/browser/net/referrer_policy_policy_handler_unittest.cc +++ b/chrome/browser/net/referrer_policy_policy_handler_unittest.cc
@@ -13,8 +13,8 @@ #include "components/policy/core/common/policy_types.h" #include "components/policy/policy_constants.h" #include "components/prefs/pref_value_map.h" -#include "content/public/common/referrer.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" namespace policy { @@ -69,13 +69,13 @@ SetPolicyValue(key::kForceLegacyDefaultReferrerPolicy, base::Value(true)); CheckAndApplyPolicySettings(); - EXPECT_TRUE(content::Referrer::ShouldForceLegacyDefaultReferrerPolicy()); + EXPECT_TRUE(blink::ReferrerUtils::ShouldForceLegacyDefaultReferrerPolicy()); } TEST_F(ReferrerPolicyPolicyHandlerTest, ValueFalse) { SetPolicyValue(key::kForceLegacyDefaultReferrerPolicy, base::Value(false)); CheckAndApplyPolicySettings(); - EXPECT_FALSE(content::Referrer::ShouldForceLegacyDefaultReferrerPolicy()); + EXPECT_FALSE(blink::ReferrerUtils::ShouldForceLegacyDefaultReferrerPolicy()); } } // namespace policy
diff --git a/chrome/browser/offline_pages/background_loader_offliner_unittest.cc b/chrome/browser/offline_pages/background_loader_offliner_unittest.cc index c866fb13..6b3cedbfb 100644 --- a/chrome/browser/offline_pages/background_loader_offliner_unittest.cc +++ b/chrome/browser/offline_pages/background_loader_offliner_unittest.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/previews/previews_ui_tab_helper.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_profile.h" +#include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/common/pref_names.h" #include "components/offline_pages/content/background_loader/background_loader_contents_stub.h" #include "components/offline_pages/core/background/load_termination_listener.h" @@ -373,7 +374,9 @@ SavePageRequest request(kRequestId, HttpUrl(), custom_tabs_client_id, creation_time, kUserRequested); - profile()->GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, true); + profile()->GetPrefs()->SetInteger( + prefs::kCookieControlsMode, + static_cast<int>(content_settings::CookieControlsMode::kBlockThirdParty)); EXPECT_FALSE(offliner()->LoadAndSave(request, completion_callback(), progress_callback())); }
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc index 0a9ef7e..ae6a89d2 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc
@@ -258,9 +258,11 @@ navigation_handle->GetReloadType() != content::ReloadType::NONE; aggregate_frame_data_->UpdateForNavigation( - navigation_handle->GetRenderFrameHost(), true /* frame_navigated */); + navigation_handle->GetRenderFrameHost(), true /* frame_navigated */, + true /* record_frame_metrics */); main_frame_data_->UpdateForNavigation(navigation_handle->GetRenderFrameHost(), - true /* frame_navigated */); + true /* frame_navigated */, + true /* record_frame_metrics */); // The main frame is never considered an ad. ad_frames_data_[navigation_handle->GetFrameTreeNodeId()] = @@ -397,7 +399,8 @@ if (should_create_new_frame_data) { if (previous_data) { - previous_data->UpdateForNavigation(ad_host, frame_navigated); + previous_data->UpdateForNavigation(ad_host, frame_navigated, + true /* record_frame_metrics */); return; } if (base::FeatureList::IsEnabled(features::kV8PerAdFrameMemoryMonitoring) && @@ -418,7 +421,8 @@ heavy_ad_threshold_noise_provider_->GetNetworkThresholdNoiseForFrame()); ad_data_iterator = --ad_frames_data_storage_.end(); ad_data = &*ad_data_iterator; - ad_data->UpdateForNavigation(ad_host, frame_navigated); + ad_data->UpdateForNavigation(ad_host, frame_navigated, + true /* record_frame_metrics */); } // Maybe update frame depth based on the new ad frames distance to the ad @@ -461,6 +465,34 @@ content::RenderFrameHost* frame_host = FindFrameMaybeUnsafe(navigation_handle); + // We want to reset the FrameData for an ad after heavy ads fires, so that we + // can trigger on subsequent navigations if the page tries to serve another ad + // in the frame. + if (navigation_handle->IsErrorPage() && + navigation_handle->GetNetErrorCode() == net::ERR_BLOCKED_BY_CLIENT && + navigation_handle->HasCommitted()) { + const auto& id_and_data = ad_frames_data_.find(frame_tree_node_id); + if (id_and_data != ad_frames_data_.end() && + id_and_data->second != ad_frames_data_storage_.end() && + id_and_data->second->heavy_ad_status_with_policy() != + FrameData::HeavyAdStatus::kNone) { + RecordPerFrameHistograms(*id_and_data->second); + id_and_data->second->RecordAdFrameLoadUkmEvent( + GetDelegate().GetPageUkmSourceId()); + ad_frames_data_storage_.erase(id_and_data->second); + ad_frames_data_.erase(id_and_data); + ad_frames_data_storage_.emplace_back( + frame_tree_node_id, heavy_ad_threshold_noise_provider_ + ->GetNetworkThresholdNoiseForFrame()); + auto ad_data_iterator = --ad_frames_data_storage_.end(); + FrameData* ad_data = &*ad_data_iterator; + ad_frames_data_[frame_tree_node_id] = ad_data_iterator; + ad_data->UpdateForNavigation(frame_host, true /*frame_navigated=*/, + false /*record_frame_metrics=*/); + return; + } + } + bool is_adframe = client->GetThrottleManager()->IsFrameTaggedAsAd(frame_host); // TODO(https://crbug.com): The following block is a hack to ignore certain
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc index 72f4cce..92d0b9e 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc
@@ -1672,15 +1672,31 @@ EXPECT_EQ(4u, console_observer.messages().size()); } +class NoHostThresholdHeavyAdsBrowserTest + : public AdsPageLoadMetricsObserverResourceBrowserTest { + public: + NoHostThresholdHeavyAdsBrowserTest() { + scoped_feature_list_.InitAndEnableFeatureWithParameters( + features::kHeavyAdPrivacyMitigations, {{"host-threshold", "100"}}); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + // Verifies that the frame is navigated to the intervention page when a // heavy ad intervention triggers. -IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest, +IN_PROC_BROWSER_TEST_F(NoHostThresholdHeavyAdsBrowserTest, HeavyAdInterventionEnabled_ErrorPageLoaded) { base::HistogramTester histogram_tester; auto incomplete_resource_response = std::make_unique<net::test_server::ControllableHttpResponse>( embedded_test_server(), "/ads_observer/incomplete_resource.js", true /*relative_url_is_prefix*/); + auto incomplete_resource_response2 = + std::make_unique<net::test_server::ControllableHttpResponse>( + embedded_test_server(), "/ads_observer/incomplete_resource2.js", + true /*relative_url_is_prefix*/); ASSERT_TRUE(embedded_test_server()->Start()); // Create a navigation observer that will watch for the intervention to @@ -1690,7 +1706,6 @@ content::TestNavigationObserver error_observer(web_contents, net::ERR_BLOCKED_BY_CLIENT); - auto waiter = CreateAdsPageLoadMetricsTestWaiter(); GURL url = embedded_test_server()->GetURL( "/ads_observer/ad_with_incomplete_resource.html"); ui_test_utils::NavigateToURL(browser(), url); @@ -1712,6 +1727,26 @@ histogram_tester.ExpectBucketCount( "Blink.UseCounter.Features", blink::mojom::WebFeature::kHeavyAdIntervention, 1); + + content::TestNavigationObserver error_observer2(web_contents, + net::ERR_BLOCKED_BY_CLIENT); + + // Test that subsequent navigations to the error page can still trigger heavy + // ads (crbug.com/1099014). + EXPECT_TRUE(content::ExecJs(web_contents, "advanceSrcdoc();", + content::EXECUTE_SCRIPT_NO_USER_GESTURE)); + + // Load a resource large enough to trigger the intervention. + LoadLargeResource(incomplete_resource_response2.get(), + kMaxHeavyAdNetworkSize); + + error_observer2.WaitForNavigationFinished(); + + // We can't check whether the navigation didn't occur because the error page + // load is not synchronous. Instead check that we didn't log intervention UMA + // that is always recorded when the intervention occurs. Both + // interventions should have been logged. + histogram_tester.ExpectTotalCount(kHeavyAdInterventionTypeHistogramId, 2); } class AdsPageLoadMetricsObserverResourceBrowserTestWithoutHeavyAdIntervention
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.cc index 80c3f35..b1306f22 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.cc
@@ -84,8 +84,10 @@ FrameData::~FrameData() = default; void FrameData::UpdateForNavigation(content::RenderFrameHost* render_frame_host, - bool frame_navigated) { + bool frame_navigated, + bool record_metrics) { frame_navigated_ = frame_navigated; + record_metrics_ = record_metrics; if (!render_frame_host) return; @@ -267,7 +269,7 @@ } bool FrameData::ShouldRecordFrameForMetrics() const { - return bytes() != 0 || !GetTotalCpuUsage().is_zero(); + return record_metrics_ && (bytes() != 0 || !GetTotalCpuUsage().is_zero()); } void FrameData::RecordAdFrameLoadUkmEvent(ukm::SourceId source_id) const {
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.h b/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.h index 9a1cb71..7aea0bb 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.h +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.h
@@ -156,7 +156,8 @@ // Update the metadata of this frame if it is being navigated. void UpdateForNavigation(content::RenderFrameHost* render_frame_host, - bool frame_navigated); + bool frame_navigated, + bool record_frame_metrics); // Updates the number of bytes loaded in the frame given a resource load. void ProcessResourceLoadInFrame( @@ -405,6 +406,12 @@ // Number of bytes of noise that should be added to the network threshold. const int heavy_ad_network_threshold_noise_; + // |record_metrics| indicates whether metrics should be logged for this frame. + // This may be false in cases where we are tracking a frame, but do not want + // to log metrics until a subsequent navigation, e.g. if a frame is currently + // navigated to the heavy ads error page. + bool record_metrics_ = true; + DISALLOW_COPY_AND_ASSIGN(FrameData); };
diff --git a/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/PaintPreviewDemoManager.java b/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/PaintPreviewDemoManager.java index b365b0dd..989d99b9 100644 --- a/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/PaintPreviewDemoManager.java +++ b/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/PaintPreviewDemoManager.java
@@ -55,7 +55,7 @@ PaintPreviewDemoManager.this::removePaintPreviewDemo, PaintPreviewDemoManager.this::addPlayerView, null, null, ChromeColors.getPrimaryBackgroundColor(mTab.getContext().getResources(), false), - () -> { + (status) -> { Toast.makeText(mTab.getContext(), R.string.paint_preview_demo_playback_failure, Toast.LENGTH_LONG)
diff --git a/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewMetricsHelper.java b/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewMetricsHelper.java index 473bfd4..7438063 100644 --- a/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewMetricsHelper.java +++ b/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewMetricsHelper.java
@@ -10,6 +10,7 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.components.paintpreview.player.CompositorStatus; import java.util.HashMap; import java.util.Map; @@ -77,6 +78,12 @@ "Browser.PaintPreview.TabbedPlayer.FirstPaintBeforeTabLoad", mFirstPaintHappened); } + void onCompositorFailure(@CompositorStatus int status) { + RecordHistogram.recordEnumeratedHistogram( + "Browser.PaintPreview.TabbedPlayer.CompositorFailureReason", status, + CompositorStatus.COUNT); + } + void recordExitMetrics(int exitCause, int snackbarShownCount) { if (exitCause == ExitCause.SNACK_BAR_ACTION) { RecordUserAction.record("PaintPreview.TabbedPlayer.Actionbar.Action");
diff --git a/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewPlayer.java b/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewPlayer.java index 7d39334..d548365 100644 --- a/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewPlayer.java +++ b/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewPlayer.java
@@ -161,7 +161,10 @@ () -> mMetricsHelper.onFirstPaint(activityCreationTimestampMs, wasBackgrounded), () -> mHasUserInteraction = true, ChromeColors.getPrimaryBackgroundColor(mTab.getContext().getResources(), false), - () -> removePaintPreview(ExitCause.COMPOSITOR_FAILURE), + (status) -> { + mMetricsHelper.onCompositorFailure(status); + removePaintPreview(ExitCause.COMPOSITOR_FAILURE); + }, /*ignoreInitialScrollOffset=*/false); mPlayerManager.setUserFrustrationCallback(this::showSnackbar); mOnDismissed = onDismissed;
diff --git a/chrome/browser/password_check/android/password_check_manager.h b/chrome/browser/password_check/android/password_check_manager.h index e841406..c6f4c5d 100644 --- a/chrome/browser/password_check/android/password_check_manager.h +++ b/chrome/browser/password_check/android/password_check_manager.h
@@ -228,8 +228,8 @@ // Used to obtain the list of compromised credentials. password_manager::CompromisedCredentialsManager - compromised_credentials_manager_{password_store_, - &saved_passwords_presenter_}; + compromised_credentials_manager_{&saved_passwords_presenter_, + password_store_}; // Adapter used to start, monitor and stop a bulk leak check. password_manager::BulkLeakCheckServiceAdapter
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 771f7fda..6f40e48 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -238,9 +238,6 @@ { key::kAllowDeletingBrowserHistory, prefs::kAllowDeletingBrowserHistory, base::Value::Type::BOOLEAN }, - { key::kBlockThirdPartyCookies, - prefs::kBlockThirdPartyCookies, - base::Value::Type::BOOLEAN }, { key::kAdsSettingForIntrusiveAdsSites, prefs::kManagedDefaultAdsSetting, base::Value::Type::INTEGER },
diff --git a/chrome/browser/prerender/prerender_unittest.cc b/chrome/browser/prerender/prerender_unittest.cc index 778ff68f..5f96d01 100644 --- a/chrome/browser/prerender/prerender_unittest.cc +++ b/chrome/browser/prerender/prerender_unittest.cc
@@ -34,6 +34,7 @@ #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" +#include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/common/pref_names.h" #include "components/prefs/pref_service.h" #include "components/prerender/browser/prerender_contents.h" @@ -503,7 +504,9 @@ GURL url("http://www.google.com/"); ASSERT_TRUE(IsNoStatePrefetchEnabled()); - profile()->GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, true); + profile()->GetPrefs()->SetInteger( + prefs::kCookieControlsMode, + static_cast<int>(content_settings::CookieControlsMode::kBlockThirdParty)); EXPECT_FALSE(AddSimplePrerender(url)); histogram_tester().ExpectUniqueSample( "Prerender.FinalStatus", FINAL_STATUS_BLOCK_THIRD_PARTY_COOKIES, 1);
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.cc b/chrome/browser/push_messaging/push_messaging_service_impl.cc index b080bde..d5d6b534 100644 --- a/chrome/browser/push_messaging/push_messaging_service_impl.cc +++ b/chrome/browser/push_messaging/push_messaging_service_impl.cc
@@ -31,6 +31,7 @@ #include "chrome/browser/push_messaging/push_messaging_constants.h" #include "chrome/browser/push_messaging/push_messaging_features.h" #include "chrome/browser/push_messaging/push_messaging_service_factory.h" +#include "chrome/browser/push_messaging/push_messaging_utils.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/common/buildflags.h" #include "chrome/common/chrome_features.h" @@ -181,13 +182,6 @@ return web_contents ? web_contents->GetMainFrame() : nullptr; } -bool IsVapidKey(const std::string& application_server_key) { - // VAPID keys are NIST P-256 public keys in uncompressed format (64 bytes), - // verified through its length and the 0x04 prefix. - return application_server_key.size() == 65 && - application_server_key[0] == 0x04; -} - } // namespace // static @@ -730,7 +724,7 @@ // TODO(peter): Move this check to the renderer process & Mojo message // validation once the flag is always enabled, and remove the // |render_process_id| and |render_frame_id| parameters from this method. - if (!IsVapidKey(application_server_key_string)) { + if (!push_messaging::IsVapidKey(application_server_key_string)) { content::RenderFrameHost* render_frame_host = content::RenderFrameHost::FromID(render_process_id, render_frame_id); content::RenderFrameHost* main_frame = @@ -769,13 +763,14 @@ GetInstanceIDDriver() ->GetInstanceID(app_identifier.app_id()) - ->GetToken(NormalizeSenderInfo(application_server_key_string), kGCMScope, - ttl, std::map<std::string, std::string>() /* options */, - {} /* flags */, - base::BindOnce(&PushMessagingServiceImpl::DidSubscribe, - weak_factory_.GetWeakPtr(), app_identifier, - application_server_key_string, - std::move(register_callback))); + ->GetToken( + push_messaging::NormalizeSenderInfo(application_server_key_string), + kGCMScope, ttl, std::map<std::string, std::string>() /* options */, + {} /* flags */, + base::BindOnce(&PushMessagingServiceImpl::DidSubscribe, + weak_factory_.GetWeakPtr(), app_identifier, + application_server_key_string, + std::move(register_callback))); } void PushMessagingServiceImpl::SubscribeEnd( @@ -813,7 +808,7 @@ switch (result) { case InstanceID::SUCCESS: { - const GURL endpoint = CreateEndpoint(subscription_id); + const GURL endpoint = push_messaging::CreateEndpoint(subscription_id); // Make sure that this subscription has associated encryption keys prior // to returning it to the developer - they'll need this information in @@ -888,7 +883,7 @@ return; } - const GURL endpoint = CreateEndpoint(subscription_id); + const GURL endpoint = push_messaging::CreateEndpoint(subscription_id); const std::string& app_id = app_identifier.app_id(); base::Optional<base::Time> expiration_time = app_identifier.expiration_time(); @@ -899,12 +894,12 @@ if (PushMessagingAppIdentifier::UseInstanceID(app_id)) { GetInstanceIDDriver()->GetInstanceID(app_id)->ValidateToken( - NormalizeSenderInfo(sender_id), kGCMScope, subscription_id, - std::move(validate_cb)); + push_messaging::NormalizeSenderInfo(sender_id), kGCMScope, + subscription_id, std::move(validate_cb)); } else { GetGCMDriver()->ValidateRegistration( - app_id, {NormalizeSenderInfo(sender_id)}, subscription_id, - std::move(validate_cb)); + app_id, {push_messaging::NormalizeSenderInfo(sender_id)}, + subscription_id, std::move(validate_cb)); } } @@ -1041,9 +1036,9 @@ if (sender_id.empty()) { std::move(unregister_callback).Run(gcm::GCMClient::INVALID_PARAMETER); } else { - GetGCMDriver()->UnregisterWithSenderId(app_id, - NormalizeSenderInfo(sender_id), - std::move(unregister_callback)); + GetGCMDriver()->UnregisterWithSenderId( + app_id, push_messaging::NormalizeSenderInfo(sender_id), + std::move(unregister_callback)); } #else GetGCMDriver()->Unregister(app_id, std::move(unregister_callback)); @@ -1263,15 +1258,10 @@ std::move(callback).Run(nullptr /* subscription */); return; } - // Currently |user_visible_only| is always true, once silent pushes are - // enabled, get this information from SW database. - auto options = blink::mojom::PushSubscriptionOptions::New(); - options->user_visible_only = true; - options->application_server_key = - std::vector<uint8_t>(sender_id.begin(), sender_id.end()); std::move(callback).Run(blink::mojom::PushSubscription::New( - endpoint, expiration_time, std::move(options), p256dh, auth)); + endpoint, expiration_time, push_messaging::MakeOptions(sender_id), p256dh, + auth)); } void PushMessagingServiceImpl::FirePushSubscriptionChange( @@ -1353,19 +1343,6 @@ remove_expired_subscriptions_callback_for_testing_ = std::move(closure); } -std::string PushMessagingServiceImpl::NormalizeSenderInfo( - const std::string& application_server_key) const { - if (!IsVapidKey(application_server_key)) - return application_server_key; - - std::string encoded_application_server_key; - base::Base64UrlEncode(application_server_key, - base::Base64UrlEncodePolicy::OMIT_PADDING, - &encoded_application_server_key); - - return encoded_application_server_key; -} - // Assumes user_visible always since this is just meant to check // if the permission was previously granted and not revoked. bool PushMessagingServiceImpl::IsPermissionSet(const GURL& origin) { @@ -1379,19 +1356,12 @@ gcm::GCMEncryptionProvider::EncryptionInfoCallback callback) { if (PushMessagingAppIdentifier::UseInstanceID(app_id)) { GetInstanceIDDriver()->GetInstanceID(app_id)->GetEncryptionInfo( - NormalizeSenderInfo(sender_id), std::move(callback)); + push_messaging::NormalizeSenderInfo(sender_id), std::move(callback)); } else { GetGCMDriver()->GetEncryptionInfo(app_id, std::move(callback)); } } -GURL PushMessagingServiceImpl::CreateEndpoint( - const std::string& subscription_id) const { - const GURL endpoint(kPushMessagingGcmEndpoint + subscription_id); - DCHECK(endpoint.is_valid()); - return endpoint; -} - gcm::GCMDriver* PushMessagingServiceImpl::GetGCMDriver() const { gcm::GCMProfileService* gcm_profile_service = gcm::GCMProfileServiceFactory::GetForProfile(profile_);
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.h b/chrome/browser/push_messaging/push_messaging_service_impl.h index 6ae77b77..f25de1b 100644 --- a/chrome/browser/push_messaging/push_messaging_service_impl.h +++ b/chrome/browser/push_messaging/push_messaging_service_impl.h
@@ -299,11 +299,6 @@ const PushMessagingAppIdentifier& app_identifier, blink::mojom::PushEventStatus status); - // Normalizes the |sender_info|. In most cases the |sender_info| will be - // passed through to the GCM Driver as-is, but NIST P-256 application server - // keys have to be encoded using the URL-safe variant of the base64 encoding. - std::string NormalizeSenderInfo(const std::string& sender_info) const; - // Checks if a given origin is allowed to use Push. bool IsPermissionSet(const GURL& origin); @@ -313,10 +308,6 @@ const std::string& sender_id, gcm::GCMEncryptionProvider::EncryptionInfoCallback callback); - // Returns the URL used to send push messages to the subscription identified - // by |subscription_id|. - GURL CreateEndpoint(const std::string& subscription_id) const; - gcm::GCMDriver* GetGCMDriver() const; instance_id::InstanceIDDriver* GetInstanceIDDriver() const;
diff --git a/chrome/browser/push_messaging/push_messaging_service_unittest.cc b/chrome/browser/push_messaging/push_messaging_service_unittest.cc index f0c6c3d..11f1487 100644 --- a/chrome/browser/push_messaging/push_messaging_service_unittest.cc +++ b/chrome/browser/push_messaging/push_messaging_service_unittest.cc
@@ -24,6 +24,7 @@ #include "chrome/browser/push_messaging/push_messaging_features.h" #include "chrome/browser/push_messaging/push_messaging_service_factory.h" #include "chrome/browser/push_messaging/push_messaging_service_impl.h" +#include "chrome/browser/push_messaging/push_messaging_utils.h" #include "chrome/test/base/testing_profile.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/gcm_driver/crypto/gcm_crypto_test_helpers.h" @@ -301,15 +302,15 @@ // NIST P-256 public keys in uncompressed format will be encoded using the // URL-safe base64 encoding by the normalization function. - EXPECT_EQ(kTestEncodedP256Key, push_service->NormalizeSenderInfo(p256dh)); + EXPECT_EQ(kTestEncodedP256Key, push_messaging::NormalizeSenderInfo(p256dh)); // Any other value, binary or not, will be passed through as-is. - EXPECT_EQ("1234567890", push_service->NormalizeSenderInfo("1234567890")); - EXPECT_EQ("foo@bar.com", push_service->NormalizeSenderInfo("foo@bar.com")); + EXPECT_EQ("1234567890", push_messaging::NormalizeSenderInfo("1234567890")); + EXPECT_EQ("foo@bar.com", push_messaging::NormalizeSenderInfo("foo@bar.com")); p256dh[0] = 0x05; // invalidate |p256dh| as a public key. - EXPECT_EQ(p256dh, push_service->NormalizeSenderInfo(p256dh)); + EXPECT_EQ(p256dh, push_messaging::NormalizeSenderInfo(p256dh)); } TEST_F(PushMessagingServiceTest, RemoveExpiredSubscriptions) {
diff --git a/chrome/browser/push_messaging/push_messaging_utils.cc b/chrome/browser/push_messaging/push_messaging_utils.cc new file mode 100644 index 0000000..b54bf14 --- /dev/null +++ b/chrome/browser/push_messaging/push_messaging_utils.cc
@@ -0,0 +1,44 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/push_messaging/push_messaging_utils.h" +#include "base/base64url.h" +#include "chrome/browser/push_messaging/push_messaging_constants.h" +#include "url/gurl.h" + +namespace push_messaging { + +GURL CreateEndpoint(const std::string& subscription_id) { + const GURL endpoint(kPushMessagingGcmEndpoint + subscription_id); + DCHECK(endpoint.is_valid()); + return endpoint; +} + +blink::mojom::PushSubscriptionOptionsPtr MakeOptions( + const std::string& sender_id) { + return blink::mojom::PushSubscriptionOptions::New( + /*user_visible_only=*/true, + std::vector<uint8_t>(sender_id.begin(), sender_id.end())); +} + +bool IsVapidKey(const std::string& application_server_key) { + // VAPID keys are NIST P-256 public keys in uncompressed format (64 bytes), + // verified through its length and the 0x04 prefix. + return application_server_key.size() == 65 && + application_server_key[0] == 0x04; +} + +std::string NormalizeSenderInfo(const std::string& application_server_key) { + if (!IsVapidKey(application_server_key)) + return application_server_key; + + std::string encoded_application_server_key; + base::Base64UrlEncode(application_server_key, + base::Base64UrlEncodePolicy::OMIT_PADDING, + &encoded_application_server_key); + + return encoded_application_server_key; +} + +} // namespace push_messaging
diff --git a/chrome/browser/push_messaging/push_messaging_utils.h b/chrome/browser/push_messaging/push_messaging_utils.h new file mode 100644 index 0000000..805deeab --- /dev/null +++ b/chrome/browser/push_messaging/push_messaging_utils.h
@@ -0,0 +1,34 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PUSH_MESSAGING_PUSH_MESSAGING_UTILS_H_ +#define CHROME_BROWSER_PUSH_MESSAGING_PUSH_MESSAGING_UTILS_H_ + +#include <string> +#include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom.h" + +class GURL; + +namespace push_messaging { + +// Returns the URL used to send push messages to the subscription identified +// by |subscription_id|. +GURL CreateEndpoint(const std::string& subscription_id); + +// Checks size and prefix to determine whether it is a VAPID key +bool IsVapidKey(const std::string& application_server_key); + +// Normalizes the |sender_info|. In most cases the |sender_info| will be +// passed through to the GCM Driver as-is, but NIST P-256 application server +// keys have to be encoded using the URL-safe variant of the base64 encoding. +std::string NormalizeSenderInfo(const std::string& sender_info); + +// Currently |user_visible_only| is always true, once silent pushes are +// enabled, get this information from SW database. +blink::mojom::PushSubscriptionOptionsPtr MakeOptions( + const std::string& sender_id); + +} // namespace push_messaging + +#endif // CHROME_BROWSER_PUSH_MESSAGING_PUSH_MESSAGING_UTILS_H_
diff --git a/chrome/browser/referrer_policy_browsertest.cc b/chrome/browser/referrer_policy_browsertest.cc index 4bcd8e0..f364e47 100644 --- a/chrome/browser/referrer_policy_browsertest.cc +++ b/chrome/browser/referrer_policy_browsertest.cc
@@ -41,6 +41,7 @@ #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/common/input/web_mouse_event.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "ui/base/page_transition_types.h" #include "ui/base/window_open_disposition.h" @@ -736,7 +737,7 @@ // These tests assume a default policy of no-referrer-when-downgrade. struct ReferrerOverrideParams { base::Optional<base::Feature> feature_to_enable; - // If true, calls content::Referrer::SetForceLegacyDefaultReferrerPolicy() + // If true, calls blink::ReferrerUtils::SetForceLegacyDefaultReferrerPolicy() // to pin the default policy to no-referrer-when-downgrade. bool force_no_referrer_when_downgrade_default; network::mojom::ReferrerPolicy baseline_policy; @@ -832,7 +833,7 @@ ReferrerOverrideTest() { if (GetParam().feature_to_enable) scoped_feature_list_.InitAndEnableFeature(*GetParam().feature_to_enable); - content::Referrer::SetForceLegacyDefaultReferrerPolicy( + blink::ReferrerUtils::SetForceLegacyDefaultReferrerPolicy( GetParam().force_no_referrer_when_downgrade_default); }
diff --git a/chrome/browser/renderer_context_menu/mock_render_view_context_menu.cc b/chrome/browser/renderer_context_menu/mock_render_view_context_menu.cc index 7b4531d..c69a9e7e 100644 --- a/chrome/browser/renderer_context_menu/mock_render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/mock_render_view_context_menu.cc
@@ -63,25 +63,17 @@ void MockRenderViewContextMenu::AddMenuItemWithIcon( int command_id, const base::string16& title, - const gfx::ImageSkia& image) { + const ui::ImageModel& icon) { MockMenuItem item; item.command_id = command_id; item.enabled = observer_->IsCommandIdEnabled(command_id); item.checked = false; item.hidden = false; item.title = title; - item.icon = gfx::Image(image); + item.icon = icon; items_.push_back(item); } -void MockRenderViewContextMenu::AddMenuItemWithIcon( - int command_id, - const base::string16& title, - const gfx::VectorIcon& icon) { - AddMenuItemWithIcon(command_id, title, - gfx::CreateVectorIcon(icon, gfx::kPlaceholderColor)); -} - void MockRenderViewContextMenu::AddCheckItem(int command_id, const base::string16& title) { MockMenuItem item; @@ -120,29 +112,19 @@ int command_id, int message_id, ui::MenuModel* model, - const gfx::ImageSkia& image) { + const ui::ImageModel& icon) { MockMenuItem item; item.command_id = command_id; item.enabled = observer_->IsCommandIdEnabled(command_id); item.checked = observer_->IsCommandIdChecked(command_id); item.hidden = false; item.title = l10n_util::GetStringUTF16(message_id); - item.icon = gfx::Image(image); + item.icon = icon; items_.push_back(item); AppendSubMenuItems(model); } -void MockRenderViewContextMenu::AddSubMenuWithStringIdAndIcon( - int command_id, - int message_id, - ui::MenuModel* model, - const gfx::VectorIcon& icon) { - AddSubMenuWithStringIdAndIcon( - command_id, message_id, model, - gfx::CreateVectorIcon(icon, gfx::kPlaceholderColor)); -} - void MockRenderViewContextMenu::AppendSubMenuItems(ui::MenuModel* model) { // Add items in the submenu |model| to |items_| so that the items can be // updated later via the RenderViewContextMenuProxy interface. @@ -180,10 +162,10 @@ } void MockRenderViewContextMenu::UpdateMenuIcon(int command_id, - const gfx::Image& image) { + const ui::ImageModel& icon) { for (auto& item : items_) { if (item.command_id == command_id) { - item.icon = image; + item.icon = icon; return; } }
diff --git a/chrome/browser/renderer_context_menu/mock_render_view_context_menu.h b/chrome/browser/renderer_context_menu/mock_render_view_context_menu.h index 43b6bf1..3cb10dd 100644 --- a/chrome/browser/renderer_context_menu/mock_render_view_context_menu.h +++ b/chrome/browser/renderer_context_menu/mock_render_view_context_menu.h
@@ -12,8 +12,8 @@ #include "base/macros.h" #include "base/strings/string16.h" #include "components/renderer_context_menu/render_view_context_menu_proxy.h" +#include "ui/base/models/image_model.h" #include "ui/base/models/simple_menu_model.h" -#include "ui/gfx/image/image.h" class PrefService; class Profile; @@ -39,7 +39,7 @@ bool checked; bool hidden; base::string16 title; - gfx::Image icon; + ui::ImageModel icon; }; explicit MockRenderViewContextMenu(bool incognito); @@ -54,10 +54,7 @@ void AddMenuItem(int command_id, const base::string16& title) override; void AddMenuItemWithIcon(int command_id, const base::string16& title, - const gfx::ImageSkia& image) override; - void AddMenuItemWithIcon(int command_id, - const base::string16& title, - const gfx::VectorIcon& icon) override; + const ui::ImageModel& icon) override; void AddCheckItem(int command_id, const base::string16& title) override; void AddSeparator() override; void AddSubMenu(int command_id, @@ -66,16 +63,12 @@ void AddSubMenuWithStringIdAndIcon(int command_id, int message_id, ui::MenuModel* model, - const gfx::ImageSkia& image) override; - void AddSubMenuWithStringIdAndIcon(int command_id, - int message_id, - ui::MenuModel* model, - const gfx::VectorIcon& icon) override; + const ui::ImageModel& icon) override; void UpdateMenuItem(int command_id, bool enabled, bool hidden, const base::string16& title) override; - void UpdateMenuIcon(int command_id, const gfx::Image& image) override; + void UpdateMenuIcon(int command_id, const ui::ImageModel& icon) override; void RemoveMenuItem(int command_id) override; void RemoveAdjacentSeparators() override; void AddSpellCheckServiceItem(bool is_checked) override;
diff --git a/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc b/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc index 049270b..03c6b11 100644 --- a/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc +++ b/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc
@@ -28,6 +28,8 @@ #include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/models/image_model.h" +#include "ui/base/models/simple_menu_model.h" #include "ui/gfx/text_constants.h" #include "ui/gfx/text_elider.h" @@ -113,8 +115,10 @@ // TODO(llin): Update the menu item after finalizing on the design. auto truncated_text = TruncateString(selected_text); #if BUILDFLAG(GOOGLE_CHROME_BRANDING) - proxy_->AddMenuItemWithIcon(IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_QUERY, - truncated_text, kAssistantIcon); + proxy_->AddMenuItemWithIcon( + IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_QUERY, truncated_text, + ui::ImageModel::FromVectorIcon(kAssistantIcon, /*color_id=*/-1, + ui::SimpleMenuModel::kDefaultIconSize)); #else proxy_->AddMenuItem(IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_QUERY, truncated_text);
diff --git a/chrome/browser/resources/chromeos/multidevice_internals/log_object.html b/chrome/browser/resources/chromeos/multidevice_internals/log_object.html index 92bef1d..c69d641 100644 --- a/chrome/browser/resources/chromeos/multidevice_internals/log_object.html +++ b/chrome/browser/resources/chromeos/multidevice_internals/log_object.html
@@ -39,6 +39,6 @@ <div id="item-metadata"> <span>[[item.time]]</span> <div id="flex"></div> - <span>[[item.file]]:[[item.line]]</span> + <span>[[getFilenameWithLine_(item.file, item.line)]]</span> </div> </div>
diff --git a/chrome/browser/resources/chromeos/multidevice_internals/log_object.js b/chrome/browser/resources/chromeos/multidevice_internals/log_object.js index e2f3ef32..cca7169 100644 --- a/chrome/browser/resources/chromeos/multidevice_internals/log_object.js +++ b/chrome/browser/resources/chromeos/multidevice_internals/log_object.js
@@ -42,4 +42,18 @@ break; } }, + + /** + * @return {string} + * @private + */ + getFilenameWithLine_() { + if (!this.item) { + return ''; + } + + // The filename is prefixed with "../../", so replace it with "//". + let filename = this.item.file.replace('../../', '//'); + return filename + ':' + this.item.line; + }, });
diff --git a/chrome/browser/resources/chromeos/multidevice_internals/logging_tab.js b/chrome/browser/resources/chromeos/multidevice_internals/logging_tab.js index 41eb864..5e3ef60e 100644 --- a/chrome/browser/resources/chromeos/multidevice_internals/logging_tab.js +++ b/chrome/browser/resources/chromeos/multidevice_internals/logging_tab.js
@@ -39,7 +39,7 @@ // Reduce the file path to just the file name for logging simplification. const file = log.file.substring(log.file.lastIndexOf('/') + 1); - return `[${log.time} ${severity} ${file} (${log.line})] ${log.text}`; + return `[${log.time} ${severity} ${file} (${log.line})] ${log.text}\n`; } Polymer({ @@ -124,7 +124,9 @@ * @return {!Array<string>} */ getSerializedLogStrings_() { - return this.logList_.map(logToSavedString_); + // Reverse the logs so that the oldest logs appear first and the newest logs + // appear last. + return this.logList_.map(logToSavedString_).reverse(); }, /**
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn index 0453afe..b16515c9 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn
@@ -12,6 +12,7 @@ ":multidevice_feature_behavior", ":multidevice_feature_item", ":multidevice_feature_toggle", + ":multidevice_notification_access_setup_dialog", ":multidevice_page", ":multidevice_smartlock_subpage", ":multidevice_subpage", @@ -62,6 +63,7 @@ ":multidevice_browser_proxy", ":multidevice_constants", ":multidevice_feature_behavior", + ":multidevice_notification_access_setup_dialog", "..:metrics_recorder", "..:os_route", "../..:router", @@ -74,6 +76,13 @@ externs_list = [ "$externs_path/pending_polymer.js" ] } +js_library("multidevice_notification_access_setup_dialog") { + deps = [ + "//ui/webui/resources/js:i18n_behavior", + "//ui/webui/resources/js:web_ui_listener_behavior", + ] +} + js_library("multidevice_radio_button") { deps = [ "//third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted", @@ -91,8 +100,8 @@ "..:os_settings_routes", "../../prefs:prefs_behavior", "//ui/webui/resources/cr_elements/cr_radio_button:cr_radio_button", - "//ui/webui/resources/js:web_ui_listener_behavior", "//ui/webui/resources/js:cr", + "//ui/webui/resources/js:web_ui_listener_behavior", ] } @@ -130,6 +139,7 @@ ":multidevice_feature_behavior.m", ":multidevice_feature_item.m", ":multidevice_feature_toggle.m", + ":multidevice_notification_access_setup_dialog.m", ":multidevice_page.m", ":multidevice_radio_button.m", ":multidevice_smartlock_subpage.m", @@ -140,7 +150,7 @@ js_library("multidevice_browser_proxy.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.m.js" ] - deps = [ + deps = [ ":multidevice_constants.m", "//ui/webui/resources/js:cr.m", ] @@ -157,8 +167,8 @@ sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_behavior.m.js" ] deps = [ ":multidevice_constants.m", - "//ui/webui/resources/js:i18n_behavior.m", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:i18n_behavior.m", ] extra_deps = [ ":modulize" ] } @@ -193,19 +203,29 @@ ":multidevice_browser_proxy.m", ":multidevice_constants.m", ":multidevice_feature_behavior.m", + ":multidevice_notification_access_setup_dialog.m", "..:metrics_recorder.m", "..:os_route.m", "../..:router.m", "../../controls:password_prompt_dialog.m", "../../prefs:prefs_behavior.m", "../localized_link:localized_link.m", - "//ui/webui/resources/js:web_ui_listener_behavior.m", - "//ui/webui/resources/js:assert.m", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":multidevice_page_module" ] } +js_library("multidevice_notification_access_setup_dialog.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.m.js" ] + deps = [ + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", + ] + extra_deps = [ ":multidevice_notification_access_setup_dialog_module" ] +} + js_library("multidevice_radio_button.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.m.js" ] deps = [ @@ -225,9 +245,9 @@ "..:os_route.m", "..:os_settings_routes.m", "../../prefs:prefs_behavior.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_radio_button:cr_radio_button.m", "//ui/webui/resources/js:web_ui_listener_behavior.m", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] extra_deps = [ ":multidevice_smartlock_subpage_module" ] externs_list = [ "$externs_path/quick_unlock_private.js" ] @@ -240,12 +260,10 @@ ":multidevice_constants.m", "..:os_route.m", "..:os_settings_routes.m", - "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior.m", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior.m", ] - extra_deps = [ - ":multidevice_subpage_module" - ] + extra_deps = [ ":multidevice_subpage_module" ] } js_library("multidevice_tether_item.m") { @@ -254,10 +272,10 @@ ":multidevice_feature_behavior.m", "..:os_route.m", "..:os_settings_routes.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider.m", "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior.m", "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] extra_deps = [ ":multidevice_tether_item_module" ] } @@ -267,6 +285,7 @@ ":modulize", ":multidevice_feature_item_module", ":multidevice_feature_toggle_module", + ":multidevice_notification_access_setup_dialog_module", ":multidevice_page_module", ":multidevice_radio_button_module", ":multidevice_smartlock_subpage_module", @@ -299,10 +318,20 @@ html_type = "dom-module" migrated_imports = os_settings_migrated_imports namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports + [ - "ui/webui/resources/html/polymer.html|Polymer,html,beforeNextRender", - "ui/webui/resources/html/assert.html|assert", - ] + auto_imports = + os_settings_auto_imports + [ + "ui/webui/resources/html/polymer.html|Polymer,html,beforeNextRender", + "ui/webui/resources/html/assert.html|assert", + ] +} + +polymer_modulizer("multidevice_notification_access_setup_dialog") { + js_file = "multidevice_notification_access_setup_dialog.js" + html_file = "multidevice_notification_access_setup_dialog.html" + html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("multidevice_radio_button") {
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.js index 8fdf6c39..e14da02 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.js
@@ -74,6 +74,16 @@ * @return {!Promise<!settings.AndroidSmsInfo>} Android SMS Info */ getAndroidSmsInfo() {} + + /** + * Attempts the phone hub notification access setup flow. + */ + attemptNotificationSetup() {} + + /** + * Cancels the phone hub notification access setup flow. + */ + cancelNotificationSetup() {} } /** @@ -130,6 +140,16 @@ getAndroidSmsInfo() { return cr.sendWithPromise('getAndroidSmsInfo'); } + + /** @override */ + attemptNotificationSetup() { + chrome.send('attemptNotificationSetup'); + } + + /** @override */ + cancelNotificationSetup() { + chrome.send('cancelNotificationSetup'); + } } cr.addSingletonGetter(MultiDeviceBrowserProxyImpl);
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.js index 7d396700a..be53a8f1c 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.js
@@ -89,7 +89,8 @@ * phoneHubNotificationsState: !settings.MultiDeviceFeatureState, * phoneHubNotificationBadgeState: !settings.MultiDeviceFeatureState, * phoneHubTaskContinuationState: !settings.MultiDeviceFeatureState, - * isAndroidSmsPairingComplete: boolean + * isAndroidSmsPairingComplete: boolean, + * isNotificationAccessGranted: boolean * }} */ /* #export */ let MultiDevicePageContentData;
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html new file mode 100644 index 0000000..a65dd3d --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html
@@ -0,0 +1,48 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/html/assert.html"> +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> +<link rel="import" href="multidevice_browser_proxy.html"> +<link rel="import" href="../../settings_shared_css.html"> + +<dom-module id="settings-multidevice-notification-access-setup-dialog"> + <template> + <style include="cr-shared-style settings-shared"> + cr-dialog::part(dialog) { + width: 320px; + } + + div[slot='body'] { + height: 100px; + } + </style> + <cr-dialog id="dialog" close-text="$i18n{close}"> + <div id="dialogTitle" slot="title">[[title_]]</div> + <div id="dialogBody" slot="body">[[description_]]</div> + <div id="buttonContainer" slot="button-container"> + <template is="dom-if" if="[[showCancelButton_(setupState_)]]" restamp> + <cr-button id="cancelButton" class="cancel-button" + on-click="onCancelClicked_"> + $i18n{cancel} + </cr-button> + </template> + <template is="dom-if" if="[[showOkButton_(setupState_)]]" restamp> + <cr-button id="okButton" on-click="onOkayButtonClicked_"> + $i18n{ok} + </cr-button> + </template> + <template is="dom-if" if="[[!setupState_]]" restamp> + <cr-button id="confirmButton" class="action-button" + on-click="onConfirmButtonClicked_"> + $i18n{confirm} + </cr-button> + </template> + </div> + </cr-dialog> + </template> + <script src="multidevice_notification_access_setup_dialog.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.js new file mode 100644 index 0000000..c2d0b8d --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.js
@@ -0,0 +1,151 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview + * This element provides the Phone Hub notification access setup flow that, when + * successfully completed, enables the feature that allows a user's phone + * notifications to be mirrored on their Chromebook. + */ + +/** + * Numerical values should not be changed because they must stay in sync with + * notification_access_setup_operation.h, with the exception of NOT_STARTED. + * @enum{number} + */ +/* #export */ const NotificationAccessSetupOperationStatus = { + NOT_STARTED: 0, + CONNECTING: 1, + TIMED_OUT_CONNECTING: 2, + CONNECTION_DISCONNECTED: 3, + SENT_MESSAGE_TO_PHONE_AND_WAITING_FOR_RESPONSE: 4, + COMPLETED_SUCCESSFULLY: 5, +}; + +Polymer({ + is: 'settings-multidevice-notification-access-setup-dialog', + + behaviors: [ + I18nBehavior, + WebUIListenerBehavior, + ], + + properties: { + /** @private {NotificationAccessSetupOperationStatus} */ + setupState_: { + type: Number, + value: NotificationAccessSetupOperationStatus.NOT_STARTED, + }, + + /** @private */ + title_: { + type: String, + computed: 'getTitle_(setupState_)', + }, + + /** @private */ + description_: { + type: String, + computed: 'getDescription_(setupState_)', + } + }, + + /** @private {?settings.MultiDeviceBrowserProxy} */ + browserProxy_: null, + + /** @override */ + ready() { + this.browserProxy_ = settings.MultiDeviceBrowserProxyImpl.getInstance(); + }, + + /** @override */ + attached() { + this.addWebUIListener( + 'settings.onNotificationAccessSetupStatusChanged', + this.onSetupStateChanged_.bind(this)); + this.$.dialog.showModal(); + }, + + /** + * @param {!NotificationAccessSetupOperationStatus} setupState + * @private + */ + onSetupStateChanged_(setupState) { + this.setupState_ = setupState; + }, + + /** @private */ + showCancelButton_() { + return this.setupState_ === + NotificationAccessSetupOperationStatus.NOT_STARTED || + this.setupState_ === + NotificationAccessSetupOperationStatus.CONNECTING || + this.setupState_ === + NotificationAccessSetupOperationStatus + .SENT_MESSAGE_TO_PHONE_AND_WAITING_FOR_RESPONSE; + }, + + /** @private */ + showOkButton_() { + return this.setupState_ === + NotificationAccessSetupOperationStatus.COMPLETED_SUCCESSFULLY; + }, + + /** @private */ + onConfirmButtonClicked_() { + this.browserProxy_.attemptNotificationSetup(); + }, + + /** @private */ + onCancelClicked_() { + this.browserProxy_.cancelNotificationSetup(); + this.$.dialog.close(); + }, + + /** @private */ + onOkayButtonClicked_() { + this.$.dialog.close(); + }, + + /** + * @return {string} The title of the dialog. + * @private + */ + getTitle_() { + const Status = NotificationAccessSetupOperationStatus; + switch (this.setupState_) { + case Status.NOT_STARTED: + return this.i18n('multideviceNotificationAccessSetupAckTitle'); + case Status.CONNECTING: + case Status.SENT_MESSAGE_TO_PHONE_AND_WAITING_FOR_RESPONSE: + return this.i18n('multideviceNotificationAccessSetupConnectingTitle'); + case Status.COMPLETED_SUCCESSFULLY: + return this.i18n('multideviceNotificationAccessSetupCompletedTitle'); + case Status.TIMED_OUT_CONNECTING: + case Status.CONNECTION_DISCONNECTED: + default: + return ''; + } + }, + + /** + * @return {string} The body text of the dialog. + * @private + */ + getDescription_() { + const Status = NotificationAccessSetupOperationStatus; + switch (this.setupState_) { + case Status.NOT_STARTED: + case Status.CONNECTING: + case Status.SENT_MESSAGE_TO_PHONE_AND_WAITING_FOR_RESPONSE: + return this.i18n('multideviceNotificationAccessSetupInstructions'); + case Status.COMPLETED_SUCCESSFULLY: + return this.i18n('multideviceNotificationAccessSetupCompletedSummary'); + case Status.TIMED_OUT_CONNECTING: + case Status.CONNECTION_DISCONNECTED: + default: + return ''; + } + }, +});
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.html index a3c918c..dbc0995d 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.html
@@ -23,6 +23,7 @@ <link rel="import" href="multidevice_constants.html"> <link rel="import" href="multidevice_feature_behavior.html"> <link rel="import" href="multidevice_feature_toggle.html"> +<link rel="import" href="multidevice_notification_access_setup_dialog.html"> <link rel="import" href="multidevice_smartlock_subpage.html"> <link rel="import" href="multidevice_subpage.html"> @@ -165,6 +166,11 @@ on-token-obtained="onTokenObtained_"> </settings-password-prompt-dialog> </template> + <template is="dom-if" if="[[showNotificationAccessSetupDialog_]]" restamp> + <settings-multidevice-notification-access-setup-dialog + on-close="onHideNotificationSetupAccessDialog_"> + </settings-multidevice-notification-access-setup-dialog> + </template> </template> <script src="multidevice_page.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js index a45d3727..3b43aac7 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js
@@ -62,6 +62,12 @@ value: false, }, + /** @private {boolean} */ + showNotificationAccessSetupDialog_: { + type: Boolean, + value: false, + }, + /** * The value of the Nearby Share feature flag which controls if the * Nearby Share settings and subpage are accessible. @@ -309,19 +315,27 @@ const feature = event.detail.feature; const enabled = event.detail.enabled; - // Disabling any feature does not require authentication, and enable some - // features does not require authentication. - if (!enabled || !this.isAuthenticationRequiredToEnable_(feature)) { - this.browserProxy_.setFeatureEnabledState(feature, enabled); - settings.recordSettingChange(); - return; - } - // If the feature required authentication to be enabled, open the password // prompt dialog. This is required every time the user enables a security- // sensitive feature (i.e., use of stale auth tokens is not acceptable). - this.featureToBeEnabledOnceAuthenticated_ = feature; - this.openPasswordPromptDialog_(); + if (enabled && this.isAuthenticationRequiredToEnable_(feature)) { + this.featureToBeEnabledOnceAuthenticated_ = feature; + this.openPasswordPromptDialog_(); + return; + } + + // If the feature to enable is Phone Hub Notifications, notification access + // must have been granted before the feature can be enabled. + if (feature === settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS && + enabled && !this.pageContentData.isNotificationAccessGranted) { + this.showNotificationAccessSetupDialog_ = true; + return; + } + + // Disabling any feature does not require authentication, and enable some + // features does not require authentication. + this.browserProxy_.setFeatureEnabledState(feature, enabled); + settings.recordSettingChange(); }, /** @@ -436,4 +450,9 @@ settings.Router.getInstance().navigateTo(settings.routes.NEARBY_SHARE); } }, + + /** @private */ + onHideNotificationSetupAccessDialog_() { + this.showNotificationAccessSetupDialog_ = false; + }, });
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp b/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp index 21ac725..b972b63 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp +++ b/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp
@@ -503,6 +503,11 @@ use_base_dir="false" compress="false" type="BINDATA" /> + <include name="IDR_OS_SETTINGS_MULTIDEVICE_NOTIFICATIONS_ACCESS_SETUP_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> <include name="IDR_OS_SETTINGS_MULTIDEVICE_SUBPAGE_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.m.js" use_base_dir="false"
diff --git a/chrome/browser/resources/settings/os_settings_resources.grd b/chrome/browser/resources/settings/os_settings_resources.grd index 1c5b05f..9d581f57 100644 --- a/chrome/browser/resources/settings/os_settings_resources.grd +++ b/chrome/browser/resources/settings/os_settings_resources.grd
@@ -1274,6 +1274,12 @@ <structure name="IDR_OS_SETTINGS_MULTIDEVICE_PAGE_JS" file="chromeos/multidevice_page/multidevice_page.js" compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_MULTIDEVICE_NOTIFICATIONS_ACCESS_SETUP_DIALOG_HTML" + file="chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_MULTIDEVICE_NOTIFICATIONS_ACCESS_SETUP_DIALOG_JS" + file="chromeos/multidevice_page/multidevice_notification_access_setup_dialog.js" + compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_MULTIDEVICE_RADIO_BUTTON_HTML" file="chromeos/multidevice_page/multidevice_radio_button.html" compress="false" type="chrome_html" />
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer.cc b/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer.cc index 425ead96..cbb4790 100644 --- a/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer.cc +++ b/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer.cc
@@ -15,8 +15,8 @@ #include "chrome/browser/sharing/sharing_constants.h" #include "chrome/grit/generated_resources.h" #include "components/sync_device_info/device_info.h" -#include "components/vector_icons/vector_icons.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/models/image_model.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/paint_vector_icon.h" @@ -78,7 +78,9 @@ l10n_util::GetStringFUTF16( IDS_CONTENT_CONTEXT_SHARING_CLICK_TO_CALL_SINGLE_DEVICE, base::UTF8ToUTF16(devices_[0]->client_name())), - vector_icons::kCallIcon); + ui::ImageModel::FromVectorIcon(controller_->GetVectorIcon(), + /*color_id=*/-1, + ui::SimpleMenuModel::kDefaultIconSize)); #endif } else { BuildSubMenu(); @@ -92,7 +94,10 @@ proxy_->AddSubMenuWithStringIdAndIcon( IDC_CONTENT_CONTEXT_SHARING_CLICK_TO_CALL_MULTIPLE_DEVICES, IDS_CONTENT_CONTEXT_SHARING_CLICK_TO_CALL_MULTIPLE_DEVICES, - sub_menu_model_.get(), vector_icons::kCallIcon); + sub_menu_model_.get(), + ui::ImageModel::FromVectorIcon(controller_->GetVectorIcon(), + /*color_id=*/-1, + ui::SimpleMenuModel::kDefaultIconSize)); #endif } }
diff --git a/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer.cc b/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer.cc index c1428c70..dc5fffe 100644 --- a/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer.cc +++ b/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer.cc
@@ -15,6 +15,7 @@ #include "chrome/grit/generated_resources.h" #include "components/sync_device_info/device_info.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/models/image_model.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/paint_vector_icon.h" @@ -73,7 +74,9 @@ l10n_util::GetStringFUTF16( IDS_CONTENT_CONTEXT_SHARING_SHARED_CLIPBOARD_SINGLE_DEVICE, base::UTF8ToUTF16(devices_[0]->client_name())), - controller_->GetVectorIcon()); + ui::ImageModel::FromVectorIcon(controller_->GetVectorIcon(), + /*color_id=*/-1, + ui::SimpleMenuModel::kDefaultIconSize)); #endif } else { BuildSubMenu(); @@ -87,7 +90,10 @@ proxy_->AddSubMenuWithStringIdAndIcon( IDC_CONTENT_CONTEXT_SHARING_SHARED_CLIPBOARD_MULTIPLE_DEVICES, IDS_CONTENT_CONTEXT_SHARING_SHARED_CLIPBOARD_MULTIPLE_DEVICES, - sub_menu_model_.get(), controller_->GetVectorIcon()); + sub_menu_model_.get(), + ui::ImageModel::FromVectorIcon(controller_->GetVectorIcon(), + /*color_id=*/-1, + ui::SimpleMenuModel::kDefaultIconSize)); #endif } }
diff --git a/chrome/browser/signin/dice_web_signin_interceptor.cc b/chrome/browser/signin/dice_web_signin_interceptor.cc index 1902261..9972a78e 100644 --- a/chrome/browser/signin/dice_web_signin_interceptor.cc +++ b/chrome/browser/signin/dice_web_signin_interceptor.cc
@@ -8,6 +8,7 @@ #include "base/check.h" #include "base/i18n/case_conversion.h" +#include "base/metrics/histogram_functions.h" #include "base/optional.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" @@ -33,6 +34,11 @@ namespace { +void RecordSigninInterceptionHeuristicOutcome( + SigninInterceptionHeuristicOutcome outcome) { + base::UmaHistogramEnumeration("Signin.Intercept.HeuristicOutcome", outcome); +} + bool IsProfileCreationAllowed() { PrefService* service = g_browser_process->local_state(); DCHECK(service); @@ -93,16 +99,27 @@ if (!base::FeatureList::IsEnabled(kDiceWebSigninInterceptionFeature)) return; - // Do not intercept signins from the Sync startup flow. Note: |is_sync_signin| - // is an approximation, and in rare cases it may be true when in fact the - // signin was not a sync signin. In this case the interception is missed. - if (is_sync_signin) + if (is_sync_signin) { + // Do not intercept signins from the Sync startup flow. + // Note: |is_sync_signin| is an approximation, and in rare cases it may be + // true when in fact the signin was not a sync signin. In this case the + // interception is missed. + RecordSigninInterceptionHeuristicOutcome( + SigninInterceptionHeuristicOutcome::kAbortSyncSignin); return; - - if (is_interception_in_progress_) - return; // Multiple concurrent interceptions are not supported. - if (!is_new_account) - return; // Do not intercept reauth. + } + if (is_interception_in_progress_) { + // Multiple concurrent interceptions are not supported. + RecordSigninInterceptionHeuristicOutcome( + SigninInterceptionHeuristicOutcome::kAbortInterceptInProgress); + return; + } + if (!is_new_account) { + // Do not intercept reauth. + RecordSigninInterceptionHeuristicOutcome( + SigninInterceptionHeuristicOutcome::kAbortAccountNotNew); + return; + } account_id_ = account_id; is_interception_in_progress_ = true; @@ -124,23 +141,34 @@ web_contents, bubble_parameters, base::BindOnce(&DiceWebSigninInterceptor::OnProfileSwitchChoice, base::Unretained(this))); - + was_interception_ui_displayed_ = true; + RecordSigninInterceptionHeuristicOutcome( + SigninInterceptionHeuristicOutcome::kInterceptProfileSwitch); return; } - if (identity_manager_->GetAccountsWithRefreshTokens().size() <= 1u || - !IsProfileCreationAllowed()) { + if (identity_manager_->GetAccountsWithRefreshTokens().size() <= 1u) { // Enterprise and multi-user bubbles are only shown if there are multiple - // accounts and profile creation is allowed. + // accounts. + RecordSigninInterceptionHeuristicOutcome( + SigninInterceptionHeuristicOutcome::kAbortSingleAccount); + Reset(); + return; + } + if (!IsProfileCreationAllowed()) { + RecordSigninInterceptionHeuristicOutcome( + SigninInterceptionHeuristicOutcome::kAbortProfileCreationDisallowed); Reset(); return; } + account_info_fetch_start_time_ = base::TimeTicks::Now(); if (account_info->IsValid()) { OnExtendedAccountInfoUpdated(*account_info); } else { on_account_info_update_timeout_.Reset(base::BindOnce( - &DiceWebSigninInterceptor::Reset, base::Unretained(this))); + &DiceWebSigninInterceptor::OnExtendedAccountInfoFetchTimeout, + base::Unretained(this))); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, on_account_info_update_timeout_.callback(), base::TimeDelta::FromSeconds(5)); @@ -161,6 +189,10 @@ } void DiceWebSigninInterceptor::Shutdown() { + if (is_interception_in_progress_ && !was_interception_ui_displayed_) { + RecordSigninInterceptionHeuristicOutcome( + SigninInterceptionHeuristicOutcome::kAbortShutdown); + } Reset(); } @@ -171,6 +203,9 @@ is_interception_in_progress_ = false; account_id_ = CoreAccountId(); dice_signed_in_profile_creator_.reset(); + was_interception_ui_displayed_ = false; + account_info_fetch_start_time_ = base::TimeTicks(); + profile_creation_start_time_ = base::TimeTicks(); } bool DiceWebSigninInterceptor::ShouldShowProfileSwitchBubble( @@ -243,6 +278,9 @@ account_info_update_observer_.RemoveAll(); on_account_info_update_timeout_.Cancel(); + base::UmaHistogramTimes( + "Signin.Intercept.AccountInfoFetchDuration", + base::TimeTicks::Now() - account_info_fetch_start_time_); base::Optional<SigninInterceptionType> interception_type; @@ -253,6 +291,8 @@ if (!interception_type) { // Signin should not be intercepted. + RecordSigninInterceptionHeuristicOutcome( + SigninInterceptionHeuristicOutcome::kAbortAccountInfoNotCompatible); Reset(); return; } @@ -263,6 +303,17 @@ web_contents(), bubble_parameters, base::BindOnce(&DiceWebSigninInterceptor::OnProfileCreationChoice, base::Unretained(this))); + was_interception_ui_displayed_ = true; + RecordSigninInterceptionHeuristicOutcome( + *interception_type == SigninInterceptionType::kEnterprise + ? SigninInterceptionHeuristicOutcome::kInterceptEnterprise + : SigninInterceptionHeuristicOutcome::kInterceptMultiUser); +} + +void DiceWebSigninInterceptor::OnExtendedAccountInfoFetchTimeout() { + RecordSigninInterceptionHeuristicOutcome( + SigninInterceptionHeuristicOutcome::kAbortAccountInfoTimeout); + Reset(); } void DiceWebSigninInterceptor::OnProfileCreationChoice(bool create) { @@ -271,6 +322,7 @@ return; } + profile_creation_start_time_ = base::TimeTicks::Now(); base::string16 profile_name; base::Optional<AccountInfo> account_info = identity_manager_ @@ -310,6 +362,9 @@ Profile* new_profile) { DCHECK(dice_signed_in_profile_creator_); dice_signed_in_profile_creator_.reset(); + base::UmaHistogramTimes( + "Signin.Intercept.ProfileCreationDuration", + base::TimeTicks::Now() - profile_creation_start_time_); if (!new_profile) { Reset();
diff --git a/chrome/browser/signin/dice_web_signin_interceptor.h b/chrome/browser/signin/dice_web_signin_interceptor.h index c587a40d..8c9672d 100644 --- a/chrome/browser/signin/dice_web_signin_interceptor.h +++ b/chrome/browser/signin/dice_web_signin_interceptor.h
@@ -12,6 +12,7 @@ #include "base/feature_list.h" #include "base/gtest_prod_util.h" #include "base/scoped_observer.h" +#include "base/time/time.h" #include "components/keyed_service/core/keyed_service.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "content/public/browser/web_contents_observer.h" @@ -27,6 +28,37 @@ class Profile; class ProfileAttributesStorage; +// Outcome of the interception heuristic (decision whether the interception +// bubble is shown or not). +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class SigninInterceptionHeuristicOutcome { + // Interception succeeded: + kInterceptProfileSwitch = 0, + kInterceptMultiUser = 1, + kInterceptEnterprise = 2, + + // Interception aborted: + // This is a "Sync" sign in and not a "web" sign in. + kAbortSyncSignin = 3, + // Another interception is already in progress. + kAbortInterceptInProgress = 4, + // This is not a new account (reauth). + kAbortAccountNotNew = 5, + // New profile is not offered when there is only one account. + kAbortSingleAccount = 6, + // Extended account info could not be downloaded. + kAbortAccountInfoTimeout = 7, + // Account info not compatible with interception (e.g. same Gaia name). + kAbortAccountInfoNotCompatible = 8, + // Profile creation disallowed. + kAbortProfileCreationDisallowed = 9, + // The interceptor was shut down before the heuristic completed. + kAbortShutdown = 10, + + kMaxValue = kAbortShutdown, +}; + // Called after web signed in, after a successful token exchange through Dice. // The DiceWebSigninInterceptor may offer the user to create a new profile or // switch to another existing profile. @@ -137,6 +169,9 @@ // signin::IdentityManager::Observer: void OnExtendedAccountInfoUpdated(const AccountInfo& info) override; + // Called when the extended account info was not updated after a timeout. + void OnExtendedAccountInfoFetchTimeout(); + // Called after the user chose whether a new profile would be created. void OnProfileCreationChoice(bool create); // Called after the user chose whether the session should continue in a new @@ -165,6 +200,10 @@ // is cancelled if the account info cannot be fetched quickly. base::CancelableOnceCallback<void()> on_account_info_update_timeout_; std::unique_ptr<DiceSignedInProfileCreator> dice_signed_in_profile_creator_; + // Used for metrics: + bool was_interception_ui_displayed_ = false; + base::TimeTicks account_info_fetch_start_time_; + base::TimeTicks profile_creation_start_time_; }; #endif // CHROME_BROWSER_SIGNIN_DICE_WEB_SIGNIN_INTERCEPTOR_H_
diff --git a/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc b/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc index 4fdc929..60aaf927 100644 --- a/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc +++ b/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc
@@ -6,6 +6,7 @@ #include "base/scoped_observer.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/metrics/histogram_tester.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile_attributes_entry.h" #include "chrome/browser/profiles/profile_attributes_storage.h" @@ -147,6 +148,7 @@ // Tests the complete interception flow including profile and browser creation. IN_PROC_BROWSER_TEST_F(DiceWebSigninInterceptorBrowserTest, InterceptionTest) { + base::HistogramTester histogram_tester; // Setup profile for interception. identity_test_env()->MakeAccountAvailable("alice@example.com"); AccountInfo account_info = @@ -211,4 +213,12 @@ EXPECT_EQ(browser()->tab_strip_model()->count(), original_tab_count - 1); EXPECT_EQ(added_browser->tab_strip_model()->GetActiveWebContents()->GetURL(), intercepted_url); + + histogram_tester.ExpectUniqueSample( + "Signin.Intercept.HeuristicOutcome", + SigninInterceptionHeuristicOutcome::kInterceptMultiUser, 1); + histogram_tester.ExpectTotalCount("Signin.Intercept.AccountInfoFetchDuration", + 1); + histogram_tester.ExpectTotalCount("Signin.Intercept.ProfileCreationDuration", + 1); }
diff --git a/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc b/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc index fc4d1c6..68f30c26 100644 --- a/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc +++ b/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc
@@ -8,6 +8,7 @@ #include "base/callback.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile_attributes_entry.h" @@ -307,21 +308,31 @@ entry->SetAuthInfo(account_info.gaia, base::UTF8ToUTF16("Bob"), /*is_consented_primary_account=*/false); + std::unique_ptr<base::HistogramTester> histogram_tester = + std::make_unique<base::HistogramTester>(); // Check that Sync signin is not intercepted. interceptor()->MaybeInterceptWebSignin(web_contents(), account_info.account_id, /*is_new_account=*/true, /*is_sync_signin=*/true); testing::Mock::VerifyAndClearExpectations(mock_delegate()); + histogram_tester->ExpectUniqueSample( + "Signin.Intercept.HeuristicOutcome", + SigninInterceptionHeuristicOutcome::kAbortSyncSignin, 1); // Check that reauth is not intercepted. + histogram_tester = std::make_unique<base::HistogramTester>(); interceptor()->MaybeInterceptWebSignin(web_contents(), account_info.account_id, /*is_new_account=*/false, /*is_sync_signin=*/false); testing::Mock::VerifyAndClearExpectations(mock_delegate()); + histogram_tester->ExpectUniqueSample( + "Signin.Intercept.HeuristicOutcome", + SigninInterceptionHeuristicOutcome::kAbortAccountNotNew, 1); // Check that interception works otherwise, as a sanity check. + histogram_tester = std::make_unique<base::HistogramTester>(); DiceWebSigninInterceptor::Delegate::BubbleParameters expected_parameters = { DiceWebSigninInterceptor::SigninInterceptionType::kProfileSwitch, account_info, AccountInfo()}; @@ -332,6 +343,9 @@ account_info.account_id, /*is_new_account=*/true, /*is_sync_signin=*/false); + histogram_tester->ExpectUniqueSample( + "Signin.Intercept.HeuristicOutcome", + SigninInterceptionHeuristicOutcome::kInterceptProfileSwitch, 1); } TEST_F(DiceWebSigninInterceptorTest, InterceptionInProgress) { @@ -362,8 +376,12 @@ EXPECT_TRUE(interceptor()->is_interception_in_progress_); // Check that there is no interception while another one is in progress. + base::HistogramTester histogram_tester; MaybeIntercept(account_info.account_id); testing::Mock::VerifyAndClearExpectations(mock_delegate()); + histogram_tester.ExpectUniqueSample( + "Signin.Intercept.HeuristicOutcome", + SigninInterceptionHeuristicOutcome::kAbortInterceptInProgress, 1); // Complete the interception that was in progress. std::move(delegate_callback).Run(false); @@ -378,6 +396,7 @@ // Interception other than the profile switch require at least 2 accounts. TEST_F(DiceWebSigninInterceptorTest, NoInterceptionWithOneAccount) { + base::HistogramTester histogram_tester; AccountInfo account_info = identity_test_env()->MakeAccountAvailable("bob@example.com"); // Interception aborts even if the account info is not available. @@ -389,11 +408,15 @@ ->IsValid()); MaybeIntercept(account_info.account_id); EXPECT_FALSE(interceptor()->is_interception_in_progress_); + histogram_tester.ExpectUniqueSample( + "Signin.Intercept.HeuristicOutcome", + SigninInterceptionHeuristicOutcome::kAbortSingleAccount, 1); } // When profile creation is disallowed, profile switch interception is still // enabled, but others are disabled. TEST_F(DiceWebSigninInterceptorTest, ProfileCreationDisallowed) { + base::HistogramTester histogram_tester; g_browser_process->local_state()->SetBoolean(prefs::kBrowserAddPersonEnabled, false); // Setup for profile switch interception. @@ -411,6 +434,9 @@ // Interception that would offer creating a new profile does not work. MaybeIntercept(other_account_info.account_id); EXPECT_FALSE(interceptor()->is_interception_in_progress_); + histogram_tester.ExpectUniqueSample( + "Signin.Intercept.HeuristicOutcome", + SigninInterceptionHeuristicOutcome::kAbortProfileCreationDisallowed, 1); // Profile switch interception still works. DiceWebSigninInterceptor::Delegate::BubbleParameters expected_parameters = { @@ -423,6 +449,7 @@ } TEST_F(DiceWebSigninInterceptorTest, WaitForAccountInfoAvailable) { + base::HistogramTester histogram_tester; AccountInfo primary_account_info = identity_test_env()->MakeUnconsentedPrimaryAccountAvailable( "bob@example.com"); @@ -442,9 +469,12 @@ MakeValidAccountInfo(&account_info); account_info.hosted_domain = "example.com"; identity_test_env()->UpdateAccountInfoForAccount(account_info); + histogram_tester.ExpectTotalCount("Signin.Intercept.AccountInfoFetchDuration", + 1); } TEST_F(DiceWebSigninInterceptorTest, AccountInfoAlreadyAvailable) { + base::HistogramTester histogram_tester; AccountInfo primary_account_info = identity_test_env()->MakeUnconsentedPrimaryAccountAvailable( "bob@example.com"); @@ -462,9 +492,15 @@ ShowSigninInterceptionBubble(web_contents(), expected_parameters, testing::_)); MaybeIntercept(account_info.account_id); + histogram_tester.ExpectTotalCount("Signin.Intercept.AccountInfoFetchDuration", + 1); + histogram_tester.ExpectUniqueSample( + "Signin.Intercept.HeuristicOutcome", + SigninInterceptionHeuristicOutcome::kInterceptEnterprise, 1); } TEST_F(DiceWebSigninInterceptorTest, MultiUserInterception) { + base::HistogramTester histogram_tester; AccountInfo primary_account_info = identity_test_env()->MakeUnconsentedPrimaryAccountAvailable( "bob@example.com"); @@ -481,4 +517,7 @@ ShowSigninInterceptionBubble(web_contents(), expected_parameters, testing::_)); MaybeIntercept(account_info.account_id); + histogram_tester.ExpectUniqueSample( + "Signin.Intercept.HeuristicOutcome", + SigninInterceptionHeuristicOutcome::kInterceptMultiUser, 1); }
diff --git a/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc b/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc index ccf6c28..d91d2cf5 100644 --- a/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc +++ b/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
@@ -1254,8 +1254,8 @@ // Tests that a same-site iframe runs its beforeunload handler when closing a // tab. Same as the test above, but for a same-site rather than cross-site // iframe. See https://crbug.com/1010456. -// Flaky on Linux and ChromeOS (crbug.com/1033002) -#if defined(OS_LINUX) || defined(OS_CHROMEOS) +// Flaky on Linux, ChromeOS and Windows (crbug.com/1033002) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_WIN) #define MAYBE_TabCloseWithSameSiteBeforeUnloadIframe \ DISABLED_TabCloseWithSameSiteBeforeUnloadIframe #else
diff --git a/chrome/browser/storage_access_api/api_browsertest.cc b/chrome/browser/storage_access_api/api_browsertest.cc index 7ee7df8..32d33729 100644 --- a/chrome/browser/storage_access_api/api_browsertest.cc +++ b/chrome/browser/storage_access_api/api_browsertest.cc
@@ -73,8 +73,11 @@ } void SetBlockThirdPartyCookies(bool value) { - browser()->profile()->GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, - value); + browser()->profile()->GetPrefs()->SetInteger( + prefs::kCookieControlsMode, + static_cast<int>( + value ? content_settings::CookieControlsMode::kBlockThirdParty + : content_settings::CookieControlsMode::kOff)); } void NavigateToPageWithFrame(const std::string& host) {
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc index 32fb8cdc..0d161a2e 100644 --- a/chrome/browser/sync/chrome_sync_client.cc +++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -221,9 +221,16 @@ #if defined(OS_ANDROID) trusted_vault_client_ = std::make_unique<TrustedVaultClientAndroid>(); #else + // TODO(crbug.com/1113597): consider destroying/notifying + // |trusted_vault_client_| upon IdentityManager shutdown, to avoid its usages + // afterwards. This can be done by tranferring |trusted_vault_client_| + // ownership to ProfileSyncService and acting on + // ProfileSyncService::Shutdown() or by handling + // IdentityManagerFactory::Observer::IdentityManagerShutdown(). trusted_vault_client_ = std::make_unique<syncer::StandaloneTrustedVaultClient>( - profile_->GetPath().Append(kTrustedVaultFilename)); + profile_->GetPath().Append(kTrustedVaultFilename), + IdentityManagerFactory::GetForProfile(profile_)); #endif // defined(OS_ANDROID) }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 229c781..ff9eaef 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2525,6 +2525,8 @@ "//chromeos/assistant:buildflags", "//chromeos/audio", "//chromeos/components/account_manager", + "//chromeos/components/bloom/public/cpp", + "//chromeos/components/bloom/public/cpp:bloom_controller_factory", "//chromeos/components/camera_app_ui", "//chromeos/components/help_app_ui", "//chromeos/components/local_search_service:local_search_service", @@ -3162,13 +3164,7 @@ } if (use_x11) { - sources += [ - "views/frame/native_browser_frame_factory_aurax11.cc", - "views/javascript_app_modal_dialog_views_x11.cc", - "views/javascript_app_modal_dialog_views_x11.h", - "views/javascript_app_modal_event_blocker_x11.cc", - "views/javascript_app_modal_event_blocker_x11.h", - ] + sources += [ "views/frame/native_browser_frame_factory_aurax11.cc" ] deps += [ "//ui/events/devices", "//ui/events/devices/x11", @@ -3575,6 +3571,8 @@ "views/location_bar/permission_chip.h", "views/location_bar/selected_keyword_view.cc", "views/location_bar/selected_keyword_view.h", + "views/location_bar/star_menu_model.cc", + "views/location_bar/star_menu_model.h", "views/location_bar/star_view.cc", "views/location_bar/star_view.h", "views/location_bar/zoom_bubble_view.cc", @@ -4305,7 +4303,11 @@ deps += [ "//apps/ui/views" ] } if (use_aura) { - sources += [ "views/chrome_javascript_app_modal_view_factory_views.cc" ] + sources += [ + "views/chrome_javascript_app_modal_view_factory_views.cc", + "views/javascript_app_modal_event_blocker_x11.cc", + "views/javascript_app_modal_event_blocker_x11.h", + ] deps += [ "//ui/wm/public" ] } }
diff --git a/chrome/browser/ui/app_list/app_context_menu_unittest.cc b/chrome/browser/ui/app_list/app_context_menu_unittest.cc index bb002b57..16b210c9 100644 --- a/chrome/browser/ui/app_list/app_context_menu_unittest.cc +++ b/chrome/browser/ui/app_list/app_context_menu_unittest.cc
@@ -44,6 +44,7 @@ #include "components/keyed_service/core/keyed_service.h" #include "components/services/app_service/public/cpp/app_update.h" #include "extensions/common/manifest_constants.h" +#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ui_base_features.h" #include "ui/display/test/test_screen.h" @@ -161,10 +162,7 @@ } } - ~AppContextMenuTest() override { - // Release profile file in order to keep right sequence. - profile_.reset(); - } + ~AppContextMenuTest() override = default; void SetUp() override { AppListTestBase::SetUp(); @@ -334,8 +332,11 @@ ValidateMenuState(menu_model.get(), states); } + apps::AppServiceTest& app_service_test() { return app_service_test_; } + private: base::test::ScopedFeatureList scoped_feature_list_; + data_decoder::test::InProcessDataDecoder in_process_data_decoder_; display::test::TestScreen test_screen_; std::unique_ptr<KeyedService> menu_manager_; std::unique_ptr<FakeAppListControllerDelegate> controller_; @@ -379,8 +380,7 @@ } TEST_P(AppContextMenuTest, ArcMenu) { - apps::AppServiceTest app_service_test; - app_service_test.SetUp(profile()); + app_service_test().SetUp(profile()); ArcAppTest arc_test; arc_test.SetUp(profile()); @@ -389,7 +389,7 @@ controller()->SetAppPinnable(app_id, AppListControllerDelegate::PIN_EDITABLE); arc_test.app_instance()->SendRefreshAppList(arc_test.fake_apps()); - app_service_test.FlushMojoCalls(); + app_service_test().FlushMojoCalls(); std::unique_ptr<AppServiceAppItem> item = GetAppListItem(profile(), app_id); @@ -412,7 +412,7 @@ EXPECT_EQ(0u, arc_test.app_instance()->launch_requests().size()); menu->ActivatedAt(0); - app_service_test.FlushMojoCalls(); + app_service_test().FlushMojoCalls(); const std::vector<std::unique_ptr<arc::FakeAppInstance::Request>>& launch_requests = arc_test.app_instance()->launch_requests(); @@ -449,7 +449,7 @@ // Test launching app shortcut item. EXPECT_EQ(0, arc_test.app_instance()->launch_app_shortcut_item_count()); menu->ActivatedAt(menu->GetItemCount() - 1); - app_service_test.FlushMojoCalls(); + app_service_test().FlushMojoCalls(); EXPECT_EQ(1, arc_test.app_instance()->launch_app_shortcut_item_count()); // This makes all apps non-ready. @@ -484,7 +484,7 @@ // Uninstall all apps. arc_test.app_instance()->SendRefreshAppList( std::vector<arc::mojom::AppInfo>()); - app_service_test.FlushMojoCalls(); + app_service_test().FlushMojoCalls(); controller()->SetAppOpen(app_id, false); // No app available case. @@ -493,8 +493,7 @@ } TEST_P(AppContextMenuTest, ArcMenuShortcut) { - apps::AppServiceTest app_service_test; - app_service_test.SetUp(profile()); + app_service_test().SetUp(profile()); ArcAppTest arc_test; arc_test.SetUp(profile()); @@ -503,7 +502,7 @@ controller()->SetAppPinnable(app_id, AppListControllerDelegate::PIN_EDITABLE); arc_test.app_instance()->SendInstallShortcuts(arc_test.fake_shortcuts()); - app_service_test.FlushMojoCalls(); + app_service_test().FlushMojoCalls(); std::unique_ptr<AppServiceAppItem> item = GetAppListItem(profile(), app_id); @@ -558,13 +557,12 @@ } TEST_P(AppContextMenuTest, ArcMenuStickyItem) { - apps::AppServiceTest app_service_test; - app_service_test.SetUp(profile()); + app_service_test().SetUp(profile()); ArcAppTest arc_test; arc_test.SetUp(profile()); arc_test.app_instance()->SendRefreshAppList(arc_test.fake_apps()); - app_service_test.FlushMojoCalls(); + app_service_test().FlushMojoCalls(); { // Verify menu of store
diff --git a/chrome/browser/ui/ash/assistant/assistant_client_impl.cc b/chrome/browser/ui/ash/assistant/assistant_client_impl.cc index 7300a78b..b8a3185 100644 --- a/chrome/browser/ui/ash/assistant/assistant_client_impl.cc +++ b/chrome/browser/ui/ash/assistant/assistant_client_impl.cc
@@ -7,6 +7,7 @@ #include <utility> #include "ash/public/cpp/assistant/assistant_interface_binder.h" +#include "ash/public/cpp/assistant/controller/assistant_interaction_controller.h" #include "ash/public/cpp/network_config_service.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/assistant/assistant_util.h" @@ -18,6 +19,8 @@ #include "chrome/browser/ui/ash/assistant/assistant_web_view_factory_impl.h" #include "chrome/browser/ui/ash/assistant/conversation_starters_client_impl.h" #include "chrome/browser/ui/ash/assistant/device_actions_delegate_impl.h" +#include "chromeos/components/bloom/public/cpp/bloom_controller.h" +#include "chromeos/components/bloom/public/cpp/bloom_controller_factory.h" #include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_switches.h" #include "chromeos/services/assistant/public/cpp/features.h" @@ -85,6 +88,13 @@ conversation_starters_client_ = std::make_unique<ConversationStartersClientImpl>(profile_); } + + if (chromeos::assistant::features::IsBloomEnabled()) { + bloom_controller_ = chromeos::bloom::BloomControllerFactory::Create( + profile->GetURLLoaderFactory(), + IdentityManagerFactory::GetForProfile(profile), + ash::AssistantInteractionController::Get()); + } } void AssistantClientImpl::MaybeStartAssistantOptInFlow() {
diff --git a/chrome/browser/ui/ash/assistant/assistant_client_impl.h b/chrome/browser/ui/ash/assistant/assistant_client_impl.h index de0fe36..9d83e64 100644 --- a/chrome/browser/ui/ash/assistant/assistant_client_impl.h +++ b/chrome/browser/ui/ash/assistant/assistant_client_impl.h
@@ -23,6 +23,12 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" +namespace chromeos { +namespace bloom { +class BloomController; +} // namespace bloom +} // namespace chromeos + class AssistantSetup; class AssistantWebViewFactoryImpl; class ConversationStartersClientImpl; @@ -100,6 +106,7 @@ std::unique_ptr<AssistantSetup> assistant_setup_; std::unique_ptr<AssistantWebViewFactoryImpl> assistant_web_view_factory_; std::unique_ptr<ConversationStartersClientImpl> conversation_starters_client_; + std::unique_ptr<chromeos::bloom::BloomController> bloom_controller_; bool initialized_ = false;
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index dc39693..d332f391 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -57,6 +57,7 @@ #include "chrome/browser/ui/location_bar/location_bar.h" #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" #include "chrome/browser/ui/qrcode_generator/qrcode_generator_bubble_controller.h" +#include "chrome/browser/ui/read_later/reading_list_model_factory.h" #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" #include "chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble_controller.h" #include "chrome/browser/ui/status_bubble.h" @@ -87,6 +88,8 @@ #include "components/google/core/common/google_util.h" #include "components/omnibox/browser/omnibox_prefs.h" #include "components/prefs/pref_service.h" +#include "components/reading_list/core/reading_list_entry.h" +#include "components/reading_list/core/reading_list_model.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "components/sessions/core/live_tab_context.h" #include "components/sessions/core/tab_restore_service.h" @@ -208,6 +211,27 @@ TabStripModel::ADD_ACTIVE); } +bool GetActiveTabURLAndTitleToSave(Browser* browser, + GURL* url, + base::string16* title) { + content::WebContents* web_contents = + browser->tab_strip_model()->GetActiveWebContents(); + // |web_contents| can be nullptr if the last tab in the browser was closed + // but the browser wasn't closed yet. https://crbug.com/799668 + if (!web_contents) + return false; + chrome::GetURLAndTitleToBookmark(web_contents, url, title); + return true; +} + +ReadingListModel* GetReadingListModel(Browser* browser) { + ReadingListModel* model = + ReadingListModelFactory::GetForBrowserContext(browser->profile()); + if (!model || !model->loaded()) + return nullptr; // Ignore requests until model has loaded. + return model; +} + } // namespace using base::UserMetricsAction; @@ -1006,6 +1030,45 @@ CanBookmarkCurrentTab(browser); } +bool MoveCurrentTabToReadLater(Browser* browser) { + GURL url; + base::string16 title; + ReadingListModel* model = GetReadingListModel(browser); + if (!model || !GetActiveTabURLAndTitleToSave(browser, &url, &title)) + return false; + model->AddEntry(url, base::UTF16ToUTF8(title), + reading_list::EntrySource::ADDED_VIA_CURRENT_APP); + // Close current tab. + int index = browser->tab_strip_model()->active_index(); + browser->tab_strip_model()->CloseWebContentsAt( + index, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB | + TabStripModel::CLOSE_USER_GESTURE); + return true; +} + +bool MarkCurrentTabAsReadInReadLater(Browser* browser) { + GURL url; + base::string16 title; + ReadingListModel* model = GetReadingListModel(browser); + if (!model || !GetActiveTabURLAndTitleToSave(browser, &url, &title)) + return false; + const ReadingListEntry* entry = model->GetEntryByURL(url); + // Mark current tab as read. + if (entry && !entry->IsRead()) + model->SetReadStatus(url, true); + return entry != nullptr; +} + +bool IsCurrentTabUnreadInReadLater(Browser* browser) { + GURL url; + base::string16 title; + ReadingListModel* model = GetReadingListModel(browser); + if (!model || !GetActiveTabURLAndTitleToSave(browser, &url, &title)) + return false; + const ReadingListEntry* entry = model->GetEntryByURL(url); + return entry && !entry->IsRead(); +} + void SaveCreditCard(Browser* browser) { WebContents* web_contents = browser->tab_strip_model()->GetActiveWebContents();
diff --git a/chrome/browser/ui/browser_commands.h b/chrome/browser/ui/browser_commands.h index 07c068bb..a153d33 100644 --- a/chrome/browser/ui/browser_commands.h +++ b/chrome/browser/ui/browser_commands.h
@@ -140,6 +140,9 @@ bool CanBookmarkCurrentTab(const Browser* browser); void BookmarkAllTabs(Browser* browser); bool CanBookmarkAllTabs(const Browser* browser); +bool MoveCurrentTabToReadLater(Browser* browser); +bool MarkCurrentTabAsReadInReadLater(Browser* browser); +bool IsCurrentTabUnreadInReadLater(Browser* browser); void SaveCreditCard(Browser* browser); void MigrateLocalCards(Browser* browser); void MaybeShowSaveLocalCardSignInPromo(Browser* browser);
diff --git a/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm b/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm index 8673014..dd8886a 100644 --- a/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm +++ b/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm
@@ -5,6 +5,7 @@ #import "chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.h" #include "base/check.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/global_keyboard_shortcuts_mac.h" #include "components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h" #include "components/remote_cocoa/common/native_widget_ns_window_host.mojom.h" @@ -91,6 +92,13 @@ // By not passing the event to AppKit, we do lose out on the brief // highlighting of the NSMenu. CommandForKeyEventResult result = CommandForKeyEvent(event); + // Ignore new tab/window events if |event| is a key repeat to prevent + // users from accidentally opening too many empty tabs or windows. + if (event.isARepeat && (result.chrome_command == IDC_NEW_TAB || + result.chrome_command == IDC_NEW_WINDOW)) { + return ui::PerformKeyEquivalentResult::kDrop; + } + if (result.found()) { auto* bridge = remote_cocoa::NativeWidgetNSWindowBridge::GetFromNativeWindow(window);
diff --git a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc index bfe61c7..742b89b 100644 --- a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc +++ b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
@@ -469,7 +469,13 @@ } // Search Back and Forward on a single occurrence. -IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, SingleOccurrence) { +// TODO(crbug.com/1119361): Test is flaky on ChromeOS. +#if defined(OS_CHROMEOS) +#define MAYBE_SingleOccurrence DISABLED_SingleOccurrence +#else +#define MAYBE_SingleOccurrence SingleOccurrence +#endif +IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, MAYBE_SingleOccurrence) { WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); ui_test_utils::NavigateToURL(browser(), GetURL("FindRandomTests.html"));
diff --git a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc index e73cf6d..3555244 100644 --- a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc +++ b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc
@@ -8,7 +8,6 @@ #include "chrome/browser/password_manager/change_password_url_service_factory.h" #include "components/password_manager/core/browser/change_password_url_service.h" #include "components/password_manager/core/browser/well_known_change_password_state.h" -#include "components/password_manager/core/browser/well_known_change_password_util.h" #include "components/password_manager/core/common/password_manager_features.h" #include "components/ukm/content/source_url_recorder.h" #include "content/public/browser/browser_context.h" @@ -29,6 +28,7 @@ using content::NavigationThrottle; using content::WebContents; using password_manager::IsWellKnownChangePasswordUrl; +using password_manager::WellKnownChangePasswordResult; using password_manager::WellKnownChangePasswordState; // Used to scope the posted navigation task to the lifetime of |web_contents|.
diff --git a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.h b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.h index a67c340..3b843b3 100644 --- a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.h +++ b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.h
@@ -10,6 +10,7 @@ #include "content/public/browser/navigation_throttle.h" #include "components/password_manager/core/browser/well_known_change_password_state.h" +#include "components/password_manager/core/browser/well_known_change_password_util.h" #include "services/metrics/public/cpp/ukm_source_id.h" class GURL; @@ -22,15 +23,6 @@ class ChangePasswordUrlService; } // namespace password_manager -// Used to report UKMs about the support for .well-known/change-password. -// These values are persisted to logs. Entries should not be renumbered and -// numeric values should never be reused. -enum class WellKnownChangePasswordResult { - kFallbackToOriginUrl = 0, - kFallbackToOverrideUrl = 1, - kUsedWellKnownChangePassword = 2, -}; - // This NavigationThrottle checks whether a site supports the // .well-known/change-password url. To check whether a site supports the // change-password url, we also request a .well-known path that is defined to @@ -63,7 +55,7 @@ // Redirects to a given URL in the same tab. void Redirect(const GURL& url); // Records the given UKM metric. - void RecordMetric(WellKnownChangePasswordResult result); + void RecordMetric(password_manager::WellKnownChangePasswordResult result); password_manager::WellKnownChangePasswordState well_known_change_password_state_{this};
diff --git a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle_browsertest.cc b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle_browsertest.cc index c34a70c..a65aae32 100644 --- a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle_browsertest.cc +++ b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle_browsertest.cc
@@ -44,6 +44,7 @@ using net::test_server::HttpResponse; using password_manager::kWellKnownChangePasswordPath; using password_manager::kWellKnownNotExistingResourcePath; +using password_manager::WellKnownChangePasswordResult; constexpr char kMockChangePasswordPath[] = "/change-password-override";
diff --git a/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.cc b/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.cc index e200e39..e3916e22 100644 --- a/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.cc +++ b/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.cc
@@ -204,14 +204,13 @@ google_util::ALLOW_SUBDOMAIN)) { replacements.push_back(learn_more_text); + checkbox_label = std::make_unique<views::StyledLabel>(this); std::vector<size_t> offsets; - checkbox_label = std::make_unique<views::StyledLabel>( - l10n_util::GetStringFUTF16( - IDS_APP_UNINSTALL_PROMPT_REMOVE_DATA_CHECKBOX_FOR_GOOGLE, - replacements, &offsets), - this); + checkbox_label->SetText(l10n_util::GetStringFUTF16( + IDS_APP_UNINSTALL_PROMPT_REMOVE_DATA_CHECKBOX_FOR_GOOGLE, replacements, + &offsets)); DCHECK_EQ(replacements.size(), offsets.size()); - offset = offsets[offsets.size() - 1]; + offset = offsets.back(); } else { auto domain = net::registry_controlled_domains::GetDomainAndRegistry( app_launch_url, @@ -222,14 +221,13 @@ replacements.push_back(base::ASCIIToUTF16(domain)); replacements.push_back(learn_more_text); + checkbox_label = std::make_unique<views::StyledLabel>(this); std::vector<size_t> offsets; - checkbox_label = std::make_unique<views::StyledLabel>( - l10n_util::GetStringFUTF16( - IDS_APP_UNINSTALL_PROMPT_REMOVE_DATA_CHECKBOX_FOR_NON_GOOGLE, - replacements, &offsets), - this); + checkbox_label->SetText(l10n_util::GetStringFUTF16( + IDS_APP_UNINSTALL_PROMPT_REMOVE_DATA_CHECKBOX_FOR_NON_GOOGLE, + replacements, &offsets)); DCHECK_EQ(replacements.size(), offsets.size()); - offset = offsets[offsets.size() - 1]; + offset = offsets.back(); } checkbox_label->AddStyleRange(
diff --git a/chrome/browser/ui/views/autofill/payments/payments_view_util.cc b/chrome/browser/ui/views/autofill/payments/payments_view_util.cc index 3433e1a..4a9bb281 100644 --- a/chrome/browser/ui/views/autofill/payments/payments_view_util.cc +++ b/chrome/browser/ui/views/autofill/payments/payments_view_util.cc
@@ -145,8 +145,8 @@ LegalMessageView::CreateLegalMessageLineLabel( const LegalMessageLine& line, views::StyledLabelListener* listener) { - std::unique_ptr<views::StyledLabel> label = - std::make_unique<views::StyledLabel>(line.text(), listener); + auto label = std::make_unique<views::StyledLabel>(listener); + label->SetText(line.text()); label->SetTextContext(CONTEXT_BODY_TEXT_LARGE); label->SetDefaultTextStyle(views::style::STYLE_SECONDARY); for (const LegalMessageLine::Link& link : line.links()) {
diff --git a/chrome/browser/ui/views/chrome_javascript_app_modal_view_factory_views.cc b/chrome/browser/ui/views/chrome_javascript_app_modal_view_factory_views.cc index 22431a9..afe16d2 100644 --- a/chrome/browser/ui/views/chrome_javascript_app_modal_view_factory_views.cc +++ b/chrome/browser/ui/views/chrome_javascript_app_modal_view_factory_views.cc
@@ -6,26 +6,41 @@ #include "base/macros.h" #include "build/build_config.h" +#include "chrome/browser/ui/blocked_content/popunder_preventer.h" +#include "chrome/browser/ui/views/javascript_app_modal_event_blocker_x11.h" #include "components/constrained_window/constrained_window_views.h" +#include "components/javascript_dialogs/app_modal_dialog_controller.h" #include "components/javascript_dialogs/app_modal_dialog_manager.h" +#include "components/javascript_dialogs/views/app_modal_dialog_view_views.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" -#if defined(USE_X11) -#include "chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.h" +#if defined(USE_OZONE) #include "ui/base/ui_base_features.h" +#include "ui/ozone/public/ozone_platform.h" #endif -#include "chrome/browser/ui/blocked_content/popunder_preventer.h" -#include "components/javascript_dialogs/app_modal_dialog_controller.h" -#include "components/javascript_dialogs/views/app_modal_dialog_view_views.h" - #if defined(USE_AURA) #include "ui/aura/window.h" #endif namespace { +bool UseEventBlocker() { +#if defined(USE_OZONE) + if (features::IsUsingOzonePlatform()) { + return ui::OzonePlatform::GetInstance() + ->GetPlatformProperties() + .app_modal_dialogs_use_event_blocker; + } +#endif +#if defined(USE_X11) + return true; +#else + return false; +#endif +} + class ChromeJavaScriptAppModalDialogViews : public javascript_dialogs::AppModalDialogViewViews { public: @@ -35,7 +50,27 @@ popunder_preventer_(parent->web_contents()) {} ~ChromeJavaScriptAppModalDialogViews() override = default; + // JavaScriptAppModalDialogViews: + void ShowAppModalDialog() override { + // BrowserView::CanActivate() ensures that other browser windows cannot be + // activated while the dialog is visible. Block events to other browser + // windows so that the user cannot interact with them. This hack is + // unnecessary on Windows and Chrome OS. + // TODO(pkotwicz): Find a better way of doing this and remove this hack. + if (UseEventBlocker() && !event_blocker_.get()) { + event_blocker_ = std::make_unique<JavascriptAppModalEventBlockerX11>( + GetWidget()->GetNativeView()); + } + AppModalDialogViewViews::ShowAppModalDialog(); + } + + // views::DialogDelegate: + void WindowClosing() override { event_blocker_.reset(); } + private: + // Blocks events to other browser windows while the dialog is open. + std::unique_ptr<JavascriptAppModalEventBlockerX11> event_blocker_; + PopunderPreventer popunder_preventer_; DISALLOW_COPY_AND_ASSIGN(ChromeJavaScriptAppModalDialogViews); @@ -43,13 +78,8 @@ javascript_dialogs::AppModalDialogView* CreateNativeJavaScriptDialog( javascript_dialogs::AppModalDialogController* dialog) { - javascript_dialogs::AppModalDialogViewViews* d = nullptr; -#if defined(USE_X11) - if (!features::IsUsingOzonePlatform()) - d = new JavaScriptAppModalDialogViewsX11(dialog); -#endif - if (!d) - d = new ChromeJavaScriptAppModalDialogViews(dialog); + javascript_dialogs::AppModalDialogViewViews* d = + new ChromeJavaScriptAppModalDialogViews(dialog); dialog->web_contents()->GetDelegate()->ActivateContents( dialog->web_contents()); gfx::NativeWindow parent_window =
diff --git a/chrome/browser/ui/views/crostini/crostini_package_install_failure_view.cc b/chrome/browser/ui/views/crostini/crostini_package_install_failure_view.cc index 7e7009c..0115627 100644 --- a/chrome/browser/ui/views/crostini/crostini_package_install_failure_view.cc +++ b/chrome/browser/ui/views/crostini/crostini_package_install_failure_view.cc
@@ -52,11 +52,10 @@ set_margins(provider->GetDialogInsetsForContentType( views::DialogContentType::TEXT, views::DialogContentType::TEXT)); - views::StyledLabel* message_label = new views::StyledLabel( - l10n_util::GetStringUTF16( - IDS_CROSTINI_PACKAGE_INSTALL_FAILURE_VIEW_MESSAGE), - nullptr); - AddChildView(message_label); + views::StyledLabel* message_label = + AddChildView(std::make_unique<views::StyledLabel>()); + message_label->SetText(l10n_util::GetStringUTF16( + IDS_CROSTINI_PACKAGE_INSTALL_FAILURE_VIEW_MESSAGE)); views::MessageBoxView* error_box = new views::MessageBoxView(base::UTF8ToUTF16(error_message));
diff --git a/chrome/browser/ui/views/device_chooser_content_view.cc b/chrome/browser/ui/views/device_chooser_content_view.cc index 0f2cd25..399436d 100644 --- a/chrome/browser/ui/views/device_chooser_content_view.cc +++ b/chrome/browser/ui/views/device_chooser_content_view.cc
@@ -157,7 +157,8 @@ size_t offset = 0; base::string16 text = l10n_util::GetStringFUTF16( IDS_BLUETOOTH_DEVICE_CHOOSER_TURN_ADAPTER_OFF, link_text, &offset); - auto adapter_off_help = std::make_unique<views::StyledLabel>(text, this); + auto adapter_off_help = std::make_unique<views::StyledLabel>(this); + adapter_off_help->SetText(text); adapter_off_help->AddStyleRange( gfx::Range(0, link_text.size()), views::StyledLabel::RangeStyleInfo::CreateForLink());
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc index 6aa83f7..86b58f0 100644 --- a/chrome/browser/ui/views/download/download_item_view.cc +++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -257,8 +257,7 @@ open_button_ = AddChildView(std::make_unique<TransparentButton>(this)); - file_name_label_ = AddChildView( - std::make_unique<views::StyledLabel>(base::string16(), nullptr)); + file_name_label_ = AddChildView(std::make_unique<views::StyledLabel>()); file_name_label_->SetTextContext(CONTEXT_DOWNLOAD_SHELF); file_name_label_->GetViewAccessibility().OverrideIsIgnored(true); const base::string16 filename = ElidedFilename(*file_name_label_); @@ -270,13 +269,11 @@ base::string16(), CONTEXT_DOWNLOAD_SHELF_STATUS)); status_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); - warning_label_ = AddChildView( - std::make_unique<views::StyledLabel>(base::string16(), nullptr)); + warning_label_ = AddChildView(std::make_unique<views::StyledLabel>()); warning_label_->SetTextContext(CONTEXT_DOWNLOAD_SHELF); warning_label_->set_can_process_events_within_subtree(false); - deep_scanning_label_ = AddChildView( - std::make_unique<views::StyledLabel>(base::string16(), nullptr)); + deep_scanning_label_ = AddChildView(std::make_unique<views::StyledLabel>()); deep_scanning_label_->SetTextContext(CONTEXT_DOWNLOAD_SHELF); deep_scanning_label_->set_can_process_events_within_subtree(false);
diff --git a/chrome/browser/ui/views/extensions/request_file_system_dialog_view.cc b/chrome/browser/ui/views/extensions/request_file_system_dialog_view.cc index cd452a4..1b3dff4b 100644 --- a/chrome/browser/ui/views/extensions/request_file_system_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/request_file_system_dialog_view.cc
@@ -92,7 +92,9 @@ : IDS_FILE_SYSTEM_REQUEST_FILE_SYSTEM_DIALOG_MESSAGE, app_name, volume_name, &placeholder_offsets); - views::StyledLabel* const label = new views::StyledLabel(message, nullptr); + views::StyledLabel* const label = + AddChildView(std::make_unique<views::StyledLabel>()); + label->SetText(message); views::StyledLabel::RangeStyleInfo bold_style; bold_style.text_style = STYLE_EMPHASIZED; @@ -106,6 +108,4 @@ bold_style); SetLayoutManager(std::make_unique<views::FillLayout>()); - - AddChildView(label); }
diff --git a/chrome/browser/ui/views/hover_button.cc b/chrome/browser/ui/views/hover_button.cc index e07767d..328b958 100644 --- a/chrome/browser/ui/views/hover_button.cc +++ b/chrome/browser/ui/views/hover_button.cc
@@ -133,8 +133,8 @@ // |label_wrapper| will hold both the title and subtitle if it exists. auto label_wrapper = std::make_unique<views::View>(); - title_ = label_wrapper->AddChildView( - std::make_unique<views::StyledLabel>(title, nullptr)); + title_ = label_wrapper->AddChildView(std::make_unique<views::StyledLabel>()); + title_->SetText(title); // Allow the StyledLabel for title to assume its preferred size on a single // line and let the flex layout attenuate its width if necessary. title_->SizeToFit(0); @@ -232,10 +232,10 @@ : base::JoinString({title_->GetText(), subtitle_->GetText()}, base::ASCIIToUTF16("\n")); - // |views::StyledLabel|s only add tooltips for any links they may have. - // However, since |HoverButton| will never insert a link inside its child - // |StyledLabel|, decide whether it needs a tooltip by checking whether the - // available space is smaller than its preferred size. + // views::StyledLabels only add tooltips for any links they may have. However, + // since HoverButton will never insert a link inside its child StyledLabel, + // decide whether it needs a tooltip by checking whether the available space + // is smaller than its preferred size. const bool needs_tooltip = label_wrapper_->GetPreferredSize().width() > label_wrapper_->width(); SetTooltipText(needs_tooltip ? accessible_name : base::string16());
diff --git a/chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.cc b/chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.cc deleted file mode 100644 index 31599da..0000000 --- a/chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.cc +++ /dev/null
@@ -1,40 +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 "chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.h" - -#include "chrome/browser/ui/blocked_content/popunder_preventer.h" -#include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/javascript_app_modal_event_blocker_x11.h" -#include "components/javascript_dialogs/app_modal_dialog_controller.h" -#include "ui/views/widget/widget.h" - -JavaScriptAppModalDialogViewsX11::JavaScriptAppModalDialogViewsX11( - javascript_dialogs::AppModalDialogController* parent) - : javascript_dialogs::AppModalDialogViewViews(parent), - popunder_preventer_(new PopunderPreventer(parent->web_contents())) { - chrome::RecordDialogCreation( - chrome::DialogIdentifier::JAVA_SCRIPT_APP_MODAL_X11); -} - -JavaScriptAppModalDialogViewsX11::~JavaScriptAppModalDialogViewsX11() { -} - -void JavaScriptAppModalDialogViewsX11::ShowAppModalDialog() { - // BrowserView::CanActivate() ensures that other browser windows cannot be - // activated for long while the dialog is visible. Block events to other - // browser windows so that the user cannot interact with other browser windows - // in the short time that the other browser windows are active. This hack is - // unnecessary on Windows and Chrome OS. - // TODO(pkotwicz): Find a better way of doing this and remove this hack. - if (!event_blocker_x11_.get()) { - event_blocker_x11_.reset( - new JavascriptAppModalEventBlockerX11(GetWidget()->GetNativeView())); - } - GetWidget()->Show(); -} - -void JavaScriptAppModalDialogViewsX11::WindowClosing() { - event_blocker_x11_.reset(); -}
diff --git a/chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.h b/chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.h deleted file mode 100644 index 68103f3..0000000 --- a/chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.h +++ /dev/null
@@ -1,39 +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 CHROME_BROWSER_UI_VIEWS_JAVASCRIPT_APP_MODAL_DIALOG_VIEWS_X11_H_ -#define CHROME_BROWSER_UI_VIEWS_JAVASCRIPT_APP_MODAL_DIALOG_VIEWS_X11_H_ - -#include <memory> - -#include "base/macros.h" -#include "components/javascript_dialogs/views/app_modal_dialog_view_views.h" - -class JavascriptAppModalEventBlockerX11; -class PopunderPreventer; - -// AppModalDialogView implementation for linux desktop. -class JavaScriptAppModalDialogViewsX11 - : public javascript_dialogs::AppModalDialogViewViews { - public: - explicit JavaScriptAppModalDialogViewsX11( - javascript_dialogs::AppModalDialogController* parent); - ~JavaScriptAppModalDialogViewsX11() override; - - // JavaScriptAppModalDialogViews: - void ShowAppModalDialog() override; - - // views::DialogDelegate: - void WindowClosing() override; - - private: - // Blocks events to other browser windows while the dialog is open. - std::unique_ptr<JavascriptAppModalEventBlockerX11> event_blocker_x11_; - - std::unique_ptr<PopunderPreventer> popunder_preventer_; - - DISALLOW_COPY_AND_ASSIGN(JavaScriptAppModalDialogViewsX11); -}; - -#endif // CHROME_BROWSER_UI_VIEWS_JAVASCRIPT_APP_MODAL_DIALOG_VIEWS_X11_H_
diff --git a/chrome/browser/ui/views/layout_provider_unittest.cc b/chrome/browser/ui/views/layout_provider_unittest.cc index f431b8da..0ba09e4 100644 --- a/chrome/browser/ui/views/layout_provider_unittest.cc +++ b/chrome/browser/ui/views/layout_provider_unittest.cc
@@ -394,7 +394,8 @@ // ChromeTypographyProvider::GetLineHeight(), which is body text. EXPECT_EQ(kBodyLineHeight, views::style::GetLineHeight(views::style::CONTEXT_LABEL, kStyle)); - views::StyledLabel styled_label(base::ASCIIToUTF16("test"), nullptr); + views::StyledLabel styled_label; + styled_label.SetText(base::ASCIIToUTF16("test")); constexpr int kStyledLabelWidth = 200; // Enough to avoid wrapping. styled_label.SizeToFit(kStyledLabelWidth); EXPECT_EQ(kBodyLineHeight, styled_label.height());
diff --git a/chrome/browser/ui/views/location_bar/star_menu_model.cc b/chrome/browser/ui/views/location_bar/star_menu_model.cc new file mode 100644 index 0000000..e987992 --- /dev/null +++ b/chrome/browser/ui/views/location_bar/star_menu_model.cc
@@ -0,0 +1,36 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/location_bar/star_menu_model.h" + +#include "chrome/grit/generated_resources.h" +#include "components/omnibox/browser/vector_icons.h" +#include "components/vector_icons/vector_icons.h" +#include "ui/base/models/image_model.h" + +StarMenuModel::StarMenuModel(ui::SimpleMenuModel::Delegate* delegate, + bool bookmarked, + bool exists_as_unread_in_read_later) + : SimpleMenuModel(delegate) { + Build(bookmarked, exists_as_unread_in_read_later); +} + +StarMenuModel::~StarMenuModel() = default; + +void StarMenuModel::Build(bool bookmarked, + bool exists_as_unread_in_read_later) { + AddItemWithStringIdAndIcon( + CommandBookmark, + bookmarked ? IDS_STAR_VIEW_MENU_EDIT_BOOKMARK + : IDS_STAR_VIEW_MENU_ADD_BOOKMARK, + ui::ImageModel::FromVectorIcon(omnibox::kStarIcon)); + // TODO(corising): Replace placeholder folder icon with read-later icon once + // available. + AddItemWithStringIdAndIcon( + exists_as_unread_in_read_later ? CommandMarkAsRead + : CommandMoveToReadLater, + exists_as_unread_in_read_later ? IDS_STAR_VIEW_MENU_MARK_AS_READ + : IDS_STAR_VIEW_MENU_MOVE_TO_READ_LATER, + ui::ImageModel::FromVectorIcon(vector_icons::kFolderIcon)); +}
diff --git a/chrome/browser/ui/views/location_bar/star_menu_model.h b/chrome/browser/ui/views/location_bar/star_menu_model.h new file mode 100644 index 0000000..e9e0bb7 --- /dev/null +++ b/chrome/browser/ui/views/location_bar/star_menu_model.h
@@ -0,0 +1,30 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_STAR_MENU_MODEL_H_ +#define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_STAR_MENU_MODEL_H_ + +#include "base/macros.h" +#include "ui/base/models/simple_menu_model.h" + +class StarMenuModel : public ui::SimpleMenuModel { + public: + StarMenuModel(ui::SimpleMenuModel::Delegate* delegate, + bool bookmarked, + bool exists_as_unread_in_read_later); + StarMenuModel(const StarMenuModel&) = delete; + StarMenuModel& operator=(const StarMenuModel&) = delete; + ~StarMenuModel() override; + + enum StarMenuCommand { + CommandBookmark, + CommandMoveToReadLater, + CommandMarkAsRead + }; + + private: + void Build(bool bookmarked, bool exists_as_unread_in_read_later); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_STAR_MENU_MODEL_H_
diff --git a/chrome/browser/ui/views/location_bar/star_view.cc b/chrome/browser/ui/views/location_bar/star_view.cc index 05edc8e..2f89bca 100644 --- a/chrome/browser/ui/views/location_bar/star_view.cc +++ b/chrome/browser/ui/views/location_bar/star_view.cc
@@ -15,9 +15,11 @@ #include "chrome/browser/ui/bookmarks/bookmark_stats.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h" #include "chrome/browser/ui/views/in_product_help/feature_promo_bubble_view.h" +#include "chrome/browser/ui/views/location_bar/star_menu_model.h" #include "chrome/grit/generated_resources.h" #include "components/bookmarks/common/bookmark_pref_names.h" #include "components/omnibox/browser/vector_icons.h" @@ -27,6 +29,7 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/paint_vector_icon.h" +#include "ui/views/controls/menu/menu_runner.h" StarView::StarView(CommandUpdater* command_updater, Browser* browser, @@ -38,6 +41,7 @@ page_action_icon_delegate), browser_(browser) { DCHECK(browser_); + edit_bookmarks_enabled_.Init( bookmarks::prefs::kEditBookmarksEnabled, browser_->profile()->GetPrefs(), base::BindRepeating(&StarView::EditBookmarksPrefUpdated, @@ -71,8 +75,19 @@ } void StarView::ExecuteCommand(ExecuteSource source) { - OnExecuting(source); - chrome::BookmarkCurrentTab(browser_); + if (base::FeatureList::IsEnabled(features::kReadLater)) { + menu_model_ = std::make_unique<StarMenuModel>( + this, active(), chrome::IsCurrentTabUnreadInReadLater(browser_)); + menu_runner_ = std::make_unique<views::MenuRunner>( + menu_model_.get(), + views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::FIXED_ANCHOR); + menu_runner_->RunMenuAt(GetWidget(), nullptr, GetAnchorBoundsInScreen(), + views::MenuAnchorPosition::kTopRight, + ui::MENU_SOURCE_NONE); + } else { + OnExecuting(source); + chrome::BookmarkCurrentTab(browser_); + } } views::BubbleDialogDelegate* StarView::GetBubble() const { @@ -95,3 +110,27 @@ void StarView::EditBookmarksPrefUpdated() { Update(); } + +void StarView::ExecuteCommand(int command_id, int event_flags) { + switch (command_id) { + case StarMenuModel::CommandBookmark: + chrome::BookmarkCurrentTab(browser_); + break; + case StarMenuModel::CommandMoveToReadLater: + chrome::MoveCurrentTabToReadLater(browser_); + break; + case StarMenuModel::CommandMarkAsRead: + chrome::MarkCurrentTabAsReadInReadLater(browser_); + break; + default: + NOTREACHED(); + } +} + +void StarView::MenuClosed(ui::SimpleMenuModel* source) { + if (!GetBubble() || !GetBubble()->GetWidget() || + !GetBubble()->GetWidget()->IsVisible()) { + SetHighlighted(false); + } + menu_runner_.reset(); +}
diff --git a/chrome/browser/ui/views/location_bar/star_view.h b/chrome/browser/ui/views/location_bar/star_view.h index 2c8c611e..40824d7e 100644 --- a/chrome/browser/ui/views/location_bar/star_view.h +++ b/chrome/browser/ui/views/location_bar/star_view.h
@@ -5,16 +5,21 @@ #ifndef CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_STAR_VIEW_H_ #define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_STAR_VIEW_H_ +#include <memory> + #include "base/macros.h" #include "base/scoped_observer.h" #include "chrome/browser/ui/views/page_action/page_action_icon_view.h" #include "components/prefs/pref_member.h" +#include "ui/base/models/simple_menu_model.h" class Browser; class CommandUpdater; +class StarMenuModel; // The star icon to show a bookmark bubble. -class StarView : public PageActionIconView { +class StarView : public PageActionIconView, + public ui::SimpleMenuModel::Delegate { public: StarView(CommandUpdater* command_updater, Browser* browser, @@ -22,6 +27,8 @@ PageActionIconView::Delegate* page_action_icon_delegate); ~StarView() override; + StarMenuModel* menu_model_for_test() { return menu_model_.get(); } + protected: // PageActionIconView: void UpdateImpl() override; @@ -36,8 +43,15 @@ void EditBookmarksPrefUpdated(); bool IsBookmarkStarHiddenByExtension() const; + // ui::SimpleMenuModel::Delegate: + void ExecuteCommand(int command_id, int event_flags) override; + void MenuClosed(ui::SimpleMenuModel* source) override; + Browser* const browser_; + std::unique_ptr<views::MenuRunner> menu_runner_; + std::unique_ptr<StarMenuModel> menu_model_; + BooleanPrefMember edit_bookmarks_enabled_; DISALLOW_COPY_AND_ASSIGN(StarView);
diff --git a/chrome/browser/ui/views/location_bar/star_view_interactive_uitest.cc b/chrome/browser/ui/views/location_bar/star_view_interactive_uitest.cc index 5794245..3b277b4 100644 --- a/chrome/browser/ui/views/location_bar/star_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/location_bar/star_view_interactive_uitest.cc
@@ -10,9 +10,13 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" +#include "chrome/browser/ui/read_later/read_later_test_utils.h" +#include "chrome/browser/ui/read_later/reading_list_model_factory.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views/location_bar/star_menu_model.h" #include "chrome/browser/ui/views/page_action/page_action_icon_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/common/pref_names.h" @@ -23,12 +27,15 @@ #include "components/bookmarks/browser/bookmark_utils.h" #include "components/bookmarks/test/bookmark_test_helpers.h" #include "components/prefs/pref_service.h" +#include "components/reading_list/core/reading_list_model.h" +#include "components/reading_list/core/reading_list_model_observer.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" #include "ui/base/ui_base_switches.h" #include "ui/events/event_utils.h" #include "ui/views/animation/test/ink_drop_host_view_test_api.h" +#include "ui/views/test/button_test_api.h" namespace { @@ -120,4 +127,109 @@ } } +class StarViewTestWithReadLaterEnabled : public InProcessBrowserTest { + public: + StarViewTestWithReadLaterEnabled() { + feature_list_.InitAndEnableFeature(features::kReadLater); + } + StarViewTestWithReadLaterEnabled(const StarViewTestWithReadLaterEnabled&) = + delete; + StarViewTestWithReadLaterEnabled& operator=( + const StarViewTestWithReadLaterEnabled&) = delete; + ~StarViewTestWithReadLaterEnabled() override = default; + + StarView* GetStarIcon() { + return static_cast<StarView*>( + BrowserView::GetBrowserViewForBrowser(browser()) + ->toolbar_button_provider() + ->GetPageActionIconView(PageActionIconType::kBookmarkStar)); + } + + void OpenStarViewMenu(StarView* star_icon) { + ui::MouseEvent pressed_event( + ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), + ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); + ui::MouseEvent released_event(ui::ET_MOUSE_RELEASED, gfx::Point(), + gfx::Point(), ui::EventTimeForNow(), + ui::EF_LEFT_MOUSE_BUTTON, + ui::EF_LEFT_MOUSE_BUTTON); + + views::test::ButtonTestApi(star_icon).NotifyClick(pressed_event); + views::test::ButtonTestApi(star_icon).NotifyClick(released_event); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +// Verifies clicking the bookmark button in the StarView's menu bookmarks the +// page. +IN_PROC_BROWSER_TEST_F(StarViewTestWithReadLaterEnabled, + AddBookmarkFromStarViewMenuBookmarksUrl) { + bookmarks::BookmarkModel* bookmark_model = + BookmarkModelFactory::GetForBrowserContext(browser()->profile()); + bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model); + + StarView* star_icon = GetStarIcon(); + const GURL current_url = + browser()->tab_strip_model()->GetActiveWebContents()->GetVisibleURL(); + + // The page should not initially be bookmarked. + EXPECT_FALSE(bookmark_model->IsBookmarked(current_url)); + EXPECT_FALSE(star_icon->active()); + + OpenStarViewMenu(star_icon); + + // The page should not be bookmarked when the menu is opened. + EXPECT_FALSE(bookmark_model->IsBookmarked(current_url)); + EXPECT_FALSE(star_icon->active()); + + StarMenuModel* menu_model = star_icon->menu_model_for_test(); + + // Activate "Add Bookmark" button in the menu and verify the bookmark is + // added. + const int bookmark_command_index = + menu_model->GetIndexOfCommandId(StarMenuModel::CommandBookmark); + menu_model->ActivatedAt(bookmark_command_index); + + EXPECT_TRUE(bookmark_model->IsBookmarked(current_url)); + EXPECT_TRUE(star_icon->active()); +} + +// Verifies clicking the Read Later button in the StarView's menu saves the page +// to the read later model. +IN_PROC_BROWSER_TEST_F(StarViewTestWithReadLaterEnabled, + AddToReadLaterFromStarViewMenuSavesUrlToReadLater) { + ReadingListModel* reading_list_model = + ReadingListModelFactory::GetForBrowserContext(browser()->profile()); + test::ReadingListLoadObserver(reading_list_model).Wait(); + GURL url("http://www.test.com/"); + ui_test_utils::NavigateToURL(browser(), url); + + StarView* star_icon = GetStarIcon(); + const GURL current_url = + browser()->tab_strip_model()->GetActiveWebContents()->GetVisibleURL(); + + // The page should not initially be in model. + EXPECT_EQ(reading_list_model->GetEntryByURL(current_url), nullptr); + EXPECT_FALSE(star_icon->active()); + + OpenStarViewMenu(star_icon); + + // The page should not be bookmarked when the menu is opened. + EXPECT_EQ(reading_list_model->GetEntryByURL(current_url), nullptr); + EXPECT_FALSE(star_icon->active()); + + StarMenuModel* menu_model = star_icon->menu_model_for_test(); + + // // Activate "Add to Read later" button in the menu and verify the entry is + // added. + const int read_later_command_index = + menu_model->GetIndexOfCommandId(StarMenuModel::CommandMoveToReadLater); + menu_model->ActivatedAt(read_later_command_index); + + EXPECT_NE(reading_list_model->GetEntryByURL(current_url), nullptr); + EXPECT_FALSE(star_icon->active()); +} + } // namespace
diff --git a/chrome/browser/ui/views/media_router/cloud_services_dialog_view.cc b/chrome/browser/ui/views/media_router/cloud_services_dialog_view.cc index a132762..66d54583 100644 --- a/chrome/browser/ui/views/media_router/cloud_services_dialog_view.cc +++ b/chrome/browser/ui/views/media_router/cloud_services_dialog_view.cc
@@ -114,10 +114,11 @@ views::StyledLabel::RangeStyleInfo::CreateForLink(); link_style.disable_line_wrapping = false; - views::StyledLabel* body_text = new views::StyledLabel(text, this); + views::StyledLabel* body_text = + AddChildView(std::make_unique<views::StyledLabel>(this)); + body_text->SetText(text); body_text->SetHorizontalAlignment(gfx::ALIGN_LEFT); body_text->AddStyleRange(learn_more_range, link_style); - AddChildView(body_text); } void CloudServicesDialogView::WindowClosing() {
diff --git a/chrome/browser/ui/views/native_file_system/native_file_system_ui_helpers.cc b/chrome/browser/ui/views/native_file_system/native_file_system_ui_helpers.cc index 4f27f26..3ebc61a 100644 --- a/chrome/browser/ui/views/native_file_system/native_file_system_ui_helpers.cc +++ b/chrome/browser/ui/views/native_file_system/native_file_system_ui_helpers.cc
@@ -20,9 +20,9 @@ url_formatter::FormatOriginForSecurityDisplay( origin, url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC); size_t offset; - auto label = std::make_unique<views::StyledLabel>( - l10n_util::GetStringFUTF16(message_id, formatted_origin, &offset), - nullptr); + auto label = std::make_unique<views::StyledLabel>(); + label->SetText( + l10n_util::GetStringFUTF16(message_id, formatted_origin, &offset)); label->SetTextContext(text_context); label->SetDefaultTextStyle(show_emphasis ? views::style::STYLE_SECONDARY : views::style::STYLE_PRIMARY); @@ -47,10 +47,9 @@ origin, url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC); base::string16 formatted_path = path.BaseName().LossyDisplayName(); std::vector<size_t> offsets; - auto label = std::make_unique<views::StyledLabel>( - l10n_util::GetStringFUTF16(message_id, formatted_origin, formatted_path, - &offsets), - nullptr); + auto label = std::make_unique<views::StyledLabel>(); + label->SetText(l10n_util::GetStringFUTF16(message_id, formatted_origin, + formatted_path, &offsets)); DCHECK_GE(offsets.size(), 2u); label->SetTextContext(text_context);
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc index cffc64f..14b41e3 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc
@@ -220,8 +220,8 @@ layout->StartRow(views::GridLayout::kFixedSize, label_column_status); - auto security_details_label = std::make_unique<views::StyledLabel>( - base::string16(), styled_label_listener); + auto security_details_label = + std::make_unique<views::StyledLabel>(styled_label_listener); security_details_label->SetID( PageInfoBubbleView::VIEW_ID_PAGE_INFO_LABEL_SECURITY_DETAILS); security_details_label_ = @@ -280,8 +280,10 @@ base::string16 text = base::ReplaceStringPlaceholders( base::ASCIIToUTF16("$1 $2"), subst, &offsets); - auto reset_cert_decisions_label = - std::make_unique<views::StyledLabel>(text, styled_label_listener_); + views::StyledLabel* reset_cert_decisions_label = + reset_decisions_label_container_->AddChildView( + std::make_unique<views::StyledLabel>(styled_label_listener_)); + reset_cert_decisions_label->SetText(text); reset_cert_decisions_label->SetID( PageInfoBubbleView::VIEW_ID_PAGE_INFO_LABEL_RESET_CERTIFICATE_DECISIONS); gfx::Range link_range(offsets[1], text.length()); @@ -293,8 +295,6 @@ reset_cert_decisions_label->AddStyleRange(link_range, link_style); // Fit the styled label to occupy available width. reset_cert_decisions_label->SizeToFit(0); - reset_decisions_label_container_->AddChildView( - std::move(reset_cert_decisions_label)); // Now that it contains a label, the container needs padding at the top. reset_decisions_label_container_->SetBorder(views::CreateEmptyBorder(
diff --git a/chrome/browser/ui/views/page_info/page_info_hover_button.cc b/chrome/browser/ui/views/page_info/page_info_hover_button.cc index a18fc7a..f3443aa 100644 --- a/chrome/browser/ui/views/page_info/page_info_hover_button.cc +++ b/chrome/browser/ui/views/page_info/page_info_hover_button.cc
@@ -59,15 +59,14 @@ icon_view_ = grid_layout->AddView(std::move(icon)); - auto title_label = - std::make_unique<views::StyledLabel>(base::string16(), nullptr); + auto title_label = std::make_unique<views::StyledLabel>(); title_label->SetTextContext(views::style::CONTEXT_LABEL); - // |views::StyledLabel|s are all multi-line. With a layout manager, - // |StyledLabel| will try use the available space to size itself, and long - // titles will wrap to the next line (for smaller |PageInfoHoverButton|s, this - // will also cover up |subtitle_|). Wrap it in a parent view with no layout - // manager to ensure it keeps its original size set by SizeToFit() above. Long - // titles will then be truncated. + // views::StyledLabels are all multi-line. With a layout manager, StyledLabel + // will try use the available space to size itself, and long titles will wrap + // to the next line (for smaller PageInfoHoverButtons, this will also cover up + // |subtitle_|). Wrap it in a parent view with no layout manager to ensure it + // keeps its original size set by SizeToFit() above. Long titles will then be + // truncated. auto title_wrapper = std::make_unique<views::View>(); title_ = title_wrapper->AddChildView(std::move(title_label)); SetTitleText(title_resource_id, secondary_text);
diff --git a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc index 3e925b6..3889bf3 100644 --- a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc +++ b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc
@@ -94,7 +94,8 @@ kSizeDeltaInPixels, gfx::Font::FontStyle::NORMAL, gfx::Font::Weight::NORMAL); - auto new_title = std::make_unique<views::StyledLabel>(title_text, nullptr); + auto new_title = std::make_unique<views::StyledLabel>(); + new_title->SetText(title_text); new_title->AddStyleRange(gfx::Range(0, title_text.length()), name_style); GetBubbleFrameView()->SetTitleView(std::move(new_title)); @@ -171,7 +172,8 @@ // More info button. auto info_text = l10n_util::GetStringUTF16(IDS_PAGE_INFO_SAFETY_TIP_MORE_INFO_LINK); - auto info_link = std::make_unique<views::StyledLabel>(info_text, this); + auto info_link = std::make_unique<views::StyledLabel>(this); + info_link->SetText(info_text); views::StyledLabel::RangeStyleInfo link_style = views::StyledLabel::RangeStyleInfo::CreateForLink(); gfx::Range details_range(0, info_text.length());
diff --git a/chrome/browser/ui/views/passwords/password_generation_confirmation_view.cc b/chrome/browser/ui/views/passwords/password_generation_confirmation_view.cc index 7bf196c..0113a46a 100644 --- a/chrome/browser/ui/views/passwords/password_generation_confirmation_view.cc +++ b/chrome/browser/ui/views/passwords/password_generation_confirmation_view.cc
@@ -32,8 +32,8 @@ SetButtons(ui::DIALOG_BUTTON_NONE); - auto label = std::make_unique<views::StyledLabel>( - controller_.save_confirmation_text(), this); + auto label = std::make_unique<views::StyledLabel>(this); + label->SetText(controller_.save_confirmation_text()); label->SetTextContext(CONTEXT_BODY_TEXT_LARGE); label->SetDefaultTextStyle(views::style::STYLE_SECONDARY); auto link_style = views::StyledLabel::RangeStyleInfo::CreateForLink();
diff --git a/chrome/browser/ui/views/passwords/post_save_compromised_bubble_view.cc b/chrome/browser/ui/views/passwords/post_save_compromised_bubble_view.cc index 3adb5efd..7ca73d76 100644 --- a/chrome/browser/ui/views/passwords/post_save_compromised_bubble_view.cc +++ b/chrome/browser/ui/views/passwords/post_save_compromised_bubble_view.cc
@@ -32,8 +32,8 @@ SetButtonLabel(ui::DIALOG_BUTTON_OK, std::move(button)); } - auto label = - std::make_unique<views::StyledLabel>(controller_.GetBody(), this); + auto label = std::make_unique<views::StyledLabel>(this); + label->SetText(controller_.GetBody()); label->SetTextContext(CONTEXT_BODY_TEXT_LARGE); label->SetDefaultTextStyle(views::style::STYLE_SECONDARY); gfx::Range range = controller_.GetSettingLinkRange();
diff --git a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc index 1cfab8a..ce5970a 100644 --- a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc
@@ -258,9 +258,10 @@ .release()); // "Edit" link. + auto edit_link = std::make_unique<views::StyledLabel>(this); base::string16 link_text = l10n_util::GetStringUTF16(IDS_AUTOFILL_WALLET_MANAGEMENT_LINK_TEXT); - auto edit_link = std::make_unique<views::StyledLabel>(link_text, this); + edit_link->SetText(link_text); edit_link->SetID( static_cast<int>(DialogViewID::GOOGLE_PAYMENTS_EDIT_LINK_LABEL)); edit_link->AddStyleRange(
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc index c5465bb..b18ec56 100644 --- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -981,6 +981,9 @@ // BEGIN_LINK and END_LINK. Find the beginning of the link range and the // length of the "settings" part, then remove the BEGIN_LINK and END_LINK // parts and linkify "settings". + // TODO(pkasting): Remove these BEGIN/END_LINK tags and use a substitution for + // "Settings", allowing this code to use the offset-returning versions of the + // l10n getters. base::string16 begin_tag = base::UTF8ToUTF16("BEGIN_LINK"); base::string16 end_tag = base::UTF8ToUTF16("END_LINK"); size_t link_begin = data_source.find(begin_tag); @@ -993,8 +996,8 @@ data_source.erase(link_end, end_tag.size()); data_source.erase(link_begin, begin_tag.size()); - std::unique_ptr<views::StyledLabel> data_source_label = - std::make_unique<views::StyledLabel>(data_source, this); + auto data_source_label = std::make_unique<views::StyledLabel>(this); + data_source_label->SetText(data_source); data_source_label->SetBorder(views::CreateEmptyBorder(22, 0, 0, 0)); data_source_label->SetID(static_cast<int>(DialogViewID::DATA_SOURCE_LABEL)); data_source_label->SetDefaultTextStyle(views::style::STYLE_DISABLED);
diff --git a/chrome/browser/ui/views/platform_keys_certificate_selector_chromeos.cc b/chrome/browser/ui/views/platform_keys_certificate_selector_chromeos.cc index 73206a5..0b76c52b 100644 --- a/chrome/browser/ui/views/platform_keys_certificate_selector_chromeos.cc +++ b/chrome/browser/ui/views/platform_keys_certificate_selector_chromeos.cc
@@ -82,12 +82,10 @@ void PlatformKeysCertificateSelector::Init() { const base::string16 name = base::ASCIIToUTF16(extension_name_); + auto label = std::make_unique<views::StyledLabel>(); size_t offset; - const base::string16 text = l10n_util::GetStringFUTF16( - IDS_PLATFORM_KEYS_SELECT_CERT_DIALOG_TEXT, name, &offset); - - std::unique_ptr<views::StyledLabel> label( - new views::StyledLabel(text, nullptr /* no listener */)); + label->SetText(l10n_util::GetStringFUTF16( + IDS_PLATFORM_KEYS_SELECT_CERT_DIALOG_TEXT, name, &offset)); views::StyledLabel::RangeStyleInfo bold_style; bold_style.text_style = STYLE_EMPHASIZED;
diff --git a/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.cc b/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.cc index 9f1a768..6a4214a5 100644 --- a/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.cc +++ b/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.cc
@@ -208,7 +208,8 @@ // Bold the domains in the message body label. views::StyledLabel* const styled_message_body_label = - new views::StyledLabel(message_body, nullptr); + content->AddChildView(std::make_unique<views::StyledLabel>()); + styled_message_body_label->SetText(message_body); views::StyledLabel::RangeStyleInfo bold_style; bold_style.text_style = STYLE_EMPHASIZED; for (size_t idx = 0; idx < placeholder_offsets.size(); idx++) { @@ -218,7 +219,6 @@ bold_style); } styled_message_body_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - content->AddChildView(std::move(styled_message_body_label)); AddChildView(std::move(illustration)); AddChildView(std::move(content)); }
diff --git a/chrome/browser/ui/views/safe_browsing/prompt_for_scanning_modal_dialog.cc b/chrome/browser/ui/views/safe_browsing/prompt_for_scanning_modal_dialog.cc index cd40003..13d0b312 100644 --- a/chrome/browser/ui/views/safe_browsing/prompt_for_scanning_modal_dialog.cc +++ b/chrome/browser/ui/views/safe_browsing/prompt_for_scanning_modal_dialog.cc
@@ -80,7 +80,8 @@ &offsets); // Add the message label. - auto label = std::make_unique<views::StyledLabel>(message_text, this); + auto label = std::make_unique<views::StyledLabel>(this); + label->SetText(message_text); gfx::Range learn_more_range(offsets[1], message_text.length()); views::StyledLabel::RangeStyleInfo link_style =
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.cc b/chrome/browser/ui/views/session_crashed_bubble_view.cc index 4330e2e..5a50d3b 100644 --- a/chrome/browser/ui/views/session_crashed_bubble_view.cc +++ b/chrome/browser/ui/views/session_crashed_bubble_view.cc
@@ -239,11 +239,12 @@ size_t offset; base::string16 link_text = l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_BUBBLE_UMA_LINK_TEXT); + auto uma_label = std::make_unique<views::StyledLabel>(this); base::string16 uma_text = l10n_util::GetStringFUTF16( IDS_SESSION_CRASHED_VIEW_UMA_OPTIN, link_text, &offset); - auto uma_label = std::make_unique<views::StyledLabel>(uma_text, this); + uma_label->SetText(uma_text); uma_label->AddStyleRange(gfx::Range(offset, offset + link_text.length()), views::StyledLabel::RangeStyleInfo::CreateForLink()); views::StyledLabel::RangeStyleInfo uma_style;
diff --git a/chrome/browser/ui/views/settings_reset_prompt_dialog.cc b/chrome/browser/ui/views/settings_reset_prompt_dialog.cc index e2d3f97f..d921156 100644 --- a/chrome/browser/ui/views/settings_reset_prompt_dialog.cc +++ b/chrome/browser/ui/views/settings_reset_prompt_dialog.cc
@@ -68,13 +68,13 @@ SetLayoutManager(std::make_unique<views::FillLayout>()); views::StyledLabel* dialog_label = - new views::StyledLabel(controller_->GetMainText(), /*listener=*/nullptr); + AddChildView(std::make_unique<views::StyledLabel>()); + dialog_label->SetText(controller_->GetMainText()); dialog_label->SetTextContext(CONTEXT_BODY_TEXT_LARGE); dialog_label->SetDefaultTextStyle(views::style::STYLE_SECONDARY); views::StyledLabel::RangeStyleInfo url_style; url_style.text_style = STYLE_EMPHASIZED_SECONDARY; dialog_label->AddStyleRange(controller_->GetMainTextUrlRange(), url_style); - AddChildView(dialog_label); } SettingsResetPromptDialog::~SettingsResetPromptDialog() {
diff --git a/chrome/browser/ui/views/sharing/sharing_dialog_view.cc b/chrome/browser/ui/views/sharing/sharing_dialog_view.cc index 9301209..2a860802 100644 --- a/chrome/browser/ui/views/sharing/sharing_dialog_view.cc +++ b/chrome/browser/ui/views/sharing/sharing_dialog_view.cc
@@ -126,10 +126,10 @@ DCHECK_NE(0, data.help_link_text_id); const base::string16 link = l10n_util::GetStringUTF16(data.help_link_text_id); size_t offset; - const base::string16 text = - show_origin ? PrepareHelpTextWithOrigin(data, link, &offset) - : PrepareHelpTextWithoutOrigin(data, link, &offset); - auto label = std::make_unique<views::StyledLabel>(text, listener); + auto label = std::make_unique<views::StyledLabel>(listener); + label->SetText(show_origin + ? PrepareHelpTextWithOrigin(data, link, &offset) + : PrepareHelpTextWithoutOrigin(data, link, &offset)); views::StyledLabel::RangeStyleInfo link_style = views::StyledLabel::RangeStyleInfo::CreateForLink(); label->AddStyleRange(gfx::Range(offset, offset + link.length()), link_style);
diff --git a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc index b0f51ed..80ff2b9 100644 --- a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc +++ b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
@@ -153,7 +153,8 @@ l10n_util::GetStringFUTF16( IDS_ENTERPRISE_SIGNIN_ALERT, domain, &offset); - auto prompt_label = std::make_unique<views::StyledLabel>(prompt_text, this); + auto prompt_label = std::make_unique<views::StyledLabel>(this); + prompt_label->SetText(prompt_text); prompt_label->SetDisplayedOnBackgroundColor(kPromptBarBackgroundColor); views::StyledLabel::RangeStyleInfo bold_style; @@ -178,8 +179,8 @@ IDS_ENTERPRISE_SIGNIN_EXPLANATION_WITH_PROFILE_CREATION : IDS_ENTERPRISE_SIGNIN_EXPLANATION_WITHOUT_PROFILE_CREATION, username, learn_more_text, &offsets); - auto explanation_label = - std::make_unique<views::StyledLabel>(signin_explanation_text, this); + auto explanation_label = std::make_unique<views::StyledLabel>(this); + explanation_label->SetText(signin_explanation_text); explanation_label->AddStyleRange( gfx::Range(offsets[1], offsets[1] + learn_more_text.size()), views::StyledLabel::RangeStyleInfo::CreateForLink());
diff --git a/chrome/browser/ui/views/toolbar/home_button.cc b/chrome/browser/ui/views/toolbar/home_button.cc index 1bbffb4..868b8e8 100644 --- a/chrome/browser/ui/views/toolbar/home_button.cc +++ b/chrome/browser/ui/views/toolbar/home_button.cc
@@ -106,9 +106,10 @@ l10n_util::GetStringUTF16(IDS_ONE_CLICK_BUBBLE_UNDO); std::vector<base::string16> message = { l10n_util::GetStringUTF16(IDS_TOOLBAR_INFORM_SET_HOME_PAGE), undo_string}; - views::StyledLabel* label = new views::StyledLabel( - base::JoinString(message, base::StringPiece16(base::ASCIIToUTF16(" "))), - this); + views::StyledLabel* label = + AddChildView(std::make_unique<views::StyledLabel>(this)); + label->SetText( + base::JoinString(message, base::StringPiece16(base::ASCIIToUTF16(" ")))); gfx::Range undo_range(label->GetText().length() - undo_string.length(), label->GetText().length()); @@ -117,7 +118,6 @@ // Ensure StyledLabel has a cached size to return in GetPreferredSize(). label->SizeToFit(0); - AddChildView(label); } void HomePageUndoBubble::StyledLabelLinkClicked(views::StyledLabel* label,
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc index b359de4..fedbb19 100644 --- a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc
@@ -16,7 +16,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h" #include "chromeos/components/multidevice/logging/logging.h" -#include "chromeos/components/phonehub/notification_access_manager.h" #include "chromeos/components/proximity_auth/proximity_auth_pref_names.h" #include "chromeos/constants/chromeos_features.h" #include "chromeos/services/multidevice_setup/public/cpp/prefs.h" @@ -44,6 +43,7 @@ const char kPageContentDataPhoneHubTaskContinuationStateKey[] = "phoneHubTaskContinuationState"; const char kPageContentDataSmartLockStateKey[] = "smartLockState"; +const char kIsNotificationAccessGranted[] = "isNotificationAccessGranted"; const char kIsAndroidSmsPairingComplete[] = "isAndroidSmsPairingComplete"; constexpr char kAndroidSmsInfoOriginKey[] = "origin"; @@ -73,7 +73,8 @@ android_sms_app_manager_(android_sms_app_manager), multidevice_setup_observer_(this), android_sms_pairing_state_tracker_observer_(this), - android_sms_app_manager_observer_(this) { + android_sms_app_manager_observer_(this), + notification_access_manager_observer_(this) { pref_change_registrar_.Init(prefs_); } @@ -134,6 +135,9 @@ if (multidevice_setup_client_) multidevice_setup_observer_.Add(multidevice_setup_client_); + if (notification_access_manager_) + notification_access_manager_observer_.Add(notification_access_manager_); + if (android_sms_pairing_state_tracker_) { android_sms_pairing_state_tracker_observer_.Add( android_sms_pairing_state_tracker_); @@ -160,8 +164,10 @@ if (multidevice_setup_client_) multidevice_setup_observer_.Remove(multidevice_setup_client_); - if (notification_access_manager_) + if (notification_access_manager_) { + notification_access_manager_observer_.Remove(notification_access_manager_); notification_access_operation_.reset(); + } if (android_sms_pairing_state_tracker_) { android_sms_pairing_state_tracker_observer_.Remove( @@ -189,6 +195,10 @@ NotifyAndroidSmsInfoChange(); } +void MultideviceHandler::OnNotificationAccessChanged() { + UpdatePageContent(); +} + void MultideviceHandler::OnPairingStateChanged() { UpdatePageContent(); NotifyAndroidSmsInfoChange(); @@ -385,7 +395,7 @@ void MultideviceHandler::OnStatusChange( phonehub::NotificationAccessSetupOperation::Status new_status) { - FireWebUIListener("notification-access-setup-operation-status-changed", + FireWebUIListener("settings.onNotificationAccessSetupStatusChanged", base::Value(static_cast<int32_t>(new_status))); if (phonehub::NotificationAccessSetupOperation::IsFinalStatus(new_status)) @@ -459,6 +469,12 @@ ? android_sms_pairing_state_tracker_->IsAndroidSmsPairingComplete() : false); + page_content_dictionary->SetBoolean( + kIsNotificationAccessGranted, + notification_access_manager_ + ? notification_access_manager_->HasAccessBeenGranted() + : false); + return page_content_dictionary; }
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h index 56fdd03..e4217ae 100644 --- a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h +++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h
@@ -12,6 +12,7 @@ #include "chrome/browser/chromeos/android_sms/android_sms_service_factory.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" #include "chromeos/components/multidevice/remote_device_ref.h" +#include "chromeos/components/phonehub/notification_access_manager.h" #include "chromeos/components/phonehub/notification_access_setup_operation.h" #include "chromeos/services/multidevice_setup/public/cpp/multidevice_setup_client.h" #include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom-forward.h" @@ -37,6 +38,7 @@ public multidevice_setup::MultiDeviceSetupClient::Observer, public multidevice_setup::AndroidSmsPairingStateTracker::Observer, public android_sms::AndroidSmsAppManager::Observer, + public phonehub::NotificationAccessManager::Observer, public phonehub::NotificationAccessSetupOperation::Delegate { public: MultideviceHandler( @@ -69,6 +71,9 @@ void OnStatusChange( phonehub::NotificationAccessSetupOperation::Status new_status) override; + // phonehub::NotificationAccessManager::Observer: + void OnNotificationAccessChanged() override; + // multidevice_setup::AndroidSmsPairingStateTracker::Observer: void OnPairingStateChanged() override; @@ -141,6 +146,9 @@ ScopedObserver<android_sms::AndroidSmsAppManager, android_sms::AndroidSmsAppManager::Observer> android_sms_app_manager_observer_; + ScopedObserver<phonehub::NotificationAccessManager, + phonehub::NotificationAccessManager::Observer> + notification_access_manager_observer_; // Used to cancel callbacks when JavaScript becomes disallowed. base::WeakPtrFactory<MultideviceHandler> callback_weak_ptr_factory_{this};
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc index 96a3b82..846566d 100644 --- a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc
@@ -361,12 +361,18 @@ fake_notification_access_manager()->SetNotificationSetupOperationStatus( status); + bool completed_successfully = status == + phonehub::NotificationAccessSetupOperation:: + Status::kCompletedSuccessfully; + if (completed_successfully) + call_data_count_before_call++; + EXPECT_EQ(call_data_count_before_call + 1u, test_web_ui()->call_data().size()); const content::TestWebUI::CallData& call_data = CallDataAtIndex(call_data_count_before_call); EXPECT_EQ("cr.webUIListenerCallback", call_data.function_name()); - EXPECT_EQ("notification-access-setup-operation-status-changed", + EXPECT_EQ("settings.onNotificationAccessSetupStatusChanged", call_data.arg1()->GetString()); EXPECT_EQ(call_data.arg2()->GetInt(), static_cast<int32_t>(status)); }
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc b/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc index c1d1df9..8107e64 100644 --- a/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc
@@ -246,6 +246,16 @@ IDS_SETTINGS_MULTIDEVICE_PHONE_HUB_NOTIFICATION_BADGE_SECTION_TITLE}, {"multidevicePhoneHubTaskContinuationItemTitle", IDS_SETTINGS_MULTIDEVICE_PHONE_HUB_TASK_CONTINUATION_SECTION_TITLE}, + {"multideviceNotificationAccessSetupAckTitle", + IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_ACK_TITLE}, + {"multideviceNotificationAccessSetupConnectingTitle", + IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_CONNECTING_TITLE}, + {"multideviceNotificationAccessSetupInstructions", + IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_INSTRUCTIONS}, + {"multideviceNotificationAccessSetupCompletedTitle", + IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_COMPLETED_TITLE}, + {"multideviceNotificationAccessSetupCompletedSummary", + IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_COMPLETED_SUMMARY}, {"multideviceInstantTetheringItemTitle", IDS_SETTINGS_MULTIDEVICE_INSTANT_TETHERING}, {"multideviceInstantTetheringItemSummary",
diff --git a/chrome/services/sharing/nearby/decoder/BUILD.gn b/chrome/services/sharing/nearby/decoder/BUILD.gn index 1d7ac30..f4845dc23 100644 --- a/chrome/services/sharing/nearby/decoder/BUILD.gn +++ b/chrome/services/sharing/nearby/decoder/BUILD.gn
@@ -37,8 +37,17 @@ ] } -fuzzer_test("nearby_decoder_fuzzer") { - sources = [ "nearby_decoder_fuzzer.cc" ] +fuzzer_test("nearby_decoder_decode_advertisement_fuzzer") { + sources = [ "nearby_decoder_decode_advertisement_fuzzer.cc" ] + deps = [ + ":decoder", + "//base", + "//mojo/core/embedder", + ] +} + +fuzzer_test("nearby_decoder_decode_frame_fuzzer") { + sources = [ "nearby_decoder_decode_frame_fuzzer.cc" ] deps = [ ":decoder", "//base",
diff --git a/chrome/services/sharing/nearby/decoder/DEPS b/chrome/services/sharing/nearby/decoder/DEPS index fa225c4..4775b2e0 100644 --- a/chrome/services/sharing/nearby/decoder/DEPS +++ b/chrome/services/sharing/nearby/decoder/DEPS
@@ -1,5 +1,5 @@ specific_include_rules = { - "nearby_decoder_fuzzer.cc": [ + ".*_fuzzer\.cc": [ "+mojo/core/embedder/embedder.h", ] }
diff --git a/chrome/services/sharing/nearby/decoder/nearby_decoder_fuzzer.cc b/chrome/services/sharing/nearby/decoder/nearby_decoder_decode_advertisement_fuzzer.cc similarity index 100% rename from chrome/services/sharing/nearby/decoder/nearby_decoder_fuzzer.cc rename to chrome/services/sharing/nearby/decoder/nearby_decoder_decode_advertisement_fuzzer.cc
diff --git a/chrome/services/sharing/nearby/decoder/nearby_decoder_decode_frame_fuzzer.cc b/chrome/services/sharing/nearby/decoder/nearby_decoder_decode_frame_fuzzer.cc new file mode 100644 index 0000000..cd68c0bb --- /dev/null +++ b/chrome/services/sharing/nearby/decoder/nearby_decoder_decode_frame_fuzzer.cc
@@ -0,0 +1,51 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/services/sharing/nearby/decoder/nearby_decoder.h" + +#include <stddef.h> +#include <stdint.h> +#include <memory> +#include <vector> + +#include "base/logging.h" +#include "base/no_destructor.h" +#include "base/run_loop.h" +#include "base/task/single_thread_task_executor.h" +#include "chrome/services/sharing/public/mojom/nearby_decoder.mojom.h" +#include "chrome/services/sharing/public/mojom/nearby_decoder_types.mojom.h" +#include "mojo/core/embedder/embedder.h" +#include "mojo/public/cpp/bindings/remote.h" + +struct Environment { + Environment() { + mojo::core::Init(); + // Disable noisy logging as per "libFuzzer in Chrome" documentation: + // testing/libfuzzer/getting_started.md#Disable-noisy-error-message-logging. + logging::SetMinLogLevel(logging::LOG_FATAL); + + // Create instance once to be reused between fuzzing rounds. + decoder = std::make_unique<sharing::NearbySharingDecoder>( + remote.BindNewPipeAndPassReceiver()); + } + + base::SingleThreadTaskExecutor task_executor; + mojo::Remote<sharing::mojom::NearbySharingDecoder> remote; + std::unique_ptr<sharing::NearbySharingDecoder> decoder; +}; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + static base::NoDestructor<Environment> environment; + + std::vector<uint8_t> buffer(data, data + size); + base::RunLoop run_loop; + environment->decoder->DecodeFrame( + buffer, + base::BindOnce([](base::RunLoop* run_loop, + sharing::mojom::FramePtr frame) { run_loop->Quit(); }, + &run_loop)); + run_loop.Run(); + + return 0; +}
diff --git a/chrome/services/sharing/nearby/nearby_connections_unittest.cc b/chrome/services/sharing/nearby/nearby_connections_unittest.cc index 9c25ebe..77a5318 100644 --- a/chrome/services/sharing/nearby/nearby_connections_unittest.cc +++ b/chrome/services/sharing/nearby/nearby_connections_unittest.cc
@@ -649,7 +649,7 @@ payload_progress_run_loop.Run(); } -// TOOD(crbug/1076008): Re-enable test after upprev NearbyConnections. +// TODO(crbug/1076008): Re-enable test after upprev NearbyConnections. TEST_F(NearbyConnectionsTest, DISABLED_SendBytesPayload) { const std::vector<uint8_t> expected_payload(std::begin(kPayload), std::end(kPayload)); @@ -693,7 +693,7 @@ send_payload_run_loop.Run(); } -// TOOD(crbug/1076008): Re-enable test after upprev NearbyConnections. +// TODO(crbug/1076008): Re-enable test after upprev NearbyConnections. TEST_F(NearbyConnectionsTest, DISABLED_SendBytesPayloadCancelled) { const std::vector<uint8_t> expected_payload(std::begin(kPayload), std::end(kPayload)); @@ -751,7 +751,7 @@ cancel_payload_run_loop.Run(); } -// TOOD(crbug/1076008): Re-enable test after upprev NearbyConnections. +// TODO(crbug/1076008): Re-enable test after upprev NearbyConnections. TEST_F(NearbyConnectionsTest, DISABLED_SendFilePayload) { const std::vector<uint8_t> expected_payload(std::begin(kPayload), std::end(kPayload));
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 07d4b69c..c6c9da6 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -4986,7 +4986,6 @@ "../browser/extensions/update_install_gate_unittest.cc", "../browser/extensions/updater/extension_update_client_command_line_config_policy_unittest.cc", "../browser/extensions/updater/extension_updater_unittest.cc", - "../browser/extensions/updater/parallel_unpacker_unittest.cc", "../browser/extensions/user_script_listener_unittest.cc", "../browser/extensions/warning_badge_service_unittest.cc", "../browser/extensions/webstore_installer_unittest.cc", @@ -6195,6 +6194,8 @@ if (toolkit_views) { sources += [ + "../browser/ui/read_later/read_later_test_utils.cc", + "../browser/ui/read_later/read_later_test_utils.h", "../browser/ui/views/bookmarks/bookmark_bar_view_test.cc", "../browser/ui/views/bookmarks/bookmark_bar_view_test_helper.h", "../browser/ui/views/certificate_selector_browsertest.cc",
diff --git a/chrome/test/data/ads_observer/ad_with_incomplete_resource.html b/chrome/test/data/ads_observer/ad_with_incomplete_resource.html index 38a8c05..b5df233c 100644 --- a/chrome/test/data/ads_observer/ad_with_incomplete_resource.html +++ b/chrome/test/data/ads_observer/ad_with_incomplete_resource.html
@@ -6,6 +6,10 @@ let adIframe = createAdIframe(); // "incomplete_resource.js" should never be a complete resource load. adIframe.srcdoc = "<link rel='preload' href='incomplete_resource.js' as='script'>"; + + function advanceSrcdoc() { + adIframe.srcdoc = "<link rel='preload' href='incomplete_resource2.js' as='script'>"; + } </script> </body>
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 72f82c9..a773a8c 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -1743,8 +1743,12 @@ "can_be_recommended": true, "policy_pref_mapping_test": [ { + "policies": { "BlockThirdPartyCookies": false }, + "prefs": { "profile.cookie_controls_mode": { "value": 0} } + }, + { "policies": { "BlockThirdPartyCookies": true }, - "prefs": { "profile.block_third_party_cookies": {} } + "prefs": { "profile.cookie_controls_mode": { "value": 1} } } ] },
diff --git a/chrome/test/data/webui/settings/chromeos/multidevice_notification_access_setup_dialog_tests.js b/chrome/test/data/webui/settings/chromeos/multidevice_notification_access_setup_dialog_tests.js new file mode 100644 index 0000000..db838dd --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/multidevice_notification_access_setup_dialog_tests.js
@@ -0,0 +1,97 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// clang-format off +// #import 'chrome://os-settings/chromeos/os_settings.js'; + +// #import {assertEquals, assertFalse, assertNotEquals, assertTrue} from '../../chai_assert.js'; +// #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +/** + * @fileoverview + * Suite of tests for multidevice-notification-access-setup-dialog element. + */ +suite('Multidevice', () => { + /** @type {?TestMultideviceBrowserProxy} */ + let browserProxy; + + /** @type {?MultideviceNotificationsOptInDialog} */ + let notificationAccessSetupDialog = null; + + /** @type {?HTMLElement} */ + let buttonContainer = null; + + /** + * @param {NotificationAccessSetupOperationStatus} status + */ + function simulateStatusChanged(status) { + cr.webUIListenerCallback('settings.onNotificationAccessSetupStatusChanged', + status); + Polymer.dom.flush(); + } + + setup(() => { + PolymerTest.clearBody(); + browserProxy = new multidevice.TestMultideviceBrowserProxy(); + settings.MultiDeviceBrowserProxyImpl.instance_ = browserProxy; + + notificationAccessSetupDialog = + document.createElement( + 'settings-multidevice-notification-access-setup-dialog'); + document.body.appendChild(notificationAccessSetupDialog); + Polymer.dom.flush(); + buttonContainer = + assert(notificationAccessSetupDialog.$$('#buttonContainer')); + }); + + test('Test success flow', async () => { + // The cancel and confirm buttons should be visible, and ok button hidden. + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertTrue(!!buttonContainer.querySelector('#confirmButton')); + assertFalse(!!buttonContainer.querySelector('#okButton')); + buttonContainer.querySelector('#confirmButton').click(); + assertEquals(browserProxy.getCallCount('attemptNotificationSetup'), 1); + + simulateStatusChanged(NotificationAccessSetupOperationStatus.CONNECTING); + + // The ok and confirm buttons should be hidden, and cancel button visible. + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#confirmButton')); + assertFalse(!!buttonContainer.querySelector('#okButton')); + + simulateStatusChanged( + NotificationAccessSetupOperationStatus.COMPLETED_SUCCESSFULLY); + + // The cancel and confirm buttons should be hidden, and ok button visible. + assertFalse(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#confirmButton')); + assertTrue(!!buttonContainer.querySelector('#okButton')); + + assertTrue(notificationAccessSetupDialog.$$('#dialog').open); + buttonContainer.querySelector('#okButton').click(); + assertFalse(notificationAccessSetupDialog.$$('#dialog').open); + }); + + test('Test cancel during connecting flow', async () => { + // The cancel and confirm buttons should be visible, and ok button hidden. + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertTrue(!!buttonContainer.querySelector('#confirmButton')); + assertFalse(!!buttonContainer.querySelector('#okButton')); + buttonContainer.querySelector('#confirmButton').click(); + assertEquals(browserProxy.getCallCount('attemptNotificationSetup'), 1); + + simulateStatusChanged(NotificationAccessSetupOperationStatus.CONNECTING); + + // The ok and confirm buttons should be hidden, and cancel button visible. + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#confirmButton')); + assertFalse(!!buttonContainer.querySelector('#okButton')); + + buttonContainer.querySelector('#cancelButton').click(); + assertEquals(browserProxy.getCallCount('cancelNotificationSetup'), 1); + + assertFalse(notificationAccessSetupDialog.$$('#dialog').open); + }); + +});
diff --git a/chrome/test/data/webui/settings/chromeos/multidevice_page_tests.js b/chrome/test/data/webui/settings/chromeos/multidevice_page_tests.js index ab03c40..6b6725b 100644 --- a/chrome/test/data/webui/settings/chromeos/multidevice_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/multidevice_page_tests.js
@@ -41,17 +41,41 @@ multidevice.createFakePageContentData(newMode, opt_newHostDeviceName)); } + /** + * @param {settings.MultiDeviceFeatureState} newState + */ function setSuiteState(newState) { setPageContentData(Object.assign( {}, multidevicePage.pageContentData, {betterTogetherState: newState})); } + /** + * @param {settings.MultiDeviceFeatureState} newState + */ function setSmartLockState(newState) { setPageContentData(Object.assign( {}, multidevicePage.pageContentData, {smartLockState: newState})); } /** + * @param {settings.MultiDeviceFeatureState} newState + */ + function setPhoneHubNotificationsState(newState) { + setPageContentData(Object.assign( + {}, multidevicePage.pageContentData, + {phoneHubNotificationsState: newState})); + } + + /** + * @param {boolean} accessGranted + */ + function setPhoneHubNotificationAccessGranted(accessGranted) { + setPageContentData(Object.assign( + {}, multidevicePage.pageContentData, + {isNotificationAccessGranted: accessGranted})); + } + + /** * @param {!settings.MultiDeviceFeature} feature The feature to change. * @param {boolean} enabled Whether to enable or disable the feature. * @param {boolean} authRequired Whether authentication is required for the @@ -77,10 +101,19 @@ // Simulate closing the password prompt dialog multidevicePage.$$('#multidevicePasswordPrompt').fire('close'); Polymer.dom.flush(); - } else { - assertFalse(multidevicePage.showPasswordPromptDialog_); } + if (enabled && + feature === settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS) { + const accessDialog = multidevicePage.$$( + 'settings-multidevice-notification-access-setup-dialog'); + assertEquals( + !accessDialog, + multidevicePage.pageContentData.isNotificationAccessGranted); + return; + } + + assertFalse(multidevicePage.showPasswordPromptDialog_); return browserProxy.whenCalled('setFeatureEnabledState').then(params => { assertEquals(feature, params[0]); assertEquals(enabled, params[1]); @@ -184,6 +217,36 @@ assertFalse(!!multidevicePage.$$('cr-policy-indicator')); }); + test('Phone hub notification access setup dialog', () => { + setPhoneHubNotificationsState( + settings.MultiDeviceFeatureState.DISABLED_BY_USER); + assertFalse(!!multidevicePage.$$( + 'settings-multidevice-notification-access-setup-dialog')); + + setPhoneHubNotificationAccessGranted(false); + simulateFeatureStateChangeRequest( + settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, + /*enabled=*/ true, /*authRequired=*/ false); + + // Close the dialog. + multidevicePage.showNotificationAccessSetupDialog_ = false; + + setPhoneHubNotificationAccessGranted(false); + simulateFeatureStateChangeRequest( + settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, + /*enabled=*/ false, /*authRequired=*/ false); + + setPhoneHubNotificationAccessGranted(true); + simulateFeatureStateChangeRequest( + settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, + /*enabled=*/ true, /*authRequired=*/ false); + + multidevicePage.pageContentData.isNotificationAccessGranted = true; + simulateFeatureStateChangeRequest( + settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, + /*enabled=*/ false, /*authRequired=*/ false); + }); + test('Disabling features never requires authentication', () => { const Feature = settings.MultiDeviceFeature;
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index d9f35c4..e014015 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -930,6 +930,31 @@ mocha.run(); }); +// Test fixture for the multidevice Notification access dialog flow. +// eslint-disable-next-line no-var +var OSSettingsMultideviceNotificationAccessDialogTest = + class extends OSSettingsBrowserTest { + /** @override */ + get browsePreload() { + return super.browsePreload + 'chromeos/multidevice_page/' + + 'multidevice_notification_access_setup_dialog.html'; + } + + /** @override */ + get extraLibraries() { + return super.extraLibraries.concat([ + BROWSER_SETTINGS_PATH + '../test_browser_proxy.js', + 'test_multidevice_browser_proxy.js', + 'multidevice_notification_access_setup_dialog_tests.js', + ]); + } +}; + +TEST_F( + 'OSSettingsMultideviceNotificationAccessDialogTest', 'AllJsTests', () => { + mocha.run(); + }); + // Test fixture for the multidevice settings subpage feature toggle. // eslint-disable-next-line no-var var OSSettingsMultideviceFeatureToggleTest =
diff --git a/chrome/test/data/webui/settings/chromeos/test_multidevice_browser_proxy.js b/chrome/test/data/webui/settings/chromeos/test_multidevice_browser_proxy.js index 4eb34b04..141c4ab9 100644 --- a/chrome/test/data/webui/settings/chromeos/test_multidevice_browser_proxy.js +++ b/chrome/test/data/webui/settings/chromeos/test_multidevice_browser_proxy.js
@@ -56,6 +56,8 @@ 'setSmartLockSignInEnabled', 'getSmartLockSignInAllowed', 'getAndroidSmsInfo', + 'attemptNotificationSetup', + 'cancelNotificationSetup', ]); this.data = createFakePageContentData( settings.MultiDeviceSettingsMode.NO_HOST_SET); @@ -113,6 +115,16 @@ this.methodCalled('getAndroidSmsInfo'); return Promise.resolve(this.androidSmsInfo); } + + /** @override */ + attemptNotificationSetup() { + this.methodCalled('attemptNotificationSetup'); + } + + /** @override */ + cancelNotificationSetup() { + this.methodCalled('cancelNotificationSetup'); + } } // #cr_define_end
diff --git a/chrome/tools/build/mac/FILES.cfg b/chrome/tools/build/mac/FILES.cfg index 3f19bd2..02691bf 100644 --- a/chrome/tools/build/mac/FILES.cfg +++ b/chrome/tools/build/mac/FILES.cfg
@@ -146,4 +146,10 @@ 'archive': 'updater.zip', 'optional': ['official'], # TODO(crbug.com/1024318): Make non-optional. }, + # Enterprise policy templates: + { + 'filename': 'gen/chrome/app/policy/mac/jamf.json', + 'buildtype': ['official'], + 'optional': ['official'], + } ]
diff --git a/chromecast/media/DEPS b/chromecast/media/DEPS index 56829e6..613654d6 100644 --- a/chromecast/media/DEPS +++ b/chromecast/media/DEPS
@@ -5,7 +5,6 @@ "+content/public/test/test_browser_thread.h", "+content/public/test/test_utils.h", "+content/renderer/media/audio/audio_device_factory.h", - "+content/renderer/media/audio/audio_output_ipc_factory.h", "+media/audio", "+media/base", "+media/cdm", @@ -17,6 +16,7 @@ "+ui/gfx/overlay_transform.h", "+services/service_manager/public", "+third_party/blink/public/platform/audio/web_audio_device_source_type.h", + "+third_party/blink/public/web/modules/media/audio/web_audio_output_ipc_factory.h", "+third_party/widevine/cdm/buildflags.h", "+third_party/widevine/cdm/widevine_cdm_common.h", ]
diff --git a/chromecast/media/audio/cast_audio_device_factory.cc b/chromecast/media/audio/cast_audio_device_factory.cc index 3ca3e601..e710b89 100644 --- a/chromecast/media/audio/cast_audio_device_factory.cc +++ b/chromecast/media/audio/cast_audio_device_factory.cc
@@ -6,12 +6,13 @@ #include <string> -#include "content/renderer/media/audio/audio_output_ipc_factory.h" +#include "base/logging.h" #include "media/audio/audio_output_device.h" #include "media/base/audio_capturer_source.h" #include "media/base/audio_parameters.h" #include "media/base/audio_renderer_sink.h" #include "media/base/output_device_info.h" +#include "third_party/blink/public/web/modules/media/audio/web_audio_output_ipc_factory.h" namespace chromecast { namespace media { @@ -82,8 +83,8 @@ const ::media::AudioSinkParameters& params, base::TimeDelta auth_timeout) { auto device = base::MakeRefCounted<::media::AudioOutputDevice>( - content::AudioOutputIPCFactory::get()->CreateAudioOutputIPC(frame_token), - content::AudioOutputIPCFactory::get()->io_task_runner(), params, + blink::WebAudioOutputIPCFactory::get()->CreateAudioOutputIPC(frame_token), + blink::WebAudioOutputIPCFactory::get()->io_task_runner(), params, auth_timeout); device->RequestDeviceAuthorization(); return device;
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 77258aa..77085de 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -13428.0.0 \ No newline at end of file +13430.0.0 \ No newline at end of file
diff --git a/chromeos/components/bloom/BUILD.gn b/chromeos/components/bloom/BUILD.gn new file mode 100644 index 0000000..a81786f --- /dev/null +++ b/chromeos/components/bloom/BUILD.gn
@@ -0,0 +1,18 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("bloom") { + sources = [ + "bloom_controller_impl.cc", + "bloom_controller_impl.h", + ] + + deps = [ + "//ash/public/cpp", + "//base", + "//chromeos/components/bloom/public/cpp", + "//components/signin/public/identity_manager", + "//services/network/public/cpp", + ] +}
diff --git a/chromeos/components/bloom/DEPS b/chromeos/components/bloom/DEPS new file mode 100644 index 0000000..c00284d3 --- /dev/null +++ b/chromeos/components/bloom/DEPS
@@ -0,0 +1,5 @@ +include_rules = [ + "+ash/public", + "+components/signin/public/identity_manager", + "+services/network/public", +]
diff --git a/chromeos/components/bloom/OWNERS b/chromeos/components/bloom/OWNERS new file mode 100644 index 0000000..0c730475 --- /dev/null +++ b/chromeos/components/bloom/OWNERS
@@ -0,0 +1,3 @@ +file://chromeos/assistant/OWNERS + +# COMPONENT: UI>Shell>Assistant
diff --git a/chromeos/components/bloom/bloom_controller_impl.cc b/chromeos/components/bloom/bloom_controller_impl.cc new file mode 100644 index 0000000..67d06b9 --- /dev/null +++ b/chromeos/components/bloom/bloom_controller_impl.cc
@@ -0,0 +1,44 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/components/bloom/bloom_controller_impl.h" + +#include "ash/public/cpp/assistant/controller/assistant_interaction_controller.h" + +namespace chromeos { +namespace bloom { + +BloomControllerImpl::BloomControllerImpl( + signin::IdentityManager* identity_manager, + ash::AssistantInteractionController* assistant_interaction_controller) + : identity_manager_(identity_manager), + assistant_interaction_controller_(assistant_interaction_controller) { + DCHECK(identity_manager_); + DCHECK(assistant_interaction_controller_); +} + +BloomControllerImpl::~BloomControllerImpl() = default; + +void BloomControllerImpl::StartInteraction() { + // TODO(jeroendh): Implement +} + +bool BloomControllerImpl::HasInteraction() const { + // TODO(jeroendh): Implement + return true; +} + +void BloomControllerImpl::StopInteraction( + BloomInteractionResolution resolution) { + // TODO(jeroendh): Implement + last_interaction_resolution_ = resolution; +} + +BloomInteractionResolution BloomControllerImpl::GetLastInteractionResolution() + const { + return last_interaction_resolution_; +} + +} // namespace bloom +} // namespace chromeos
diff --git a/chromeos/components/bloom/bloom_controller_impl.h b/chromeos/components/bloom/bloom_controller_impl.h new file mode 100644 index 0000000..6a8900b --- /dev/null +++ b/chromeos/components/bloom/bloom_controller_impl.h
@@ -0,0 +1,56 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_COMPONENTS_BLOOM_BLOOM_CONTROLLER_IMPL_H_ +#define CHROMEOS_COMPONENTS_BLOOM_BLOOM_CONTROLLER_IMPL_H_ + +#include "chromeos/components/bloom/public/cpp/bloom_controller.h" + +namespace ash { +class AssistantInteractionController; +} // namespace ash + +namespace signin { +class IdentityManager; +} // namespace signin + +namespace chromeos { +namespace bloom { + +class BloomInteraction; +class ScreenshotGrabber; + +class BloomControllerImpl : public BloomController { + public: + BloomControllerImpl( + signin::IdentityManager* identity_manager, + ash::AssistantInteractionController* assistant_interaction_controller); + BloomControllerImpl(const BloomControllerImpl&) = delete; + BloomControllerImpl& operator=(const BloomControllerImpl&) = delete; + ~BloomControllerImpl() override; + + // BloomController implementation: + void StartInteraction() override; + BloomInteractionResolution GetLastInteractionResolution() const override; + + bool HasInteraction() const; + void StopInteraction(BloomInteractionResolution resolution); + + signin::IdentityManager* identity_manager() { return identity_manager_; } + ash::AssistantInteractionController* assistant_interaction_controller() { + return assistant_interaction_controller_; + } + + private: + signin::IdentityManager* const identity_manager_; + ash::AssistantInteractionController* const assistant_interaction_controller_; + + BloomInteractionResolution last_interaction_resolution_ = + BloomInteractionResolution::kNormal; +}; + +} // namespace bloom +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_BLOOM_BLOOM_CONTROLLER_IMPL_H_
diff --git a/chromeos/components/bloom/public/cpp/BUILD.gn b/chromeos/components/bloom/public/cpp/BUILD.gn new file mode 100644 index 0000000..1a21e67 --- /dev/null +++ b/chromeos/components/bloom/public/cpp/BUILD.gn
@@ -0,0 +1,35 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +assert(is_chromeos, "Non-Chrome-OS builds must not depend on //chromeos") + +component("cpp") { + sources = [ + "bloom_controller.cc", + "bloom_controller.h", + "bloom_interaction_resolution.cc", + "bloom_interaction_resolution.h", + ] + + deps = [ "//base" ] + + defines = [ "IS_BLOOM_IMPL" ] + + # Prevent conflict with other targets called 'cpp'. + output_name = "bloom_public" +} + +component("bloom_controller_factory") { + sources = [ + "bloom_controller_factory.cc", + "bloom_controller_factory.h", + ] + + deps = [ + "//base", + "//chromeos/components/bloom", + ] + + defines = [ "IS_BLOOM_IMPL" ] +}
diff --git a/chromeos/components/bloom/public/cpp/bloom_controller.cc b/chromeos/components/bloom/public/cpp/bloom_controller.cc new file mode 100644 index 0000000..ad7981d --- /dev/null +++ b/chromeos/components/bloom/public/cpp/bloom_controller.cc
@@ -0,0 +1,33 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/components/bloom/public/cpp/bloom_controller.h" +#include "base/check_op.h" + +namespace chromeos { +namespace bloom { + +namespace { + +BloomController* g_instance = nullptr; + +} // namespace + +// static +BloomController* BloomController::Get() { + return g_instance; +} + +BloomController::BloomController() { + DCHECK_EQ(g_instance, nullptr); + g_instance = this; +} + +BloomController::~BloomController() { + DCHECK_EQ(g_instance, this); + g_instance = nullptr; +} + +} // namespace bloom +} // namespace chromeos
diff --git a/chromeos/components/bloom/public/cpp/bloom_controller.h b/chromeos/components/bloom/public/cpp/bloom_controller.h new file mode 100644 index 0000000..692c161 --- /dev/null +++ b/chromeos/components/bloom/public/cpp/bloom_controller.h
@@ -0,0 +1,38 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_COMPONENTS_BLOOM_PUBLIC_CPP_BLOOM_CONTROLLER_H_ +#define CHROMEOS_COMPONENTS_BLOOM_PUBLIC_CPP_BLOOM_CONTROLLER_H_ + +#include <memory> + +#include "base/component_export.h" +#include "chromeos/components/bloom/public/cpp/bloom_interaction_resolution.h" + +namespace chromeos { +namespace bloom { + +// Main controller for the Bloom integration. +class COMPONENT_EXPORT(BLOOM) BloomController { + public: + BloomController(); + BloomController(const BloomController&) = delete; + BloomController& operator=(const BloomController&) = delete; + virtual ~BloomController(); + + // Access the existing Bloom controller. + static BloomController* Get(); + + // Starts an interaction. This will ask the user for a screenshot, analyze the + // content and display the result. + virtual void StartInteraction() = 0; + + // Returns the result of the last interaction. + virtual BloomInteractionResolution GetLastInteractionResolution() const = 0; +}; + +} // namespace bloom +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_BLOOM_PUBLIC_CPP_BLOOM_CONTROLLER_H_
diff --git a/chromeos/components/bloom/public/cpp/bloom_controller_factory.cc b/chromeos/components/bloom/public/cpp/bloom_controller_factory.cc new file mode 100644 index 0000000..52acc0e8 --- /dev/null +++ b/chromeos/components/bloom/public/cpp/bloom_controller_factory.cc
@@ -0,0 +1,23 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/components/bloom/public/cpp/bloom_controller_factory.h" + +#include "base/callback.h" +#include "chromeos/components/bloom/bloom_controller_impl.h" + +namespace chromeos { +namespace bloom { + +// static +std::unique_ptr<BloomController> BloomControllerFactory::Create( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + signin::IdentityManager* identity_manager, + ash::AssistantInteractionController* assistant_interaction_controller) { + return std::make_unique<BloomControllerImpl>( + identity_manager, assistant_interaction_controller); +} + +} // namespace bloom +} // namespace chromeos
diff --git a/chromeos/components/bloom/public/cpp/bloom_controller_factory.h b/chromeos/components/bloom/public/cpp/bloom_controller_factory.h new file mode 100644 index 0000000..659bfa9 --- /dev/null +++ b/chromeos/components/bloom/public/cpp/bloom_controller_factory.h
@@ -0,0 +1,42 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_COMPONENTS_BLOOM_PUBLIC_CPP_BLOOM_CONTROLLER_FACTORY_H_ +#define CHROMEOS_COMPONENTS_BLOOM_PUBLIC_CPP_BLOOM_CONTROLLER_FACTORY_H_ + +#include <memory> + +#include "base/component_export.h" +#include "base/memory/scoped_refptr.h" + +namespace ash { +class AssistantInteractionController; +} // namespace ash + +namespace network { +class SharedURLLoaderFactory; +} // namespace network + +namespace signin { +class IdentityManager; +} // namespace signin + +namespace chromeos { +namespace bloom { + +class BloomController; + +class COMPONENT_EXPORT(BLOOM) BloomControllerFactory { + public: + // Create the Bloom controller. Can only be invoked once. + static std::unique_ptr<BloomController> Create( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + signin::IdentityManager* identity_manager, + ash::AssistantInteractionController* assistant_interaction_controller); +}; + +} // namespace bloom +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_BLOOM_PUBLIC_CPP_BLOOM_CONTROLLER_FACTORY_H_
diff --git a/chromeos/components/bloom/public/cpp/bloom_interaction_resolution.cc b/chromeos/components/bloom/public/cpp/bloom_interaction_resolution.cc new file mode 100644 index 0000000..60ca91f --- /dev/null +++ b/chromeos/components/bloom/public/cpp/bloom_interaction_resolution.cc
@@ -0,0 +1,23 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/components/bloom/public/cpp/bloom_interaction_resolution.h" + +namespace chromeos { +namespace bloom { + +#define CASE(name) \ + case BloomInteractionResolution::name: \ + return #name; + +std::string ToString(BloomInteractionResolution resolution) { + switch (resolution) { + CASE(kNormal); + CASE(kNoAccessToken); + CASE(kNoScreenshot); + } +} + +} // namespace bloom +} // namespace chromeos
diff --git a/chromeos/components/bloom/public/cpp/bloom_interaction_resolution.h b/chromeos/components/bloom/public/cpp/bloom_interaction_resolution.h new file mode 100644 index 0000000..295250f --- /dev/null +++ b/chromeos/components/bloom/public/cpp/bloom_interaction_resolution.h
@@ -0,0 +1,28 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_COMPONENTS_BLOOM_PUBLIC_CPP_BLOOM_INTERACTION_RESOLUTION_H_ +#define CHROMEOS_COMPONENTS_BLOOM_PUBLIC_CPP_BLOOM_INTERACTION_RESOLUTION_H_ + +#include <string> + +namespace chromeos { +namespace bloom { + +enum class BloomInteractionResolution { + // Bloom interaction completed normally. + kNormal = 0, + // Bloom interaction failed to fetch an access token. + kNoAccessToken = 1, + // Bloom interaction failed to take a screenshot + // (or the user aborted while taking a screenshot). + kNoScreenshot = 2, +}; + +std::string ToString(BloomInteractionResolution resolution); + +} // namespace bloom +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_BLOOM_PUBLIC_CPP_BLOOM_INTERACTION_RESOLUTION_H_
diff --git a/chromeos/components/phonehub/notification_access_setup_operation.h b/chromeos/components/phonehub/notification_access_setup_operation.h index 93833b57..d211fff 100644 --- a/chromeos/components/phonehub/notification_access_setup_operation.h +++ b/chromeos/components/phonehub/notification_access_setup_operation.h
@@ -27,7 +27,7 @@ class NotificationAccessSetupOperation { public: // Note: Numerical values should not be changed because they must stay in - // sync with values declared in JS. + // sync with multidevice_notification_access_setup_dialog.js. enum class Status { // Connecting to the phone in order to set up notification access. kConnecting = 0,
diff --git a/chromeos/components/scanning/mojom/BUILD.gn b/chromeos/components/scanning/mojom/BUILD.gn new file mode 100644 index 0000000..6085366 --- /dev/null +++ b/chromeos/components/scanning/mojom/BUILD.gn
@@ -0,0 +1,11 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//mojo/public/tools/bindings/mojom.gni") + +mojom("mojom") { + sources = [ "scanning.mojom" ] + + public_deps = [ "//mojo/public/mojom/base" ] +}
diff --git a/chromeos/components/scanning/mojom/OWNERS b/chromeos/components/scanning/mojom/OWNERS new file mode 100644 index 0000000..08850f4 --- /dev/null +++ b/chromeos/components/scanning/mojom/OWNERS
@@ -0,0 +1,2 @@ +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromeos/components/scanning/mojom/scanning.mojom b/chromeos/components/scanning/mojom/scanning.mojom new file mode 100644 index 0000000..358ce95 --- /dev/null +++ b/chromeos/components/scanning/mojom/scanning.mojom
@@ -0,0 +1,26 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module chromeos.scanning.mojom; + +import "mojo/public/mojom/base/string16.mojom"; +import "mojo/public/mojom/base/unguessable_token.mojom"; + +// Represents a connected scanner. +struct Scanner { + // The scanner's unique identifier. + mojo_base.mojom.UnguessableToken id; + // The scanner's display name. + mojo_base.mojom.String16 display_name; +}; + +// Interface used to obtain information about and interact with connected +// scanners. It is implemented in the browser and exposed to the Scan app +// (chrome://scanning). +interface ScanService { + // Returns the connected scanners. Obtaining a scanner's capabilities is + // implemented in a separate method to minimize the amount of time clients + // must wait before receiving the scanners and displaying their display names. + GetScanners() => (array<Scanner> scanners); +};
diff --git a/components/autofill/android/BUILD.gn b/components/autofill/android/BUILD.gn index 219ef4c2..b2f3237 100644 --- a/components/autofill/android/BUILD.gn +++ b/components/autofill/android/BUILD.gn
@@ -40,10 +40,10 @@ ":autofill_java_resources", "//base:base_java", "//content/public/android:content_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", - "//ui/android:ui_java", + "//third_party/android_deps:androidx_core_core_java", + "//ui/android:ui_no_recycler_view_java", ] sources = [ "java/src/org/chromium/components/autofill/AutofillDelegate.java",
diff --git a/components/autofill/android/provider/BUILD.gn b/components/autofill/android/provider/BUILD.gn index 263b88a..bff17102 100644 --- a/components/autofill/android/provider/BUILD.gn +++ b/components/autofill/android/provider/BUILD.gn
@@ -14,7 +14,7 @@ "//components/version_info/android:version_constants_java", "//content/public/android:content_java", "//third_party/android_deps:androidx_annotation_annotation_java", - "//ui/android:ui_java", + "//ui/android:ui_no_recycler_view_java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] sources = [
diff --git a/components/autofill/ios/form_util/resources/fill.js b/components/autofill/ios/form_util/resources/fill.js index 8c33cbc..6117e8b 100644 --- a/components/autofill/ios/form_util/resources/fill.js +++ b/components/autofill/ios/form_util/resources/fill.js
@@ -2320,7 +2320,10 @@ __gCrWeb.fill.setUniqueIDIfNeeded = function(element) { try { const uniqueID = Symbol.for(__gCrWeb.fill.UNIQUE_ID_SYMBOL_NAME); - if (typeof element[uniqueID] === 'undefined') { + // Do not assign element id value if the base value for the document + // is not set. + if (typeof document[uniqueID] !== 'undefined' && + typeof element[uniqueID] === 'undefined') { element[uniqueID] = document[uniqueID]++; } } catch (e) {
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h index 544a947..736ea0c8 100644 --- a/components/autofill_assistant/browser/actions/action_delegate.h +++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -130,7 +130,8 @@ std::unique_ptr<std::vector<UserAction>> user_actions, bool disable_force_expand_sheet, base::OnceCallback<void()> end_on_navigation_callback = base::DoNothing(), - bool browse_mode = false) = 0; + bool browse_mode = false, + bool browse_mode_invisible = false) = 0; // Have the UI leave the prompt state and go back to its previous state. virtual void CleanUpAfterPrompt() = 0;
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h index 2aeff07..27169c74 100644 --- a/components/autofill_assistant/browser/actions/mock_action_delegate.h +++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -77,11 +77,12 @@ void(const ElementFinder::Result& element, base::OnceCallback<void(const ClientStatus&)> callback)); - MOCK_METHOD4(Prompt, + MOCK_METHOD5(Prompt, void(std::unique_ptr<std::vector<UserAction>> user_actions, bool disable_force_expand_sheet, base::OnceCallback<void()> end_on_navigation_callback, - bool browse_mode)); + bool browse_mode, + bool browse_mode_invisible)); MOCK_METHOD0(CleanUpAfterPrompt, void()); MOCK_METHOD1(SetBrowseDomainsWhitelist, void(std::vector<std::string> domains));
diff --git a/components/autofill_assistant/browser/actions/prompt_action.cc b/components/autofill_assistant/browser/actions/prompt_action.cc index 9f1cd9c..d58874a 100644 --- a/components/autofill_assistant/browser/actions/prompt_action.cc +++ b/components/autofill_assistant/browser/actions/prompt_action.cc
@@ -162,7 +162,8 @@ } delegate_->Prompt( std::move(user_actions), proto_.prompt().disable_force_expand_sheet(), - std::move(end_on_navigation_callback), proto_.prompt().browse_mode()); + std::move(end_on_navigation_callback), proto_.prompt().browse_mode(), + proto_.prompt().browse_mode_invisible()); precondition_changed_ = false; }
diff --git a/components/autofill_assistant/browser/actions/prompt_action_unittest.cc b/components/autofill_assistant/browser/actions/prompt_action_unittest.cc index afb7d7a6..3e66b265 100644 --- a/components/autofill_assistant/browser/actions/prompt_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/prompt_action_unittest.cc
@@ -45,13 +45,14 @@ EXPECT_CALL(mock_action_delegate_, OnWaitForDom(_, _, _, _)) .WillRepeatedly(Invoke(this, &PromptActionTest::FakeWaitForDom)); - ON_CALL(mock_action_delegate_, Prompt(_, _, _, _)) - .WillByDefault(Invoke( + ON_CALL(mock_action_delegate_, Prompt(_, _, _, _, _)) + .WillByDefault( [this](std::unique_ptr<std::vector<UserAction>> user_actions, bool disable_force_expand_sheet, - base::OnceCallback<void()> callback, bool browse_mode) { + base::OnceCallback<void()> callback, bool browse_mode, + bool browse_mode_invisible) { user_actions_ = std::move(user_actions); - })); + }); prompt_proto_ = proto_.mutable_prompt(); } @@ -370,7 +371,7 @@ ok_proto->mutable_chip()->set_type(HIGHLIGHTED_ACTION); ok_proto->set_server_payload("ok"); - EXPECT_CALL(mock_action_delegate_, Prompt(_, Eq(false), _, Eq(false))); + EXPECT_CALL(mock_action_delegate_, Prompt(_, false, _, false, false)); PromptAction action(&mock_action_delegate_, proto_); action.ProcessAction(callback_.Get()); } @@ -382,7 +383,7 @@ ok_proto->set_server_payload("ok"); prompt_proto_->set_disable_force_expand_sheet(true); - EXPECT_CALL(mock_action_delegate_, Prompt(_, Eq(true), _, Eq(false))); + EXPECT_CALL(mock_action_delegate_, Prompt(_, true, _, false, false)); PromptAction action(&mock_action_delegate_, proto_); action.ProcessAction(callback_.Get()); } @@ -394,7 +395,20 @@ ok_proto->set_server_payload("ok"); prompt_proto_->set_browse_mode(true); - EXPECT_CALL(mock_action_delegate_, Prompt(_, Eq(false), _, Eq(true))); + EXPECT_CALL(mock_action_delegate_, Prompt(_, false, _, true, false)); + PromptAction action(&mock_action_delegate_, proto_); + action.ProcessAction(callback_.Get()); +} + +TEST_F(PromptActionTest, RunPromptInInvisibleBrowseMode) { + auto* ok_proto = prompt_proto_->add_choices(); + ok_proto->mutable_chip()->set_text("Ok"); + ok_proto->mutable_chip()->set_type(HIGHLIGHTED_ACTION); + ok_proto->set_server_payload("ok"); + + prompt_proto_->set_browse_mode(true); + prompt_proto_->set_browse_mode_invisible(true); + EXPECT_CALL(mock_action_delegate_, Prompt(_, false, _, true, true)); PromptAction action(&mock_action_delegate_, proto_); action.ProcessAction(callback_.Get()); } @@ -427,14 +441,14 @@ } TEST_F(PromptActionTest, EndActionOnNavigation) { - EXPECT_CALL(mock_action_delegate_, Prompt(_, _, _, _)) - .WillOnce( - Invoke([this](std::unique_ptr<std::vector<UserAction>> user_actions, - bool disable_force_expand_sheet, - base::OnceCallback<void()> callback, bool browse_mode) { - user_actions_ = std::move(user_actions); - std::move(callback).Run(); - })); + EXPECT_CALL(mock_action_delegate_, Prompt(_, _, _, _, _)) + .WillOnce([this](std::unique_ptr<std::vector<UserAction>> user_actions, + bool disable_force_expand_sheet, + base::OnceCallback<void()> callback, bool browse_mode, + bool browse_mode_invisible) { + user_actions_ = std::move(user_actions); + std::move(callback).Run(); + }); prompt_proto_->set_end_on_navigation(true); prompt_proto_->add_choices()->mutable_chip()->set_text("ok");
diff --git a/components/autofill_assistant/browser/actions/show_generic_ui_action_unittest.cc b/components/autofill_assistant/browser/actions/show_generic_ui_action_unittest.cc index e5129d0..469beb5 100644 --- a/components/autofill_assistant/browser/actions/show_generic_ui_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/show_generic_ui_action_unittest.cc
@@ -116,7 +116,7 @@ TEST_F(ShowGenericUiActionTest, GoesIntoPromptState) { InSequence seq; - EXPECT_CALL(mock_action_delegate_, Prompt(_, _, _, _)).Times(1); + EXPECT_CALL(mock_action_delegate_, Prompt(_, _, _, _, _)).Times(1); EXPECT_CALL(mock_action_delegate_, OnSetGenericUi(_, _, _)).Times(1); EXPECT_CALL(mock_action_delegate_, ClearGenericUi()).Times(1); EXPECT_CALL(mock_action_delegate_, CleanUpAfterPrompt()).Times(1); @@ -469,12 +469,13 @@ std::move(view_inflation_finished_callback) .Run(ClientStatus(ACTION_APPLIED)); })); - EXPECT_CALL(mock_action_delegate_, Prompt(_, _, _, _)) - .WillOnce(Invoke( - [](std::unique_ptr<std::vector<UserAction>> user_actions, - bool disable_force_expand_sheet, - base::OnceCallback<void()> end_navigation_callback, - bool browse_mode) { std::move(end_navigation_callback).Run(); })); + EXPECT_CALL(mock_action_delegate_, Prompt(_, _, _, _, _)) + .WillOnce([](std::unique_ptr<std::vector<UserAction>> user_actions, + bool disable_force_expand_sheet, + base::OnceCallback<void()> end_navigation_callback, + bool browse_mode, bool browse_mode_invisible) { + std::move(end_navigation_callback).Run(); + }); EXPECT_CALL(mock_action_delegate_, CleanUpAfterPrompt()).Times(1); EXPECT_CALL( callback_, @@ -490,12 +491,13 @@ TEST_F(ShowGenericUiActionTest, BreakingNavigationBeforeUiIsSet) { // End action immediately with ACTION_APPLIED after it goes into prompt. - EXPECT_CALL(mock_action_delegate_, Prompt(_, _, _, _)) - .WillOnce(Invoke( - [](std::unique_ptr<std::vector<UserAction>> user_actions, - bool disable_force_expand_sheet, - base::OnceCallback<void()> end_navigation_callback, - bool browse_mode) { std::move(end_navigation_callback).Run(); })); + EXPECT_CALL(mock_action_delegate_, Prompt(_, _, _, _, _)) + .WillOnce([](std::unique_ptr<std::vector<UserAction>> user_actions, + bool disable_force_expand_sheet, + base::OnceCallback<void()> end_navigation_callback, + bool browse_mode, bool browse_mode_invisible) { + std::move(end_navigation_callback).Run(); + }); ON_CALL(mock_action_delegate_, OnSetGenericUi(_, _, _)) .WillByDefault( Invoke([&](std::unique_ptr<GenericUserInterfaceProto> generic_ui,
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc index eb6faea7..ced45b0a 100644 --- a/components/autofill_assistant/browser/controller.cc +++ b/components/autofill_assistant/browser/controller.cc
@@ -49,13 +49,13 @@ // // Note that the UI might be shown in RUNNING state, even if it doesn't require // it. -bool StateNeedsUiInRegularScript(AutofillAssistantState state) { +bool StateNeedsUiInRegularScript(AutofillAssistantState state, + bool browse_mode_invisible) { switch (state) { case AutofillAssistantState::PROMPT: case AutofillAssistantState::AUTOSTART_FALLBACK_PROMPT: case AutofillAssistantState::MODAL_DIALOG: case AutofillAssistantState::STARTING: - case AutofillAssistantState::BROWSE: return true; case AutofillAssistantState::INACTIVE: @@ -63,11 +63,14 @@ case AutofillAssistantState::STOPPED: case AutofillAssistantState::RUNNING: return false; + + case AutofillAssistantState::BROWSE: + return browse_mode_invisible; } } -// Same as |StateNeedsUiInRegularScript|, but does not show UI in STARTING or -// BROWSE state. +// Same as |StateNeedsUiInRegularScript|, but does not show UI in STARTING +// state. bool StateNeedsUiInLiteScript(AutofillAssistantState state) { switch (state) { case AutofillAssistantState::PROMPT: @@ -382,6 +385,10 @@ } } +void Controller::SetBrowseModeInvisible(bool invisible) { + browse_mode_invisible_ = invisible; +} + void Controller::AddNavigationListener( ScriptExecutorDelegate::NavigationListener* listener) { navigation_listeners_.AddObserver(listener); @@ -703,6 +710,10 @@ RequireUI(); } else if (needs_ui_ && state == AutofillAssistantState::TRACKING) { needs_ui_ = false; + } else if (browse_mode_invisible_ && needs_ui_ && + state == AutofillAssistantState::BROWSE) { + client_->DestroyUI(); + needs_ui_ = false; } if (ShouldCheckScripts()) { @@ -1917,7 +1928,7 @@ bool Controller::StateNeedsUI(AutofillAssistantState state) { if (!trigger_context_ || !trigger_context_->is_lite_script()) { - return StateNeedsUiInRegularScript(state); + return StateNeedsUiInRegularScript(state, browse_mode_invisible_); } return StateNeedsUiInLiteScript(state); }
diff --git a/components/autofill_assistant/browser/controller.h b/components/autofill_assistant/browser/controller.h index dd32747..f6006aa 100644 --- a/components/autofill_assistant/browser/controller.h +++ b/components/autofill_assistant/browser/controller.h
@@ -143,6 +143,7 @@ base::OnceCallback<void(const ClientStatus&)> view_inflation_finished_callback) override; void ClearGenericUi() override; + void SetBrowseModeInvisible(bool invisible) override; // Show the UI if it's not already shown. This is only meaningful while in // states where showing the UI is optional, such as RUNNING, in tracking mode. @@ -497,6 +498,7 @@ bool expand_sheet_for_prompt_action_ = true; std::vector<std::string> browse_domains_whitelist_; + bool browse_mode_invisible_ = false; // Only set during a ShowGenericUiAction. std::unique_ptr<GenericUserInterfaceProto> generic_user_interface_;
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.cc b/components/autofill_assistant/browser/fake_script_executor_delegate.cc index 27ab678d..8fab50b3 100644 --- a/components/autofill_assistant/browser/fake_script_executor_delegate.cc +++ b/components/autofill_assistant/browser/fake_script_executor_delegate.cc
@@ -237,4 +237,6 @@ void FakeScriptExecutorDelegate::SetOverlayBehavior( ConfigureUiStateProto::OverlayBehavior overaly_behavior) {} +void FakeScriptExecutorDelegate::SetBrowseModeInvisible(bool invisible) {} + } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.h b/components/autofill_assistant/browser/fake_script_executor_delegate.h index ff38b8f..1680d6a 100644 --- a/components/autofill_assistant/browser/fake_script_executor_delegate.h +++ b/components/autofill_assistant/browser/fake_script_executor_delegate.h
@@ -92,6 +92,7 @@ void ClearGenericUi() override; void SetOverlayBehavior( ConfigureUiStateProto::OverlayBehavior overlay_behavior) override; + void SetBrowseModeInvisible(bool invisible) override; ClientSettings* GetMutableSettings() { return &client_settings_; }
diff --git a/components/autofill_assistant/browser/lite_service.h b/components/autofill_assistant/browser/lite_service.h index 3e90af7..e1a6911 100644 --- a/components/autofill_assistant/browser/lite_service.h +++ b/components/autofill_assistant/browser/lite_service.h
@@ -68,9 +68,9 @@ bool result, const std::string& response); - // Stops the script and closes autobot without showing an error message. - // This is done by running an explicit stop action, followed by an empty - // response in |GetNextActions|. + // Stops the script and closes autofill assistant without showing an error + // message. This is done by running an explicit stop action, followed by an + // empty response in |GetNextActions|. void StopWithoutErrorMessage(ResponseCallback callback, Metrics::LiteScriptFinishedState state);
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc index b9ef1dc..961593a 100644 --- a/components/autofill_assistant/browser/script_executor.cc +++ b/components/autofill_assistant/browser/script_executor.cc
@@ -427,10 +427,12 @@ std::unique_ptr<std::vector<UserAction>> user_actions, bool disable_force_expand_sheet, base::OnceCallback<void()> end_on_navigation_callback, - bool browse_mode) { + bool browse_mode, + bool browse_mode_invisible) { // First communicate to the delegate that prompt actions should or should not // expand the sheet intitially. delegate_->SetExpandSheetForPromptAction(!disable_force_expand_sheet); + delegate_->SetBrowseModeInvisible(browse_mode_invisible); if (browse_mode) { delegate_->EnterState(AutofillAssistantState::BROWSE); } else if (delegate_->EnterState(AutofillAssistantState::PROMPT)) { @@ -471,6 +473,7 @@ delegate_->ClearTouchableElementArea(); delegate_->SetExpandSheetForPromptAction(true); + delegate_->SetBrowseModeInvisible(false); delegate_->EnterState(AutofillAssistantState::RUNNING); }
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h index b62fa73..4af332f8 100644 --- a/components/autofill_assistant/browser/script_executor.h +++ b/components/autofill_assistant/browser/script_executor.h
@@ -147,7 +147,8 @@ void Prompt(std::unique_ptr<std::vector<UserAction>> user_actions, bool disable_force_expand_sheet, base::OnceCallback<void()> end_on_navigation_callback, - bool browse_mode) override; + bool browse_mode, + bool browse_mode_invisible) override; void CleanUpAfterPrompt() override; void SetBrowseDomainsWhitelist(std::vector<std::string> domains) override; void FillAddressForm(
diff --git a/components/autofill_assistant/browser/script_executor_delegate.h b/components/autofill_assistant/browser/script_executor_delegate.h index 4809e69e..6170d75 100644 --- a/components/autofill_assistant/browser/script_executor_delegate.h +++ b/components/autofill_assistant/browser/script_executor_delegate.h
@@ -180,6 +180,10 @@ // Clears the generic UI. virtual void ClearGenericUi() = 0; + // Sets whether browse mode should be invisible or not. Must be set before + // calling |EnterState(BROWSE)| to take effect. + virtual void SetBrowseModeInvisible(bool invisible) = 0; + protected: virtual ~ScriptExecutorDelegate() {} };
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index a6c3a70a..57986f6 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -1449,6 +1449,16 @@ // TODO(marianfe): Consider introducing a BrowseAction instead. optional bool browse_mode = 7; + // EXPERIMENTAL. + // Only relevant if |browse_mode| is true. If set, the bottom sheet will + // completely disappear when the action starts, and re-appear when the action + // ends. + // + // Note: invisible prompts can't show chips to the user. This flag is intended + // to be used with prompts that exclusively use choices which are + // auto-selected based on DOM state, i.e., |auto_select_when|. + optional bool browse_mode_invisible = 10; + // When set to true, end prompt on navigation events happening during a prompt // action. The result sent back to the server in // ProcessedActionProto.prompt_choice will have |navigation_ended| set to
diff --git a/components/browser_ui/modaldialog/android/BUILD.gn b/components/browser_ui/modaldialog/android/BUILD.gn index e43c6a6..f3dc112 100644 --- a/components/browser_ui/modaldialog/android/BUILD.gn +++ b/components/browser_ui/modaldialog/android/BUILD.gn
@@ -75,13 +75,10 @@ testonly = true create_srcjar = false - sources = [ - "test/java/res/drawable/ic_add.xml", - "test/java/res/values/ids.xml", - "test/java/res/values/strings.xml", - ] + sources = [ "test/java/res/values/ids.xml" ] deps = [ ":java_resources", + "//components/browser_ui/strings/android:browser_ui_strings_grd", "//ui/android:ui_java_resources", ] }
diff --git a/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogViewTest.java b/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogViewTest.java index 225470cf..5017137 100644 --- a/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogViewTest.java +++ b/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogViewTest.java
@@ -159,7 +159,7 @@ public void testTitleIcon() { // Verify that the icon set from builder is displayed. PropertyModel model = createModel(mModelBuilder.with( - ModalDialogProperties.TITLE_ICON, getActivity(), R.drawable.ic_add)); + ModalDialogProperties.TITLE_ICON, getActivity(), R.drawable.ic_business)); onView(allOf(withId(R.id.title), withParent(withId(R.id.title_container)))) .check(matches(not(isDisplayed()))); onView(allOf(withId(R.id.title_icon), withParent(withId(R.id.title_container))))
diff --git a/components/browser_ui/modaldialog/android/test/java/res/drawable/ic_add.xml b/components/browser_ui/modaldialog/android/test/java/res/drawable/ic_add.xml deleted file mode 100644 index f652b82d..0000000 --- a/components/browser_ui/modaldialog/android/test/java/res/drawable/ic_add.xml +++ /dev/null
@@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- 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. --> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - tools:targetApi="21" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" - android:fillColor="@android:color/black" /> -</vector>
diff --git a/components/browser_ui/modaldialog/android/test/java/res/values/strings.xml b/components/browser_ui/modaldialog/android/test/java/res/values/strings.xml deleted file mode 100644 index 4285811..0000000 --- a/components/browser_ui/modaldialog/android/test/java/res/values/strings.xml +++ /dev/null
@@ -1,10 +0,0 @@ -<?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. --> -<resources> - <string name="title" translatable="false">Title</string> - <string name="more" translatable="false">More</string> - <string name="cancel" translatable="false">Cancel</string> - <string name="ok" translatable="false">OK</string> -</resources>
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/FourStateCookieSettingsPreference.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/FourStateCookieSettingsPreference.java index f2353a6ba2..888d39bd 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/FourStateCookieSettingsPreference.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/FourStateCookieSettingsPreference.java
@@ -47,7 +47,7 @@ // Whether the cookies content setting is enforced. public boolean cookiesContentSettingEnforced; // Whether third-party blocking is enforced. - public boolean thirdPartyBlockingEnforced; + public boolean cookieControlsModeEnforced; } // Keeps the params that are applied to the UI if the params are set before the UI is ready. @@ -166,7 +166,7 @@ button.setEnabled(false); } mManagedView.setVisibility( - (params.cookiesContentSettingEnforced || params.thirdPartyBlockingEnforced) + (params.cookiesContentSettingEnforced || params.cookieControlsModeEnforced) ? View.VISIBLE : View.GONE); @@ -208,10 +208,10 @@ * policy restrictions. */ private RadioButtonWithDescription[] getEnforcedButtons(Params params) { - if (!params.cookiesContentSettingEnforced && !params.thirdPartyBlockingEnforced) { + if (!params.cookiesContentSettingEnforced && !params.cookieControlsModeEnforced) { return buttons(); } - if (params.cookiesContentSettingEnforced && params.thirdPartyBlockingEnforced) { + if (params.cookiesContentSettingEnforced && params.cookieControlsModeEnforced) { return buttons(mAllowButton, mBlockThirdPartyIncognitoButton, mBlockThirdPartyButton, mBlockButton); } @@ -223,7 +223,8 @@ mBlockThirdPartyButton, mBlockButton); } } - if (params.blockThirdPartyCookies) { + if (params.blockThirdPartyCookies + || params.cookieControlsMode == CookieControlsMode.BLOCK_THIRD_PARTY) { return buttons(mAllowButton, mBlockThirdPartyIncognitoButton); } else { return buttons(mBlockThirdPartyIncognitoButton, mBlockThirdPartyButton);
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java index f66cb86..22e6219 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java
@@ -1084,8 +1084,7 @@ params.blockThirdPartyCookies = prefService.getBoolean(BLOCK_THIRD_PARTY_COOKIES); params.cookieControlsMode = prefService.getInteger(COOKIE_CONTROLS_MODE); params.cookiesContentSettingEnforced = mCategory.isManaged(); - params.thirdPartyBlockingEnforced = - prefService.isManagedPreference(BLOCK_THIRD_PARTY_COOKIES); + params.cookieControlsModeEnforced = prefService.isManagedPreference(COOKIE_CONTROLS_MODE); fourStateCookieToggle.setState(params); }
diff --git a/components/content_settings/android/cookie_controls_bridge.cc b/components/content_settings/android/cookie_controls_bridge.cc index f310f08d..de8f12f 100644 --- a/components/content_settings/android/cookie_controls_bridge.cc +++ b/components/content_settings/android/cookie_controls_bridge.cc
@@ -94,7 +94,7 @@ browser_context::BrowserContextFromJavaHandle(jbrowser_context_handle); return permissions::PermissionsClient::Get() ->GetCookieSettings(context) - ->IsCookieControlsEnabled(); + ->ShouldBlockThirdPartyCookies(); } static jlong JNI_CookieControlsBridge_Init(
diff --git a/components/content_settings/browser/ui/cookie_controls_controller.cc b/components/content_settings/browser/ui/cookie_controls_controller.cc index 69b81482..d0f3a2ed 100644 --- a/components/content_settings/browser/ui/cookie_controls_controller.cc +++ b/components/content_settings/browser/ui/cookie_controls_controller.cc
@@ -59,7 +59,7 @@ std::pair<CookieControlsStatus, CookieControlsEnforcement> CookieControlsController::GetStatus(content::WebContents* web_contents) { - if (!cookie_settings_->IsCookieControlsEnabled()) { + if (!cookie_settings_->ShouldBlockThirdPartyCookies()) { return {CookieControlsStatus::kDisabled, CookieControlsEnforcement::kNoEnforcement}; }
diff --git a/components/content_settings/browser/ui/cookie_controls_controller.h b/components/content_settings/browser/ui/cookie_controls_controller.h index bdb1a78..d9f21eef 100644 --- a/components/content_settings/browser/ui/cookie_controls_controller.h +++ b/components/content_settings/browser/ui/cookie_controls_controller.h
@@ -12,7 +12,6 @@ #include "components/content_settings/core/common/cookie_controls_enforcement.h" #include "components/content_settings/core/common/cookie_controls_status.h" #include "components/prefs/pref_change_registrar.h" -#include "content/public/browser/web_contents.h" namespace content { class WebContents;
diff --git a/components/content_settings/core/browser/cookie_settings.cc b/components/content_settings/core/browser/cookie_settings.cc index b92a1d8..49764076 100644 --- a/components/content_settings/core/browser/cookie_settings.cc +++ b/components/content_settings/core/browser/cookie_settings.cc
@@ -40,10 +40,6 @@ content_settings_observer_.Add(host_content_settings_map_.get()); pref_change_registrar_.Init(prefs); pref_change_registrar_.Add( - prefs::kBlockThirdPartyCookies, - base::BindRepeating(&CookieSettings::OnCookiePreferencesChanged, - base::Unretained(this))); - pref_change_registrar_.Add( prefs::kCookieControlsMode, base::BindRepeating(&CookieSettings::OnCookiePreferencesChanged, base::Unretained(this))); @@ -245,12 +241,6 @@ CookieSettings::~CookieSettings() = default; bool CookieSettings::IsCookieControlsEnabled() { -#if !defined(OS_IOS) - if (pref_change_registrar_.prefs()->GetBoolean( - prefs::kBlockThirdPartyCookies)) { - return true; - } -#endif #if defined(OS_IOS) if (!base::FeatureList::IsEnabled(kImprovedCookieControls)) return false; @@ -285,8 +275,6 @@ DCHECK(thread_checker_.CalledOnValidThread()); bool new_block_third_party_cookies = - pref_change_registrar_.prefs()->GetBoolean( - prefs::kBlockThirdPartyCookies) || IsCookieControlsEnabled(); // Safe to read |block_third_party_cookies_| without locking here because the
diff --git a/components/content_settings/core/browser/cookie_settings_policy_handler.cc b/components/content_settings/core/browser/cookie_settings_policy_handler.cc index 7d61c9bb..22cbf96 100644 --- a/components/content_settings/core/browser/cookie_settings_policy_handler.cc +++ b/components/content_settings/core/browser/cookie_settings_policy_handler.cc
@@ -6,29 +6,24 @@ #include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/common/pref_names.h" +#include "components/policy/core/browser/configuration_policy_handler.h" #include "components/policy/core/common/policy_map.h" #include "components/policy/policy_constants.h" #include "components/prefs/pref_value_map.h" namespace content_settings { -CookieSettingsPolicyHandler::CookieSettingsPolicyHandler() = default; +CookieSettingsPolicyHandler::CookieSettingsPolicyHandler() + : policy::TypeCheckingPolicyHandler(policy::key::kBlockThirdPartyCookies, + base::Value::Type::BOOLEAN) {} CookieSettingsPolicyHandler::~CookieSettingsPolicyHandler() = default; -bool CookieSettingsPolicyHandler::CheckPolicySettings( - const policy::PolicyMap& policies, - policy::PolicyErrorMap* errors) { - return true; -} - void CookieSettingsPolicyHandler::ApplyPolicySettings( const policy::PolicyMap& policies, PrefValueMap* prefs) { - // When third party cookie blocking is set by policy, the cookie controls UI - // can't be enabled. const base::Value* third_party_cookie_blocking = - policies.GetValue(policy::key::kBlockThirdPartyCookies); + policies.GetValue(policy_name()); if (third_party_cookie_blocking) { prefs->SetInteger( prefs::kCookieControlsMode,
diff --git a/components/content_settings/core/browser/cookie_settings_policy_handler.h b/components/content_settings/core/browser/cookie_settings_policy_handler.h index 391e97b..d391c28e 100644 --- a/components/content_settings/core/browser/cookie_settings_policy_handler.h +++ b/components/content_settings/core/browser/cookie_settings_policy_handler.h
@@ -12,16 +12,14 @@ namespace content_settings { -// A ConfigurationPolicyHandler which forces kCookieControlsEnabled to false -// when BlockThirdPartyCookies is set by policy. -class CookieSettingsPolicyHandler : public policy::ConfigurationPolicyHandler { +// A ConfigurationPolicyHandler which sets kCookieControlsEnabled to +// kOff/kBlockThirdParty based on the BlockThirdPartyCookies policy. +class CookieSettingsPolicyHandler : public policy::TypeCheckingPolicyHandler { public: CookieSettingsPolicyHandler(); ~CookieSettingsPolicyHandler() override; - // ConfigurationPolicyHandler: - bool CheckPolicySettings(const policy::PolicyMap& policies, - policy::PolicyErrorMap* errors) override; + // TypeCheckingPolicyHandler: void ApplyPolicySettings(const policy::PolicyMap& policies, PrefValueMap* prefs) override;
diff --git a/components/content_settings/core/browser/cookie_settings_unittest.cc b/components/content_settings/core/browser/cookie_settings_unittest.cc index f029297..ac5fa75 100644 --- a/components/content_settings/core/browser/cookie_settings_unittest.cc +++ b/components/content_settings/core/browser/cookie_settings_unittest.cc
@@ -85,8 +85,13 @@ kHttpsSubdomainSite("https://www.example.com"), kHttpsSite8080("https://example.com:8080"), kAllHttpsSitesPattern(ContentSettingsPattern::FromString("https://*")) { - feature_list_.InitAndDisableFeature( - net::features::kSameSiteByDefaultCookies); + feature_list_.InitWithFeatures( + { +#ifdef OS_IOS + kImprovedCookieControls, +#endif + }, + {net::features::kSameSiteByDefaultCookies}); } ~CookieSettingsTest() override { settings_map_->ShutdownOnUIThread(); } @@ -168,33 +173,21 @@ } TEST_F(CookieSettingsTest, CookiesBlockThirdParty) { - prefs_.SetBoolean(prefs::kBlockThirdPartyCookies, true); + prefs_.SetInteger(prefs::kCookieControlsMode, + static_cast<int>(CookieControlsMode::kBlockThirdParty)); EXPECT_FALSE( cookie_settings_->IsCookieAccessAllowed(kBlockedSite, kFirstPartySite)); EXPECT_FALSE(cookie_settings_->IsCookieSessionOnly(kBlockedSite)); } -// Test fixture with ImprovedCookieControls enabled. -class ImprovedCookieControlsCookieSettingsTest : public CookieSettingsTest { - public: - ImprovedCookieControlsCookieSettingsTest() { -#if defined(OS_IOS) - feature_list_.InitAndEnableFeature(kImprovedCookieControls); -#endif - } - - private: - base::test::ScopedFeatureList feature_list_; -}; - -TEST_F(ImprovedCookieControlsCookieSettingsTest, CookiesControlsDefault) { +TEST_F(CookieSettingsTest, CookiesControlsDefault) { EXPECT_TRUE( cookie_settings_->IsCookieAccessAllowed(kBlockedSite, kFirstPartySite)); EXPECT_FALSE(cookie_settings_incognito_->IsCookieAccessAllowed( kBlockedSite, kFirstPartySite)); } -TEST_F(ImprovedCookieControlsCookieSettingsTest, CookiesControlsEnabled) { +TEST_F(CookieSettingsTest, CookiesControlsEnabled) { prefs_.SetInteger(prefs::kCookieControlsMode, static_cast<int>(CookieControlsMode::kBlockThirdParty)); EXPECT_FALSE( @@ -203,7 +196,7 @@ kBlockedSite, kFirstPartySite)); } -TEST_F(ImprovedCookieControlsCookieSettingsTest, CookiesControlsDisabled) { +TEST_F(CookieSettingsTest, CookiesControlsDisabled) { prefs_.SetInteger(prefs::kCookieControlsMode, static_cast<int>(CookieControlsMode::kOff)); EXPECT_TRUE( @@ -212,8 +205,7 @@ kBlockedSite, kFirstPartySite)); } -TEST_F(ImprovedCookieControlsCookieSettingsTest, - CookiesControlsEnabledForIncognito) { +TEST_F(CookieSettingsTest, CookiesControlsEnabledForIncognito) { prefs_.SetInteger(prefs::kCookieControlsMode, static_cast<int>(CookieControlsMode::kIncognitoOnly)); EXPECT_TRUE( @@ -271,7 +263,8 @@ cookie_settings_->IsCookieAccessAllowed(kBlockedSite, kFirstPartySite)); EXPECT_TRUE(cookie_settings_->IsCookieSessionOnly(kBlockedSite)); - prefs_.SetBoolean(prefs::kBlockThirdPartyCookies, true); + prefs_.SetInteger(prefs::kCookieControlsMode, + static_cast<int>(CookieControlsMode::kBlockThirdParty)); EXPECT_TRUE( cookie_settings_->IsCookieAccessAllowed(kBlockedSite, kFirstPartySite)); EXPECT_TRUE(cookie_settings_->IsCookieSessionOnly(kBlockedSite)); @@ -388,7 +381,8 @@ TEST_F(CookieSettingsTest, CookiesThirdPartyBlockedExplicitAllow) { cookie_settings_->SetCookieSetting(kAllowedSite, CONTENT_SETTING_ALLOW); - prefs_.SetBoolean(prefs::kBlockThirdPartyCookies, true); + prefs_.SetInteger(prefs::kCookieControlsMode, + static_cast<int>(CookieControlsMode::kBlockThirdParty)); EXPECT_TRUE( cookie_settings_->IsCookieAccessAllowed(kAllowedSite, kFirstPartySite)); EXPECT_FALSE(cookie_settings_->IsCookieSessionOnly(kAllowedSite)); @@ -400,7 +394,8 @@ TEST_F(CookieSettingsTest, CookiesThirdPartyBlockedAllSitesAllowed) { cookie_settings_->SetCookieSetting(kAllowedSite, CONTENT_SETTING_ALLOW); - prefs_.SetBoolean(prefs::kBlockThirdPartyCookies, true); + prefs_.SetInteger(prefs::kCookieControlsMode, + static_cast<int>(CookieControlsMode::kBlockThirdParty)); // As an example for a url that matches all hosts but not all origins, // match all HTTPS sites. settings_map_->SetContentSettingCustomScope( @@ -455,7 +450,8 @@ const GURL top_level_url = GURL(kFirstPartySite); const GURL url = GURL(kAllowedSite); - prefs_.SetBoolean(prefs::kBlockThirdPartyCookies, false); + prefs_.SetInteger(prefs::kCookieControlsMode, + static_cast<int>(CookieControlsMode::kOff)); base::HistogramTester histogram_tester; histogram_tester.ExpectTotalCount(kAllowedRequestsHistogram, 0); @@ -479,7 +475,8 @@ const GURL top_level_url = GURL(kFirstPartySite); const GURL url = GURL(kAllowedSite); - prefs_.SetBoolean(prefs::kBlockThirdPartyCookies, true); + prefs_.SetInteger(prefs::kCookieControlsMode, + static_cast<int>(CookieControlsMode::kBlockThirdParty)); settings_map_->SetContentSettingCustomScope( ContentSettingsPattern::FromURLNoWildcard(url), @@ -501,7 +498,8 @@ base::HistogramTester histogram_tester; histogram_tester.ExpectTotalCount(kAllowedRequestsHistogram, 0); - prefs_.SetBoolean(prefs::kBlockThirdPartyCookies, true); + prefs_.SetInteger(prefs::kCookieControlsMode, + static_cast<int>(CookieControlsMode::kBlockThirdParty)); settings_map_->SetContentSettingCustomScope( ContentSettingsPattern::FromURLNoWildcard(url), @@ -532,7 +530,8 @@ base::HistogramTester histogram_tester; histogram_tester.ExpectTotalCount(kAllowedRequestsHistogram, 0); - prefs_.SetBoolean(prefs::kBlockThirdPartyCookies, true); + prefs_.SetInteger(prefs::kCookieControlsMode, + static_cast<int>(CookieControlsMode::kBlockThirdParty)); settings_map_->SetContentSettingCustomScope( ContentSettingsPattern::FromURLNoWildcard(url), @@ -575,7 +574,8 @@ const GURL top_level_url = GURL(kFirstPartySite); const GURL url = GURL(kHttpSite); - prefs_.SetBoolean(prefs::kBlockThirdPartyCookies, true); + prefs_.SetInteger(prefs::kCookieControlsMode, + static_cast<int>(CookieControlsMode::kBlockThirdParty)); settings_map_->SetContentSettingCustomScope( ContentSettingsPattern::FromURLNoWildcard(url), @@ -601,7 +601,8 @@ const GURL top_level_url = GURL(kHttpSite); const GURL url = GURL(kFirstPartySite); - prefs_.SetBoolean(prefs::kBlockThirdPartyCookies, true); + prefs_.SetInteger(prefs::kCookieControlsMode, + static_cast<int>(CookieControlsMode::kBlockThirdParty)); settings_map_->SetContentSettingCustomScope( ContentSettingsPattern::FromURLNoWildcard(url), @@ -648,7 +649,8 @@ const GURL top_level_url = GURL(kFirstPartySite); const GURL url = GURL(kAllowedSite); - prefs_.SetBoolean(prefs::kBlockThirdPartyCookies, true); + prefs_.SetInteger(prefs::kCookieControlsMode, + static_cast<int>(CookieControlsMode::kBlockThirdParty)); settings_map_->SetContentSettingCustomScope( ContentSettingsPattern::FromURLNoWildcard(url), @@ -697,7 +699,8 @@ } TEST_F(CookieSettingsTest, ExtensionsThirdParty) { - prefs_.SetBoolean(prefs::kBlockThirdPartyCookies, true); + prefs_.SetInteger(prefs::kCookieControlsMode, + static_cast<int>(CookieControlsMode::kBlockThirdParty)); // XHRs stemming from extensions are exempt from third-party cookie blocking // rules (as the first party is always the extension's security origin). @@ -711,7 +714,8 @@ EXPECT_TRUE( cookie_settings_->IsCookieAccessAllowed(kHttpsSite, kFirstPartySite)); - prefs_.SetBoolean(prefs::kBlockThirdPartyCookies, true); + prefs_.SetInteger(prefs::kCookieControlsMode, + static_cast<int>(CookieControlsMode::kBlockThirdParty)); EXPECT_FALSE( cookie_settings_->IsThirdPartyAccessAllowed(kFirstPartySite, nullptr)); EXPECT_FALSE( @@ -757,7 +761,8 @@ TEST_F(CookieSettingsTest, ThirdPartySettingObserver) { CookieSettingsObserver observer(cookie_settings_.get()); EXPECT_FALSE(observer.last_value()); - prefs_.SetBoolean(prefs::kBlockThirdPartyCookies, true); + prefs_.SetInteger(prefs::kCookieControlsMode, + static_cast<int>(CookieControlsMode::kBlockThirdParty)); EXPECT_TRUE(observer.last_value()); } @@ -844,7 +849,7 @@ // Test fixture with SameSiteByDefaultCookies enabled. class SameSiteByDefaultCookieSettingsTest : public CookieSettingsTest { public: - SameSiteByDefaultCookieSettingsTest() : CookieSettingsTest() { + SameSiteByDefaultCookieSettingsTest() { feature_list_.InitAndEnableFeature( net::features::kSameSiteByDefaultCookies); }
diff --git a/components/crash/content/browser/crash_metrics_reporter_android.cc b/components/crash/content/browser/crash_metrics_reporter_android.cc index 7cce720..55bd51cb 100644 --- a/components/crash/content/browser/crash_metrics_reporter_android.cc +++ b/components/crash/content/browser/crash_metrics_reporter_android.cc
@@ -117,9 +117,9 @@ base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES || info.app_state == base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES; const bool intentional_kill = info.was_killed_intentionally_by_browser; - // TODO(crbug.com/1115517): Take into account renderer_shutdown_requested. const bool android_oom_kill = !info.was_killed_intentionally_by_browser && - !crashed && !info.normal_termination; + !crashed && !info.normal_termination && + !info.renderer_shutdown_requested; const bool renderer_visible = info.renderer_has_visible_clients; const bool renderer_subframe = info.renderer_was_subframe; const bool renderer_allocation_failed = @@ -171,7 +171,7 @@ ReportCrashCount(ProcessedCrashCounts:: kRendererForegroundVisibleNormalTermNoMinidump, &reported_counts); - } else { + } else if (!info.renderer_shutdown_requested) { DCHECK(android_oom_kill); if (renderer_subframe) { ReportCrashCount(
diff --git a/components/discardable_memory/common/discardable_shared_memory_heap.cc b/components/discardable_memory/common/discardable_shared_memory_heap.cc index d7f83bfb..53030c9 100644 --- a/components/discardable_memory/common/discardable_shared_memory_heap.cc +++ b/components/discardable_memory/common/discardable_shared_memory_heap.cc
@@ -259,28 +259,32 @@ auto* total_dump = pmd->CreateAllocatorDump(base::StringPrintf( "discardable/child_0x%" PRIXPTR, reinterpret_cast<uintptr_t>(this))); const size_t freelist_size = GetSizeOfFreeLists(); - const size_t total_size = GetSize(); total_dump->AddScalar("freelist_size", base::trace_event::MemoryAllocatorDump::kUnitsBytes, freelist_size); - total_dump->AddScalar("virtual_size", - base::trace_event::MemoryAllocatorDump::kUnitsBytes, - total_size); if (args.level_of_detail == base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND) { + // These metrics (size and virtual size) are also reported by each + // individual segment. If we report both, then the counts are artificially + // inflated in detailed dumps, depending on aggregation (for instance, in + // about:tracing's UI). + const size_t total_size = GetSize(); total_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, base::trace_event::MemoryAllocatorDump::kUnitsBytes, total_size - freelist_size); - return true; + total_dump->AddScalar("virtual_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + total_size); + } else { + // This iterates over all the memory allocated by the heap, and calls + // |OnMemoryDump| for each. It does not contain any information about the + // DiscardableSharedMemoryHeap itself. + std::for_each(memory_segments_.begin(), memory_segments_.end(), + [pmd](const std::unique_ptr<ScopedMemorySegment>& segment) { + segment->OnMemoryDump(pmd); + }); } - // This iterates over all the memory allocated by the heap, and calls - // |OnMemoryDump| for each. It does not contain any information about the - // DiscardableSharedMemoryHeap itself. - std::for_each(memory_segments_.begin(), memory_segments_.end(), - [pmd](const std::unique_ptr<ScopedMemorySegment>& segment) { - segment->OnMemoryDump(pmd); - }); return true; }
diff --git a/components/discardable_memory/common/discardable_shared_memory_heap_unittest.cc b/components/discardable_memory/common/discardable_shared_memory_heap_unittest.cc index 71dcbb6..5d3a784 100644 --- a/components/discardable_memory/common/discardable_shared_memory_heap_unittest.cc +++ b/components/discardable_memory/common/discardable_shared_memory_heap_unittest.cc
@@ -9,6 +9,7 @@ #include <utility> #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/memory/discardable_shared_memory.h" #include "base/process/process_metrics.h" #include "base/strings/stringprintf.h" @@ -407,5 +408,38 @@ } } +TEST(DiscardableSharedMemoryHeapTest, DetailedDumpsDontContainRedundantData) { + using testing::ByRef; + using testing::Contains; + using testing::Eq; + using testing::Not; + DiscardableSharedMemoryHeap heap; + + base::trace_event::MemoryDumpArgs args = { + base::trace_event::MemoryDumpLevelOfDetail::DETAILED}; + size_t block_size = base::GetPageSize(); + + auto memory = std::make_unique<base::DiscardableSharedMemory>(); + ASSERT_TRUE(memory->CreateAndMap(block_size)); + auto span = heap.Grow(std::move(memory), block_size, 1, base::DoNothing()); + + base::trace_event::ProcessMemoryDump pmd(args); + heap.OnMemoryDump(args, &pmd); + auto* dump = pmd.GetAllocatorDump(base::StringPrintf( + "discardable/child_0x%" PRIXPTR, reinterpret_cast<uintptr_t>(&heap))); + ASSERT_NE(nullptr, dump); + + base::trace_event::MemoryAllocatorDump::Entry freelist("freelist_size", + "bytes", 0); + EXPECT_THAT(dump->entries(), Contains(Eq(ByRef(freelist)))); + + // Detailed dumps do not contain virtual size. + base::trace_event::MemoryAllocatorDump::Entry virtual_size( + "virtual_size", "bytes", block_size); + EXPECT_THAT(dump->entries(), Not(Contains(Eq(ByRef(virtual_size))))); + + heap.MergeIntoFreeLists(std::move(span)); +} + } // namespace } // namespace discardable_memory
diff --git a/components/embedder_support/android/BUILD.gn b/components/embedder_support/android/BUILD.gn index 5740262..3ebad27 100644 --- a/components/embedder_support/android/BUILD.gn +++ b/components/embedder_support/android/BUILD.gn
@@ -105,7 +105,7 @@ "//base:base_java", "//content/public/android:content_java", "//third_party/android_deps:androidx_annotation_annotation_java", - "//ui/android:ui_java", + "//ui/android:ui_no_recycler_view_java", ] sources = [ "java/src/org/chromium/components/embedder_support/view/ContentView.java", @@ -117,7 +117,7 @@ "//base:base_java", "//base:jni_java", "//content/public/android:content_java", - "//ui/android:ui_java", + "//ui/android:ui_no_recycler_view_java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] sources = [ "java/src/org/chromium/components/embedder_support/view/ContentViewRenderView.java" ] @@ -181,7 +181,7 @@ "//content/public/android:content_java", "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_core_core_java", - "//ui/android:ui_java", + "//ui/android:ui_no_recycler_view_java", ] resources_package = "org.chromium.components.embedder_support.delegate" annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] @@ -229,7 +229,7 @@ "//content/public/android:content_java", "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/blink/public:blink_headers_java", - "//ui/android:ui_java", + "//ui/android:ui_no_recycler_view_java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] sources = [ "java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuParams.java" ]
diff --git a/components/location/android/BUILD.gn b/components/location/android/BUILD.gn index 871738e..3d1ad4c 100644 --- a/components/location/android/BUILD.gn +++ b/components/location/android/BUILD.gn
@@ -15,7 +15,7 @@ deps = [ "//base:base_java", "//third_party/android_deps:androidx_annotation_annotation_java", - "//ui/android:ui_java", + "//ui/android:ui_no_recycler_view_java", ] sources = [ "java/src/org/chromium/components/location/LocationUtils.java" ] srcjar_deps = [ ":location_settings_dialog_enums_java" ] @@ -26,7 +26,7 @@ ":location_java", "//base:base_java", "//base:jni_java", - "//ui/android:ui_java", + "//ui/android:ui_no_recycler_view_java", ] sources = [ "java/src/org/chromium/components/location/LocationSettings.java" ]
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn index 797f5583..1aad8f4 100644 --- a/components/metrics/BUILD.gn +++ b/components/metrics/BUILD.gn
@@ -217,6 +217,9 @@ if (!is_ios) { static_library("content") { sources = [ + "content/content_stability_metrics_provider.cc", + "content/content_stability_metrics_provider.h", + "content/extensions_helper.h", "content/gpu_metrics_provider.cc", "content/gpu_metrics_provider.h", "content/rendering_perf_metrics_provider.cc", @@ -228,8 +231,12 @@ deps = [ "//base", "//content/public/browser", + "//extensions/buildflags", "//gpu/config", ] + if (is_android) { + deps += [ "//components/crash/content/browser" ] + } } }
diff --git a/components/metrics/content/DEPS b/components/metrics/content/DEPS index 9c560c67..c8b2783 100644 --- a/components/metrics/content/DEPS +++ b/components/metrics/content/DEPS
@@ -1,6 +1,9 @@ include_rules = [ + "+components/crash", "+content/public/browser", + "+content/public/common", "+gpu/config", + "+ppapi/buildflags/buildflags.h", ] specific_include_rules = {
diff --git a/chrome/browser/metrics/chrome_stability_metrics_provider.cc b/components/metrics/content/content_stability_metrics_provider.cc similarity index 68% rename from chrome/browser/metrics/chrome_stability_metrics_provider.cc rename to components/metrics/content/content_stability_metrics_provider.cc index 194e837..9a3deef 100644 --- a/chrome/browser/metrics/chrome_stability_metrics_provider.cc +++ b/components/metrics/content/content_stability_metrics_provider.cc
@@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/metrics/chrome_stability_metrics_provider.h" +#include "components/metrics/content/content_stability_metrics_provider.h" #include <vector> #include "base/check.h" #include "base/notreached.h" #include "build/build_config.h" +#include "components/metrics/content/extensions_helper.h" #include "content/public/browser/browser_child_process_observer.h" #include "content/public/browser/child_process_data.h" #include "content/public/browser/child_process_termination_info.h" @@ -16,28 +17,23 @@ #include "content/public/browser/notification_types.h" #include "content/public/browser/render_process_host.h" #include "content/public/common/process_type.h" -#include "extensions/buildflags/buildflags.h" #include "ppapi/buildflags/buildflags.h" #if defined(OS_ANDROID) #include "components/crash/content/browser/crash_metrics_reporter_android.h" #endif -#if BUILDFLAG(ENABLE_EXTENSIONS) -#include "extensions/browser/process_map.h" -#endif +namespace metrics { -#if BUILDFLAG(ENABLE_PLUGINS) -#include "chrome/browser/metrics/plugin_metrics_provider.h" -#endif - -ChromeStabilityMetricsProvider::ChromeStabilityMetricsProvider( - PrefService* local_state) +ContentStabilityMetricsProvider::ContentStabilityMetricsProvider( + PrefService* local_state, + std::unique_ptr<ExtensionsHelper> extensions_helper) : #if defined(OS_ANDROID) scoped_observer_(this), #endif // defined(OS_ANDROID) - helper_(local_state) { + helper_(local_state), + extensions_helper_(std::move(extensions_helper)) { BrowserChildProcessObserver::Add(this); registrar_.Add(this, content::NOTIFICATION_LOAD_START, @@ -56,27 +52,25 @@ #endif // defined(OS_ANDROID) } -ChromeStabilityMetricsProvider::~ChromeStabilityMetricsProvider() { +ContentStabilityMetricsProvider::~ContentStabilityMetricsProvider() { registrar_.RemoveAll(); BrowserChildProcessObserver::Remove(this); } -void ChromeStabilityMetricsProvider::OnRecordingEnabled() { -} +void ContentStabilityMetricsProvider::OnRecordingEnabled() {} -void ChromeStabilityMetricsProvider::OnRecordingDisabled() { -} +void ContentStabilityMetricsProvider::OnRecordingDisabled() {} -void ChromeStabilityMetricsProvider::ProvideStabilityMetrics( - metrics::SystemProfileProto* system_profile_proto) { +void ContentStabilityMetricsProvider::ProvideStabilityMetrics( + SystemProfileProto* system_profile_proto) { helper_.ProvideStabilityMetrics(system_profile_proto); } -void ChromeStabilityMetricsProvider::ClearSavedStabilityMetrics() { +void ContentStabilityMetricsProvider::ClearSavedStabilityMetrics() { helper_.ClearSavedStabilityMetrics(); } -void ChromeStabilityMetricsProvider::Observe( +void ContentStabilityMetricsProvider::Observe( int type, const content::NotificationSource& source, const content::NotificationDetails& details) { @@ -88,15 +82,10 @@ case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { content::ChildProcessTerminationInfo* process_info = content::Details<content::ChildProcessTerminationInfo>(details).ptr(); - bool was_extension_process = false; -#if BUILDFLAG(ENABLE_EXTENSIONS) - content::RenderProcessHost* host = - content::Source<content::RenderProcessHost>(source).ptr(); - if (extensions::ProcessMap::Get(host->GetBrowserContext()) - ->Contains(host->GetID())) { - was_extension_process = true; - } -#endif + bool was_extension_process = + extensions_helper_ && + extensions_helper_->IsExtensionProcess( + content::Source<content::RenderProcessHost>(source).ptr()); helper_.LogRendererCrash(was_extension_process, process_info->status, process_info->exit_code); break; @@ -107,15 +96,10 @@ break; case content::NOTIFICATION_RENDERER_PROCESS_CREATED: { - bool was_extension_process = false; -#if BUILDFLAG(ENABLE_EXTENSIONS) - content::RenderProcessHost* host = - content::Source<content::RenderProcessHost>(source).ptr(); - if (extensions::ProcessMap::Get(host->GetBrowserContext()) - ->Contains(host->GetID())) { - was_extension_process = true; - } -#endif + bool was_extension_process = + extensions_helper_ && + extensions_helper_->IsExtensionProcess( + content::Source<content::RenderProcessHost>(source).ptr()); helper_.LogRendererLaunched(was_extension_process); break; } @@ -126,15 +110,17 @@ } } -void ChromeStabilityMetricsProvider::BrowserChildProcessCrashed( +void ContentStabilityMetricsProvider::BrowserChildProcessCrashed( const content::ChildProcessData& data, const content::ChildProcessTerminationInfo& info) { DCHECK(!data.metrics_name.empty()); #if BUILDFLAG(ENABLE_PLUGINS) // Exclude plugin crashes from the count below because we report them via // a separate UMA metric. - if (PluginMetricsProvider::IsPluginProcess(data.process_type)) + if (data.process_type == content::PROCESS_TYPE_PPAPI_PLUGIN || + data.process_type == content::PROCESS_TYPE_PPAPI_BROKER) { return; + } #endif if (data.process_type == content::PROCESS_TYPE_UTILITY) @@ -142,7 +128,7 @@ helper_.BrowserChildProcessCrashed(); } -void ChromeStabilityMetricsProvider::BrowserChildProcessLaunchedAndConnected( +void ContentStabilityMetricsProvider::BrowserChildProcessLaunchedAndConnected( const content::ChildProcessData& data) { DCHECK(!data.metrics_name.empty()); if (data.process_type == content::PROCESS_TYPE_UTILITY) @@ -150,7 +136,7 @@ } #if defined(OS_ANDROID) -void ChromeStabilityMetricsProvider::OnCrashDumpProcessed( +void ContentStabilityMetricsProvider::OnCrashDumpProcessed( int rph_id, const crash_reporter::CrashMetricsReporter::ReportedCrashTypeSet& reported_counts) { @@ -163,5 +149,6 @@ helper_.IncreaseGpuCrashCount(); } } - #endif // defined(OS_ANDROID) + +} // namespace metrics
diff --git a/components/metrics/content/content_stability_metrics_provider.h b/components/metrics/content/content_stability_metrics_provider.h new file mode 100644 index 0000000..3f34e64 --- /dev/null +++ b/components/metrics/content/content_stability_metrics_provider.h
@@ -0,0 +1,106 @@ +// 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 COMPONENTS_METRICS_CONTENT_CONTENT_STABILITY_METRICS_PROVIDER_H_ +#define COMPONENTS_METRICS_CONTENT_CONTENT_STABILITY_METRICS_PROVIDER_H_ + +#include <memory> + +#include "base/gtest_prod_util.h" +#include "base/scoped_observer.h" +#include "build/build_config.h" +#include "components/metrics/metrics_provider.h" +#include "components/metrics/stability_metrics_helper.h" +#include "content/public/browser/browser_child_process_observer.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" + +#if defined(OS_ANDROID) +#include "components/crash/content/browser/crash_metrics_reporter_android.h" +#endif // defined(OS_ANDROID) + +class PrefService; + +FORWARD_DECLARE_TEST(ChromeStabilityMetricsProviderTest, + BrowserChildProcessObserverGpu); +FORWARD_DECLARE_TEST(ChromeStabilityMetricsProviderTest, + BrowserChildProcessObserverUtility); +FORWARD_DECLARE_TEST(ChromeStabilityMetricsProviderTest, NotificationObserver); + +namespace metrics { + +class ExtensionsHelper; + +// ContentStabilityMetricsProvider gathers and logs Chrome-specific stability- +// related metrics. +class ContentStabilityMetricsProvider + : public MetricsProvider, + public content::BrowserChildProcessObserver, +#if defined(OS_ANDROID) + public crash_reporter::CrashMetricsReporter::Observer, +#endif + public content::NotificationObserver { + public: + // |extensions_helper| is used to determine if a process corresponds to an + // extension and is optional. If an ExtensionsHelper is not supplied it is + // assumed the process does not correspond to an extension. + ContentStabilityMetricsProvider( + PrefService* local_state, + std::unique_ptr<ExtensionsHelper> extensions_helper); + ContentStabilityMetricsProvider(const ContentStabilityMetricsProvider&) = + delete; + ContentStabilityMetricsProvider& operator=( + const ContentStabilityMetricsProvider&) = delete; + ~ContentStabilityMetricsProvider() override; + + // MetricsDataProvider: + void OnRecordingEnabled() override; + void OnRecordingDisabled() override; + void ProvideStabilityMetrics( + SystemProfileProto* system_profile_proto) override; + void ClearSavedStabilityMetrics() override; + + private: + FRIEND_TEST_ALL_PREFIXES(::ChromeStabilityMetricsProviderTest, + BrowserChildProcessObserverGpu); + FRIEND_TEST_ALL_PREFIXES(::ChromeStabilityMetricsProviderTest, + BrowserChildProcessObserverUtility); + FRIEND_TEST_ALL_PREFIXES(::ChromeStabilityMetricsProviderTest, + NotificationObserver); + + // content::NotificationObserver: + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override; + + // content::BrowserChildProcessObserver: + void BrowserChildProcessCrashed( + const content::ChildProcessData& data, + const content::ChildProcessTerminationInfo& info) override; + void BrowserChildProcessLaunchedAndConnected( + const content::ChildProcessData& data) override; + +#if defined(OS_ANDROID) + // crash_reporter::CrashMetricsReporter::Observer: + void OnCrashDumpProcessed( + int rph_id, + const crash_reporter::CrashMetricsReporter::ReportedCrashTypeSet& + reported_counts) override; + + ScopedObserver<crash_reporter::CrashMetricsReporter, + crash_reporter::CrashMetricsReporter::Observer> + scoped_observer_; +#endif // defined(OS_ANDROID) + + StabilityMetricsHelper helper_; + + // Registrar for receiving stability-related notifications. + content::NotificationRegistrar registrar_; + + std::unique_ptr<ExtensionsHelper> extensions_helper_; +}; + +} // namespace metrics + +#endif // COMPONENTS_METRICS_CONTENT_CONTENT_STABILITY_METRICS_PROVIDER_H_
diff --git a/components/metrics/content/extensions_helper.h b/components/metrics/content/extensions_helper.h new file mode 100644 index 0000000..20c67bc8 --- /dev/null +++ b/components/metrics/content/extensions_helper.h
@@ -0,0 +1,29 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_METRICS_CONTENT_EXTENSIONS_HELPER_H_ +#define COMPONENTS_METRICS_CONTENT_EXTENSIONS_HELPER_H_ + +namespace content { +class RenderProcessHost; +} + +namespace metrics { + +// ExtensionsHelper is used by ContentStabilityMetricsProvider to determine +// if a RenderProcessHost hosts an extension. This is separate from +// ContentStabilityMetricsProvider to avoid this code depending directly on +// extensions. +class ExtensionsHelper { + public: + virtual ~ExtensionsHelper() = default; + + // Returns true if |render_process_host| is hosting an extension. + virtual bool IsExtensionProcess( + content::RenderProcessHost* render_process_host) = 0; +}; + +} // namespace metrics + +#endif // COMPONENTS_METRICS_CONTENT_EXTENSIONS_HELPER_H_
diff --git a/components/paint_preview/common/paint_preview_tracker.cc b/components/paint_preview/common/paint_preview_tracker.cc index 25ea7cba..66bbe4c 100644 --- a/components/paint_preview/common/paint_preview_tracker.cc +++ b/components/paint_preview/common/paint_preview_tracker.cc
@@ -44,8 +44,7 @@ bool is_main_frame) : guid_(guid), embedding_token_(embedding_token), - is_main_frame_(is_main_frame), - scroll_(SkISize::Make(0, 0)) {} + is_main_frame_(is_main_frame) {} PaintPreviewTracker::~PaintPreviewTracker() { DCHECK(states_.empty()); @@ -96,8 +95,7 @@ const gfx::Rect& rect, const base::UnguessableToken& embedding_token) { sk_sp<SkPicture> pic = SkPicture::MakePlaceholder( - SkRect::MakeXYWH(rect.x() + scroll_.width(), rect.y() + scroll_.height(), - rect.width(), rect.height())); + SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height())); const uint32_t content_id = pic->uniqueID(); DCHECK(!base::Contains(picture_context_.content_id_to_embedding_token, content_id)); @@ -106,10 +104,6 @@ return content_id; } -void PaintPreviewTracker::SetScrollForFrame(const SkISize& scroll) { - scroll_ = scroll; -} - void PaintPreviewTracker::AddGlyphs(const SkTextBlob* blob) { if (!blob) return; @@ -170,8 +164,8 @@ DCHECK(it != subframe_pics_.end()); SkRect rect = it->second->cullRect(); - SkMatrix matrix = SkMatrix::Translate(rect.x(), rect.y()); - canvas->drawPicture(it->second, &matrix, nullptr); + SkMatrix subframe_offset = SkMatrix::Translate(rect.x(), rect.y()); + canvas->drawPicture(it->second, &subframe_offset, nullptr); } void PaintPreviewTracker::MoveLinks(std::vector<mojom::LinkDataPtr>* out) {
diff --git a/components/paint_preview/common/paint_preview_tracker.h b/components/paint_preview/common/paint_preview_tracker.h index 9a9f176..4828a9b 100644 --- a/components/paint_preview/common/paint_preview_tracker.h +++ b/components/paint_preview/common/paint_preview_tracker.h
@@ -62,9 +62,6 @@ const gfx::Rect& rect, const base::UnguessableToken& embedding_token); - // Sets the scroll position for the top layer frame. - void SetScrollForFrame(const SkISize& scroll); - // Adds the glyphs in |blob| to the glyph usage tracker for the |blob|'s // associated typface. void AddGlyphs(const SkTextBlob* blob); @@ -85,7 +82,8 @@ // be considered immutable. // Inserts the OOP subframe placeholder associated with |content_id| into - // |canvas|. + // |canvas|. The cull rect of the placeholder will encode the position and + // size of the the subframe in its parent's coordinate system. void CustomDataToSkPictureCallback(SkCanvas* canvas, uint32_t content_id); // Expose internal maps for use in MakeSerialProcs(). @@ -111,7 +109,6 @@ const base::Optional<base::UnguessableToken> embedding_token_; const bool is_main_frame_; - SkISize scroll_; SkMatrix matrix_; std::vector<SkMatrix> states_;
diff --git a/components/paint_preview/common/paint_preview_tracker_unittest.cc b/components/paint_preview/common/paint_preview_tracker_unittest.cc index 8b62b00..f84d7e1 100644 --- a/components/paint_preview/common/paint_preview_tracker_unittest.cc +++ b/components/paint_preview/common/paint_preview_tracker_unittest.cc
@@ -4,12 +4,14 @@ #include "components/paint_preview/common/paint_preview_tracker.h" +#include "base/containers/flat_map.h" #include "base/unguessable_token.h" #include "components/paint_preview/common/serial_utils.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/core/SkPictureRecorder.h" +#include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkTextBlob.h" #include "ui/gfx/geometry/rect.h" @@ -23,6 +25,36 @@ bool was_called; }; +// A test canvas for checking that the pictures drawn to it have the cull rect +// we expect them to. +class ExpectSubframeCanvas : public SkCanvas { + public: + void onDrawPicture(const SkPicture* picture, + const SkMatrix*, + const SkPaint*) override { + drawn_pictures_.insert({picture->uniqueID(), picture->cullRect()}); + } + + void ExpectHasPicture(uint32_t expected_picture_id, + const gfx::Rect& expected_bounds) { + auto it = drawn_pictures_.find(expected_picture_id); + if (it == drawn_pictures_.end()) { + ADD_FAILURE() << "Picture ID was not recorded."; + return; + } + + SkIRect rect = it->second.round(); + EXPECT_EQ(rect.x(), expected_bounds.x()); + EXPECT_EQ(rect.y(), expected_bounds.y()); + EXPECT_EQ(rect.width(), expected_bounds.width()); + EXPECT_EQ(rect.height(), expected_bounds.height()); + } + + private: + // Map of picture id to expected bounds of pictures drawn into this canvas. + base::flat_map<uint32_t, SkRect> drawn_pictures_; +}; + } // namespace TEST(PaintPreviewTrackerTest, TestGetters) { @@ -52,42 +84,10 @@ EXPECT_EQ(context->content_id_to_embedding_token[content_id], kEmbeddingTokenChild); - SkPictureRecorder recorder; - SkCanvas* canvas = recorder.beginRecording(100, 100); - tracker.CustomDataToSkPictureCallback(canvas, content_id); - sk_sp<SkPicture> pic = recorder.finishRecordingAsPicture(); + ExpectSubframeCanvas canvas; + tracker.CustomDataToSkPictureCallback(&canvas, content_id); - // TODO(crbug/1009552): find a good way to check that a filler picture was - // actually inserted into |pic|. This is difficult without using the - // underlying private picture record. -} - -TEST(PaintPreviewTrackerTest, TestRemoteFramePlaceholderPictureWithScroll) { - const base::UnguessableToken kDocToken = base::UnguessableToken::Create(); - const base::UnguessableToken kEmbeddingToken = - base::UnguessableToken::Create(); - PaintPreviewTracker tracker(kDocToken, kEmbeddingToken, true); - tracker.SetScrollForFrame(SkISize::Make(10, 20)); - - const base::UnguessableToken kEmbeddingTokenChild = - base::UnguessableToken::Create(); - gfx::Rect rect(50, 40, 30, 20); - uint32_t content_id = - tracker.CreateContentForRemoteFrame(rect, kEmbeddingTokenChild); - PictureSerializationContext* context = - tracker.GetPictureSerializationContext(); - EXPECT_TRUE(context->content_id_to_embedding_token.count(content_id)); - EXPECT_EQ(context->content_id_to_embedding_token[content_id], - kEmbeddingTokenChild); - - SkPictureRecorder recorder; - SkCanvas* canvas = recorder.beginRecording(100, 100); - tracker.CustomDataToSkPictureCallback(canvas, content_id); - sk_sp<SkPicture> pic = recorder.finishRecordingAsPicture(); - - // TODO(crbug/1009552): find a good way to check that a filler picture was - // actually inserted into |pic|. This is difficult without using the - // underlying private picture record. + canvas.ExpectHasPicture(content_id, rect); } TEST(PaintPreviewTrackerTest, TestGlyphRunList) {
diff --git a/components/paint_preview/common/serial_utils.cc b/components/paint_preview/common/serial_utils.cc index 800f12b..ff06e2f4 100644 --- a/components/paint_preview/common/serial_utils.cc +++ b/components/paint_preview/common/serial_utils.cc
@@ -18,10 +18,12 @@ #pragma pack(push, 1) struct SerializedRectData { uint32_t content_id; - int64_t x; - int64_t y; - int64_t width; - int64_t height; + + // The size of the subframe in the local coordinates when it was drawn. + int64_t subframe_width; + int64_t subframe_height; + + // The rect of the subframe in its parent frame's root coordinate system. int64_t transformed_x; int64_t transformed_y; int64_t transformed_width; @@ -39,10 +41,10 @@ if (it == context->content_id_to_transformed_clip.end()) return nullptr; + // This data originates from |PaintPreviewTracker|. const SkRect& transformed_cull_rect = it->second; SerializedRectData rect_data = { - picture->uniqueID(), picture->cullRect().x(), - picture->cullRect().y(), picture->cullRect().width(), + picture->uniqueID(), picture->cullRect().width(), picture->cullRect().height(), transformed_cull_rect.x(), transformed_cull_rect.y(), transformed_cull_rect.width(), transformed_cull_rect.height()}; @@ -71,7 +73,7 @@ return subset_data; } -// Deserializies a clip rect for a subframe within the main SkPicture. These +// Deserializes a clip rect for a subframe within the main SkPicture. These // represent subframes and require special decoding as they are custom data // rather than a valid SkPicture. // Precondition: the version of the SkPicture should be checked prior to @@ -106,21 +108,19 @@ memcpy(&rect_data, data, sizeof(rect_data)); auto* context = reinterpret_cast<LoadedFramesDeserialContext*>(ctx); - auto it = context->subframes.find(rect_data.content_id); - if (it == context->subframes.end()) + auto it = context->find(rect_data.content_id); + if (it == context->end()) return MakeEmptyPicture(); // Scroll and clip the subframe manually since the picture in |ctx| does not // encode this information. - SkRect subframe_bounds = SkRect::MakeWH(rect_data.width, rect_data.height); - subframe_bounds.offset(-context->scroll_offsets.width(), - -context->scroll_offsets.height()); + SkRect subframe_bounds = + SkRect::MakeWH(rect_data.subframe_width, rect_data.subframe_height); SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(subframe_bounds); canvas->clipRect(subframe_bounds); SkMatrix apply_scroll_offsets = SkMatrix::Translate( - -context->scroll_offsets.width() - it->second.scroll_offsets.width(), - -context->scroll_offsets.height() - it->second.scroll_offsets.height()); + -it->second.scroll_offsets.width(), -it->second.scroll_offsets.height()); canvas->drawPicture(it->second.picture, &apply_scroll_offsets, nullptr); return recorder.finishRecordingAsPicture(); } @@ -147,9 +147,6 @@ FrameAndScrollOffsets& FrameAndScrollOffsets::operator=( const FrameAndScrollOffsets&) = default; -LoadedFramesDeserialContext::LoadedFramesDeserialContext() = default; -LoadedFramesDeserialContext::~LoadedFramesDeserialContext() = default; - sk_sp<SkPicture> MakeEmptyPicture() { // Effectively a no-op. SkPictureRecorder rec;
diff --git a/components/paint_preview/common/serial_utils.h b/components/paint_preview/common/serial_utils.h index 619ce16a..e2fddc7 100644 --- a/components/paint_preview/common/serial_utils.h +++ b/components/paint_preview/common/serial_utils.h
@@ -69,20 +69,11 @@ gfx::Size scroll_offsets; }; -// Deserialization context for |MakeDeserialProcs| that contains the information -// needed to embed a subframe within its parent frame. -struct LoadedFramesDeserialContext { - LoadedFramesDeserialContext(); - ~LoadedFramesDeserialContext(); - - // The scroll offsets for the current frame. - gfx::Size scroll_offsets; - - // Maps a content ID to a frame's picture. A frame's subframes should be - // loaded into this context before |MakeDeserialProcs| is called to ensure - // that the resulting |SkPicture| contains all subframes. - base::flat_map<uint32_t, FrameAndScrollOffsets> subframes; -}; +// Maps a content ID to a frame's picture. A frame's subframes should be +// loaded into this context before |MakeDeserialProcs| is called to ensure +// that the resulting |SkPicture| contains all subframes. +using LoadedFramesDeserialContext = + base::flat_map<uint32_t, FrameAndScrollOffsets>; // Creates a no-op SkPicture. sk_sp<SkPicture> MakeEmptyPicture();
diff --git a/components/paint_preview/player/BUILD.gn b/components/paint_preview/player/BUILD.gn index 052be10..c3237358 100644 --- a/components/paint_preview/player/BUILD.gn +++ b/components/paint_preview/player/BUILD.gn
@@ -4,6 +4,7 @@ source_set("player") { sources = [ + "compositor_status.h", "player_compositor_delegate.cc", "player_compositor_delegate.h", ]
diff --git a/components/paint_preview/player/android/BUILD.gn b/components/paint_preview/player/android/BUILD.gn index 10353812..d96e8b2 100644 --- a/components/paint_preview/player/android/BUILD.gn +++ b/components/paint_preview/player/android/BUILD.gn
@@ -4,6 +4,10 @@ import("//build/config/android/rules.gni") +java_cpp_enum("compositor_status_generated_enum") { + sources = [ "//components/paint_preview/player/compositor_status.h" ] +} + source_set("android") { sources = [ "player_compositor_delegate_android.cc", @@ -74,6 +78,8 @@ "java/src/org/chromium/components/paintpreview/player/frame/PlayerFrameViewport.java", ] + srcjar_deps = [ ":compositor_status_generated_enum" ] + deps = [ "//base:base_java", "//base:jni_java",
diff --git a/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/PlayerCompositorDelegateImpl.java b/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/PlayerCompositorDelegateImpl.java index faa5eb6..d9a5647 100644 --- a/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/PlayerCompositorDelegateImpl.java +++ b/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/PlayerCompositorDelegateImpl.java
@@ -36,7 +36,7 @@ PlayerCompositorDelegateImpl(NativePaintPreviewServiceProvider service, GURL url, String directoryKey, @NonNull CompositorListener compositorListener, - Runnable compositorErrorCallback) { + Callback<Integer> compositorErrorCallback) { mCompositorListener = compositorListener; if (service != null && service.getNativeService() != 0) { mNativePlayerCompositorDelegate = PlayerCompositorDelegateImplJni.get().initialize(this, @@ -130,7 +130,7 @@ @NativeMethods interface Natives { long initialize(PlayerCompositorDelegateImpl caller, long nativePaintPreviewBaseService, - String urlSpec, String directoryKey, Runnable compositorErrorCallback); + String urlSpec, String directoryKey, Callback<Integer> compositorErrorCallback); void destroy(long nativePlayerCompositorDelegateAndroid); void requestBitmap(long nativePlayerCompositorDelegateAndroid, UnguessableToken frameGuid, Callback<Bitmap> bitmapCallback, Runnable errorCallback, float scaleFactor,
diff --git a/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/PlayerManager.java b/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/PlayerManager.java index 637b718e..d1390df 100644 --- a/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/PlayerManager.java +++ b/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/PlayerManager.java
@@ -15,6 +15,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import org.chromium.base.Callback; import org.chromium.base.TraceEvent; import org.chromium.base.UnguessableToken; import org.chromium.components.paintpreview.browser.NativePaintPreviewServiceProvider; @@ -63,7 +64,7 @@ String directoryKey, @NonNull LinkClickHandler linkClickHandler, @Nullable Runnable refreshCallback, Runnable viewReadyCallback, @Nullable Runnable firstPaintListener, Runnable userInteractionCallback, - int backgroundColor, Runnable compositorErrorCallback, + int backgroundColor, Callback<Integer> compositorErrorCallback, boolean ignoreInitialScrollOffset) { TraceEvent.startAsync(sInitEvent, hashCode()); mContext = context;
diff --git a/components/paint_preview/player/android/javatests/src/org/chromium/components/paintpreview/player/PaintPreviewPlayerTest.java b/components/paint_preview/player/android/javatests/src/org/chromium/components/paintpreview/player/PaintPreviewPlayerTest.java index ac411ca7..b4d2268 100644 --- a/components/paint_preview/player/android/javatests/src/org/chromium/components/paintpreview/player/PaintPreviewPlayerTest.java +++ b/components/paint_preview/player/android/javatests/src/org/chromium/components/paintpreview/player/PaintPreviewPlayerTest.java
@@ -206,7 +206,7 @@ Assert.fail("View Ready callback occurred, but expected a failure."); }, null, null, 0xffffffff, - () -> { compositorErrorCallback.notifyCalled(); }, false); + (status) -> { compositorErrorCallback.notifyCalled(); }, false); mPlayerManager.setCompressOnClose(false); }); compositorErrorCallback.waitForFirst(); @@ -358,7 +358,7 @@ mPlayerManager = new PlayerManager(new GURL(TEST_URL), getActivity(), service, TEST_DIRECTORY_KEY, mLinkClickHandler, mRefreshedCallback::notifyCalled, viewReady::notifyCalled, null, null, 0xffffffff, - () -> { mInitializationFailed = true; }, false); + (status) -> { mInitializationFailed = true; }, false); mPlayerManager.setCompressOnClose(false); getActivity().setContentView(mPlayerManager.getView()); });
diff --git a/components/paint_preview/player/android/player_compositor_delegate_android.cc b/components/paint_preview/player/android/player_compositor_delegate_android.cc index 6ee6ced..1b2dced 100644 --- a/components/paint_preview/player/android/player_compositor_delegate_android.cc +++ b/components/paint_preview/player/android/player_compositor_delegate_android.cc
@@ -84,7 +84,7 @@ DirectoryKey{ base::android::ConvertJavaStringToUTF8(env, j_directory_key)}, base::BindOnce( - &base::android::RunRunnableAndroid, + &base::android::RunIntCallbackAndroid, ScopedJavaGlobalRef<jobject>(j_compositor_error_callback))), request_id_(0), startup_timestamp_(base::TimeTicks::Now()) { @@ -92,23 +92,23 @@ } void PlayerCompositorDelegateAndroid::OnCompositorReady( - mojom::PaintPreviewCompositor::BeginCompositeStatus status, + CompositorStatus compositor_status, mojom::PaintPreviewBeginCompositeResponsePtr composite_response) { - bool compositor_started = - status == mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess || - status == - mojom::PaintPreviewCompositor::BeginCompositeStatus::kPartialSuccess; + bool compositor_started = CompositorStatus::OK == compositor_status; base::UmaHistogramBoolean( "Browser.PaintPreview.Player.CompositorProcessStartedCorrectly", compositor_started); if (!compositor_started && compositor_error_) { - LOG(ERROR) << "Compositor process failed to begin with code: " << status; - std::move(compositor_error_).Run(); + LOG(ERROR) << "Compositor process failed to begin with code: " + << static_cast<int>(compositor_status); + std::move(compositor_error_).Run(static_cast<int>(compositor_status)); return; } - base::UmaHistogramTimes( - "Browser.PaintPreview.Player.CompositorProcessStartupTime", - base::TimeTicks::Now() - startup_timestamp_); + auto delta = base::TimeTicks::Now() - startup_timestamp_; + if (delta.InMicroseconds() >= 0) { + base::UmaHistogramTimes( + "Browser.PaintPreview.Player.CompositorProcessStartupTime", delta); + } JNIEnv* env = base::android::AttachCurrentThread(); std::vector<base::UnguessableToken> all_guids; @@ -243,13 +243,16 @@ j_bitmap); }, j_bitmap_callback, j_error_callback))); + if (request_id == 0) { + auto delta = base::TimeTicks::Now() - startup_timestamp_; + if (delta.InMicroseconds() >= 0) { + base::UmaHistogramTimes("Browser.PaintPreview.Player.TimeToFirstBitmap", + delta); + } + } } else { base::android::RunRunnableAndroid(j_error_callback); } - if (request_id == 0) { - base::UmaHistogramTimes("Browser.PaintPreview.Player.TimeToFirstBitmap", - base::TimeTicks::Now() - startup_timestamp_); - } } ScopedJavaLocalRef<jstring> PlayerCompositorDelegateAndroid::OnClick(
diff --git a/components/paint_preview/player/android/player_compositor_delegate_android.h b/components/paint_preview/player/android/player_compositor_delegate_android.h index ad20969..7952151 100644 --- a/components/paint_preview/player/android/player_compositor_delegate_android.h +++ b/components/paint_preview/player/android/player_compositor_delegate_android.h
@@ -26,7 +26,7 @@ const base::android::JavaParamRef<jobject>& j_compositor_error_callback); void OnCompositorReady( - mojom::PaintPreviewCompositor::BeginCompositeStatus status, + CompositorStatus compositor_status, mojom::PaintPreviewBeginCompositeResponsePtr composite_response) override; // Called from Java when there is a request for a new bitmap. When the bitmap
diff --git a/components/paint_preview/player/compositor_status.h b/components/paint_preview/player/compositor_status.h new file mode 100644 index 0000000..0ed7597 --- /dev/null +++ b/components/paint_preview/player/compositor_status.h
@@ -0,0 +1,26 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_PAINT_PREVIEW_PLAYER_COMPOSITOR_STATUS_H_ +#define COMPONENTS_PAINT_PREVIEW_PLAYER_COMPOSITOR_STATUS_H_ + +namespace paint_preview { + +// GENERATED_JAVA_ENUM_PACKAGE: ( +// org.chromium.components.paintpreview.player) +enum class CompositorStatus : int { + OK, + URL_MISMATCH, + COMPOSITOR_SERVICE_DISCONNECT, + COMPOSITOR_CLIENT_DISCONNECT, + PROTOBUF_DESERIALIZATION_ERROR, + COMPOSITOR_DESERIALIZATION_ERROR, + INVALID_ROOT_FRAME_SKP, + INVALID_REQUEST, + COUNT, +}; + +} // namespace paint_preview + +#endif // COMPONENTS_PAINT_PREVIEW_PLAYER_COMPOSITOR_STATUS_H_
diff --git a/components/paint_preview/player/player_compositor_delegate.cc b/components/paint_preview/player/player_compositor_delegate.cc index f37540d..097348d 100644 --- a/components/paint_preview/player/player_compositor_delegate.cc +++ b/components/paint_preview/player/player_compositor_delegate.cc
@@ -12,6 +12,7 @@ #include "base/files/file_path.h" #include "base/memory/read_only_shared_memory_region.h" #include "base/memory/weak_ptr.h" +#include "base/notreached.h" #include "base/optional.h" #include "base/strings/string_piece.h" #include "base/strings/utf_string_conversions.h" @@ -98,7 +99,7 @@ PaintPreviewBaseService* paint_preview_service, const GURL& expected_url, const DirectoryKey& key, - base::OnceClosure compositor_error, + base::OnceCallback<void(int)> compositor_error, bool skip_service_launch) : compositor_error_(std::move(compositor_error)), paint_preview_service_(paint_preview_service), @@ -139,10 +140,35 @@ } } +void PlayerCompositorDelegate::OnCompositorReadyStatusAdapter( + mojom::PaintPreviewCompositor::BeginCompositeStatus status, + mojom::PaintPreviewBeginCompositeResponsePtr composite_response) { + CompositorStatus new_status; + switch (status) { + // falltrhough + case mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess: + case mojom::PaintPreviewCompositor::BeginCompositeStatus::kPartialSuccess: + new_status = CompositorStatus::OK; + break; + case mojom::PaintPreviewCompositor::BeginCompositeStatus:: + kDeserializingFailure: + new_status = CompositorStatus::COMPOSITOR_DESERIALIZATION_ERROR; + break; + case mojom::PaintPreviewCompositor::BeginCompositeStatus:: + kCompositingFailure: + new_status = CompositorStatus::INVALID_ROOT_FRAME_SKP; + break; + default: + NOTREACHED(); + } + OnCompositorReady(new_status, std::move(composite_response)); +} + void PlayerCompositorDelegate::OnCompositorServiceDisconnected() { LOG(ERROR) << "Compositor service disconnected."; if (compositor_error_) - std::move(compositor_error_).Run(); + std::move(compositor_error_) + .Run(static_cast<int>(CompositorStatus::COMPOSITOR_SERVICE_DISCONNECT)); } void PlayerCompositorDelegate::OnCompositorClientCreated( @@ -161,26 +187,21 @@ std::unique_ptr<PaintPreviewProto> proto) { if (!proto || !proto->IsInitialized()) { // TODO(crbug.com/1021590): Handle initialization errors. - OnCompositorReady(mojom::PaintPreviewCompositor::BeginCompositeStatus:: - kCompositingFailure, + OnCompositorReady(CompositorStatus::PROTOBUF_DESERIALIZATION_ERROR, nullptr); return; } auto proto_url = GURL(proto->metadata().url()); if (expected_url != proto_url) { - OnCompositorReady(mojom::PaintPreviewCompositor::BeginCompositeStatus:: - kDeserializingFailure, - nullptr); + OnCompositorReady(CompositorStatus::URL_MISMATCH, nullptr); return; } hit_testers_ = BuildHitTesters(*proto); if (!paint_preview_compositor_client_) { - OnCompositorReady(mojom::PaintPreviewCompositor::BeginCompositeStatus:: - kCompositingFailure, - nullptr); + OnCompositorReady(CompositorStatus::COMPOSITOR_CLIENT_DISCONNECT, nullptr); return; } @@ -197,22 +218,21 @@ mojom::PaintPreviewBeginCompositeRequestPtr begin_composite_request) { // TODO(crbug.com/1021590): Handle initialization errors. if (!begin_composite_request) { - OnCompositorReady(mojom::PaintPreviewCompositor::BeginCompositeStatus:: - kCompositingFailure, - nullptr); + OnCompositorReady(CompositorStatus::INVALID_REQUEST, nullptr); return; } paint_preview_compositor_client_->BeginSeparatedFrameComposite( std::move(begin_composite_request), - base::BindOnce(&PlayerCompositorDelegate::OnCompositorReady, + base::BindOnce(&PlayerCompositorDelegate::OnCompositorReadyStatusAdapter, weak_factory_.GetWeakPtr())); } void PlayerCompositorDelegate::OnCompositorClientDisconnected() { LOG(ERROR) << "Compositor client disconnected."; if (compositor_error_) - std::move(compositor_error_).Run(); + std::move(compositor_error_) + .Run(static_cast<int>(CompositorStatus::COMPOSITOR_CLIENT_DISCONNECT)); } void PlayerCompositorDelegate::RequestBitmap(
diff --git a/components/paint_preview/player/player_compositor_delegate.h b/components/paint_preview/player/player_compositor_delegate.h index 2c4936f..636bc5ba 100644 --- a/components/paint_preview/player/player_compositor_delegate.h +++ b/components/paint_preview/player/player_compositor_delegate.h
@@ -12,6 +12,7 @@ #include "base/unguessable_token.h" #include "components/paint_preview/browser/hit_tester.h" #include "components/paint_preview/browser/paint_preview_base_service.h" +#include "components/paint_preview/player/compositor_status.h" #include "components/paint_preview/public/paint_preview_compositor_client.h" #include "components/paint_preview/public/paint_preview_compositor_service.h" #include "components/services/paint_preview_compositor/public/mojom/paint_preview_compositor.mojom.h" @@ -32,7 +33,7 @@ PlayerCompositorDelegate(PaintPreviewBaseService* paint_preview_service, const GURL& url, const DirectoryKey& key, - base::OnceClosure compositor_error, + base::OnceCallback<void(int)> compositor_error, bool skip_service_launch = false); virtual ~PlayerCompositorDelegate(); @@ -42,7 +43,7 @@ void SetCompressOnClose(bool compress) { compress_on_close_ = compress; } virtual void OnCompositorReady( - mojom::PaintPreviewCompositor::BeginCompositeStatus status, + CompositorStatus compositor_status, mojom::PaintPreviewBeginCompositeResponsePtr composite_response) {} // Called when there is a request for a new bitmap. When the bitmap @@ -59,9 +60,13 @@ const gfx::Rect& rect); protected: - base::OnceClosure compositor_error_; + base::OnceCallback<void(int)> compositor_error_; private: + void OnCompositorReadyStatusAdapter( + mojom::PaintPreviewCompositor::BeginCompositeStatus status, + mojom::PaintPreviewBeginCompositeResponsePtr composite_response); + void OnCompositorServiceDisconnected(); void OnCompositorClientCreated(const GURL& expected_url,
diff --git a/components/paint_preview/renderer/paint_preview_recorder_impl.cc b/components/paint_preview/renderer/paint_preview_recorder_impl.cc index a828cb19..b7898ceb 100644 --- a/components/paint_preview/renderer/paint_preview_recorder_impl.cc +++ b/components/paint_preview/renderer/paint_preview_recorder_impl.cc
@@ -187,7 +187,6 @@ auto tracker = std::make_unique<PaintPreviewTracker>( params->guid, frame->GetEmbeddingToken(), is_main_frame_); auto size = frame->GetScrollOffset(); - tracker->SetScrollForFrame(SkISize::Make(size.width, size.height)); response->scroll_offsets = gfx::Size(size.width, size.height); cc::PaintRecorder recorder;
diff --git a/components/password_manager/core/browser/ui/compromised_credentials_manager.cc b/components/password_manager/core/browser/ui/compromised_credentials_manager.cc index 115556c..e79ed75f 100644 --- a/components/password_manager/core/browser/ui/compromised_credentials_manager.cc +++ b/components/password_manager/core/browser/ui/compromised_credentials_manager.cc
@@ -34,22 +34,24 @@ // Transparent comparator that can compare CompromisedCredentials and // autofill::PasswordForm. struct CredentialWithoutPasswordLess { - static std::tuple<const std::string&, const base::string16&> - CredentialOriginAndUsername(const autofill::PasswordForm& form) { - return std::tie(form.signon_realm, form.username_value); - } - - static std::tuple<const std::string&, const base::string16&> - CredentialOriginAndUsername(const CompromisedCredentials& c) { - return std::tie(c.signon_realm, c.username); - } - template <typename T, typename U> bool operator()(const T& lhs, const U& rhs) const { - return CredentialOriginAndUsername(lhs) < CredentialOriginAndUsername(rhs); + return CredentialOriginAndUsernameAndStore(lhs) < + CredentialOriginAndUsernameAndStore(rhs); } using is_transparent = void; + + private: + static auto CredentialOriginAndUsernameAndStore( + const autofill::PasswordForm& form) { + return std::tie(form.signon_realm, form.username_value, form.in_store); + } + + static auto CredentialOriginAndUsernameAndStore( + const CompromisedCredentials& c) { + return std::tie(c.signon_realm, c.username, c.in_store); + } }; CompromiseTypeFlags ConvertCompromiseType(CompromiseType type) { @@ -184,11 +186,14 @@ CredentialWithPassword&& other) = default; CompromisedCredentialsManager::CompromisedCredentialsManager( - scoped_refptr<PasswordStore> store, - SavedPasswordsPresenter* presenter) - : store_(std::move(store)), - presenter_(presenter), - compromised_credentials_reader_(store_.get()) { + SavedPasswordsPresenter* presenter, + scoped_refptr<PasswordStore> profile_store, + scoped_refptr<PasswordStore> account_store) + : presenter_(presenter), + profile_store_(std::move(profile_store)), + account_store_(std::move(account_store)), + compromised_credentials_reader_(profile_store_.get(), + account_store_.get()) { observed_compromised_credentials_reader_.Add( &compromised_credentials_reader_); observed_saved_password_presenter_.Add(presenter_); @@ -211,7 +216,10 @@ if (saved_password.password_value == credential.password() && CanonicalizeUsername(saved_password.username_value) == canonicalized_username) { - store_->AddCompromisedCredentials({ + PasswordStore& store = saved_password.IsUsingAccountStore() + ? *account_store_ + : *profile_store_; + store.AddCompromisedCredentials({ .signon_realm = saved_password.signon_realm, .username = saved_password.username_value, .create_time = base::Time::Now(), @@ -235,7 +243,7 @@ return false; for (size_t i = 1; i < forms.size(); ++i) - store_->RemoveLogin(forms[i]); + profile_store_->RemoveLogin(forms[i]); // Note: We Invoke EditPassword on the presenter rather than UpdateLogin() on // the store, so that observers of the presenter get notified of this event. @@ -252,7 +260,7 @@ // credentials were deleted. const auto& saved_passwords = it->second.forms; for (const autofill::PasswordForm& saved_password : saved_passwords) - store_->RemoveLogin(saved_password); + profile_store_->RemoveLogin(saved_password); return !saved_passwords.empty(); }
diff --git a/components/password_manager/core/browser/ui/compromised_credentials_manager.h b/components/password_manager/core/browser/ui/compromised_credentials_manager.h index 8393a9c..ac58a19 100644 --- a/components/password_manager/core/browser/ui/compromised_credentials_manager.h +++ b/components/password_manager/core/browser/ui/compromised_credentials_manager.h
@@ -112,8 +112,10 @@ CredentialsView credentials) = 0; }; - explicit CompromisedCredentialsManager(scoped_refptr<PasswordStore> store, - SavedPasswordsPresenter* presenter); + CompromisedCredentialsManager( + SavedPasswordsPresenter* presenter, + scoped_refptr<PasswordStore> profile_store, + scoped_refptr<PasswordStore> account_store = nullptr); ~CompromisedCredentialsManager() override; void Init(); @@ -160,15 +162,16 @@ void UpdateCachedDataAndNotifyObservers( SavedPasswordsPresenter::SavedPasswordsView saved_passwords); - // The password store containing the compromised credentials. - scoped_refptr<PasswordStore> store_; - // A weak handle to the presenter used to join the list of compromised // credentials with saved passwords. Needs to outlive this instance. SavedPasswordsPresenter* presenter_ = nullptr; + // The password stores containing the compromised credentials. + scoped_refptr<PasswordStore> profile_store_; + scoped_refptr<PasswordStore> account_store_; + // The reader used to read the compromised credentials from the password - // store. + // stores. CompromisedCredentialsReader compromised_credentials_reader_; // Cache of the most recently obtained compromised credentials.
diff --git a/components/password_manager/core/browser/ui/compromised_credentials_manager_unittest.cc b/components/password_manager/core/browser/ui/compromised_credentials_manager_unittest.cc index 114cb18..4d22e109 100644 --- a/components/password_manager/core/browser/ui/compromised_credentials_manager_unittest.cc +++ b/components/password_manager/core/browser/ui/compromised_credentials_manager_unittest.cc
@@ -27,6 +27,7 @@ constexpr char kPassword1[] = "f00b4r"; constexpr char kPassword2[] = "s3cr3t"; +constexpr char kPassword3[] = "484her"; using autofill::PasswordForm; using ::testing::ElementsAre; @@ -71,7 +72,7 @@ base::ASCIIToUTF16(password)); } -CredentialWithPassword MakeComprmisedCredential( +CredentialWithPassword MakeCompromisedCredential( PasswordForm form, CompromisedCredentials credential) { CredentialWithPassword credential_with_password((CredentialView(form))); @@ -103,7 +104,7 @@ scoped_refptr<TestPasswordStore> store_ = base::MakeRefCounted<TestPasswordStore>(); SavedPasswordsPresenter presenter_{store_}; - CompromisedCredentialsManager provider_{store_, &presenter_}; + CompromisedCredentialsManager provider_{&presenter_, store_}; }; } // namespace @@ -249,7 +250,7 @@ RunUntilIdle(); CredentialWithPassword expected = - MakeComprmisedCredential(password, credential); + MakeCompromisedCredential(password, credential); expected.password = password.password_value; EXPECT_THAT(provider().GetCompromisedCredentials(), ElementsAre(expected)); } @@ -269,7 +270,7 @@ store().AddCompromisedCredentials(phished); RunUntilIdle(); - CredentialWithPassword expected = MakeComprmisedCredential(password, leaked); + CredentialWithPassword expected = MakeCompromisedCredential(password, leaked); expected.password = password.password_value; expected.compromise_type = (CompromiseTypeFlags::kCredentialLeaked | CompromiseTypeFlags::kCredentialPhished); @@ -288,9 +289,9 @@ MakeCompromised(kExampleCom, kUsername1), MakeCompromised(kExampleCom, kUsername2)}; - std::vector<CredentialWithPassword> expected; - expected.push_back(MakeComprmisedCredential(passwords[0], credentials[0])); - expected.push_back(MakeComprmisedCredential(passwords[1], credentials[1])); + std::vector<CredentialWithPassword> expected = { + MakeCompromisedCredential(passwords[0], credentials[0]), + MakeCompromisedCredential(passwords[1], credentials[1])}; store().AddLogin(passwords[0]); RunUntilIdle(); @@ -336,9 +337,9 @@ RunUntilIdle(); CredentialWithPassword expected1 = - MakeComprmisedCredential(passwords[0], credentials[0]); + MakeCompromisedCredential(passwords[0], credentials[0]); CredentialWithPassword expected2 = - MakeComprmisedCredential(passwords[1], credentials[1]); + MakeCompromisedCredential(passwords[1], credentials[1]); EXPECT_THAT(provider().GetCompromisedCredentials(), ElementsAre(expected1, expected2)); @@ -394,9 +395,9 @@ RunUntilIdle(); CredentialWithPassword expected1 = - MakeComprmisedCredential(passwords[0], credential); + MakeCompromisedCredential(passwords[0], credential); CredentialWithPassword expected2 = - MakeComprmisedCredential(passwords[1], credential); + MakeCompromisedCredential(passwords[1], credential); EXPECT_THAT(provider().GetCompromisedCredentials(), ElementsAre(expected1, expected2)); @@ -417,7 +418,7 @@ RunUntilIdle(); CredentialWithPassword expected = - MakeComprmisedCredential(passwords[0], credential); + MakeCompromisedCredential(passwords[0], credential); EXPECT_THAT(provider().GetCompromisedCredentials(), ElementsAre(expected)); } @@ -434,13 +435,10 @@ MakeCompromised(kExampleCom, kUsername1), MakeCompromised(kExampleOrg, kUsername2)}; - std::vector<CredentialWithPassword> credentuals_with_password; - credentuals_with_password.push_back( - MakeComprmisedCredential(passwords[0], credentials[0])); - credentuals_with_password.push_back( - MakeComprmisedCredential(passwords[1], credentials[0])); - credentuals_with_password.push_back( - MakeComprmisedCredential(passwords[2], credentials[1])); + std::vector<CredentialWithPassword> credentials_with_password = { + MakeCompromisedCredential(passwords[0], credentials[0]), + MakeCompromisedCredential(passwords[1], credentials[0]), + MakeCompromisedCredential(passwords[2], credentials[1])}; store().AddLogin(passwords[0]); store().AddLogin(passwords[1]); @@ -449,13 +447,13 @@ store().AddCompromisedCredentials(credentials[1]); RunUntilIdle(); - EXPECT_THAT(provider().GetSavedPasswordsFor(credentuals_with_password[0]), + EXPECT_THAT(provider().GetSavedPasswordsFor(credentials_with_password[0]), ElementsAreArray(store().stored_passwords().at(kExampleCom))); - EXPECT_THAT(provider().GetSavedPasswordsFor(credentuals_with_password[1]), + EXPECT_THAT(provider().GetSavedPasswordsFor(credentials_with_password[1]), ElementsAreArray(store().stored_passwords().at(kExampleCom))); - EXPECT_THAT(provider().GetSavedPasswordsFor(credentuals_with_password[2]), + EXPECT_THAT(provider().GetSavedPasswordsFor(credentials_with_password[2]), ElementsAreArray(store().stored_passwords().at(kExampleOrg))); } @@ -472,7 +470,7 @@ RunUntilIdle(); CredentialWithPassword expected = - MakeComprmisedCredential(password_form, compromised_credential); + MakeCompromisedCredential(password_form, compromised_credential); expected.create_time = base::Time::Now(); provider().SaveCompromisedCredential(credential); @@ -493,7 +491,7 @@ RunUntilIdle(); CredentialWithPassword expected = - MakeComprmisedCredential(password_form, credential); + MakeCompromisedCredential(password_form, credential); provider().UpdateCompromisedCredentials(expected, kPassword2); RunUntilIdle(); @@ -512,7 +510,7 @@ RunUntilIdle(); CredentialWithPassword expected = - MakeComprmisedCredential(password, credential); + MakeCompromisedCredential(password, credential); expected.password = password.password_value; EXPECT_THAT(provider().GetCompromisedCredentials(), ElementsAre(expected)); @@ -522,4 +520,126 @@ EXPECT_THAT(provider().GetCompromisedCredentials(), IsEmpty()); } +namespace { +class CompromisedCredentialsManagerWithTwoStoresTest : public ::testing::Test { + protected: + CompromisedCredentialsManagerWithTwoStoresTest() { + profile_store_->Init(/*prefs=*/nullptr); + account_store_->Init(/*prefs=*/nullptr); + } + + ~CompromisedCredentialsManagerWithTwoStoresTest() override { + account_store_->ShutdownOnUIThread(); + profile_store_->ShutdownOnUIThread(); + task_env_.RunUntilIdle(); + } + + TestPasswordStore& profile_store() { return *profile_store_; } + TestPasswordStore& account_store() { return *account_store_; } + CompromisedCredentialsManager& provider() { return provider_; } + + void RunUntilIdle() { task_env_.RunUntilIdle(); } + + private: + base::test::SingleThreadTaskEnvironment task_env_; + scoped_refptr<TestPasswordStore> profile_store_ = + base::MakeRefCounted<TestPasswordStore>(/*is_account_store=*/false); + scoped_refptr<TestPasswordStore> account_store_ = + base::MakeRefCounted<TestPasswordStore>(/*is_account_store=*/true); + SavedPasswordsPresenter presenter_{profile_store_, account_store_}; + CompromisedCredentialsManager provider_{&presenter_, profile_store_, + account_store_}; +}; +} // namespace + +// Tests that verifies mapping compromised credentials to passwords works +// correctly. +TEST_F(CompromisedCredentialsManagerWithTwoStoresTest, + MapCompromisedPasswordsToPasswords) { + // Add credentials for both `kExampleCom` and `kExampleOrg` in both stores + // with the same username and difference passwords. For `kUsername1`, the + // `kPassword1` are `kPassword2` are compromised while + // `kPassword3` is safe. + std::vector<PasswordForm> profile_store_passwords = { + MakeSavedPassword(kExampleCom, kUsername1, kPassword1), + MakeSavedPassword(kExampleOrg, kUsername1, kPassword3)}; + for (const PasswordForm& profile_password : profile_store_passwords) + profile_store().AddLogin(profile_password); + + std::vector<PasswordForm> account_store_passwords = { + MakeSavedPassword(kExampleCom, kUsername1, kPassword3), + MakeSavedPassword(kExampleOrg, kUsername1, kPassword2)}; + for (const PasswordForm& account_password : account_store_passwords) + account_store().AddLogin(account_password); + + // Mark `kPassword1` to be compromised in the profile store, and `kPassword2` + // to be compromised in the account store. + profile_store().AddCompromisedCredentials( + MakeCompromised(kExampleCom, kUsername1)); + account_store().AddCompromisedCredentials( + MakeCompromised(kExampleOrg, kUsername1)); + + RunUntilIdle(); + + // Each password should be joined only with compromised credential from + // their store. + EXPECT_THAT( + provider().GetSavedPasswordsFor( + CredentialView(kExampleCom, GURL(), base::ASCIIToUTF16(kUsername1), + base::ASCIIToUTF16(kPassword1))), + ElementsAreArray(profile_store().stored_passwords().at(kExampleCom))); + + EXPECT_THAT(provider().GetSavedPasswordsFor(CredentialView( + kExampleOrg, GURL(), base::ASCIIToUTF16(kUsername1), + base::ASCIIToUTF16(kPassword3))), + IsEmpty()); + + EXPECT_THAT(provider().GetSavedPasswordsFor(CredentialView( + kExampleCom, GURL(), base::ASCIIToUTF16(kUsername1), + base::ASCIIToUTF16(kPassword3))), + IsEmpty()); + + EXPECT_THAT( + provider().GetSavedPasswordsFor( + CredentialView(kExampleOrg, GURL(), base::ASCIIToUTF16(kUsername1), + base::ASCIIToUTF16(kPassword2))), + ElementsAreArray(account_store().stored_passwords().at(kExampleOrg))); +} + +// Test verifies that saving LeakCheckCredential via provider adds expected +// compromised credential to the correct store. +TEST_F(CompromisedCredentialsManagerWithTwoStoresTest, + SaveCompromisedPassword) { + ASSERT_TRUE(profile_store().compromised_credentials().empty()); + ASSERT_TRUE(account_store().compromised_credentials().empty()); + // Add `kUsername1`,`kPassword1` to both stores. + // And add `kUsername1`,`kPassword2` to the account store only. + profile_store().AddLogin( + MakeSavedPassword(kExampleCom, kUsername1, kPassword1)); + + account_store().AddLogin( + MakeSavedPassword(kExampleOrg, kUsername1, kPassword1)); + account_store().AddLogin( + MakeSavedPassword(kExampleCom, kUsername1, kPassword2)); + + RunUntilIdle(); + + // Mark `kUsername1`, `kPassword1` as compromised, a new entry should be + // added to both stores. + provider().SaveCompromisedCredential( + MakeLeakCredential(kUsername1, kPassword1)); + RunUntilIdle(); + + EXPECT_EQ(1U, profile_store().compromised_credentials().size()); + EXPECT_EQ(1U, account_store().compromised_credentials().size()); + + // Now, mark `kUsername1`, `kPassword2` as compromised, a new entry should be + // added only to the account store. + provider().SaveCompromisedCredential( + MakeLeakCredential(kUsername1, kPassword2)); + RunUntilIdle(); + + EXPECT_EQ(1U, profile_store().compromised_credentials().size()); + EXPECT_EQ(2U, account_store().compromised_credentials().size()); +} } // namespace password_manager
diff --git a/components/password_manager/core/browser/well_known_change_password_util.h b/components/password_manager/core/browser/well_known_change_password_util.h index 14196147..fd296a8e 100644 --- a/components/password_manager/core/browser/well_known_change_password_util.h +++ b/components/password_manager/core/browser/well_known_change_password_util.h
@@ -11,6 +11,15 @@ namespace password_manager { +// Used to report UKMs about the support for .well-known/change-password. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class WellKnownChangePasswordResult { + kFallbackToOriginUrl = 0, + kFallbackToOverrideUrl = 1, + kUsedWellKnownChangePassword = 2, +}; + // Path for Well-Known change password url // Spec: https://wicg.github.io/change-password-url/ extern const char kWellKnownChangePasswordPath[];
diff --git a/components/renderer_context_menu/render_view_context_menu_base.cc b/components/renderer_context_menu/render_view_context_menu_base.cc index b5fac6e..8c079b6 100644 --- a/components/renderer_context_menu/render_view_context_menu_base.cc +++ b/components/renderer_context_menu/render_view_context_menu_base.cc
@@ -209,17 +209,8 @@ void RenderViewContextMenuBase::AddMenuItemWithIcon( int command_id, const base::string16& title, - const gfx::ImageSkia& image) { - menu_model_.AddItemWithIcon(command_id, title, - ui::ImageModel::FromImageSkia(image)); -} - -void RenderViewContextMenuBase::AddMenuItemWithIcon( - int command_id, - const base::string16& title, - const gfx::VectorIcon& icon) { - menu_model_.AddItemWithIcon(command_id, title, - ui::ImageModel::FromVectorIcon(icon)); + const ui::ImageModel& icon) { + menu_model_.AddItemWithIcon(command_id, title, icon); } void RenderViewContextMenuBase::AddCheckItem(int command_id, @@ -241,18 +232,9 @@ int command_id, int message_id, ui::MenuModel* model, - const gfx::ImageSkia& image) { - menu_model_.AddSubMenuWithStringIdAndIcon( - command_id, message_id, model, ui::ImageModel::FromImageSkia(image)); -} - -void RenderViewContextMenuBase::AddSubMenuWithStringIdAndIcon( - int command_id, - int message_id, - ui::MenuModel* model, - const gfx::VectorIcon& icon) { - menu_model_.AddSubMenuWithStringIdAndIcon( - command_id, message_id, model, ui::ImageModel::FromVectorIcon(icon)); + const ui::ImageModel& icon) { + menu_model_.AddSubMenuWithStringIdAndIcon(command_id, message_id, model, + icon); } void RenderViewContextMenuBase::UpdateMenuItem(int command_id, @@ -271,12 +253,12 @@ } void RenderViewContextMenuBase::UpdateMenuIcon(int command_id, - const gfx::Image& image) { + const ui::ImageModel& icon) { int index = menu_model_.GetIndexOfCommandId(command_id); if (index == -1) return; - menu_model_.SetIcon(index, ui::ImageModel::FromImage(image)); + menu_model_.SetIcon(index, icon); #if defined(OS_CHROMEOS) if (toolkit_delegate_) toolkit_delegate_->RebuildMenu();
diff --git a/components/renderer_context_menu/render_view_context_menu_base.h b/components/renderer_context_menu/render_view_context_menu_base.h index 2fc1837..4fe4c282 100644 --- a/components/renderer_context_menu/render_view_context_menu_base.h +++ b/components/renderer_context_menu/render_view_context_menu_base.h
@@ -97,10 +97,7 @@ void AddMenuItem(int command_id, const base::string16& title) override; void AddMenuItemWithIcon(int command_id, const base::string16& title, - const gfx::ImageSkia& image) override; - void AddMenuItemWithIcon(int command_id, - const base::string16& title, - const gfx::VectorIcon& icon) override; + const ui::ImageModel& icon) override; void AddCheckItem(int command_id, const base::string16& title) override; void AddSeparator() override; void AddSubMenu(int command_id, @@ -109,16 +106,12 @@ void AddSubMenuWithStringIdAndIcon(int command_id, int message_id, ui::MenuModel* model, - const gfx::ImageSkia& image) override; - void AddSubMenuWithStringIdAndIcon(int command_id, - int message_id, - ui::MenuModel* model, - const gfx::VectorIcon& icon) override; + const ui::ImageModel& icon) override; void UpdateMenuItem(int command_id, bool enabled, bool hidden, const base::string16& title) override; - void UpdateMenuIcon(int command_id, const gfx::Image& image) override; + void UpdateMenuIcon(int command_id, const ui::ImageModel& icon) override; void RemoveMenuItem(int command_id) override; void RemoveAdjacentSeparators() override; content::RenderViewHost* GetRenderViewHost() const override;
diff --git a/components/renderer_context_menu/render_view_context_menu_proxy.h b/components/renderer_context_menu/render_view_context_menu_proxy.h index 33b34387..1f8a9ea 100644 --- a/components/renderer_context_menu/render_view_context_menu_proxy.h +++ b/components/renderer_context_menu/render_view_context_menu_proxy.h
@@ -13,13 +13,8 @@ class WebContents; } -namespace gfx { -class Image; -class ImageSkia; -struct VectorIcon; -} - namespace ui { +class ImageModel; class MenuModel; } @@ -84,10 +79,7 @@ virtual void AddMenuItem(int command_id, const base::string16& title) = 0; virtual void AddMenuItemWithIcon(int command_id, const base::string16& title, - const gfx::ImageSkia& image) = 0; - virtual void AddMenuItemWithIcon(int command_id, - const base::string16& title, - const gfx::VectorIcon& image) = 0; + const ui::ImageModel& icon) = 0; virtual void AddCheckItem(int command_id, const base::string16& title) = 0; virtual void AddSeparator() = 0; @@ -98,11 +90,7 @@ virtual void AddSubMenuWithStringIdAndIcon(int command_id, int message_id, ui::MenuModel* model, - const gfx::ImageSkia& image) = 0; - virtual void AddSubMenuWithStringIdAndIcon(int command_id, - int message_id, - ui::MenuModel* model, - const gfx::VectorIcon& image) = 0; + const ui::ImageModel& icon) = 0; // Update the status and text of the specified context-menu item. virtual void UpdateMenuItem(int command_id, @@ -111,7 +99,7 @@ const base::string16& title) = 0; // Update the icon of the specified context-menu item. - virtual void UpdateMenuIcon(int command_id, const gfx::Image& image) = 0; + virtual void UpdateMenuIcon(int command_id, const ui::ImageModel& icon) = 0; // Remove the specified context-menu item. virtual void RemoveMenuItem(int command_id) = 0;
diff --git a/components/services/paint_preview_compositor/paint_preview_compositor_impl.cc b/components/services/paint_preview_compositor/paint_preview_compositor_impl.cc index a05b029c..85bfdc78 100644 --- a/components/services/paint_preview_compositor/paint_preview_compositor_impl.cc +++ b/components/services/paint_preview_compositor/paint_preview_compositor_impl.cc
@@ -337,9 +337,6 @@ // before the current frame is loaded to ensure the order of loading is // topologically sorted. LoadedFramesDeserialContext deserial_context; - deserial_context.scroll_offsets = gfx::Size( - frame_proto.has_scroll_offset_x() ? frame_proto.scroll_offset_x() : 0, - frame_proto.has_scroll_offset_y() ? frame_proto.scroll_offset_y() : 0); *subframe_failed = false; for (const auto& id_pair : frame_proto.content_id_to_embedding_tokens()) { @@ -396,7 +393,7 @@ subframe_proto_it->has_scroll_offset_y() ? subframe_proto_it->scroll_offset_y() : 0); - deserial_context.subframes.insert({id_pair.content_id(), frame}); + deserial_context.insert({id_pair.content_id(), frame}); } auto recording_it = recording_map->find(frame_guid);
diff --git a/components/services/paint_preview_compositor/paint_preview_compositor_impl_unittest.cc b/components/services/paint_preview_compositor/paint_preview_compositor_impl_unittest.cc index 9354210..2796be83 100644 --- a/components/services/paint_preview_compositor/paint_preview_compositor_impl_unittest.cc +++ b/components/services/paint_preview_compositor/paint_preview_compositor_impl_unittest.cc
@@ -208,10 +208,6 @@ // observing it. PaintPreviewTracker tracker(base::UnguessableToken::Create(), guid, set_is_main_frame); - if (set_is_main_frame) { - tracker.SetScrollForFrame( - SkISize::Make(scroll_offsets.width(), scroll_offsets.height())); - } mojom::FrameDataPtr expected_frame_data = mojom::FrameData::New(); expected_frame_data->scroll_extents = scroll_extents; expected_frame_data->scroll_offsets = scroll_offsets;
diff --git a/components/signin/core/browser/android/BUILD.gn b/components/signin/core/browser/android/BUILD.gn index 8e50995..4b08d8a 100644 --- a/components/signin/core/browser/android/BUILD.gn +++ b/components/signin/core/browser/android/BUILD.gn
@@ -39,7 +39,6 @@ "java/src/org/chromium/components/signin/AuthException.java", "java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java", "java/src/org/chromium/components/signin/ChildAccountStatus.java", - "java/src/org/chromium/components/signin/ChromeSigninController.java", "java/src/org/chromium/components/signin/GmsAvailabilityException.java", "java/src/org/chromium/components/signin/GmsJustUpdatedException.java", "java/src/org/chromium/components/signin/MutableObservableValue.java",
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/ChromeSigninController.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/ChromeSigninController.java deleted file mode 100644 index d55b7a3..0000000 --- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/ChromeSigninController.java +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.components.signin; - -import org.chromium.base.ContextUtils; - -/** - * Caches the signed-in username in the app prefs. - */ -@Deprecated -public class ChromeSigninController { - public static final String TAG = "ChromeSigninController"; - - private static final String SIGNED_IN_ACCOUNT_KEY = "google.services.username"; - - private static final Object LOCK = new Object(); - - private static ChromeSigninController sChromeSigninController; - - private ChromeSigninController() {} - - /** - * A factory method for the ChromeSigninController. - * - * @return a singleton instance of the ChromeSigninController - */ - public static ChromeSigninController get() { - synchronized (LOCK) { - if (sChromeSigninController == null) { - sChromeSigninController = new ChromeSigninController(); - } - } - return sChromeSigninController; - } - - // TODO(https://crbug.com/1046412): Remove after migrating downstream usages to - // SigninPreferencesManager. - public String getSignedInAccountName() { - return ContextUtils.getAppSharedPreferences().getString(SIGNED_IN_ACCOUNT_KEY, null); - } -}
diff --git a/components/sync/trusted_vault/standalone_trusted_vault_backend.cc b/components/sync/trusted_vault/standalone_trusted_vault_backend.cc index 6c859c7..5c569c3 100644 --- a/components/sync/trusted_vault/standalone_trusted_vault_backend.cc +++ b/components/sync/trusted_vault/standalone_trusted_vault_backend.cc
@@ -73,12 +73,12 @@ FindUserVault(account_info.gaia); // TODO(crbug.com/1094326): currently there is no guarantee that - // |syncing_account_| is set before FetchKeys() call and this may cause + // |primary_account_| is set before FetchKeys() call and this may cause // redundant sync error in the UI (for key retrieval), especially during the // browser startup. Try to find a way to avoid this issue. if (!base::FeatureList::IsEnabled(switches::kFollowTrustedVaultKeyRotation) || - !syncing_account_.has_value() || - syncing_account_->gaia != account_info.gaia || !per_user_vault || + !primary_account_.has_value() || + primary_account_->gaia != account_info.gaia || !per_user_vault || !per_user_vault->keys_are_stale() || !per_user_vault->local_device_registration_info().device_registered()) { // Keys download attempt is not needed or not possible. @@ -87,7 +87,7 @@ } // Current state guarantees there is no ongoing requests to the server: - // 1. Current |syncing_account_| is |account_info|, so there is no ongoing + // 1. Current |primary_account_| is |account_info|, so there is no ongoing // request for other accounts. // 2. Device is already registered, so there is no device registration for // |account_info|. @@ -120,7 +120,7 @@ .key_material(); std::vector<uint8_t> last_key_bytes(last_key.begin(), last_key.end()); connection_->DownloadKeys( - *syncing_account_, last_key_bytes, + *primary_account_, last_key_bytes, per_user_vault->last_vault_key_version(), std::move(key_pair), base::BindOnce(&StandaloneTrustedVaultBackend::OnKeysDownloaded, weak_factory_for_connection_.GetWeakPtr(), @@ -156,15 +156,15 @@ AbandonConnectionRequest(); } -void StandaloneTrustedVaultBackend::SetSyncingAccount( - const base::Optional<CoreAccountInfo>& syncing_account) { - if (syncing_account == syncing_account_) { +void StandaloneTrustedVaultBackend::SetPrimaryAccount( + const base::Optional<CoreAccountInfo>& primary_account) { + if (primary_account == primary_account_) { return; } - syncing_account_ = syncing_account; + primary_account_ = primary_account; AbandonConnectionRequest(); - if (syncing_account_.has_value()) { - MaybeRegisterDevice(syncing_account_->gaia); + if (primary_account_.has_value()) { + MaybeRegisterDevice(primary_account_->gaia); } } @@ -182,6 +182,11 @@ return true; } +base::Optional<CoreAccountInfo> +StandaloneTrustedVaultBackend::GetPrimaryAccountForTesting() const { + return primary_account_; +} + sync_pb::LocalDeviceRegistrationInfo StandaloneTrustedVaultBackend::GetDeviceRegistrationInfoForTesting( const std::string& gaia_id) { @@ -197,8 +202,8 @@ if (!base::FeatureList::IsEnabled(switches::kFollowTrustedVaultKeyRotation)) { return; } - if (!syncing_account_.has_value() || syncing_account_->gaia != gaia_id) { - // Device registration is supported only for |syncing_account_|. + if (!primary_account_.has_value() || primary_account_->gaia != gaia_id) { + // Device registration is supported only for |primary_account_|. return; } sync_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(gaia_id); @@ -247,7 +252,7 @@ // one ongoing request. AbandonConnectionRequest(); connection_->RegisterDevice( - *syncing_account_, last_key_bytes, + *primary_account_, last_key_bytes, per_user_vault->last_vault_key_version(), key_pair->public_key(), base::BindOnce(&StandaloneTrustedVaultBackend::OnDeviceRegistered, weak_factory_for_connection_.GetWeakPtr(), gaia_id)); @@ -256,9 +261,9 @@ void StandaloneTrustedVaultBackend::OnDeviceRegistered( const std::string& gaia_id, TrustedVaultRequestStatus status) { - // If |syncing_account_| was changed meanwhile, this callback must be + // If |primary_account_| was changed meanwhile, this callback must be // cancelled. - DCHECK(syncing_account_ && syncing_account_->gaia == gaia_id); + DCHECK(primary_account_ && primary_account_->gaia == gaia_id); sync_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(gaia_id); DCHECK(per_user_vault); @@ -285,7 +290,7 @@ TrustedVaultRequestStatus status, const std::vector<std::vector<uint8_t>>& vault_keys, int last_vault_key_version) { - DCHECK(syncing_account_ && syncing_account_->gaia == gaia_id); + DCHECK(primary_account_ && primary_account_->gaia == gaia_id); DCHECK(!ongoing_fetch_keys_callback_.is_null()); DCHECK(ongoing_fetch_keys_gaia_id_ == gaia_id);
diff --git a/components/sync/trusted_vault/standalone_trusted_vault_backend.h b/components/sync/trusted_vault/standalone_trusted_vault_backend.h index ff709c6..b05a074 100644 --- a/components/sync/trusted_vault/standalone_trusted_vault_backend.h +++ b/components/sync/trusted_vault/standalone_trusted_vault_backend.h
@@ -64,9 +64,11 @@ // Removes all keys for all accounts from both memory and |file_path_|. void RemoveAllStoredKeys(); - // Sets/resets |syncing_account_|. - void SetSyncingAccount( - const base::Optional<CoreAccountInfo>& syncing_account); + // Sets/resets |primary_account_|. + void SetPrimaryAccount( + const base::Optional<CoreAccountInfo>& primary_account); + + base::Optional<CoreAccountInfo> GetPrimaryAccountForTesting() const; sync_pb::LocalDeviceRegistrationInfo GetDeviceRegistrationInfoForTesting( const std::string& gaia_id); @@ -102,9 +104,9 @@ sync_pb::LocalTrustedVault data_; - // Only current |syncing_account_| can be used for communication with trusted + // Only current |primary_account_| can be used for communication with trusted // vault server. - base::Optional<CoreAccountInfo> syncing_account_; + base::Optional<CoreAccountInfo> primary_account_; // Used for communication with trusted vault server. std::unique_ptr<TrustedVaultConnection> connection_;
diff --git a/components/sync/trusted_vault/standalone_trusted_vault_backend_unittest.cc b/components/sync/trusted_vault/standalone_trusted_vault_backend_unittest.cc index 39341e5..d6bc767 100644 --- a/components/sync/trusted_vault/standalone_trusted_vault_backend_unittest.cc +++ b/components/sync/trusted_vault/standalone_trusted_vault_backend_unittest.cc
@@ -96,16 +96,16 @@ TrustedVaultConnection::RegisterDeviceCallback callback) { device_registration_callback = std::move(callback); }); - // Setting the syncing account will trigger device registration. - backend()->SetSyncingAccount(account_info); + // Setting the primary account will trigger device registration. + backend()->SetPrimaryAccount(account_info); EXPECT_FALSE(device_registration_callback.is_null()); // Pretend that the registration completed successfully. std::move(device_registration_callback) .Run(TrustedVaultRequestStatus::kSuccess); - // Reset syncing account. - backend()->SetSyncingAccount(base::nullopt); + // Reset primary account. + backend()->SetPrimaryAccount(base::nullopt); std::string device_private_key_material = backend_->GetDeviceRegistrationInfoForTesting(account_info.gaia) @@ -143,8 +143,8 @@ device_registration_callback = std::move(callback); }); - // Setting the syncing account will trigger device registration. - backend()->SetSyncingAccount(account_info); + // Setting the primary account will trigger device registration. + backend()->SetPrimaryAccount(account_info); ASSERT_FALSE(device_registration_callback.is_null()); // Pretend that the registration completed successfully. @@ -176,7 +176,7 @@ // Make keys downloading theoretically possible. StoreKeysAndMimicDeviceRegistration(kVaultKeys, kLastKeyVersion, account_info); - backend()->SetSyncingAccount(account_info); + backend()->SetPrimaryAccount(account_info); EXPECT_CALL(*connection(), DownloadKeys(_, _, _, _, _)).Times(0); @@ -202,7 +202,7 @@ StoreKeysAndMimicDeviceRegistration({kInitialVaultKey}, kInitialLastKeyVersion, account_info); EXPECT_TRUE(backend()->MarkKeysAsStale(account_info)); - backend()->SetSyncingAccount(account_info); + backend()->SetPrimaryAccount(account_info); const std::vector<std::vector<uint8_t>> kNewVaultKeys = {kInitialVaultKey, {1, 3, 2}};
diff --git a/components/sync/trusted_vault/standalone_trusted_vault_client.cc b/components/sync/trusted_vault/standalone_trusted_vault_client.cc index 66f46c1..ace680a 100644 --- a/components/sync/trusted_vault/standalone_trusted_vault_client.cc +++ b/components/sync/trusted_vault/standalone_trusted_vault_client.cc
@@ -27,13 +27,100 @@ base::MayBlock(), base::TaskPriority::USER_VISIBLE, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}; +class PrimaryAccountObserver : public signin::IdentityManager::Observer { + public: + PrimaryAccountObserver( + scoped_refptr<base::SequencedTaskRunner> backend_task_runner, + scoped_refptr<StandaloneTrustedVaultBackend> backend, + signin::IdentityManager* identity_manager); + PrimaryAccountObserver(const PrimaryAccountObserver& other) = delete; + PrimaryAccountObserver& operator=(const PrimaryAccountObserver& other) = + delete; + ~PrimaryAccountObserver() override; + + // signin::IdentityManager::Observer implementation. + void OnPrimaryAccountSet( + const CoreAccountInfo& primary_account_info) override; + void OnPrimaryAccountCleared( + const CoreAccountInfo& previous_primary_account_info) override; + void OnUnconsentedPrimaryAccountChanged( + const CoreAccountInfo& unconsented_primary_account_info) override; + + private: + void UpdatePrimaryAccountIfNeeded(); + + const scoped_refptr<base::SequencedTaskRunner> backend_task_runner_; + const scoped_refptr<StandaloneTrustedVaultBackend> backend_; + signin::IdentityManager* const identity_manager_; + CoreAccountInfo primary_account_; +}; + +PrimaryAccountObserver::PrimaryAccountObserver( + scoped_refptr<base::SequencedTaskRunner> backend_task_runner, + scoped_refptr<StandaloneTrustedVaultBackend> backend, + signin::IdentityManager* identity_manager) + : backend_task_runner_(backend_task_runner), + backend_(backend), + identity_manager_(identity_manager) { + DCHECK(backend_task_runner_); + DCHECK(backend_); + DCHECK(identity_manager_); + + identity_manager_->AddObserver(this); + UpdatePrimaryAccountIfNeeded(); +} + +PrimaryAccountObserver::~PrimaryAccountObserver() { + identity_manager_->RemoveObserver(this); +} + +void PrimaryAccountObserver::OnPrimaryAccountSet( + const CoreAccountInfo& primary_account_info) { + UpdatePrimaryAccountIfNeeded(); +} + +void PrimaryAccountObserver::OnPrimaryAccountCleared( + const CoreAccountInfo& previous_primary_account_info) { + UpdatePrimaryAccountIfNeeded(); +} + +void PrimaryAccountObserver::OnUnconsentedPrimaryAccountChanged( + const CoreAccountInfo& unconsented_primary_account_info) { + UpdatePrimaryAccountIfNeeded(); +} + +void PrimaryAccountObserver::UpdatePrimaryAccountIfNeeded() { + CoreAccountInfo primary_account = identity_manager_->GetPrimaryAccountInfo( + signin::ConsentLevel::kNotRequired); + if (primary_account == primary_account_) { + return; + } + primary_account_ = primary_account; + + // IdentityManager returns empty CoreAccountInfo if there is no primary + // account. + base::Optional<CoreAccountInfo> optional_primary_account; + if (!primary_account_.IsEmpty()) { + optional_primary_account = primary_account_; + } + + backend_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&StandaloneTrustedVaultBackend::SetPrimaryAccount, + backend_, optional_primary_account)); +} + } // namespace StandaloneTrustedVaultClient::StandaloneTrustedVaultClient( - const base::FilePath& file_path) - : file_path_(file_path), + const base::FilePath& file_path, + signin::IdentityManager* identity_manager) + : identity_manager_(identity_manager), + file_path_(file_path), backend_task_runner_( - base::ThreadPool::CreateSequencedTaskRunner(kBackendTaskTraits)) {} + base::ThreadPool::CreateSequencedTaskRunner(kBackendTaskTraits)) { + DCHECK(identity_manager_); +} StandaloneTrustedVaultClient::~StandaloneTrustedVaultClient() = default; @@ -98,6 +185,16 @@ std::move(cb)); } +void StandaloneTrustedVaultClient::FetchBackendPrimaryAccountForTesting( + base::OnceCallback<void(const base::Optional<CoreAccountInfo>&)> cb) const { + base::PostTaskAndReplyWithResult( + backend_task_runner_.get(), FROM_HERE, + base::BindOnce( + &StandaloneTrustedVaultBackend::GetPrimaryAccountForTesting, + backend_), + std::move(cb)); +} + void StandaloneTrustedVaultClient::TriggerLazyInitializationIfNeeded() { if (backend_) { return; @@ -117,8 +214,12 @@ FROM_HERE, base::BindOnce(&StandaloneTrustedVaultBackend::ReadDataFromDisk, backend_)); - // TODO(crbug.com/1113597): populate current syncing account to |backend_| - // here and upon syncing account change. + + // |primary_account_observer_| will populate primary account to |backend_| + // whenever it changes and upon construction, if there is a primary account + // already. + primary_account_observer_ = std::make_unique<PrimaryAccountObserver>( + backend_task_runner_, backend_, identity_manager_); } bool StandaloneTrustedVaultClient::IsInitializationTriggeredForTesting() const {
diff --git a/components/sync/trusted_vault/standalone_trusted_vault_client.h b/components/sync/trusted_vault/standalone_trusted_vault_client.h index 78ffa18..ca93faa 100644 --- a/components/sync/trusted_vault/standalone_trusted_vault_client.h +++ b/components/sync/trusted_vault/standalone_trusted_vault_client.h
@@ -13,6 +13,7 @@ #include "base/files/file_path.h" #include "base/memory/scoped_refptr.h" #include "base/sequenced_task_runner.h" +#include "components/signin/public/identity_manager/identity_manager.h" #include "components/sync/driver/trusted_vault_client.h" struct CoreAccountInfo; @@ -28,8 +29,9 @@ // Reading of the file is done lazily. class StandaloneTrustedVaultClient : public TrustedVaultClient { public: - // TODO(crbug.com/1113597): plumb IdentityManager into ctor. - explicit StandaloneTrustedVaultClient(const base::FilePath& file_path); + // |identity_manager| must not be null and must outlive this object. + StandaloneTrustedVaultClient(const base::FilePath& file_path, + signin::IdentityManager* identity_manager); StandaloneTrustedVaultClient(const StandaloneTrustedVaultClient& other) = delete; StandaloneTrustedVaultClient& operator=( @@ -54,12 +56,18 @@ // Runs |cb| when all requests have completed. void WaitForFlushForTesting(base::OnceClosure cb) const; + void FetchBackendPrimaryAccountForTesting( + base::OnceCallback<void(const base::Optional<CoreAccountInfo>&)> callback) + const; bool IsInitializationTriggeredForTesting() const; void SetRecoverabilityDegradedForTesting(); private: void TriggerLazyInitializationIfNeeded(); + // Never null and must outlive this object. + signin::IdentityManager* identity_manager_; + const base::FilePath file_path_; const scoped_refptr<base::SequencedTaskRunner> backend_task_runner_; @@ -69,6 +77,11 @@ // |backend_task_runner_| and destroyed (refcounted) on any thread. scoped_refptr<StandaloneTrustedVaultBackend> backend_; + // Observes changes of primary account and populates them into |backend_|. + // Created lazily together with |backend_| and holds reference to it and + // |backend_task_runner_|. + std::unique_ptr<signin::IdentityManager::Observer> primary_account_observer_; + bool is_recoverability_degraded_for_testing_ = false; };
diff --git a/components/sync/trusted_vault/standalone_trusted_vault_client_unittest.cc b/components/sync/trusted_vault/standalone_trusted_vault_client_unittest.cc index 7608eb8..50cd48c 100644 --- a/components/sync/trusted_vault/standalone_trusted_vault_client_unittest.cc +++ b/components/sync/trusted_vault/standalone_trusted_vault_client_unittest.cc
@@ -13,6 +13,7 @@ #include "components/os_crypt/os_crypt.h" #include "components/os_crypt/os_crypt_mocker.h" #include "components/signin/public/identity_manager/account_info.h" +#include "components/signin/public/identity_manager/identity_test_environment.h" #include "components/sync/protocol/local_trusted_vault.pb.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -65,7 +66,7 @@ StandaloneTrustedVaultClientTest() : file_path_(CreateUniqueTempDir(&temp_dir_) .Append(base::FilePath(FILE_PATH_LITERAL("some_file")))), - client_(file_path_) {} + client_(file_path_, identity_env_.identity_manager()) {} ~StandaloneTrustedVaultClientTest() override = default; @@ -84,9 +85,23 @@ loop.Run(); } + base::Optional<CoreAccountInfo> FetchBackendPrimaryAccountAndWait() { + base::RunLoop loop; + base::Optional<CoreAccountInfo> fetched_primary_account; + client_.FetchBackendPrimaryAccountForTesting(base::BindLambdaForTesting( + [&](const base::Optional<CoreAccountInfo>& primary_account) { + fetched_primary_account = primary_account; + loop.Quit(); + })); + loop.Run(); + return fetched_primary_account; + } + base::test::TaskEnvironment task_environment_; base::ScopedTempDir temp_dir_; const base::FilePath file_path_; + // |identity_env_| should outlive |client_|. + signin::IdentityTestEnvironment identity_env_; StandaloneTrustedVaultClient client_; }; @@ -175,7 +190,8 @@ WaitForFlush(); // Instantiate a second client to read the file. - StandaloneTrustedVaultClient other_client(file_path_); + StandaloneTrustedVaultClient other_client(file_path_, + identity_env_.identity_manager()); EXPECT_THAT(FetchKeysAndWaitForClient(kGaiaId1, &other_client), ElementsAre(kKey1)); EXPECT_THAT(FetchKeysAndWaitForClient(kGaiaId2, &other_client), @@ -205,6 +221,47 @@ EXPECT_FALSE(base::PathExists(file_path_)); } +// ChromeOS doesn't support sign-out. +#if !defined(OS_CHROMEOS) +TEST_F(StandaloneTrustedVaultClientTest, ShouldPopulatePrimaryAccountChanges) { + ASSERT_FALSE(client_.IsInitializationTriggeredForTesting()); + + // Set initial primary account before backend initialization. + const std::string email1 = "user1@gmail.com"; + identity_env_.SetPrimaryAccount(email1); + + // Trigger backend initialization. + ASSERT_THAT(FetchKeysAndWait("user1"), IsEmpty()); + ASSERT_TRUE(client_.IsInitializationTriggeredForTesting()); + + // Verify that current primary account corresponds to |email1|. + base::Optional<CoreAccountInfo> current_primary_account = + FetchBackendPrimaryAccountAndWait(); + ASSERT_THAT(current_primary_account, Ne(base::nullopt)); + EXPECT_THAT(current_primary_account->email, Eq(email1)); + + // Remove primary account. + identity_env_.ClearPrimaryAccount(); + current_primary_account = FetchBackendPrimaryAccountAndWait(); + EXPECT_THAT(current_primary_account, Eq(base::nullopt)); + + // Set new primary account. + const std::string email2 = "user2@gmail.com"; + identity_env_.SetPrimaryAccount(email2); + current_primary_account = FetchBackendPrimaryAccountAndWait(); + ASSERT_THAT(current_primary_account, Ne(base::nullopt)); + EXPECT_THAT(current_primary_account->email, Eq(email2)); + + // Set unconsented primary account. + const std::string email3 = "user3@gmail.com"; + identity_env_.ClearPrimaryAccount(); + identity_env_.SetUnconsentedPrimaryAccount(email3); + current_primary_account = FetchBackendPrimaryAccountAndWait(); + ASSERT_THAT(current_primary_account, Ne(base::nullopt)); + EXPECT_THAT(current_primary_account->email, Eq(email3)); +} +#endif + } // namespace } // namespace syncer
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index e11f416..a9d641d 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -642,7 +642,7 @@ deps = [ "//base:base_java", "//base:jni_java", - "//ui/android:ui_full_java", + "//ui/android:ui_no_recycler_view_java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] sources = [
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc index 2aae62b..0bc6363 100644 --- a/content/browser/accessibility/browser_accessibility_android.cc +++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -992,7 +992,6 @@ case ax::mojom::Role::kMenuBar: message_id = IDS_AX_ROLE_MENU_BAR; break; - case ax::mojom::Role::kMenuButton: case ax::mojom::Role::kMenuItem: message_id = IDS_AX_ROLE_MENU_ITEM; break;
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc index ce8fb53..ce8253a 100644 --- a/content/browser/accessibility/browser_accessibility_com_win.cc +++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -1630,26 +1630,6 @@ return ToBrowserAccessibilityComWin(Manager()->GetFromID(id)); } -bool BrowserAccessibilityComWin::IsListBoxOptionOrMenuListOption() { - if (!owner()->PlatformGetParent()) - return false; - - ax::mojom::Role role = owner()->GetRole(); - ax::mojom::Role parent_role = owner()->PlatformGetParent()->GetRole(); - - if (role == ax::mojom::Role::kListBoxOption && - parent_role == ax::mojom::Role::kListBox) { - return true; - } - - if (role == ax::mojom::Role::kMenuListOption && - parent_role == ax::mojom::Role::kMenuListPopup) { - return true; - } - - return false; -} - void BrowserAccessibilityComWin::FireNativeEvent(LONG win_event_type) const { // We only allow events on descendants of a platform leaf when that platform // leaf is a popup button parent of a menu list popup. On Windows, the menu
diff --git a/content/browser/accessibility/browser_accessibility_com_win.h b/content/browser/accessibility/browser_accessibility_com_win.h index f839748..46b96f4 100644 --- a/content/browser/accessibility/browser_accessibility_com_win.h +++ b/content/browser/accessibility/browser_accessibility_com_win.h
@@ -400,10 +400,6 @@ // TODO(nektar): Rename this function to GetFromNodeID. BrowserAccessibilityComWin* GetFromID(int32_t id) const; - // Returns true if this is a list box option with a parent of type list box, - // or a menu list option with a parent of type menu list popup. - bool IsListBoxOptionOrMenuListOption(); - // Fire a Windows-specific accessibility event notification on this node. void FireNativeEvent(LONG win_event_type) const; struct WinAttributes {
diff --git a/content/browser/device/device_service.cc b/content/browser/device/device_service.cc index 6f9144c2..6a37826 100644 --- a/content/browser/device/device_service.cc +++ b/content/browser/device/device_service.cc
@@ -49,12 +49,14 @@ mojo::PendingRemote<network::mojom::URLLoaderClient> client, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) override { - GetContentClient() - ->browser() - ->GetSystemSharedURLLoaderFactory() - ->CreateLoaderAndStart(std::move(receiver), routing_id, request_id, - options, url_request, std::move(client), - traffic_annotation); + auto factory = + GetContentClient()->browser()->GetSystemSharedURLLoaderFactory(); + if (!factory) + return; + + factory->CreateLoaderAndStart(std::move(receiver), routing_id, request_id, + options, url_request, std::move(client), + traffic_annotation); } // SharedURLLoaderFactory implementation:
diff --git a/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc b/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc index 913ce4a..b3f2e2e75 100644 --- a/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc +++ b/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc
@@ -29,7 +29,7 @@ static constexpr const char* kOrigin4 = "https://test.com"; static const blink::mojom::FeaturePolicyFeature kDefaultEnabledFeature = - blink::mojom::FeaturePolicyFeature::kDocumentWrite; + blink::mojom::FeaturePolicyFeature::kSyncXHR; static const blink::mojom::FeaturePolicyFeature kDefaultSelfFeature = blink::mojom::FeaturePolicyFeature::kGeolocation;
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index 2b94b8b2..6c6c7b5 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -49,7 +49,6 @@ #include "content/browser/web_package/web_bundle_utils.h" #include "content/browser/webui/url_data_manager_backend.h" #include "content/browser/webui/web_ui_url_loader_factory_internal.h" -#include "content/common/net/record_load_histograms.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -89,6 +88,7 @@ #include "services/network/public/mojom/url_loader_factory.mojom.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/loader/mime_sniffing_throttle.h" +#include "third_party/blink/public/common/loader/record_load_histograms.h" #include "third_party/blink/public/common/loader/throttling_url_loader.h" #include "third_party/blink/public/common/mime_util/mime_util.h" @@ -309,9 +309,9 @@ // request. The net::OK check may not be necessary - the case where OK is // received without receiving any headers looks broken, anyways. if (!received_response_ && (!status_ || status_->error_code != net::OK)) { - RecordLoadHistograms(url::Origin::Create(url_), - resource_request_->destination, - status_ ? status_->error_code : net::ERR_ABORTED); + blink::RecordLoadHistograms( + url::Origin::Create(url_), resource_request_->destination, + status_ ? status_->error_code : net::ERR_ABORTED); } }
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 0a3af064..802b728 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -5093,6 +5093,7 @@ observers_.ForEachObserver([&](WebContentsObserver* observer) { observer->DidChangeThemeColor(); }); + last_sent_theme_color_ = source->theme_color(); } }
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 0e961bb..be1e157 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -18,7 +18,6 @@ #include "content/common/content_switches_internal.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" -#include "content/public/common/referrer.h" #include "device/fido/features.h" #include "device/gamepad/public/cpp/gamepad_features.h" #include "gpu/config/gpu_switches.h" @@ -28,6 +27,7 @@ #include "services/network/public/cpp/features.h" #include "services/network/public/cpp/network_switches.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "third_party/blink/public/common/switches.h" #include "third_party/blink/public/platform/web_runtime_features.h" #include "ui/accessibility/accessibility_features.h" @@ -341,6 +341,7 @@ {wf::EnableMediaFeeds, media::kMediaFeeds, kUseFeatureState}, {wf::EnableRestrictGamepadAccess, features::kRestrictGamepadAccess, kEnableOnly}, + {wf::EnableCompositeSVG, blink::features::kCompositeSVG, kUseFeatureState}, {wf::EnableCompositingOptimizations, blink::features::kCompositingOptimizations, kUseFeatureState}, {wf::EnableConversionMeasurementInfraSupport, @@ -625,7 +626,7 @@ WebRuntimeFeatures::EnableReducedReferrerGranularity( base::FeatureList::IsEnabled( blink::features::kReducedReferrerGranularity) && - !content::Referrer::ShouldForceLegacyDefaultReferrerPolicy()); + !blink::ReferrerUtils::ShouldForceLegacyDefaultReferrerPolicy()); if (base::FeatureList::IsEnabled( blink::features::kAppCacheRequireOriginTrial)) {
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 262eeee..8355177 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -157,8 +157,6 @@ "navigation_params.h", "navigation_params_mojom_traits.h", "navigation_params_utils.h", - "net/record_load_histograms.cc", - "net/record_load_histograms.h", "origin_util.cc", "page_messages.h", "page_state_serialization.cc",
diff --git a/content/common/net/OWNERS b/content/common/net/OWNERS deleted file mode 100644 index b772929..0000000 --- a/content/common/net/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -file://net/OWNERS - -# COMPONENT: Internals>Network -# TEAM: net-dev@chromium.org
diff --git a/content/common/net/record_load_histograms.h b/content/common/net/record_load_histograms.h deleted file mode 100644 index e3eafa54..0000000 --- a/content/common/net/record_load_histograms.h +++ /dev/null
@@ -1,23 +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 CONTENT_COMMON_NET_RECORD_LOAD_HISTOGRAMS_H_ -#define CONTENT_COMMON_NET_RECORD_LOAD_HISTOGRAMS_H_ - -#include "services/network/public/mojom/fetch_api.mojom-shared.h" -#include "url/origin.h" - -namespace content { - -// Logs histograms when a resource destined for a renderer (One with a -// network::mojom::RequestDestination) finishes loading, or when a load is -// aborted. Not used for internal network requests initiated by the browser -// itself. -void RecordLoadHistograms(const url::Origin& origin, - network::mojom::RequestDestination destination, - int net_error); - -} // namespace content - -#endif // CONTENT_COMMON_NET_RECORD_LOAD_HISTOGRAMS_H_
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index 4589c1b..cb42ffd 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -109,7 +109,8 @@ "//third_party/blink/public/mojom:android_mojo_bindings_java", "//third_party/blink/public/mojom:mojom_core_java", "//third_party/blink/public/mojom:mojom_platform_java", - "//ui/android:ui_java", + "//ui/android:ui_no_recycler_view_java", + "//ui/android:ui_utils_java", "//ui/gfx/geometry/mojom:mojom_java", "//url:gurl_java", "//url:origin_java",
diff --git a/content/public/common/referrer.cc b/content/public/common/referrer.cc index 22e7ffb..c1d9d1bb 100644 --- a/content/public/common/referrer.cc +++ b/content/public/common/referrer.cc
@@ -72,17 +72,6 @@ } // static -void Referrer::SetForceLegacyDefaultReferrerPolicy(bool force) { - blink::ReferrerUtils::ReadModifyWriteForceLegacyPolicyFlag(force); -} - -// static -bool Referrer::ShouldForceLegacyDefaultReferrerPolicy() { - return blink::ReferrerUtils::ReadModifyWriteForceLegacyPolicyFlag( - base::nullopt); -} - -// static network::mojom::ReferrerPolicy Referrer::ConvertToPolicy(int32_t policy) { return mojo::ConvertIntToMojoEnum<network::mojom::ReferrerPolicy>(policy) .value_or(network::mojom::ReferrerPolicy::kDefault);
diff --git a/content/public/test/referrer_unittest.cc b/content/public/test/referrer_unittest.cc index 1ae04b42..c3ff9a0 100644 --- a/content/public/test/referrer_unittest.cc +++ b/content/public/test/referrer_unittest.cc
@@ -110,24 +110,4 @@ } } -TEST(DefaultReferrerPolicyTest, SetAndGetForceLegacy) { - EXPECT_FALSE(content::Referrer::ShouldForceLegacyDefaultReferrerPolicy()); - content::Referrer::SetForceLegacyDefaultReferrerPolicy(true); - EXPECT_TRUE(content::Referrer::ShouldForceLegacyDefaultReferrerPolicy()); -} - -TEST(DefaultReferrerPolicyTest, ForceLegacyOnly) { - content::Referrer::SetForceLegacyDefaultReferrerPolicy(true); - EXPECT_EQ(blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), - net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE); -} - -TEST(DefaultReferrerPolicyTest, FeatureAndForceLegacy) { - base::test::ScopedFeatureList f; - f.InitAndEnableFeature(blink::features::kReducedReferrerGranularity); - content::Referrer::SetForceLegacyDefaultReferrerPolicy(true); - EXPECT_EQ(blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), - net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE); -} - } // namespace content
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index ebb030a..21c03c04 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -137,8 +137,6 @@ "media/audio/audio_device_factory.h", "media/audio/audio_input_ipc_factory.cc", "media/audio/audio_input_ipc_factory.h", - "media/audio/audio_output_ipc_factory.cc", - "media/audio/audio_output_ipc_factory.h", "media/audio/audio_renderer_mixer_manager.cc", "media/audio/audio_renderer_mixer_manager.h", "media/audio/audio_renderer_sink_cache.h", @@ -146,8 +144,6 @@ "media/audio/audio_renderer_sink_cache_impl.h", "media/audio/mojo_audio_input_ipc.cc", "media/audio/mojo_audio_input_ipc.h", - "media/audio/mojo_audio_output_ipc.cc", - "media/audio/mojo_audio_output_ipc.h", "media/audio_decoder.cc", "media/audio_decoder.h", "media/batching_media_log.cc",
diff --git a/content/renderer/loader/resource_load_stats.cc b/content/renderer/loader/resource_load_stats.cc index ce2bc5b0..4e286d5c 100644 --- a/content/renderer/loader/resource_load_stats.cc +++ b/content/renderer/loader/resource_load_stats.cc
@@ -6,7 +6,6 @@ #include "base/bind.h" #include "base/metrics/histogram_macros.h" -#include "content/common/net/record_load_histograms.h" #include "content/renderer/render_frame_impl.h" #include "content/renderer/render_thread_impl.h" #include "net/base/ip_endpoint.h" @@ -15,6 +14,7 @@ #include "services/network/public/mojom/fetch_api.mojom.h" #include "services/network/public/mojom/url_response_head.mojom.h" #include "third_party/blink/public/common/loader/network_utils.h" +#include "third_party/blink/public/common/loader/record_load_histograms.h" #include "third_party/blink/public/common/loader/resource_type_util.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h" @@ -204,9 +204,9 @@ int render_frame_id, blink::mojom::ResourceLoadInfoPtr resource_load_info, const network::URLLoaderCompletionStatus& status) { - RecordLoadHistograms(url::Origin::Create(resource_load_info->final_url), - resource_load_info->request_destination, - status.error_code); + blink::RecordLoadHistograms( + url::Origin::Create(resource_load_info->final_url), + resource_load_info->request_destination, status.error_code); resource_load_info->was_cached = status.exists_in_cache; resource_load_info->net_error = status.error_code; @@ -230,8 +230,9 @@ int render_frame_id, blink::mojom::ResourceLoadInfoPtr resource_load_info, int net_error) { - RecordLoadHistograms(url::Origin::Create(resource_load_info->final_url), - resource_load_info->request_destination, net_error); + blink::RecordLoadHistograms( + url::Origin::Create(resource_load_info->final_url), + resource_load_info->request_destination, net_error); auto task_runner = RenderThreadImpl::DeprecatedGetMainTaskRunner(); if (!task_runner)
diff --git a/content/renderer/media/audio/audio_device_factory.cc b/content/renderer/media/audio/audio_device_factory.cc index 8b80a66..98fc2d6 100644 --- a/content/renderer/media/audio/audio_device_factory.cc +++ b/content/renderer/media/audio/audio_device_factory.cc
@@ -17,7 +17,6 @@ #include "build/build_config.h" #include "content/common/content_constants_internal.h" #include "content/renderer/media/audio/audio_input_ipc_factory.h" -#include "content/renderer/media/audio/audio_output_ipc_factory.h" #include "content/renderer/media/audio/audio_renderer_mixer_manager.h" #include "content/renderer/media/audio/audio_renderer_sink_cache_impl.h" #include "content/renderer/media/audio/mojo_audio_input_ipc.h" @@ -28,6 +27,7 @@ #include "media/base/audio_renderer_mixer_input.h" #include "media/base/media_switches.h" #include "third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom.h" +#include "third_party/blink/public/web/modules/media/audio/web_audio_output_ipc_factory.h" namespace content { @@ -59,10 +59,11 @@ const base::UnguessableToken& frame_token, const media::AudioSinkParameters& params, base::TimeDelta auth_timeout) { - CHECK(AudioOutputIPCFactory::get()); + CHECK(blink::WebAudioOutputIPCFactory::get()); auto device = base::MakeRefCounted<media::AudioOutputDevice>( - AudioOutputIPCFactory::get()->CreateAudioOutputIPC(frame_token), - AudioOutputIPCFactory::get()->io_task_runner(), params, auth_timeout); + blink::WebAudioOutputIPCFactory::get()->CreateAudioOutputIPC(frame_token), + blink::WebAudioOutputIPCFactory::get()->io_task_runner(), params, + auth_timeout); device->RequestDeviceAuthorization(); return device; }
diff --git a/content/renderer/media/audio/audio_output_ipc_factory.cc b/content/renderer/media/audio/audio_output_ipc_factory.cc deleted file mode 100644 index 6651543..0000000 --- a/content/renderer/media/audio/audio_output_ipc_factory.cc +++ /dev/null
@@ -1,109 +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. - -#include "content/renderer/media/audio/audio_output_ipc_factory.h" - -#include <utility> - -#include "base/bind.h" -#include "base/check_op.h" -#include "base/single_thread_task_runner.h" -#include "content/renderer/media/audio/mojo_audio_output_ipc.h" -#include "third_party/blink/public/common/browser_interface_broker_proxy.h" - -namespace content { - -AudioOutputIPCFactory* AudioOutputIPCFactory::instance_ = nullptr; - -AudioOutputIPCFactory::AudioOutputIPCFactory( - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) - : io_task_runner_(std::move(io_task_runner)) { - DCHECK(!instance_); - instance_ = this; -} - -AudioOutputIPCFactory::~AudioOutputIPCFactory() { - // Allow destruction in tests. - DCHECK(factory_remotes_.empty()); - DCHECK_EQ(instance_, this); - instance_ = nullptr; -} - -std::unique_ptr<media::AudioOutputIPC> -AudioOutputIPCFactory::CreateAudioOutputIPC( - const base::UnguessableToken& frame_token) const { - // Unretained is safe due to the contract at the top of the header file. - return std::make_unique<MojoAudioOutputIPC>( - base::BindRepeating(&AudioOutputIPCFactory::GetRemoteFactory, - base::Unretained(this), frame_token), - io_task_runner_); -} - -void AudioOutputIPCFactory::RegisterRemoteFactory( - const base::UnguessableToken& frame_token, - blink::BrowserInterfaceBrokerProxy* interface_broker) { - mojo::PendingRemote<blink::mojom::RendererAudioOutputStreamFactory> - factory_remote; - interface_broker->GetInterface( - factory_remote.InitWithNewPipeAndPassReceiver()); - // Unretained is safe due to the contract at the top of the header file. - // It's safe to pass the |factory_remote| PendingRemote between threads. - io_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&AudioOutputIPCFactory::RegisterRemoteFactoryOnIOThread, - base::Unretained(this), frame_token, - std::move(factory_remote))); -} - -void AudioOutputIPCFactory::MaybeDeregisterRemoteFactory( - const base::UnguessableToken& frame_token) { - io_task_runner_->PostTask( - FROM_HERE, - base::BindOnce( - &AudioOutputIPCFactory::MaybeDeregisterRemoteFactoryOnIOThread, - base::Unretained(this), frame_token)); -} - -blink::mojom::RendererAudioOutputStreamFactory* -AudioOutputIPCFactory::GetRemoteFactory( - const base::UnguessableToken& frame_token) const { - DCHECK(io_task_runner_->BelongsToCurrentThread()); - auto it = factory_remotes_.find(frame_token); - return it == factory_remotes_.end() ? nullptr : it->second.get(); -} - -void AudioOutputIPCFactory::RegisterRemoteFactoryOnIOThread( - const base::UnguessableToken& frame_token, - mojo::PendingRemote<blink::mojom::RendererAudioOutputStreamFactory> - factory_pending_remote) { - DCHECK(io_task_runner_->BelongsToCurrentThread()); - std::pair<StreamFactoryMap::iterator, bool> emplace_result = - factory_remotes_.emplace(frame_token, std::move(factory_pending_remote)); - - DCHECK(emplace_result.second) << "Attempt to register a factory for a " - "frame which already has a factory " - "registered."; - - auto& emplaced_factory = emplace_result.first->second; - DCHECK(emplaced_factory.is_bound()) - << "Factory is not bound to a remote implementation."; - - // Unretained is safe because |this| owns the remote, so a connection error - // cannot trigger after destruction. - emplaced_factory.set_disconnect_handler(base::BindOnce( - &AudioOutputIPCFactory::MaybeDeregisterRemoteFactoryOnIOThread, - base::Unretained(this), frame_token)); -} - -void AudioOutputIPCFactory::MaybeDeregisterRemoteFactoryOnIOThread( - const base::UnguessableToken& frame_token) { - DCHECK(io_task_runner_->BelongsToCurrentThread()); - // This function can be called both by the frame and the connection error - // handler of the factory remote. Calling erase multiple times even though - // there is nothing to erase is safe, so we don't have to handle this in any - // particular way. - factory_remotes_.erase(frame_token); -} - -} // namespace content
diff --git a/content/renderer/media/audio/audio_output_ipc_factory.h b/content/renderer/media/audio/audio_output_ipc_factory.h deleted file mode 100644 index d950e66e..0000000 --- a/content/renderer/media/audio/audio_output_ipc_factory.h +++ /dev/null
@@ -1,98 +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. - -#ifndef CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_OUTPUT_IPC_FACTORY_H_ -#define CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_OUTPUT_IPC_FACTORY_H_ - -#include <memory> - -#include "base/containers/flat_map.h" -#include "base/memory/ref_counted.h" -#include "content/common/content_export.h" -#include "mojo/public/cpp/bindings/pending_remote.h" -#include "mojo/public/cpp/bindings/remote.h" -#include "third_party/blink/public/mojom/media/renderer_audio_output_stream_factory.mojom.h" - -namespace base { -class SingleThreadTaskRunner; -} - -namespace media { -class AudioOutputIPC; -} - -namespace blink { -class BrowserInterfaceBrokerProxy; -} - -namespace content { - -// This is a factory for AudioOutputIPC objects. It is threadsafe. This class -// is designed to be leaked at shutdown, as it posts tasks to itself using -// base::Unretained and also hands out references to itself in the -// AudioOutputIPCs it creates, but in the case where the owner is sure that -// there are no outstanding references (such as in a unit test), the class can -// be destructed. -// TODO(maxmorin): Registering the factories for each frame will become -// unnecessary when https://crbug.com/668275 is fixed. When that is done, this -// class can be greatly simplified. -class CONTENT_EXPORT AudioOutputIPCFactory { - public: - AudioOutputIPCFactory( - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner); - ~AudioOutputIPCFactory(); - - static AudioOutputIPCFactory* get() { return instance_; } - - const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner() const { - return io_task_runner_; - } - - // Enables |this| to create MojoAudioOutputIPCs for the specified frame. - // Does nothing if not using mojo factories. - void RegisterRemoteFactory( - const base::UnguessableToken& frame_token, - blink::BrowserInterfaceBrokerProxy* interface_broker); - - // Every call to the above method must be matched by a call to this one when - // the frame is destroyed. Does nothing if not using mojo factories. - void MaybeDeregisterRemoteFactory(const base::UnguessableToken& frame_token); - - // The returned object may only be used on |io_task_runner()|. - std::unique_ptr<media::AudioOutputIPC> CreateAudioOutputIPC( - const base::UnguessableToken& frame_token) const; - - private: - using StreamFactoryMap = base::flat_map< - base::UnguessableToken, - mojo::Remote<blink::mojom::RendererAudioOutputStreamFactory>>; - - blink::mojom::RendererAudioOutputStreamFactory* GetRemoteFactory( - const base::UnguessableToken& frame_token) const; - - void RegisterRemoteFactoryOnIOThread( - const base::UnguessableToken& frame_token, - mojo::PendingRemote<blink::mojom::RendererAudioOutputStreamFactory> - factory_pending_remote); - - void MaybeDeregisterRemoteFactoryOnIOThread( - const base::UnguessableToken& frame_token); - - // Indicates whether mojo factories are used. - bool UsingMojoFactories() const; - - // Maps frame id to the corresponding factory. - StreamFactoryMap factory_remotes_; - - const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; - - // Global instance, set in constructor and unset in destructor. - static AudioOutputIPCFactory* instance_; - - DISALLOW_COPY_AND_ASSIGN(AudioOutputIPCFactory); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_OUTPUT_IPC_FACTORY_H_
diff --git a/content/renderer/pepper/pepper_platform_audio_output.cc b/content/renderer/pepper/pepper_platform_audio_output.cc index e1f5a45d..b6160a8a 100644 --- a/content/renderer/pepper/pepper_platform_audio_output.cc +++ b/content/renderer/pepper/pepper_platform_audio_output.cc
@@ -12,9 +12,9 @@ #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "content/child/child_process.h" -#include "content/renderer/media/audio/audio_output_ipc_factory.h" #include "content/renderer/pepper/audio_helper.h" #include "ppapi/shared_impl/ppb_audio_config_shared.h" +#include "third_party/blink/public/web/modules/media/audio/web_audio_output_ipc_factory.h" namespace content { @@ -136,7 +136,8 @@ DCHECK(client); client_ = client; - ipc_ = AudioOutputIPCFactory::get()->CreateAudioOutputIPC(source_frame_token); + ipc_ = blink::WebAudioOutputIPCFactory::get()->CreateAudioOutputIPC( + source_frame_token); CHECK(ipc_); media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
diff --git a/content/renderer/pepper/pepper_platform_audio_output_dev.cc b/content/renderer/pepper/pepper_platform_audio_output_dev.cc index 08c620e..9d1b5ff 100644 --- a/content/renderer/pepper/pepper_platform_audio_output_dev.cc +++ b/content/renderer/pepper/pepper_platform_audio_output_dev.cc
@@ -14,13 +14,13 @@ #include "build/build_config.h" #include "content/child/child_process.h" #include "content/common/content_constants_internal.h" -#include "content/renderer/media/audio/audio_output_ipc_factory.h" #include "content/renderer/pepper/audio_helper.h" #include "content/renderer/pepper/pepper_audio_output_host.h" #include "content/renderer/pepper/pepper_media_device_manager.h" #include "content/renderer/render_frame_impl.h" #include "media/audio/audio_device_description.h" #include "ppapi/shared_impl/ppb_audio_config_shared.h" +#include "third_party/blink/public/web/modules/media/audio/web_audio_output_ipc_factory.h" #include "third_party/blink/public/web/web_local_frame.h" namespace { @@ -260,7 +260,7 @@ client_ = client; - ipc_ = AudioOutputIPCFactory::get()->CreateAudioOutputIPC( + ipc_ = blink::WebAudioOutputIPCFactory::get()->CreateAudioOutputIPC( render_frame->GetWebFrame()->GetFrameToken()); CHECK(ipc_);
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 64135cd..2b9f3b0b 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -60,7 +60,6 @@ #include "content/common/navigation_params.h" #include "content/common/navigation_params_mojom_traits.h" #include "content/common/navigation_params_utils.h" -#include "content/common/net/record_load_histograms.h" #include "content/common/page_messages.h" #include "content/common/render_accessibility.mojom.h" #include "content/common/renderer_host.mojom.h" @@ -110,7 +109,6 @@ #include "content/renderer/loader/web_url_request_util.h" #include "content/renderer/loader/web_worker_fetch_context_impl.h" #include "content/renderer/media/audio/audio_device_factory.h" -#include "content/renderer/media/audio/audio_output_ipc_factory.h" #include "content/renderer/media/audio/audio_renderer_sink_cache.h" #include "content/renderer/media/media_permission_dispatcher.h" #include "content/renderer/mhtml_handle_writer.h" @@ -158,6 +156,7 @@ #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/input/web_keyboard_event.h" +#include "third_party/blink/public/common/loader/record_load_histograms.h" #include "third_party/blink/public/common/loader/url_loader_throttle.h" #include "third_party/blink/public/common/logging/logging_utils.h" #include "third_party/blink/public/common/service_worker/service_worker_utils.h" @@ -188,6 +187,7 @@ #include "third_party/blink/public/platform/web_url_response.h" #include "third_party/blink/public/platform/web_vector.h" #include "third_party/blink/public/web/blink.h" +#include "third_party/blink/public/web/modules/media/audio/web_audio_output_ipc_factory.h" #include "third_party/blink/public/web/modules/media/webmediaplayer_util.h" #include "third_party/blink/public/web/modules/mediastream/web_media_stream_device_observer.h" #include "third_party/blink/public/web/web_autofill_client.h" @@ -2040,8 +2040,8 @@ // embedder can call GetWebFrame on any RenderFrame. GetContentClient()->renderer()->RenderFrameCreated(this); - // AudioOutputIPCFactory may be null in tests. - if (auto* factory = AudioOutputIPCFactory::get()) + // blink::WebAudioOutputIPCFactory may be null in tests. + if (auto* factory = blink::WebAudioOutputIPCFactory::get()) factory->RegisterRemoteFactory(GetWebFrame()->GetFrameToken(), GetBrowserInterfaceBroker()); @@ -3063,9 +3063,9 @@ void RenderFrameImpl::NotifyResourceLoadCompleted( blink::mojom::ResourceLoadInfoPtr resource_load_info, const network::URLLoaderCompletionStatus& status) { - RecordLoadHistograms(url::Origin::Create(resource_load_info->final_url), - resource_load_info->request_destination, - status.error_code); + blink::RecordLoadHistograms( + url::Origin::Create(resource_load_info->final_url), + resource_load_info->request_destination, status.error_code); DidCompleteResponse(resource_load_info->request_id, status); GetFrameHost()->ResourceLoadComplete(std::move(resource_load_info)); } @@ -4160,7 +4160,7 @@ for (auto& observer : observers_) observer.WillDetach(); - if (auto* factory = AudioOutputIPCFactory::get()) + if (auto* factory = blink::WebAudioOutputIPCFactory::get()) factory->MaybeDeregisterRemoteFactory(GetWebFrame()->GetFrameToken()); // Send a state update before the frame is detached. @@ -4417,8 +4417,8 @@ // RenderFrameHostImpl. browser_interface_broker_receiver = browser_interface_broker_proxy_.Reset(); - // AudioOutputIPCFactory may be null in tests. - if (auto* factory = AudioOutputIPCFactory::get()) { + // blink::WebAudioOutputIPCFactory may be null in tests. + if (auto* factory = blink::WebAudioOutputIPCFactory::get()) { // The RendererAudioOutputStreamFactory must be readily accessible on the // IO thread when it's needed, because the main thread may block while // waiting for the factory call to finish on the IO thread, so if we tried
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index 6721d865..51f5c9d 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h
@@ -41,7 +41,6 @@ #include "content/renderer/compositor/compositor_dependencies.h" #include "content/renderer/discardable_memory_utils.h" #include "content/renderer/media/audio/audio_input_ipc_factory.h" -#include "content/renderer/media/audio/audio_output_ipc_factory.h" #include "gpu/ipc/client/gpu_channel_host.h" #include "ipc/ipc_sync_channel.h" #include "media/media_buildflags.h" @@ -61,6 +60,7 @@ #include "third_party/blink/public/platform/scheduler/web_rail_mode_observer.h" #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h" #include "third_party/blink/public/platform/web_connection_type.h" +#include "third_party/blink/public/web/modules/media/audio/web_audio_output_ipc_factory.h" #include "third_party/blink/public/web/web_memory_statistics.h" #include "ui/gfx/native_widget_types.h" @@ -523,7 +523,7 @@ base::Optional<AudioInputIPCFactory> audio_input_ipc_factory_; // Provides AudioOutputIPC objects for audio output devices. Initialized in // Init. - base::Optional<AudioOutputIPCFactory> audio_output_ipc_factory_; + base::Optional<blink::WebAudioOutputIPCFactory> audio_output_ipc_factory_; // Used on the render thread. std::unique_ptr<blink::WebVideoCaptureImplManager> vc_manager_;
diff --git a/content/shell/renderer/web_test/web_ax_object_proxy.cc b/content/shell/renderer/web_test/web_ax_object_proxy.cc index 1cc6896..ceaccee 100644 --- a/content/shell/renderer/web_test/web_ax_object_proxy.cc +++ b/content/shell/renderer/web_test/web_ax_object_proxy.cc
@@ -261,8 +261,6 @@ return result.append("Math"); case ax::mojom::Role::kMenuBar: return result.append("MenuBar"); - case ax::mojom::Role::kMenuButton: - return result.append("MenuButton"); case ax::mojom::Role::kMenuItem: return result.append("MenuItem"); case ax::mojom::Role::kMenuItemCheckBox:
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 0635d10..15bad59 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -2044,13 +2044,11 @@ "../renderer/loader/test_request_peer.h", "../renderer/loader/url_loader_client_impl_unittest.cc", "../renderer/loader/web_url_loader_impl_unittest.cc", - "../renderer/media/audio/audio_output_ipc_factory_unittest.cc", "../renderer/media/audio/audio_renderer_mixer_manager_unittest.cc", "../renderer/media/audio/audio_renderer_sink_cache_unittest.cc", "../renderer/media/audio/mock_audio_device_factory.cc", "../renderer/media/audio/mock_audio_device_factory.h", "../renderer/media/audio/mojo_audio_input_ipc_unittest.cc", - "../renderer/media/audio/mojo_audio_output_ipc_unittest.cc", "../renderer/media/batching_media_log_unittest.cc", "../renderer/media/inspector_media_event_handler_unittest.cc", "../renderer/media/power_status_helper_impl_unittest.cc",
diff --git a/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-auralinux.txt b/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-auralinux.txt index 4de62c6..25423dc9 100644 --- a/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-auralinux.txt +++ b/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-auralinux.txt
@@ -1,3 +1,3 @@ [document web] ++[panel] -++++[menu item] name='Menu button' \ No newline at end of file +++++[menu item] name='Menu item'
diff --git a/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-blink.txt b/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-blink.txt index 0632a3f..61558b9 100644 --- a/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-blink.txt +++ b/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-blink.txt
@@ -2,4 +2,4 @@ ++genericContainer ignored ++++genericContainer ignored ++++++group -++++++++menuButton name='Menu button' +++++++++menuItem name='Menu item'
diff --git a/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-mac.txt b/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-mac.txt index e7643190..fa05943 100644 --- a/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-mac.txt +++ b/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-mac.txt
@@ -1,3 +1,3 @@ AXWebArea ++AXGroup -++++AXMenuButton AXTitle='Menu button' +++++AXMenuItem AXTitle='Menu item'
diff --git a/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-uia-win.txt index 4f3320c..40276bc3 100644 --- a/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-uia-win.txt
@@ -1,3 +1,3 @@ Document ++Group -++++MenuItem Name='Menu button' \ No newline at end of file +++++MenuItem Name='Menu item'
diff --git a/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-win.txt b/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-win.txt index fb03bc8..38ee260d 100644 --- a/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-win.txt +++ b/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-win.txt
@@ -1,3 +1,3 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ++ROLE_SYSTEM_GROUPING xml-roles:group -++++ROLE_SYSTEM_MENUITEM name='Menu button' FOCUSABLE xml-roles:menuitem +++++ROLE_SYSTEM_MENUITEM name='Menu item' FOCUSABLE xml-roles:menuitem
diff --git a/content/test/data/accessibility/aria/aria-menuitem-in-group.html b/content/test/data/accessibility/aria/aria-menuitem-in-group.html index b064bcd..170ef6b1 100644 --- a/content/test/data/accessibility/aria/aria-menuitem-in-group.html +++ b/content/test/data/accessibility/aria/aria-menuitem-in-group.html
@@ -4,7 +4,7 @@ <html> <body> <div role="group"> - <div tabindex="0" role="menuitem">Menu button</div> + <div tabindex="0" role="menuitem">Menu item</div> </div> </body> </html>
diff --git a/content/test/data/accessibility/html/modal-dialog-opened-expected-uia-win.txt b/content/test/data/accessibility/html/modal-dialog-opened-expected-uia-win.txt index d0b1c1a..8ef172d7 100644 --- a/content/test/data/accessibility/html/modal-dialog-opened-expected-uia-win.txt +++ b/content/test/data/accessibility/html/modal-dialog-opened-expected-uia-win.txt
@@ -3,4 +3,4 @@ ++++Text Name='The dialog subtree should be the only text content in the accessibility tree. ' ++++Hyperlink Name='Link inside the dialog.' ++++++Text Name='Link inside the dialog.' IsControlElement=false -++Menu IsControlElement=false Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false \ No newline at end of file +++List IsControlElement=false Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false \ No newline at end of file
diff --git a/content/test/data/accessibility/html/modal-dialog-opened-expected-win.txt b/content/test/data/accessibility/html/modal-dialog-opened-expected-win.txt index da520f6..5d9fd4d 100644 --- a/content/test/data/accessibility/html/modal-dialog-opened-expected-win.txt +++ b/content/test/data/accessibility/html/modal-dialog-opened-expected-win.txt
@@ -3,4 +3,4 @@ ++++ROLE_SYSTEM_STATICTEXT name='The dialog subtree should be the only text content in the accessibility tree. ' ++++ROLE_SYSTEM_LINK name='Link inside the dialog.' FOCUSABLE ++++++ROLE_SYSTEM_STATICTEXT name='Link inside the dialog.' -++ROLE_SYSTEM_MENUPOPUP INVISIBLE \ No newline at end of file +++ROLE_SYSTEM_LIST INVISIBLE \ No newline at end of file
diff --git a/content/test/data/accessibility/html/modal-dialog-stack-expected-uia-win.txt b/content/test/data/accessibility/html/modal-dialog-stack-expected-uia-win.txt index 8e3f560c..64e0b93 100644 --- a/content/test/data/accessibility/html/modal-dialog-stack-expected-uia-win.txt +++ b/content/test/data/accessibility/html/modal-dialog-stack-expected-uia-win.txt
@@ -1,5 +1,5 @@ Document -++Menu IsControlElement=false Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false +++List IsControlElement=false Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false ++Pane IsControlElement=false Window.IsModal=true ++++Text Name='This is the now active dialog. Of course it should be in the tree. ' ++++Button Name='This is in the active dialog and should be in the tree.' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/modal-dialog-stack-expected-win.txt b/content/test/data/accessibility/html/modal-dialog-stack-expected-win.txt index f49562a..fdedce904 100644 --- a/content/test/data/accessibility/html/modal-dialog-stack-expected-win.txt +++ b/content/test/data/accessibility/html/modal-dialog-stack-expected-win.txt
@@ -1,5 +1,5 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE -++ROLE_SYSTEM_MENUPOPUP INVISIBLE +++ROLE_SYSTEM_LIST INVISIBLE ++ROLE_SYSTEM_DIALOG IA2_STATE_MODAL ++++ROLE_SYSTEM_STATICTEXT name='This is the now active dialog. Of course it should be in the tree. ' ++++ROLE_SYSTEM_PUSHBUTTON name='This is in the active dialog and should be in the tree.' FOCUSABLE \ No newline at end of file
diff --git a/docs/README.md b/docs/README.md index 90753e4..9d2af07 100644 --- a/docs/README.md +++ b/docs/README.md
@@ -154,6 +154,8 @@ chrome:// URLs). * [Watchlists](infra/watchlists.md) - Use watchlists to get notified of CLs you are interested in. +* [Shutdown](shutdown.md) - Explains the steps of Chrome shutdown, to make it + easier to determine where to add a new shutdown operation. ### Testing * [Running and Debugging Web Tests](testing/web_tests.md)
diff --git a/docs/shutdown.md b/docs/shutdown.md new file mode 100644 index 0000000..4165def --- /dev/null +++ b/docs/shutdown.md
@@ -0,0 +1,96 @@ +# Chrome Shutdown + +[TOC] + +This documents shutdown steps on Windows, Mac and Linux. + +On Android, the system can terminate the Chrome app at any point without running +any shutdown step. + +TODO: Document ChromeOS shutdown. + +## Step 1: Exiting the main loop + +Shutdown starts when nothing keeps Chrome alive. Typically, this happens when +all browser windows are closed, but other things can [keep Chrome +alive](https://source.chromium.org/chromium/chromium/src/+/master:components/keep_alive_registry/keep_alive_types.h). + +When nothing keeps Chrome alive, `BrowserProcessImpl::Unpin` asks the main +thread's message loop to quit as soon as it no longer has tasks ready to run +immediately. + +``` +base::RunLoop::QuitWhenIdle +… +BrowserProcessImpl::Unpin +BrowserProcessImpl::OnKeepAliveStateChanged +KeepAliveRegistry::OnKeepAliveStateChanged +KeepAliveRegistry::Unregister +ScopedKeepAlive::~ScopedKeepAlive +... +Browser::UnregisterKeepAlive +BrowserList::RemoveBrowser +Browser::~Browser +``` + +Following this request, `ChromeBrowserMainParts::MainMessageLoopRun` exits. Tasks +posted to the main thread without a delay prior to this point are guaranteed to +have run; tasks posted to the main thread after this point will never run. + +## Step 2: Cleaning up, after main loop exit + +`BrowserMainRunnerImpl::Shutdown` is called on the main thread. Within that +method, `BrowserMainLoop::ShutdownThreadsAndCleanUp` orchestrates the main +shutdown steps. + +`ChromeBrowserMainParts::PostMainMessageLoopRun` is invoked. It invokes the +`PostMainMessageLoopRun` method of each `ChromeBrowserMainExtraParts` instance. +This is a good place to perform shutdown steps of a component that require the +IO thread, the `ThreadPool` or the `Profile` to still be available. + +`ChromeBrowserMainParts::PostMainMessageLoopRun` also invokes +`BrowserProcessImpl::StartTearDown` which deletes many services owned by +`BrowserProcessImpl` (aka `g_browser_process`). One of these services is the +`ProfileManager`. Deleting the `ProfileManager` deletes `Profiles`. As part of +deleting a `Profile`, its `KeyedServices` are deleted, including: + +* Sync Service +* History Service + +## Step 3: Joining other threads + +The IO thread is joined. No IPC or Mojo can be received after this. + +`ThreadPool` shutdown starts. At this point, no new `SKIP_ON_SHUTDOWN` or +`CONTINUE_ON_SHUTDOWN` task can start running (they are deleted without +running). The main thread blocks until all `SKIP_ON_SHUTDOWN` tasks that started +running prior to `ThreadPool` shutdown start are complete, and all +`BLOCK_SHUTDOWN` tasks are complete (irrespective of whether they were posted +before or after `ThreadPool` shutdown start). When no more `SKIP_ON_SHUTDOWN` is +running and no more `BLOCK_SHUTDOWN` task is queued or running, the main thread +is unblocked and `ThreadPool` shutdown is considered complete. Note: +`CONTINUE_ON_SHUTDOWN` tasks that started before `ThreadPool` shutdown may still +be running. + +At this point, new tasks posted to the IO thread or to the `ThreadPool` cannot +run. It is illegal to post a `BLOCK_SHUTDOWN` task to the `ThreadPool` (enforced +by a `DCHECK`). + +## Step 4: Cleaning up, after joining other threads + +`ChromeBrowserMainParts::PostDestroyThreads` is invoked. It invokes +`BrowserProcessImpl::PostDestroyThreads`. Since it is guaranteed that no +`SKIP_ON_SHUTDOWN` or `BLOCK_SHUTDOWN` task is running at this point, it is a +good place to delete objects accessed directly from these tasks. + +Then, if a new Chrome executable, it is swapped with the current one +(Windows-only). + +``` +upgrade_util::SwapNewChromeExeIfPresent +browser_shutdown::ShutdownPostThreadsStop +ChromeBrowserMainParts::PostDestroyThreads +content::BrowserMainLoop::ShutdownThreadsAndCleanUp +content::BrowserMainLoop::ShutdownThreadsAndCleanUp +content::BrowserMainRunnerImpl::Shutdown +```
diff --git a/docs/speed/metrics_changelog/2020_06_cls.md b/docs/speed/metrics_changelog/2020_06_cls.md new file mode 100644 index 0000000..52813fa --- /dev/null +++ b/docs/speed/metrics_changelog/2020_06_cls.md
@@ -0,0 +1,21 @@ +# Cumulative Layout Shift Changes in M85 + +## Changes in Chrome 85 +Prior to Chrome 85, there was a [bug](https://bugs.chromium.org/p/chromium/issues/detail?id=1088311) +in Cumulative Layout Shift on pages with video elements. Hovering over the video +element so that the thumb slider was visible would result in layout shifts when +it moved. The bug was fixed in Chrome 85. The source code of the change can be +seen [here](https://chromium-review.googlesource.com/c/chromium/src/+/2233310). + +## How does this affect a site's metrics? + +This change only affects metrics for a very small amount of sites. Desktop sites +with video elements that users hover their mouse over for an extended period of +time will have lower CLS values starting in Chrome 85. + +We do not see an impact from this change in our overall metrics, so we believe +the effect on most sites will be minimal. + +## When were users affected? + +Most users were updated to Chrome 85 the week of August 24, 2020.
diff --git a/docs/speed/metrics_changelog/2020_06_fcp.md b/docs/speed/metrics_changelog/2020_06_fcp.md new file mode 100644 index 0000000..3ec1798 --- /dev/null +++ b/docs/speed/metrics_changelog/2020_06_fcp.md
@@ -0,0 +1,21 @@ +# First Contentful Paint Changes in M84 + +## Changes in Chrome 84 +Starting in Chrome 84, content with opacity:0 is no longer counted as the +first contentful paint. This brings behavior in line with the +[specification](https://www.w3.org/TR/paint-timing/). +The source code of the change can be seen +[here](https://chromium-review.googlesource.com/c/chromium/src/+/2145134). + +## How does this affect a site's metrics? + +This change affects sites whose content is all opacity:0 during the first paint. +After this change, the first contentful paint will be reported the next time +visible content paints. + +We do not see an impact from this change in our overall metrics, so we believe +the effect on most sites will be minimal. + +## When were users affected? + +Most users were updated to Chrome 84 the week of July 13, 2020.
diff --git a/docs/speed/metrics_changelog/2020_07_fcp.md b/docs/speed/metrics_changelog/2020_07_fcp.md new file mode 100644 index 0000000..94bdbaff --- /dev/null +++ b/docs/speed/metrics_changelog/2020_07_fcp.md
@@ -0,0 +1,24 @@ +# First Contentful Paint Changes in M86 + +## Changes in Chrome 86 +In Chrome 86, some small changes were made to First Contentful Paint to bring +its implementation in line with the [specification](https://www.w3.org/TR/paint-timing/). + +The changes are: + * Video elements now trigger FCP when painted. [Source code for this change](https://chromium-review.googlesource.com/c/chromium/src/+/2276244). + * Only SVG elements with content now trigger FCP. Previously empty SVG paints triggered SVG. [Source code for this change](https://chromium-review.googlesource.com/c/chromium/src/+/2285532). + * WebGL2 canvases now trigger FCP when painted. [Source code for this change](https://chromium-review.googlesource.com/c/chromium/src/+/2348694). + +## How does this affect a site's metrics? + +This change affects a small set of sites: + * Sites with a first contentful paint which is only a video element without a `poster` attribute will have an earlier FCP time. + * Sites with a first contentful paint which is only an empty SVG element will have a later FCP time. + * Sites with a first contentful paint which is only a WebGL canvas will have an earlier FCP time. + +We do not see an impact from this change in our overall metrics, so we believe +the effect on most sites will be minimal. + +## When were users affected? + +Most users were updated to Chrome 86 the week of October 5, 2020.
diff --git a/docs/speed/metrics_changelog/2020_08_lcp.md b/docs/speed/metrics_changelog/2020_08_lcp.md new file mode 100644 index 0000000..b9170b5 --- /dev/null +++ b/docs/speed/metrics_changelog/2020_08_lcp.md
@@ -0,0 +1,23 @@ +# Largest Contentful Paint Changes in M86 + +## Changes in Chrome 86 +Prior to Chrome 86, there was a [bug](https://bugs.chromium.org/p/chromium/issues/detail?id=1092473) +in Largest Contentful Paint on some pages where the largest contentful element +initially has opacity:0. The bug was fixed in Chrome 86. The source code of the +change can be seen [here](https://chromium-review.googlesource.com/c/chromium/src/+/2316788). + +## How does this affect a site's metrics? + +This change only affects metrics for a very small amount of sites. Generally +sites whose largest contentful elements are opacity:0 initially are using A/B +testing frameworks which initially clear the page before displaying the correct +content. Sites using this technique will now see a longer LCP, reflecting the +time until the largest contentful paint is visible to the user, instead of the +time it is loaded in the DOM but invisible. + +We do not see an impact from this change in our overall metrics, so we believe +the effect on most sites will be minimal. + +## When were users affected? + +Most users were updated to Chrome 86 the week of October 5, 2020.
diff --git a/docs/speed/metrics_changelog/cls.md b/docs/speed/metrics_changelog/cls.md index b2fd866..a2d8fa1 100644 --- a/docs/speed/metrics_changelog/cls.md +++ b/docs/speed/metrics_changelog/cls.md
@@ -8,6 +8,8 @@ * an element and its descendants if they move together, and * inline elements and texts in a block after a shifted text. These changes will affect layout instability score for the specific cases. +* Chrome 85 + * Metric definition improvement: [Cumulative Layout Shift ignores layout shifts from video slider thumb](2020_06_cls.md) * Chrome 79 * Metric is elevated to stable; changes in metric definition will be reported in this log. * Chrome 77
diff --git a/docs/speed/metrics_changelog/fcp.md b/docs/speed/metrics_changelog/fcp.md index 1d8545c46..ef2c9f4 100644 --- a/docs/speed/metrics_changelog/fcp.md +++ b/docs/speed/metrics_changelog/fcp.md
@@ -2,8 +2,12 @@ This is a list of changes to [First Contentful Paint](https://web.dev/fcp). +* Chrome 86 + * Metric definition improvements: [First Contentful Paint reported for videos, webgl2 canvases, and non-contentful SVG](2020_07_fcp.md) +* Chrome 84 + * Metric definition improvement: [First Contentful Paint not reported for opacity:0](2020_06_fcp.md) * Chrome 77 * Metric definition improvement: [First Contentful Paint ending switches from swap time to presentation time](2019_12_fcp.md) * Chrome performance regression: [First Contentful Paint regression (recovered in Chrome 78)](2019_12_fcp.md) * Chrome 60 - * Metric exposed via API: [First Contentful Paint](https://web.dev/first-contentful-paint/) available via [Paint Timing API](https://w3c.github.io/paint-timing/#first-contentful-paint) \ No newline at end of file + * Metric exposed via API: [First Contentful Paint](https://web.dev/first-contentful-paint/) available via [Paint Timing API](https://w3c.github.io/paint-timing/#first-contentful-paint)
diff --git a/docs/speed/metrics_changelog/lcp.md b/docs/speed/metrics_changelog/lcp.md index 80aabcf..5d114ddf4 100644 --- a/docs/speed/metrics_changelog/lcp.md +++ b/docs/speed/metrics_changelog/lcp.md
@@ -2,6 +2,8 @@ This is a list of changes to [Largest Contentful Paint](https://web.dev/lcp). +* Chrome 86 + * Metric definition improvement: [Largest Contentful Paint ignores paints with opacity 0](2020_08_lcp.md) * Chrome 83 * Metric definition improvement: [Largest Contentful Paint measurement stops at first input or scroll](2020_05_lcp.md) * Metric definition improvement: [Largest Contentful Paint properly accounts for visual size of background images](2020_05_lcp.md)
diff --git a/docs/updating_clang.md b/docs/updating_clang.md index e32b7ca..05737095 100644 --- a/docs/updating_clang.md +++ b/docs/updating_clang.md
@@ -7,7 +7,9 @@ An archive of all packages built so far is at https://is.gd/chromeclang 1. Check that https://ci.chromium.org/p/chromium/g/chromium.clang/console - looks reasonably green. + looks reasonably green. Red bots with seemingly normal test failures are + usually ok, that likely means the test is broken with the stable Clang as + well. 1. Sync your Chromium tree to the latest revision to pick up any plugin changes. 1. Run [go/chrome-push-clang-to-goma](https://goto.google.com/chrome-push-clang-to-goma). @@ -18,6 +20,12 @@ https://crbug.com/1034081). Then it will push the packages to goma. If you do not have the necessary credentials to do the upload, ask clang@chromium.org to find someone who does. + * Alternatively, to create your own roll CL, you can manually run + `tools/clang/scripts/upload_revision.py` with a recent upstream LLVM + commit hash as the argument. After the `*_upload_clang` trybots are + successfully finished, run + [go/chrome-promote-clang](https://goto.google.com/chrome-promote-clang) + on the new Clang package name. 1. Run an exhaustive set of try jobs to test the new compiler. The CL description created previously by upload_revision.py includes `Cq-Include-Trybots:` lines for all needed bots, so it's sufficient to just
diff --git a/extensions/common/api/automation.idl b/extensions/common/api/automation.idl index c6ef2e9c..938092ad 100644 --- a/extensions/common/api/automation.idl +++ b/extensions/common/api/automation.idl
@@ -211,7 +211,6 @@ math, menu, menuBar, - menuButton, menuItem, menuItemCheckBox, menuItemRadio,
diff --git a/gpu/command_buffer/common/gpu_memory_buffer_support.cc b/gpu/command_buffer/common/gpu_memory_buffer_support.cc index c268bc1..388de9f4 100644 --- a/gpu/command_buffer/common/gpu_memory_buffer_support.cc +++ b/gpu/command_buffer/common/gpu_memory_buffer_support.cc
@@ -55,7 +55,7 @@ uint32_t GetPlatformSpecificTextureTarget() { #if defined(OS_MAC) return macos_specific_texture_target; -#elif defined(OS_ANDROID) || defined(OS_LINUX) +#elif defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) return GL_TEXTURE_EXTERNAL_OES; #elif defined(OS_WIN) || defined(OS_FUCHSIA) return GL_TEXTURE_2D; @@ -85,7 +85,7 @@ GPU_EXPORT bool NativeBufferNeedsPlatformSpecificTextureTarget( gfx::BufferFormat format) { -#if defined(USE_OZONE) || defined(OS_LINUX) +#if defined(USE_OZONE) || defined(OS_LINUX) || defined(OS_CHROMEOS) // Always use GL_TEXTURE_2D as the target for RGB textures. // https://crbug.com/916728 if (format == gfx::BufferFormat::R_8 || format == gfx::BufferFormat::RG_88 ||
diff --git a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc index 8f9eb62b..4dd9c92 100644 --- a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc +++ b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
@@ -29,7 +29,7 @@ #include "ui/gl/gl_image.h" #include "ui/gl/test/gl_image_test_support.h" -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #include "gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.h" #include "ui/gfx/linux/client_native_pixmap_factory_dmabuf.h" #endif @@ -72,7 +72,7 @@ GLManager gl_; }; -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) class GpuMemoryBufferTestEGL : public testing::Test, public gpu::GpuCommandBufferTestEGL { public: @@ -90,7 +90,7 @@ bool egl_initialized_{false}; std::unique_ptr<gfx::ClientNativePixmapFactory> native_pixmap_factory_; }; -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) namespace { @@ -361,7 +361,7 @@ glDeleteTextures(1, &texture_id); } -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // Test glCreateImageCHROMIUM with gfx::NATIVE_PIXMAP. Basically the test // reproduces the situation where some dmabuf fds are available outside the // gpu process and the user wants to import them using glCreateImageCHROMIUM. @@ -475,7 +475,7 @@ glDestroyImageCHROMIUM(image_id); glDeleteTextures(1, &texture_id); } -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) INSTANTIATE_TEST_SUITE_P( GpuMemoryBufferTests,
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory.cc b/gpu/ipc/service/gpu_memory_buffer_factory.cc index 57af72e..be28596 100644 --- a/gpu/ipc/service/gpu_memory_buffer_factory.cc +++ b/gpu/ipc/service/gpu_memory_buffer_factory.cc
@@ -12,7 +12,7 @@ #include "gpu/ipc/service/gpu_memory_buffer_factory_io_surface.h" #endif -#if defined(OS_LINUX) || defined(OS_FUCHSIA) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_FUCHSIA) #include "gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.h" #endif @@ -34,7 +34,7 @@ return std::make_unique<GpuMemoryBufferFactoryIOSurface>(); #elif defined(OS_ANDROID) return std::make_unique<GpuMemoryBufferFactoryAndroidHardwareBuffer>(); -#elif defined(OS_LINUX) || defined(OS_FUCHSIA) +#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_FUCHSIA) return std::make_unique<GpuMemoryBufferFactoryNativePixmap>( vulkan_context_provider); #elif defined(OS_WIN)
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index 07d2951..89cdcdd5 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -652,7 +652,10 @@ if (self.appState.foregroundActiveScene) { return self.appState.foregroundActiveScene.interfaceProvider; } - return self.appState.connectedScenes[0].interfaceProvider; + NSArray<SceneState*>* connectedScenes = self.appState.connectedScenes; + + return connectedScenes.count == 0 ? nil + : connectedScenes[0].interfaceProvider; } - (BOOL)isFirstLaunchAfterUpgrade {
diff --git a/ios/chrome/browser/passwords/BUILD.gn b/ios/chrome/browser/passwords/BUILD.gn index 525e3c9..e8c655e 100644 --- a/ios/chrome/browser/passwords/BUILD.gn +++ b/ios/chrome/browser/passwords/BUILD.gn
@@ -197,6 +197,7 @@ "//components/prefs:test_support", "//components/safe_browsing/core/common:safe_browsing_prefs", "//components/security_state/ios", + "//components/ukm:test_support", "//google_apis", "//ios/chrome/browser/autofill", "//ios/chrome/browser/browser_state:test_support",
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_check_manager.mm b/ios/chrome/browser/passwords/ios_chrome_password_check_manager.mm index 371f141..c050e0d 100644 --- a/ios/chrome/browser/passwords/ios_chrome_password_check_manager.mm +++ b/ios/chrome/browser/passwords/ios_chrome_password_check_manager.mm
@@ -95,8 +95,8 @@ browser_state, ServiceAccessType::EXPLICIT_ACCESS)), saved_passwords_presenter_(password_store_), - compromised_credentials_manager_(password_store_, - &saved_passwords_presenter_), + compromised_credentials_manager_(&saved_passwords_presenter_, + password_store_), bulk_leak_check_service_adapter_( &saved_passwords_presenter_, IOSChromeBulkLeakCheckServiceFactory::GetForBrowserState(
diff --git a/ios/chrome/browser/passwords/well_known_change_password_tab_helper.h b/ios/chrome/browser/passwords/well_known_change_password_tab_helper.h index 9a862d58..700b898f 100644 --- a/ios/chrome/browser/passwords/well_known_change_password_tab_helper.h +++ b/ios/chrome/browser/passwords/well_known_change_password_tab_helper.h
@@ -6,6 +6,7 @@ #include "components/password_manager/core/browser/change_password_url_service.h" #include "components/password_manager/core/browser/well_known_change_password_state.h" +#include "components/password_manager/core/browser/well_known_change_password_util.h" #include "ios/web/public/navigation/web_state_policy_decider.h" #include "ios/web/public/web_state_observer.h" #import "ios/web/public/web_state_user_data.h" @@ -67,6 +68,8 @@ void OnProcessingFinished(bool is_supported) override; // Redirects to a given URL in the same tab. void Redirect(const GURL& url); + // Records the given UKM metric. + void RecordMetric(WellKnownChangePasswordResult result); web::WebState* web_state_ = nullptr; ProcessingState processing_state_ = kWaitingForFirstRequest;
diff --git a/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm b/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm index 6df6b59..1c6a5ed 100644 --- a/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm +++ b/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm
@@ -7,12 +7,14 @@ #import <Foundation/Foundation.h> #include "base/logging.h" -#include "components/password_manager/core/browser/well_known_change_password_util.h" #include "components/password_manager/core/common/password_manager_features.h" +#import "components/ukm/ios/ukm_url_recorder.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/passwords/ios_chrome_change_password_url_service_factory.h" #import "ios/web/public/navigation/navigation_context.h" #import "net/base/mac/url_conversions.h" +#include "services/metrics/public/cpp/ukm_builders.h" +#include "services/metrics/public/cpp/ukm_recorder.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -124,12 +126,19 @@ if (is_supported) { std::move(response_policy_callback_) .Run(web::WebStatePolicyDecider::PolicyDecision::Allow()); + RecordMetric(WellKnownChangePasswordResult::kUsedWellKnownChangePassword); } else { std::move(response_policy_callback_) .Run(web::WebStatePolicyDecider::PolicyDecision::Cancel()); GURL redirect_url = change_password_url_service_->GetChangePasswordUrl(request_url_); - Redirect(redirect_url.is_valid() ? redirect_url : request_url_.GetOrigin()); + if (redirect_url.is_valid()) { + RecordMetric(WellKnownChangePasswordResult::kFallbackToOverrideUrl); + Redirect(redirect_url); + } else { + RecordMetric(WellKnownChangePasswordResult::kFallbackToOriginUrl); + Redirect(request_url_.GetOrigin()); + } } } @@ -143,4 +152,12 @@ } } +void WellKnownChangePasswordTabHelper::RecordMetric( + WellKnownChangePasswordResult result) { + ukm::SourceId source_id = ukm::GetSourceIdForWebStateDocument(web_state_); + ukm::builders::PasswordManager_WellKnownChangePasswordResult(source_id) + .SetWellKnownChangePasswordResult(static_cast<int64_t>(result)) + .Record(ukm::UkmRecorder::Get()); +} + WEB_STATE_USER_DATA_KEY_IMPL(WellKnownChangePasswordTabHelper)
diff --git a/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm b/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm index b3bb727..5930ea4 100644 --- a/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm +++ b/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm
@@ -10,6 +10,7 @@ #include "base/test/scoped_feature_list.h" #include "components/password_manager/core/browser/well_known_change_password_util.h" #include "components/password_manager/core/common/password_manager_features.h" +#include "components/ukm/test_ukm_recorder.h" #include "ios/chrome/browser/passwords/ios_chrome_change_password_url_service_factory.h" #import "ios/web/public/navigation/navigation_manager.h" #import "ios/web/public/test/fakes/test_web_client.h" @@ -24,6 +25,7 @@ #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 "services/metrics/public/cpp/ukm_builders.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" @@ -41,6 +43,7 @@ using net::test_server::HttpResponse; using password_manager::kWellKnownChangePasswordPath; using password_manager::kWellKnownNotExistingResourcePath; +using password_manager::WellKnownChangePasswordResult; // ServerResponse describes how a server should respond to a given path. struct ServerResponse { @@ -77,6 +80,8 @@ class WellKnownChangePasswordTabHelperTest : public web::TestWebClient, public web::WebTestWithWebState { public: + using UkmBuilder = + ukm::builders::PasswordManager_WellKnownChangePasswordResult; WellKnownChangePasswordTabHelperTest() { feature_list_.InitAndEnableFeature( password_manager::features::kWellKnownChangePassword); @@ -104,6 +109,7 @@ SetSharedURLLoaderFactory( base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory_)); + test_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>(); } // Sets a response for the |test_url_loader_factory_| with the |test_server_| @@ -113,6 +119,15 @@ test_url_loader_factory_.AddResponse(test_server_->GetURL(path).spec(), "", status_code); } + + void ExpectUkmMetric(WellKnownChangePasswordResult expected) { + auto entries = test_recorder_->GetEntriesByName(UkmBuilder::kEntryName); + // Expect one recorded metric. + ASSERT_EQ(1, static_cast<int>(entries.size())); + test_recorder_->ExpectEntryMetric( + entries[0], UkmBuilder::kWellKnownChangePasswordResultName, + static_cast<int64_t>(expected)); + } // Waits until the navigation is complete and waits for backgroundtasks to // complete. Returns false when timed out. bool WaitUntilLoaded(); @@ -124,6 +139,7 @@ std::unique_ptr<EmbeddedTestServer> test_server_ = std::make_unique<EmbeddedTestServer>(); TestChangePasswordUrlService* url_service_ = nullptr; + std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_recorder_; private: // Returns a response for the given request. Uses |path_response_map_| to @@ -185,6 +201,7 @@ test_server_->GetURL(kWellKnownChangePasswordPath)); ASSERT_TRUE(WaitUntilLoaded()); EXPECT_EQ(GetNavigatedUrl().path(), kWellKnownChangePasswordPath); + ExpectUkmMetric(WellKnownChangePasswordResult::kUsedWellKnownChangePassword); } TEST_F(WellKnownChangePasswordTabHelperTest, @@ -200,6 +217,7 @@ test_server_->GetURL(kWellKnownChangePasswordPath)); ASSERT_TRUE(WaitUntilLoaded()); EXPECT_EQ(GetNavigatedUrl().path(), "/change-password"); + ExpectUkmMetric(WellKnownChangePasswordResult::kUsedWellKnownChangePassword); } TEST_F(WellKnownChangePasswordTabHelperTest, @@ -212,6 +230,7 @@ test_server_->GetURL(kWellKnownChangePasswordPath)); ASSERT_TRUE(WaitUntilLoaded()); EXPECT_EQ(GetNavigatedUrl().path(), "/"); + ExpectUkmMetric(WellKnownChangePasswordResult::kFallbackToOriginUrl); } TEST_F(WellKnownChangePasswordTabHelperTest, NoSupportForChangePassword_Ok) { @@ -223,6 +242,7 @@ test_server_->GetURL(kWellKnownChangePasswordPath)); ASSERT_TRUE(WaitUntilLoaded()); EXPECT_EQ(GetNavigatedUrl().path(), "/"); + ExpectUkmMetric(WellKnownChangePasswordResult::kFallbackToOriginUrl); } TEST_F(WellKnownChangePasswordTabHelperTest, @@ -235,6 +255,7 @@ test_server_->GetURL(kWellKnownChangePasswordPath)); ASSERT_TRUE(WaitUntilLoaded()); EXPECT_EQ(GetNavigatedUrl().path(), "/"); + ExpectUkmMetric(WellKnownChangePasswordResult::kFallbackToOriginUrl); } TEST_F(WellKnownChangePasswordTabHelperTest, @@ -248,4 +269,5 @@ test_server_->GetURL(kWellKnownChangePasswordPath)); ASSERT_TRUE(WaitUntilLoaded()); EXPECT_EQ(GetNavigatedUrl().path(), kMockChangePasswordPath); + ExpectUkmMetric(WellKnownChangePasswordResult::kFallbackToOverrideUrl); }
diff --git a/ios/chrome/browser/snapshots/snapshot_browser_agent.h b/ios/chrome/browser/snapshots/snapshot_browser_agent.h index 0eee04e9..09adf24 100644 --- a/ios/chrome/browser/snapshots/snapshot_browser_agent.h +++ b/ios/chrome/browser/snapshots/snapshot_browser_agent.h
@@ -34,6 +34,9 @@ // performing any necessary migrations. void PerformStorageMaintenance(); + // Permanently removes all snapshots. + void RemoveAllSnapshots(); + SnapshotCache* snapshot_cache() { return snapshot_cache_; } private:
diff --git a/ios/chrome/browser/snapshots/snapshot_browser_agent.mm b/ios/chrome/browser/snapshots/snapshot_browser_agent.mm index 2cc3014..9dd59ef 100644 --- a/ios/chrome/browser/snapshots/snapshot_browser_agent.mm +++ b/ios/chrome/browser/snapshots/snapshot_browser_agent.mm
@@ -97,6 +97,10 @@ PurgeUnusedSnapshots(); } +void SnapshotBrowserAgent::RemoveAllSnapshots() { + [snapshot_cache_ removeAllImages]; +} + void SnapshotBrowserAgent::MigrateStorageIfNecessary() { DCHECK(snapshot_cache_); base::FilePath legacy_directory;
diff --git a/ios/chrome/browser/snapshots/snapshot_cache.h b/ios/chrome/browser/snapshots/snapshot_cache.h index 1304760..48597def 100644 --- a/ios/chrome/browser/snapshots/snapshot_cache.h +++ b/ios/chrome/browser/snapshots/snapshot_cache.h
@@ -50,22 +50,11 @@ - (void)setImage:(UIImage*)image withSnapshotID:(NSString*)snapshotID; -// Removes the image from both the LRU and disk cache, unless it is marked for -// deferred deletion. Images marked for deferred deletion can only be removed by -// calling |-removeMarkedImages|. +// Removes the image from both the LRU and disk. - (void)removeImageWithSnapshotID:(NSString*)snapshotID; -// Marks an image for deferred deletion. The image will not be immediately -// deleted when |-removeImageWithSnapshotID:| is called. Images marked for -// deferred deletion can only be removed by calling |-removeMarkedImages|. -- (void)markImageWithSnapshotID:(NSString*)snapshotID; - -// Removes all marked images from both the LRU and disk cache. -- (void)removeMarkedImages; - -// Unmarks all images, so they remain in the cache. They are no longer marked -// for deferred deletion. -- (void)unmarkAllImages; +// Removes all images from the LRU and disk. +- (void)removeAllImages; // Moves all images for |snapshotIDs| from |sourcePath| to the current storage // path of this snapshot cache. Deletes the folder |sourcePath| after migration, @@ -78,6 +67,7 @@ // background thread. - (void)purgeCacheOlderThan:(const base::Time&)date keeping:(NSSet*)liveSnapshotIDs; + // Hint that the snapshot for |snapshotID| will likely be saved to disk when the // application is backgrounded. The snapshot is then saved in memory, so it // does not need to be read off disk.
diff --git a/ios/chrome/browser/snapshots/snapshot_cache.mm b/ios/chrome/browser/snapshots/snapshot_cache.mm index 40b48a8..a434ced 100644 --- a/ios/chrome/browser/snapshots/snapshot_cache.mm +++ b/ios/chrome/browser/snapshots/snapshot_cache.mm
@@ -48,8 +48,6 @@ @interface SnapshotCache () // List of observers to be notified of changes to the snapshot cache. @property(nonatomic, strong) SnapshotCacheObservers* observers; -// Marked set of identifiers for which images should not be immediately deleted. -@property(nonatomic, strong) NSMutableSet<NSString*>* markedIDs; @end namespace { @@ -252,7 +250,6 @@ [self createStorageIfNecessary]; _observers = [SnapshotCacheObservers observers]; - _markedIDs = [[NSMutableSet alloc] init]; [[NSNotificationCenter defaultCenter] addObserver:self @@ -351,9 +348,6 @@ - (void)removeImageWithSnapshotID:(NSString*)snapshotID { DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - // Do not immediately delete if the ID is marked. - if ([self.markedIDs containsObject:snapshotID]) - return; [_lruCache removeObjectForKey:snapshotID]; @@ -375,20 +369,29 @@ })); } -- (void)markImageWithSnapshotID:(NSString*)snapshotID { - [self.markedIDs addObject:snapshotID]; -} +- (void)removeAllImages { + DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); -- (void)removeMarkedImages { - while (self.markedIDs.count > 0) { - NSString* snapshotID = [self.markedIDs anyObject]; - [self.markedIDs removeObject:snapshotID]; - [self removeImageWithSnapshotID:snapshotID]; - } -} + [_lruCache removeAllObjects]; -- (void)unmarkAllImages { - [self.markedIDs removeAllObjects]; + if (!_taskRunner) + return; + // Copy ivars used by the block so that it does not reference |self|. + const base::FilePath cacheDirectory = _cacheDirectory; + _taskRunner->PostTask( + FROM_HERE, base::BindOnce(^{ + if (cacheDirectory.empty() || !base::DirectoryExists(cacheDirectory)) { + return; + } + if (!base::DeletePathRecursively(cacheDirectory)) { + DLOG(ERROR) << "Error deleting snapshots storage. " + << cacheDirectory.AsUTF8Unsafe(); + } + if (!base::CreateDirectory(cacheDirectory)) { + DLOG(ERROR) << "Error creating snapshot storage " + << cacheDirectory.AsUTF8Unsafe(); + } + })); } - (base::FilePath)imagePathForSnapshotID:(NSString*)snapshotID {
diff --git a/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm b/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm index b8465de..a6e80a1 100644 --- a/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm +++ b/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm
@@ -651,39 +651,34 @@ EXPECT_FALSE(base::PathExists(retinaFile)); } -// Tests that a marked image does not immediately delete when calling -// |-removeImageWithSnapshotID:|. Calling |-removeMarkedImages| immediately -// deletes the marked image. -TEST_F(SnapshotCacheTest, MarkedImageNotImmediatelyDeleted) { +// Tests that image immediately deletes when calling +// |-removeImageWithSnapshotID:|. +TEST_F(SnapshotCacheTest, ImageDeleted) { SnapshotCache* cache = GetSnapshotCache(); UIImage* image = GenerateRandomImage(CGSizeMake(kSnapshotPixelSize, kSnapshotPixelSize)); [cache setImage:image withSnapshotID:@"snapshotID"]; base::FilePath image_path = [cache imagePathForSnapshotID:@"snapshotID"]; - [cache markImageWithSnapshotID:@"snapshotID"]; [cache removeImageWithSnapshotID:@"snapshotID"]; // Give enough time for deletion. FlushRunLoops(); - EXPECT_TRUE(base::PathExists(image_path)); - [cache removeMarkedImages]; - FlushRunLoops(); EXPECT_FALSE(base::PathExists(image_path)); } -// Tests that unmarked images are not deleted when calling -// |-removeMarkedImages|. -TEST_F(SnapshotCacheTest, UnmarkedImageNotDeleted) { +// Tests that all images are deleted when calling |-removeAllImages|. +TEST_F(SnapshotCacheTest, AllImagesDeleted) { SnapshotCache* cache = GetSnapshotCache(); UIImage* image = GenerateRandomImage(CGSizeMake(kSnapshotPixelSize, kSnapshotPixelSize)); - [cache setImage:image withSnapshotID:@"snapshotID"]; - base::FilePath image_path = [cache imagePathForSnapshotID:@"snapshotID"]; - [cache markImageWithSnapshotID:@"snapshotID"]; - [cache unmarkAllImages]; - [cache removeMarkedImages]; + [cache setImage:image withSnapshotID:@"snapshotID-1"]; + [cache setImage:image withSnapshotID:@"snapshotID-2"]; + base::FilePath image_1_path = [cache imagePathForSnapshotID:@"snapshotID-1"]; + base::FilePath image_2_path = [cache imagePathForSnapshotID:@"snapshotID-2"]; + [cache removeAllImages]; // Give enough time for deletion. FlushRunLoops(); - EXPECT_TRUE(base::PathExists(image_path)); + EXPECT_FALSE(base::PathExists(image_1_path)); + EXPECT_FALSE(base::PathExists(image_2_path)); } // Tests that observers are notified when a snapshot is cached and removed.
diff --git a/ios/chrome/browser/snapshots/snapshot_tab_helper.h b/ios/chrome/browser/snapshots/snapshot_tab_helper.h index 2f2ee6c..0639b792 100644 --- a/ios/chrome/browser/snapshots/snapshot_tab_helper.h +++ b/ios/chrome/browser/snapshots/snapshot_tab_helper.h
@@ -78,6 +78,15 @@ // Instructs the helper not to snapshot content for the next page load event. void IgnoreNextLoad(); + // Hint that the snapshot will likely be saved to disk when the application is + // backgrounded. The snapshot is then saved in memory, so it does not need to + // be read off disk. + void WillBeSavedGreyWhenBackgrounding(); + + // Write a grey copy of the snapshot to disk, but if and only if a color + // version of the snapshot already exists in memory or on disk. + void SaveGreyInBackground(); + private: friend class web::WebStateUserData<SnapshotTabHelper>; @@ -97,6 +106,7 @@ void OnManagerShuttingDown(infobars::InfoBarManager* manager) override; web::WebState* web_state_ = nullptr; + NSString* tab_id_ = nil; SnapshotGenerator* snapshot_generator_ = nil; infobars::InfoBarManager* infobar_manager_ = nullptr;
diff --git a/ios/chrome/browser/snapshots/snapshot_tab_helper.mm b/ios/chrome/browser/snapshots/snapshot_tab_helper.mm index 300e7c3..38d93f80 100644 --- a/ios/chrome/browser/snapshots/snapshot_tab_helper.mm +++ b/ios/chrome/browser/snapshots/snapshot_tab_helper.mm
@@ -11,6 +11,7 @@ #include "components/infobars/core/infobar.h" #include "components/infobars/core/infobar_delegate.h" #include "ios/chrome/browser/infobars/infobar_manager_impl.h" +#import "ios/chrome/browser/snapshots/snapshot_cache.h" #import "ios/chrome/browser/snapshots/snapshot_generator.h" #import "ios/chrome/browser/ui/infobars/infobar_feature.h" #include "ios/chrome/browser/ui/util/ui_util.h" @@ -101,7 +102,6 @@ } void SnapshotTabHelper::RemoveSnapshot() { - DCHECK(web_state_); [snapshot_generator_ removeSnapshot]; } @@ -109,13 +109,24 @@ ignore_next_load_ = true; } +void SnapshotTabHelper::WillBeSavedGreyWhenBackgrounding() { + [snapshot_generator_.snapshotCache willBeSavedGreyWhenBackgrounding:tab_id_]; +} + +void SnapshotTabHelper::SaveGreyInBackground() { + [snapshot_generator_.snapshotCache saveGreyInBackgroundForSnapshotID:tab_id_]; +} + SnapshotTabHelper::SnapshotTabHelper(web::WebState* web_state, NSString* tab_id) : web_state_(web_state), + tab_id_([tab_id copy]), web_state_observer_(this), infobar_observer_(this), weak_ptr_factory_(this) { + DCHECK(web_state_); + DCHECK(tab_id_.length > 0); snapshot_generator_ = [[SnapshotGenerator alloc] initWithWebState:web_state_ - tabID:tab_id]; + tabID:tab_id_]; web_state_observer_.Add(web_state_); // Supports missing InfoBarManager to make testing easier. @@ -180,6 +191,7 @@ DCHECK_EQ(web_state_, web_state); web_state_observer_.Remove(web_state); web_state_ = nullptr; + tab_id_ = nil; } void SnapshotTabHelper::OnInfoBarAdded(infobars::InfoBar* infobar) {
diff --git a/ios/chrome/browser/tabs/tab_model.mm b/ios/chrome/browser/tabs/tab_model.mm index 1b0c3e7..dba66bf 100644 --- a/ios/chrome/browser/tabs/tab_model.mm +++ b/ios/chrome/browser/tabs/tab_model.mm
@@ -35,10 +35,8 @@ #import "ios/chrome/browser/sessions/session_restoration_browser_agent.h" #import "ios/chrome/browser/sessions/session_service_ios.h" #import "ios/chrome/browser/sessions/session_window_ios.h" -#import "ios/chrome/browser/snapshots/snapshot_browser_agent.h" -#import "ios/chrome/browser/snapshots/snapshot_cache.h" +#import "ios/chrome/browser/snapshots/snapshot_tab_helper.h" #import "ios/chrome/browser/tabs/tab_parenting_observer.h" -#import "ios/chrome/browser/web/tab_id_tab_helper.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_list_observer.h" #import "ios/chrome/browser/web_state_list/web_usage_enabler/web_usage_enabler_browser_agent.h" @@ -133,9 +131,6 @@ // Weak reference to the session restoration agent. SessionRestorationBrowserAgent* _sessionRestorationBrowserAgent; - // Used for saving gray images. - SnapshotBrowserAgent* _snapshotBrowserAgent; - // Used to ensure thread-safety of the certificate policy management code. base::CancelableTaskTracker _clearPoliciesTaskTracker; @@ -180,8 +175,6 @@ SessionRestorationBrowserAgent::FromBrowser(browser); _webEnabler = WebUsageEnablerBrowserAgent::FromBrowser(browser); - _snapshotBrowserAgent = SnapshotBrowserAgent::FromBrowser(browser); - _webStateListObservers.push_back(std::make_unique<TabParentingObserver>()); for (const auto& webStateListObserver : _webStateListObservers) @@ -239,12 +232,8 @@ // TODO(crbug.com/1115611): Move to SceneController. - (void)willResignActive:(NSNotification*)notify { if (_webEnabler->IsWebUsageEnabled() && _webStateList->GetActiveWebState()) { - NSString* tabId = - TabIdTabHelper::FromWebState(_webStateList->GetActiveWebState()) - ->tab_id(); - - [_snapshotBrowserAgent->snapshot_cache() - willBeSavedGreyWhenBackgrounding:tabId]; + SnapshotTabHelper::FromWebState(_webStateList->GetActiveWebState()) + ->WillBeSavedGreyWhenBackgrounding(); } } @@ -268,12 +257,8 @@ // Write out a grey version of the current website to disk. if (_webEnabler->IsWebUsageEnabled() && _webStateList->GetActiveWebState()) { - NSString* tabId = - TabIdTabHelper::FromWebState(_webStateList->GetActiveWebState()) - ->tab_id(); - - [_snapshotBrowserAgent->snapshot_cache() - saveGreyInBackgroundForSnapshotID:tabId]; + SnapshotTabHelper::FromWebState(_webStateList->GetActiveWebState()) + ->SaveGreyInBackground(); } }
diff --git a/ios/chrome/browser/ui/authentication/BUILD.gn b/ios/chrome/browser/ui/authentication/BUILD.gn index 03f0169..027b52e 100644 --- a/ios/chrome/browser/ui/authentication/BUILD.gn +++ b/ios/chrome/browser/ui/authentication/BUILD.gn
@@ -170,6 +170,21 @@ ] } +source_set("internal+eg2") { + defines = [ "CHROME_EARL_GREY_2" ] + configs += [ + "//build/config/compiler:enable_arc", + "//build/config/ios:xctest_config", + ] + testonly = true + visibility = [ ":*" ] + sources = [ + "signin_earl_grey_app_interface.h", + "signin_earl_grey_app_interface_stub.mm", + ] + deps = [ "//ios/third_party/earl_grey2:test_lib" ] +} + source_set("eg_test_support+eg2") { defines = [ "CHROME_EARL_GREY_2" ] configs += [ @@ -180,12 +195,11 @@ sources = [ "signin_earl_grey.h", "signin_earl_grey.mm", - "signin_earl_grey_app_interface.h", - "signin_earl_grey_app_interface_stub.mm", "signin_earl_grey_ui.h", "signin_earl_grey_ui.mm", ] deps = [ + ":internal+eg2", "//base", "//base/test:test_support", "//ios/chrome/app/strings",
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm index f3e2cec4..a9849fa 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -477,6 +477,11 @@ @"%@%li", kContentSuggestionsMostVisitedAccessibilityIdentifierPrefix, indexPath.row]; + // Apple doesn't handle the transparency of the background during animations + // linked to context menus. To prevent the cell from turning black during + // animations, its background is set to be the same as the NTP background. + // See: crbug.com/1120321. + cell.backgroundColor = ntp_home::kNTPBackgroundColor(); [self.collectionViewModel itemAtIndexPath:indexPath] .accessibilityIdentifier = cell.accessibilityIdentifier; }
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm b/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm index 5652580..900a33f228 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm +++ b/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm
@@ -87,6 +87,9 @@ // Stores the current content type in the clipboard. This is only valid if // |hasCopiedContent| is YES. @property(nonatomic, assign) ClipboardContentType copiedContentType; +// Stores whether the cached clipboard state is currently being updated. See +// |-updateCachedClipboardState| for more information. +@property(nonatomic, assign) BOOL isUpdatingCachedClipboardState; // Starts voice search, updating the NamedGuide to be constrained to the // trailing button. @@ -574,6 +577,14 @@ } - (void)updateCachedClipboardState { + // Sometimes, checking the clipboard state itself causes the clipboard to + // emit a UIPasteboardChangedNotification, leading to an infinite loop. For + // now, just prevent re-checking the clipboard state, but hopefully this will + // be fixed in a future iOS version (see crbug.com/1049053 for crash details). + if (self.isUpdatingCachedClipboardState) { + return; + } + self.isUpdatingCachedClipboardState = YES; self.hasCopiedContent = NO; ClipboardRecentContent* clipboardRecentContent = ClipboardRecentContent::GetInstance(); @@ -597,6 +608,7 @@ matched_types.end()) { weakSelf.copiedContentType = ClipboardContentType::Text; } + weakSelf.isUpdatingCachedClipboardState = NO; })); }
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm index a88d946..7a6c83c 100644 --- a/ios/chrome/browser/ui/main/scene_controller.mm +++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -216,7 +216,6 @@ if (self) { _sceneState = sceneState; [_sceneState addObserver:self]; - [_sceneState.appState addObserver:self]; // The window is necessary very early in the app/scene lifecycle, so it // should be created right away. // When multiwindow is supported, the window is created by SceneDelegate, @@ -503,6 +502,8 @@ [self startUpChromeUI]; } + [self.sceneState.appState addObserver:self]; + self.hasInitializedUI = YES; } @@ -676,6 +677,8 @@ self.browserViewWrangler = nil; self.hasInitializedUI = NO; + + [self.sceneState.appState removeObserver:self]; } #pragma mark - First Run
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm b/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm index 0bfb48d..a5791c9 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm
@@ -89,6 +89,9 @@ // Stores the current content type in the clipboard. This is only valid if // |hasCopiedContent| is YES. @property(nonatomic, assign) ClipboardContentType copiedContentType; +// Stores whether the cached clipboard state is currently being updated. See +// |-updateCachedClipboardState| for more information. +@property(nonatomic, assign) BOOL isUpdatingCachedClipboardState; @end @@ -414,6 +417,14 @@ } - (void)updateCachedClipboardState { + // Sometimes, checking the clipboard state itself causes the clipboard to + // emit a UIPasteboardChangedNotification, leading to an infinite loop. For + // now, just prevent re-checking the clipboard state, but hopefully this will + // be fixed in a future iOS version (see crbug.com/1049053 for crash details). + if (self.isUpdatingCachedClipboardState) { + return; + } + self.isUpdatingCachedClipboardState = YES; self.hasCopiedContent = NO; ClipboardRecentContent* clipboardRecentContent = ClipboardRecentContent::GetInstance(); @@ -437,6 +448,7 @@ matched_types.end()) { weakSelf.copiedContentType = ClipboardContentType::Text; } + self.isUpdatingCachedClipboardState = NO; })); }
diff --git a/ios/chrome/browser/ui/settings/safety_check/OWNERS b/ios/chrome/browser/ui/settings/safety_check/OWNERS new file mode 100644 index 0000000..046d8a7 --- /dev/null +++ b/ios/chrome/browser/ui/settings/safety_check/OWNERS
@@ -0,0 +1,5 @@ +harrisonsean@chromium.org +javierrobles@chromium.org + +# TEAM: ios-directory-owners@chromium.org +# OS: iOS
diff --git a/ios/chrome/browser/ui/settings/sync/utils/sync_util.mm b/ios/chrome/browser/ui/settings/sync/utils/sync_util.mm index ac75145c..acfc431e 100644 --- a/ios/chrome/browser/ui/settings/sync/utils/sync_util.mm +++ b/ios/chrome/browser/ui/settings/sync/utils/sync_util.mm
@@ -26,14 +26,17 @@ // to the user. This was added for crbug/265352 to quantify how often this // bug shows up in the wild. The logged histogram count should be interpreted // as a ratio of the number of active sync users. -enum ErrorState { +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum InfobarSyncError { SYNC_SIGN_IN_NEEDS_UPDATE = 1, - SYNC_SERVICE_UNAVAILABLE, - SYNC_NEEDS_PASSPHRASE, - SYNC_UNRECOVERABLE_ERROR, - SYNC_SYNC_SETTINGS_NOT_CONFIRMED, - SYNC_NEEDS_TRUSTED_VAULT_KEY, - SYNC_ERROR_COUNT + // DEPRECATED. No longer recorded. + // SYNC_SERVICE_UNAVAILABLE = 2 + SYNC_NEEDS_PASSPHRASE = 3, + SYNC_UNRECOVERABLE_ERROR = 4, + SYNC_SYNC_SETTINGS_NOT_CONFIRMED = 5, + SYNC_NEEDS_TRUSTED_VAULT_KEY = 6, + kMaxValue = SYNC_NEEDS_TRUSTED_VAULT_KEY, }; } // namespace @@ -179,11 +182,12 @@ return false; // Logs when an infobar is shown to user. See crbug/265352. - ErrorState loggedErrorState = SYNC_ERROR_COUNT; + InfobarSyncError loggedErrorState; switch (errorState) { case SyncSetupService::kNoSyncServiceError: case SyncSetupService::kSyncServiceCouldNotConnect: case SyncSetupService::kSyncServiceServiceUnavailable: + loggedErrorState = kMaxValue; NOTREACHED(); break; case SyncSetupService::kSyncServiceSignInNeedsUpdate: @@ -202,8 +206,7 @@ loggedErrorState = SYNC_SYNC_SETTINGS_NOT_CONFIRMED; break; } - UMA_HISTOGRAM_ENUMERATION("Sync.SyncErrorInfobarDisplayed", loggedErrorState, - SYNC_ERROR_COUNT); + UMA_HISTOGRAM_ENUMERATION("Sync.SyncErrorInfobarDisplayed", loggedErrorState); DCHECK(web_state); infobars::InfoBarManager* infoBarManager =
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_mediator.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_mediator.mm index 1d2183f..82f098e 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_mediator.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_mediator.mm
@@ -298,18 +298,12 @@ - (void)closeAllItems { // This is a no-op if |webStateList| is already empty. self.webStateList->CloseAllWebStates(WebStateList::CLOSE_USER_ACTION); + SnapshotBrowserAgent::FromBrowser(self.browser)->RemoveAllSnapshots(); } - (void)saveAndCloseAllItems { if (self.webStateList->empty()) return; - // Tell the cache to mark these images for deletion, rather than immediately - // deleting them. - for (int i = 0; i < self.webStateList->count(); i++) { - web::WebState* webState = self.webStateList->GetWebStateAt(i); - TabIdTabHelper* tabHelper = TabIdTabHelper::FromWebState(webState); - [self.snapshotCache markImageWithSnapshotID:tabHelper->tab_id()]; - } self.closedSessionWindow = SerializeWebStateList(self.webStateList); int old_size = self.tabRestoreService ? self.tabRestoreService->entries().size() : 0; @@ -328,8 +322,6 @@ self.closedSessionWindow = nil; [self removeEntriesFromTabRestoreService]; self.syncedClosedTabsCount = 0; - // Unmark all images for deletion since they are now active tabs again. - [self.snapshotCache unmarkAllImages]; } - (void)discardSavedClosedItems { @@ -337,8 +329,7 @@ return; self.syncedClosedTabsCount = 0; self.closedSessionWindow = nil; - // Delete all marked images from the cache. - [self.snapshotCache removeMarkedImages]; + SnapshotBrowserAgent::FromBrowser(self.browser)->RemoveAllSnapshots(); } #pragma mark GridCommands helpers
diff --git a/ios/web/browsing_data/browsing_data_remover_unittest.mm b/ios/web/browsing_data/browsing_data_remover_unittest.mm index 2210783..abe56a1 100644 --- a/ios/web/browsing_data/browsing_data_remover_unittest.mm +++ b/ios/web/browsing_data/browsing_data_remover_unittest.mm
@@ -134,6 +134,10 @@ // Tests that removing the cookies remove them from the cookie store. TEST_F(BrowsingDataRemoverTest, RemoveCookie) { + // TODO(crbug.com/1121425): Currently failing on iOS14. + if (@available(iOS 14, *)) { + return; + } ASSERT_TRUE(AddCookie()); ASSERT_TRUE(HasCookies(true));
diff --git a/media/capture/video/fake_video_capture_device_factory.cc b/media/capture/video/fake_video_capture_device_factory.cc index 9a28f8a..f45dafa 100644 --- a/media/capture/video/fake_video_capture_device_factory.cc +++ b/media/capture/video/fake_video_capture_device_factory.cc
@@ -208,7 +208,7 @@ int entry_index = 0; for (const auto& entry : devices_config_) { VideoCaptureApi api = -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) VideoCaptureApi::LINUX_V4L2_SINGLE_PLANE; #elif defined(OS_MAC) VideoCaptureApi::MACOSX_AVFOUNDATION;
diff --git a/media/capture/video/file_video_capture_device_factory.cc b/media/capture/video/file_video_capture_device_factory.cc index 7957082..d899c50 100644 --- a/media/capture/video/file_video_capture_device_factory.cc +++ b/media/capture/video/file_video_capture_device_factory.cc
@@ -52,7 +52,7 @@ VideoCaptureApi::WIN_DIRECT_SHOW; #elif defined(OS_MAC) VideoCaptureApi::MACOSX_AVFOUNDATION; -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) || defined(OS_CHROMEOS) VideoCaptureApi::LINUX_V4L2_SINGLE_PLANE; #else VideoCaptureApi::UNKNOWN;
diff --git a/media/capture/video/video_capture_buffer_pool_impl.cc b/media/capture/video/video_capture_buffer_pool_impl.cc index 4a260cc4..1a4b2ca 100644 --- a/media/capture/video/video_capture_buffer_pool_impl.cc +++ b/media/capture/video/video_capture_buffer_pool_impl.cc
@@ -58,7 +58,7 @@ int buffer_id) { // This requires platforms where base::SharedMemoryHandle is backed by a // file descriptor. -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) base::AutoLock lock(lock_); VideoCaptureBufferTracker* tracker = GetTracker(buffer_id);
diff --git a/media/capture/video/video_capture_device_client.cc b/media/capture/video/video_capture_device_client.cc index 43a88b7..4d933062 100644 --- a/media/capture/video/video_capture_device_client.cc +++ b/media/capture/video/video_capture_device_client.cc
@@ -301,7 +301,7 @@ // see http://linuxtv.org/downloads/v4l-dvb-apis/packed-rgb.html. // Windows RGB24 defines blue at lowest byte, // see https://msdn.microsoft.com/en-us/library/windows/desktop/dd407253 -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) fourcc_format = libyuv::FOURCC_RAW; #elif defined(OS_WIN) fourcc_format = libyuv::FOURCC_24BG;
diff --git a/media/capture/video/video_capture_device_client_unittest.cc b/media/capture/video/video_capture_device_client_unittest.cc index 9bd1d329..5e3dfa8 100644 --- a/media/capture/video/video_capture_device_client_unittest.cc +++ b/media/capture/video/video_capture_device_client_unittest.cc
@@ -227,7 +227,7 @@ PIXEL_FORMAT_NV21, PIXEL_FORMAT_YUY2, PIXEL_FORMAT_UYVY, -#if defined(OS_WIN) || defined(OS_LINUX) +#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) PIXEL_FORMAT_RGB24, #endif PIXEL_FORMAT_ARGB,
diff --git a/media/capture/video/win/video_capture_device_factory_win.cc b/media/capture/video/win/video_capture_device_factory_win.cc index 4ae6beb..769b0f6d 100644 --- a/media/capture/video/win/video_capture_device_factory_win.cc +++ b/media/capture/video/win/video_capture_device_factory_win.cc
@@ -50,6 +50,18 @@ const char kPidPrefix[] = "pid_"; // Also contains '\0'. const size_t kVidPidSize = 4; +// AQS device selector string to filter enumerated DeviceInformation objects to +// KSCATEGORY_SENSOR_CAMERA (Class GUID 24e552d7-6523-47F7-a647-d3465bf1f5ca) +// OR KSCATEGORY_VIDEO_CAMERA (Class GUID e5323777-f976-4f5b-9b55-b94699c46e44). +const wchar_t* kVideoAndSensorCamerasAqsString = + L"(System.Devices.InterfaceClassGuid:=" + L"\"{e5323777-f976-4f5b-9b55-b94699c46e44}\" AND " + L"(System.Devices.WinPhone8CameraFlags:=[] OR " + L"System.Devices.WinPhone8CameraFlags:<4096)) OR " + L"System.Devices.InterfaceClassGuid:=" + L"\"{24e552d7-6523-47f7-a647-d3465bf1f5ca}\" AND " + L"System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True"; + // Avoid enumerating and/or using certain devices due to they provoking crashes // or any other reason (http://crbug.com/378494). This enum is defined for the // purposes of UMA collection. Existing entries cannot be removed. @@ -542,8 +554,9 @@ } IAsyncOperation<DeviceInformationCollection*>* async_op; - hr = dev_info_statics->FindAllAsyncDeviceClass( - ABI::Windows::Devices::Enumeration::DeviceClass_VideoCapture, &async_op); + ScopedHString aqs_filter = + ScopedHString::Create(kVideoAndSensorCamerasAqsString); + hr = dev_info_statics->FindAllAsyncAqsFilter(aqs_filter.get(), &async_op); if (FAILED(hr)) { UWP_ENUM_ERROR_HANDLER(hr, "Find all devices asynchronously failed: "); return;
diff --git a/media/gpu/test/video_encoder/video_encoder_client.h b/media/gpu/test/video_encoder/video_encoder_client.h index 4811c23..9461ab66 100644 --- a/media/gpu/test/video_encoder/video_encoder_client.h +++ b/media/gpu/test/video_encoder/video_encoder_client.h
@@ -37,7 +37,7 @@ static constexpr uint32_t kDefaultBitrate = 200000; VideoEncoderClientConfig(const Video* video, VideoCodecProfile output_profile, - uint32_t bitrate = kDefaultBitrate); + uint32_t bitrate); VideoEncoderClientConfig(const VideoEncoderClientConfig&); // The output output profile to be used.
diff --git a/media/gpu/video_encode_accelerator_tests.cc b/media/gpu/video_encode_accelerator_tests.cc index 857710f9..7e05457 100644 --- a/media/gpu/video_encode_accelerator_tests.cc +++ b/media/gpu/video_encode_accelerator_tests.cc
@@ -252,8 +252,9 @@ // Encode video from start to end. Multiple buffer encodes will be queued in the // encoder, without waiting for the result of the previous encode requests. -TEST_F(VideoEncoderTest, FlushAtEndOfStream_MultipleOutstandingDecodes) { - VideoEncoderClientConfig config(g_env->Video(), g_env->Profile()); +TEST_F(VideoEncoderTest, FlushAtEndOfStream_MultipleOutstandingEncodes) { + VideoEncoderClientConfig config(g_env->Video(), g_env->Profile(), + g_env->Bitrate()); config.max_outstanding_encode_requests = 4; auto encoder = CreateVideoEncoder(g_env->Video(), config);
diff --git a/media/video/fake_gpu_memory_buffer.cc b/media/video/fake_gpu_memory_buffer.cc index 6fbdb059..ef2b49d 100644 --- a/media/video/fake_gpu_memory_buffer.cc +++ b/media/video/fake_gpu_memory_buffer.cc
@@ -10,7 +10,7 @@ #include "media/base/format_utils.h" #include "media/base/video_frame.h" -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> @@ -48,7 +48,7 @@ } // namespace -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) base::ScopedFD GetDummyFD() { base::ScopedFD fd(open("/dev/zero", O_RDWR)); DCHECK(fd.is_valid()); @@ -73,7 +73,7 @@ static base::NoDestructor<base::AtomicSequenceNumber> buffer_id_generator; handle_.id = gfx::GpuMemoryBufferId(buffer_id_generator->GetNext()); -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) for (size_t i = 0; i < VideoFrame::NumPlanes(video_pixel_format_); i++) { const gfx::Size plane_size_in_bytes = VideoFrame::PlaneSize(video_pixel_format_, i, size_); @@ -81,7 +81,7 @@ plane_size_in_bytes.width(), 0, plane_size_in_bytes.GetArea(), GetDummyFD()); } -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) } FakeGpuMemoryBuffer::~FakeGpuMemoryBuffer() = default; @@ -129,7 +129,7 @@ gfx::GpuMemoryBufferHandle handle; handle.type = gfx::NATIVE_PIXMAP; handle.id = handle_.id; -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) handle.native_pixmap_handle = gfx::CloneHandleForIPC(handle_.native_pixmap_handle); #endif
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc index cb443c90..cff6651 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -573,7 +573,7 @@ } bool is_software_backed_video_frame = !video_frame->HasTextures(); -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) is_software_backed_video_frame &= !video_frame->HasDmaBufs(); #endif
diff --git a/services/device/screen_orientation/BUILD.gn b/services/device/screen_orientation/BUILD.gn index ceec11a..de70dc03 100644 --- a/services/device/screen_orientation/BUILD.gn +++ b/services/device/screen_orientation/BUILD.gn
@@ -42,7 +42,7 @@ sources = [ "android/java/src/org/chromium/device/screen_orientation/ScreenOrientationListener.java" ] deps = [ "//base:base_java", - "//ui/android:ui_java", + "//ui/android:ui_no_recycler_view_java", ] } }
diff --git a/services/network/public/cpp/request_destination.cc b/services/network/public/cpp/request_destination.cc index 4cc1933..38884cc 100644 --- a/services/network/public/cpp/request_destination.cc +++ b/services/network/public/cpp/request_destination.cc
@@ -10,7 +10,7 @@ network::mojom::RequestDestination dest) { switch (dest) { case network::mojom::RequestDestination::kEmpty: - return "empty"; + return ""; case network::mojom::RequestDestination::kAudio: return "audio"; case network::mojom::RequestDestination::kAudioWorklet:
diff --git a/services/network/sec_header_helpers.cc b/services/network/sec_header_helpers.cc index 7e64d9cc..dc1dc70e 100644 --- a/services/network/sec_header_helpers.cc +++ b/services/network/sec_header_helpers.cc
@@ -138,7 +138,12 @@ // Sec-Fetch-Dest void SetSecFetchDestHeader(net::URLRequest* request, network::mojom::RequestDestination dest) { - std::string header_value = RequestDestinationToString(dest); + // https://w3c.github.io/webappsec-fetch-metadata/#abstract-opdef-set-dest + // If r's destination is the empty string, set header's value to the string + // "empty". Otherwise, set header's value to r's destination. + std::string header_value = dest == mojom::RequestDestination::kEmpty + ? "empty" + : RequestDestinationToString(dest); request->SetExtraRequestHeaderByName(kSecFetchDest, header_value, true); }
diff --git a/testing/buildbot/filters/android.emulator_m.content_browsertests.filter b/testing/buildbot/filters/android.emulator_m.content_browsertests.filter index a21ad8f..9bc9a4a 100644 --- a/testing/buildbot/filters/android.emulator_m.content_browsertests.filter +++ b/testing/buildbot/filters/android.emulator_m.content_browsertests.filter
@@ -56,4 +56,4 @@ -RenderFrameHostImplBrowserTest.VisibilityScrolledOutOfView # crbug.com/1120813 --P/CompositorImplBrowserTestRefreshRate.VideoPreference +-P/CompositorImplBrowserTestRefreshRate.VideoPreference/*
diff --git a/third_party/blink/common/BUILD.gn b/third_party/blink/common/BUILD.gn index befabe9f..f52b74a6c 100644 --- a/third_party/blink/common/BUILD.gn +++ b/third_party/blink/common/BUILD.gn
@@ -108,6 +108,7 @@ "loader/mime_sniffing_throttle.cc", "loader/mime_sniffing_url_loader.cc", "loader/network_utils.cc", + "loader/record_load_histograms.cc", "loader/referrer_utils.cc", "loader/resource_type_util.cc", "loader/throttling_url_loader.cc",
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 35268351..959556f4 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -692,6 +692,11 @@ const base::Feature kCrOSAutoSelect{"CrOSAutoSelect", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enables compositing of eligible SVG elements to improve animation +// performance. See crbug.com/1101002. +const base::Feature kCompositeSVG{"CompositeSVG", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kCompositingOptimizations{ "CompositingOptimizations", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/common/net/record_load_histograms.cc b/third_party/blink/common/loader/record_load_histograms.cc similarity index 92% rename from content/common/net/record_load_histograms.cc rename to third_party/blink/common/loader/record_load_histograms.cc index a02b49cf..2823576 100644 --- a/content/common/net/record_load_histograms.cc +++ b/third_party/blink/common/loader/record_load_histograms.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 "content/common/net/record_load_histograms.h" +#include "third_party/blink/public/common/loader/record_load_histograms.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" @@ -11,7 +11,7 @@ #include "net/base/url_util.h" #include "url/gurl.h" -namespace content { +namespace blink { void RecordLoadHistograms(const url::Origin& origin, network::mojom::RequestDestination destination, @@ -40,4 +40,4 @@ } } -} // namespace content +} // namespace blink
diff --git a/third_party/blink/common/loader/referrer_utils.cc b/third_party/blink/common/loader/referrer_utils.cc index c5c7bc8..7b410d9 100644 --- a/third_party/blink/common/loader/referrer_utils.cc +++ b/third_party/blink/common/loader/referrer_utils.cc
@@ -10,6 +10,28 @@ #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/switches.h" +namespace { + +// Using an atomic is necessary because this code is called from both the +// browser and the renderer (so that access is not on a single sequence when in +// single-process mode), and because it is called from multiple threads within +// the renderer. +bool ReadModifyWriteForceLegacyPolicyFlag( + base::Optional<bool> maybe_new_value) { + // Default to false in the browser process (it is not expected + // that the browser will be provided this switch). + // The value is propagated to other processes through the command line. + DCHECK(base::CommandLine::InitializedForCurrentProcess()); + static std::atomic<bool> value( + base::CommandLine::ForCurrentProcess()->HasSwitch( + blink::switches::kForceLegacyDefaultReferrerPolicy)); + if (!maybe_new_value.has_value()) + return value; + return value.exchange(*maybe_new_value); +} + +} // namespace + namespace blink { network::mojom::ReferrerPolicy ReferrerUtils::NetToMojoReferrerPolicy( @@ -48,30 +70,18 @@ if (!base::FeatureList::IsEnabled(features::kReducedReferrerGranularity)) return net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE; - bool should_force_legacy_default_referrer_policy = - ReadModifyWriteForceLegacyPolicyFlag(base::nullopt); - return should_force_legacy_default_referrer_policy + return ShouldForceLegacyDefaultReferrerPolicy() ? net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE : net::ReferrerPolicy:: REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN; } -// Using an atomic is necessary because this code is called from both the -// browser and the renderer (so that access is not on a single sequence when in -// single-process mode), and because it is called from multiple threads within -// the renderer. -bool ReferrerUtils::ReadModifyWriteForceLegacyPolicyFlag( - base::Optional<bool> maybe_new_value) { - // Default to false in the browser process (it is not expected - // that the browser will be provided this switch). - // The value is propagated to other processes through the command line. - DCHECK(base::CommandLine::InitializedForCurrentProcess()); - static std::atomic<bool> value( - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kForceLegacyDefaultReferrerPolicy)); - if (!maybe_new_value.has_value()) - return value; - return value.exchange(*maybe_new_value); +void ReferrerUtils::SetForceLegacyDefaultReferrerPolicy(bool force) { + ReadModifyWriteForceLegacyPolicyFlag(force); +} + +bool ReferrerUtils::ShouldForceLegacyDefaultReferrerPolicy() { + return ReadModifyWriteForceLegacyPolicyFlag(base::nullopt); } } // namespace blink
diff --git a/third_party/blink/common/loader/referrer_utils_unittest.cc b/third_party/blink/common/loader/referrer_utils_unittest.cc index 435ac5d..6d00d76b 100644 --- a/third_party/blink/common/loader/referrer_utils_unittest.cc +++ b/third_party/blink/common/loader/referrer_utils_unittest.cc
@@ -22,4 +22,24 @@ net::ReferrerPolicy::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN); } +TEST(DefaultReferrerPolicyTest, SetAndGetForceLegacy) { + EXPECT_FALSE(blink::ReferrerUtils::ShouldForceLegacyDefaultReferrerPolicy()); + blink::ReferrerUtils::SetForceLegacyDefaultReferrerPolicy(true); + EXPECT_TRUE(blink::ReferrerUtils::ShouldForceLegacyDefaultReferrerPolicy()); +} + +TEST(DefaultReferrerPolicyTest, ForceLegacyOnly) { + blink::ReferrerUtils::SetForceLegacyDefaultReferrerPolicy(true); + EXPECT_EQ(blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), + net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE); +} + +TEST(DefaultReferrerPolicyTest, FeatureAndForceLegacy) { + base::test::ScopedFeatureList f; + f.InitAndEnableFeature(blink::features::kReducedReferrerGranularity); + blink::ReferrerUtils::SetForceLegacyDefaultReferrerPolicy(true); + EXPECT_EQ(blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), + net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE); +} + } // namespace blink
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index d24b32ac..3bbcce1c 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -278,6 +278,7 @@ "platform/websocket_handshake_throttle.h", "web/blink.h", "web/modules/autofill/web_form_element_observer.h", + "web/modules/media/audio/web_audio_output_ipc_factory.h", "web/modules/media/webmediaplayer_util.h", "web/modules/mediastream/encoded_video_frame.h", "web/modules/mediastream/media_stream_video_sink.h",
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn index 56f55a8..4d63d23 100644 --- a/third_party/blink/public/common/BUILD.gn +++ b/third_party/blink/public/common/BUILD.gn
@@ -116,6 +116,7 @@ "loader/mime_sniffing_url_loader.h", "loader/network_utils.h", "loader/previews_state.h", + "loader/record_load_histograms.h", "loader/referrer_utils.h", "loader/resource_type_util.h", "loader/url_loader_factory_bundle.h",
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index edba1c2..19471ff 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -277,6 +277,7 @@ BLINK_COMMON_EXPORT extern const base::Feature kCrOSAutoSelect; +BLINK_COMMON_EXPORT extern const base::Feature kCompositeSVG; BLINK_COMMON_EXPORT extern const base::Feature kCompositingOptimizations; BLINK_COMMON_EXPORT extern const base::Feature kReducedReferrerGranularity;
diff --git a/third_party/blink/public/common/loader/record_load_histograms.h b/third_party/blink/public/common/loader/record_load_histograms.h new file mode 100644 index 0000000..2907426 --- /dev/null +++ b/third_party/blink/public/common/loader/record_load_histograms.h
@@ -0,0 +1,25 @@ +// 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 THIRD_PARTY_BLINK_PUBLIC_COMMON_LOADER_RECORD_LOAD_HISTOGRAMS_H_ +#define THIRD_PARTY_BLINK_PUBLIC_COMMON_LOADER_RECORD_LOAD_HISTOGRAMS_H_ + +#include "services/network/public/mojom/fetch_api.mojom-shared.h" +#include "third_party/blink/public/common/common_export.h" +#include "url/origin.h" + +namespace blink { + +// Logs histograms when a resource destined for a renderer (One with a +// network::mojom::RequestDestination) finishes loading, or when a load is +// aborted. Not used for internal network requests initiated by the browser +// itself. +BLINK_COMMON_EXPORT void RecordLoadHistograms( + const url::Origin& origin, + network::mojom::RequestDestination destination, + int net_error); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_LOADER_RECORD_LOAD_HISTOGRAMS_H_
diff --git a/third_party/blink/public/common/loader/referrer_utils.h b/third_party/blink/public/common/loader/referrer_utils.h index 466255c..0136839ca 100644 --- a/third_party/blink/public/common/loader/referrer_utils.h +++ b/third_party/blink/public/common/loader/referrer_utils.h
@@ -19,8 +19,13 @@ static BLINK_COMMON_EXPORT net::ReferrerPolicy GetDefaultNetReferrerPolicy(); - static BLINK_COMMON_EXPORT bool ReadModifyWriteForceLegacyPolicyFlag( - base::Optional<bool> maybe_new_value); + // Configures retaining the pre-M80 default referrer + // policy of no-referrer-when-downgrade. + // TODO(crbug.com/1016541): After M88, remove when the corresponding + // enterprise policy has been deleted. + static BLINK_COMMON_EXPORT void SetForceLegacyDefaultReferrerPolicy( + bool force); + static BLINK_COMMON_EXPORT bool ShouldForceLegacyDefaultReferrerPolicy(); }; } // namespace blink
diff --git a/third_party/blink/public/mojom/feature_policy/document_policy_feature.mojom b/third_party/blink/public/mojom/feature_policy/document_policy_feature.mojom index 86ee7e7..ed7c671 100644 --- a/third_party/blink/public/mojom/feature_policy/document_policy_feature.mojom +++ b/third_party/blink/public/mojom/feature_policy/document_policy_feature.mojom
@@ -26,6 +26,10 @@ kUnsizedMedia = 7, // Restricts the usage of layout-causing animations in a document. kLayoutAnimations = 8, + // Controls the ability of the document to use several dynamic markup API + // which interfere with document's input stream (document.write(), + // document.close(), etc.). + kDocumentWrite = 9, // Don't change assigned numbers of any item, and don't reuse removed slots. // Add new features at the end of the enum. // Also, run update_document_policy_enum.py in
diff --git a/third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom b/third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom index 4a8a505..f44b30c 100644 --- a/third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom +++ b/third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom
@@ -49,10 +49,6 @@ kPictureInPicture = 26, // Controls the ability to block and interfere with vertical scrolling. kVerticalScroll = 27, - // Controls the ability of the document to use several dynamic markup API - // which interfere with document's input stream (document.write(), - // document.close(), etc.). - kDocumentWrite = 28, // Controls access to Screen Wake Lock kScreenWakeLock = 31, // These are the defined sandbox features implemented as policy-controlled
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index 2811c80..3303e3c 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -253,6 +253,7 @@ BLINK_PLATFORM_EXPORT static void EnableConversionMeasurementInfraSupport( bool); + BLINK_PLATFORM_EXPORT static void EnableCompositeSVG(bool); BLINK_PLATFORM_EXPORT static void EnableCompositingOptimizations(bool); private:
diff --git a/third_party/blink/public/web/modules/media/audio/web_audio_output_ipc_factory.h b/third_party/blink/public/web/modules/media/audio/web_audio_output_ipc_factory.h new file mode 100644 index 0000000..adb61e6 --- /dev/null +++ b/third_party/blink/public/web/modules/media/audio/web_audio_output_ipc_factory.h
@@ -0,0 +1,72 @@ +// 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. + +#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIA_AUDIO_WEB_AUDIO_OUTPUT_IPC_FACTORY_H_ +#define THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIA_AUDIO_WEB_AUDIO_OUTPUT_IPC_FACTORY_H_ + +#include <memory> + +#include "base/memory/scoped_refptr.h" +#include "base/unguessable_token.h" +#include "third_party/blink/public/platform/web_common.h" + +namespace base { +class SingleThreadTaskRunner; +} + +namespace media { +class AudioOutputIPC; +} + +namespace blink { +class BrowserInterfaceBrokerProxy; + +// This is a factory for AudioOutputIPC objects. It is threadsafe. This class +// is designed to be leaked at shutdown, as it posts tasks to itself using +// base::Unretained and also hands out references to itself in the +// AudioOutputIPCs it creates, but in the case where the owner is sure that +// there are no outstanding references (such as in a unit test), the class can +// be destructed. +// TODO(maxmorin): Registering the factories for each frame will become +// unnecessary when https://crbug.com/668275 is fixed. When that is done, this +// class can be greatly simplified. +class BLINK_MODULES_EXPORT WebAudioOutputIPCFactory { + public: + explicit WebAudioOutputIPCFactory( + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner); + ~WebAudioOutputIPCFactory(); + + static WebAudioOutputIPCFactory* get() { return instance_; } + + const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner() const; + + // Enables |this| to create MojoAudioOutputIPCs for the specified frame. + // Does nothing if not using mojo factories. + void RegisterRemoteFactory( + const base::UnguessableToken& frame_token, + blink::BrowserInterfaceBrokerProxy* interface_broker); + + // Every call to the above method must be matched by a call to this one when + // the frame is destroyed. Does nothing if not using mojo factories. + void MaybeDeregisterRemoteFactory(const base::UnguessableToken& frame_token); + + // The returned object may only be used on |io_task_runner()|. + std::unique_ptr<media::AudioOutputIPC> CreateAudioOutputIPC( + const base::UnguessableToken& frame_token) const; + + private: + // TODO(https://crbug.com/787252): When this header gets moved out of the + // Blink public API layer, move this Pimpl class back to its outer class. + class Impl; + std::unique_ptr<Impl> impl_; + + // Global instance, set in constructor and unset in destructor. + static WebAudioOutputIPCFactory* instance_; + + DISALLOW_COPY_AND_ASSIGN(WebAudioOutputIPCFactory); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIA_AUDIO_WEB_AUDIO_OUTPUT_IPC_FACTORY_H_
diff --git a/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt b/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt index fff0e107..55eca856 100644 --- a/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt +++ b/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt
@@ -77,6 +77,7 @@ LogActivity=|GetterOnly|SetterOnly LogAllWorlds NewObject +NoAllocDirectCall Measure MeasureAs=* NamedConstructor=*
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.cc b/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.cc index 0e69088..05457977 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.cc
@@ -463,7 +463,8 @@ v8::Local<v8::FunctionTemplate> interface_template, v8::Local<v8::Signature> signature, const Configuration& method, - const DOMWrapperWorld& world) { + const DOMWrapperWorld& world, + const v8::CFunction* v8_c_function = nullptr) { if (!WorldConfigurationApplies(method, world)) return; @@ -488,7 +489,7 @@ v8::Local<v8::FunctionTemplate> function_template = v8::FunctionTemplate::New( isolate, callback, v8::Local<v8::Value>(), signature, method.length, - v8::ConstructorBehavior::kAllow, side_effect_type); + v8::ConstructorBehavior::kAllow, side_effect_type, v8_c_function); function_template->RemovePrototype(); function_template->SetAcceptAnyReceiver( method.access_check_configuration == @@ -792,6 +793,22 @@ interface_template, signature, methods[i], world); } +void V8DOMConfiguration::InstallMethods( + v8::Isolate* isolate, + const DOMWrapperWorld& world, + v8::Local<v8::ObjectTemplate> instance_template, + v8::Local<v8::ObjectTemplate> prototype_template, + v8::Local<v8::FunctionTemplate> interface_template, + v8::Local<v8::Signature> signature, + const NoAllocDirectCallMethodConfiguration* methods, + size_t method_count) { + for (size_t i = 0; i < method_count; ++i) { + InstallMethodInternal( + isolate, instance_template, prototype_template, interface_template, + signature, methods[i].method_config, world, &methods[i].v8_c_function); + } +} + void V8DOMConfiguration::InstallMethod( v8::Isolate* isolate, const DOMWrapperWorld& world,
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h b/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h index 5bceb00..a88efd6 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h +++ b/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h
@@ -34,6 +34,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h" #include "third_party/blink/renderer/platform/bindings/v8_private_property.h" +#include "v8/include/v8-fast-api-calls.h" #include "v8/include/v8.h" namespace blink { @@ -89,9 +90,12 @@ // AttributeConfiguration translates into calls to SetNativeDataProperty() on // either of instance or prototype object (or their object template). struct AttributeConfiguration { - AttributeConfiguration& operator=(const AttributeConfiguration&) = delete; DISALLOW_NEW(); - const char* const name; + + public: + AttributeConfiguration& operator=(const AttributeConfiguration&) = delete; + + const char* name; v8::AccessorNameGetterCallback getter; v8::AccessorNameSetterCallback setter; @@ -140,9 +144,12 @@ // either of instance, prototype, or interface object (or their object // template). struct AccessorConfiguration { - AccessorConfiguration& operator=(const AccessorConfiguration&) = delete; DISALLOW_NEW(); - const char* const name; + + public: + AccessorConfiguration& operator=(const AccessorConfiguration&) = delete; + + const char* name; v8::FunctionCallback getter; v8::FunctionCallback setter; // V8PrivateProperty::CachedAccessor @@ -211,6 +218,9 @@ // object's constants. It sets the constant on both the FunctionTemplate and // the ObjectTemplate. PropertyAttributes is always ReadOnly. struct ConstantConfiguration { + DISALLOW_NEW(); + + public: constexpr ConstantConfiguration(const char* name, ConstantType type, int value) @@ -220,8 +230,8 @@ double value) : name(name), type(type), dvalue(value) {} ConstantConfiguration& operator=(const ConstantConfiguration&) = delete; - DISALLOW_NEW(); - const char* const name; + + const char* name; ConstantType type; union { int ivalue; @@ -243,8 +253,8 @@ ConstantCallbackConfiguration& operator=( const ConstantCallbackConfiguration&) = delete; - const char* const name; - const v8::AccessorNameGetterCallback getter; + const char* name; + v8::AccessorNameGetterCallback getter; }; // Constant installation @@ -296,13 +306,16 @@ // object's callbacks. It sets a method on instance, prototype or // interface object (or their object tepmplate). struct MethodConfiguration { - MethodConfiguration& operator=(const MethodConfiguration&) = delete; DISALLOW_NEW(); + + public: + MethodConfiguration& operator=(const MethodConfiguration&) = delete; + v8::Local<v8::String> MethodName(v8::Isolate* isolate) const { return V8AtomicString(isolate, name); } - const char* const name; + const char* name; v8::FunctionCallback callback; int length; // v8::PropertyAttribute @@ -320,15 +333,18 @@ }; struct SymbolKeyedMethodConfiguration { + DISALLOW_NEW(); + + public: SymbolKeyedMethodConfiguration& operator=( const SymbolKeyedMethodConfiguration&) = delete; - DISALLOW_NEW(); + v8::Local<v8::Name> MethodName(v8::Isolate* isolate) const { return get_symbol(isolate); } v8::Local<v8::Symbol> (*get_symbol)(v8::Isolate*); - const char* const symbol_alias; + const char* symbol_alias; v8::FunctionCallback callback; // SymbolKeyedMethodConfiguration doesn't support per-world bindings. int length; @@ -344,6 +360,17 @@ unsigned side_effect_type : 1; }; + struct NoAllocDirectCallMethodConfiguration { + DISALLOW_NEW(); + + public: + NoAllocDirectCallMethodConfiguration& operator=( + const NoAllocDirectCallMethodConfiguration&) = delete; + + MethodConfiguration method_config; + v8::CFunction v8_c_function; + }; + static void InstallMethods(v8::Isolate*, const DOMWrapperWorld&, v8::Local<v8::ObjectTemplate> instance_template, @@ -352,6 +379,15 @@ v8::Local<v8::Signature>, const MethodConfiguration*, size_t method_count); + static void InstallMethods(v8::Isolate*, + const DOMWrapperWorld&, + v8::Local<v8::ObjectTemplate> instance_template, + v8::Local<v8::ObjectTemplate> prototype_template, + v8::Local<v8::FunctionTemplate> interface_template, + v8::Local<v8::Signature>, + const NoAllocDirectCallMethodConfiguration*, + size_t method_count); + static void InstallMethod(v8::Isolate*, const DOMWrapperWorld&, v8::Local<v8::ObjectTemplate> instance_template,
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni index a8dbc80..ff90454 100644 --- a/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -788,6 +788,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client_type.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_color_gamut.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_color_gamut.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_codec_state.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_codec_state.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_connection_type.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_connection_type.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_contact_property.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni index 2b6010d..d3d26144 100644 --- a/third_party/blink/renderer/bindings/idl_in_modules.gni +++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -736,6 +736,7 @@ "//third_party/blink/renderer/modules/webcodecs/audio_frame.idl", "//third_party/blink/renderer/modules/webcodecs/audio_frame_init.idl", "//third_party/blink/renderer/modules/webcodecs/audio_frame_output_callback.idl", + "//third_party/blink/renderer/modules/webcodecs/codec_state.idl", "//third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk.idl", "//third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk_init.idl", "//third_party/blink/renderer/modules/webcodecs/encoded_audio_config.idl",
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py index 4ccb29a..587ec371 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
@@ -95,7 +95,8 @@ def callback_function_name(cg_context, overload_index=None, - for_cross_origin=False): + for_cross_origin=False, + no_alloc_direct_call=False): assert isinstance(cg_context, CodeGenContext) def _cxx_name(name): @@ -150,6 +151,8 @@ suffix = "CrossOrigin" elif overload_index is not None: suffix = "Overload{}".format(overload_index + 1) + elif no_alloc_direct_call: + suffix = "NoAllocDirectCallback" else: suffix = "Callback" @@ -2114,6 +2117,54 @@ return SequenceNode([named_ctor_def, EmptyNode(), func_def]) +def make_no_alloc_direct_call_callback_def(cg_context, function_name): + assert isinstance(cg_context, CodeGenContext) + assert isinstance(function_name, str) + + assert cg_context.operation_group and len(cg_context.operation_group) == 1 + + func_like = cg_context.operation_group[0] + + return_type = ("void" if func_like.return_type.is_void else + blink_type_info(func_like.return_type).value_t) + arg_type_and_names = [(blink_type_info(arg.idl_type).value_t, + name_style.arg_f("arg{}_{}", index + 1, + arg.identifier)) + for index, arg in enumerate(func_like.arguments)] + arg_decls = ["v8::ApiObject arg0_receiver"] + [ + "{} {}".format(arg_type, arg_name) + for arg_type, arg_name in arg_type_and_names + ] + func_def = CxxFuncDefNode(name=function_name, + arg_decls=arg_decls, + return_type=return_type) + body = func_def.body + + pattern = """\ +ThreadState::NoAllocationScope no_alloc_scope(ThreadState::Current()); +v8::Object* v8_receiver = reinterpret_cast<v8::Object*>(&arg0_receiver); +v8::Isolate* isolate = v8_receiver->GetIsolate(); +v8::Isolate::DisallowJavascriptExecutionScope no_js_exec_scope( + isolate, + v8::Isolate::DisallowJavascriptExecutionScope::CRASH_ON_FAILURE); +{blink_class}* blink_receiver = + ToScriptWrappable(v8_receiver)->ToImpl<{blink_class}>(); +return blink_receiver->{member_func}({blink_arguments});\ +""" + blink_class = blink_class_name(cg_context.interface) + member_func = backward_compatible_api_func(cg_context) + blink_arguments = ", ".join( + [arg_name for arg_type, arg_name in arg_type_and_names]) + body.append( + TextNode( + _format(pattern, + blink_class=blink_class, + member_func=member_func, + blink_arguments=blink_arguments))) + + return func_def + + def make_operation_entry(cg_context): assert isinstance(cg_context, CodeGenContext) @@ -2163,7 +2214,9 @@ return func_def -def make_operation_callback_def(cg_context, function_name): +def make_operation_callback_def(cg_context, + function_name, + no_alloc_direct_callback_name=None): assert isinstance(cg_context, CodeGenContext) assert isinstance(function_name, str) @@ -2171,6 +2224,19 @@ assert (not ("Custom" in operation_group.extended_attributes) or len(operation_group) == 1) + assert (not ("NoAllocDirectCall" in operation_group.extended_attributes) + or len(operation_group) == 1) + + if "NoAllocDirectCall" in operation_group.extended_attributes: + return ListNode([ + make_operation_function_def( + cg_context.make_copy(operation=operation_group[0]), + function_name), + EmptyNode(), + make_no_alloc_direct_call_callback_def( + cg_context.make_copy(operation=operation_group[0]), + no_alloc_direct_callback_name), + ]) if len(operation_group) == 1: return make_operation_function_def( @@ -4278,49 +4344,6 @@ return "V8PrivateProperty::CachedAccessor::{}".format(value or "kNone") -def _make_property_entry_v8_property_attribute(property_): - values = [] - if "NotEnumerable" in property_.extended_attributes: - values.append("v8::DontEnum") - if "LegacyUnforgeable" in property_.extended_attributes: - if not isinstance(property_, web_idl.Attribute): - values.append("v8::ReadOnly") - values.append("v8::DontDelete") - if not values: - values.append("v8::None") - if len(values) == 1: - return values[0] - else: - return "static_cast<v8::PropertyAttribute>({})".format( - " | ".join(values)) - - -def _make_property_entry_on_which_object(property_): - ON_INSTANCE = "V8DOMConfiguration::kOnInstance" - ON_PROTOTYPE = "V8DOMConfiguration::kOnPrototype" - ON_INTERFACE = "V8DOMConfiguration::kOnInterface" - if isinstance(property_, web_idl.Constant): - return ON_INTERFACE - if hasattr(property_, "is_static") and property_.is_static: - return ON_INTERFACE - if "Global" in property_.owner.extended_attributes: - return ON_INSTANCE - if "LegacyUnforgeable" in property_.extended_attributes: - return ON_INSTANCE - return ON_PROTOTYPE - - -def _make_property_entry_check_receiver(property_): - if ("LenientThis" in property_.extended_attributes - or (isinstance(property_, web_idl.Attribute) - and property_.idl_type.unwrap().is_promise) - or (isinstance(property_, web_idl.OverloadGroup) - and property_[0].return_type.unwrap().is_promise)): - return "V8DOMConfiguration::kDoNotCheckHolder" - else: - return "V8DOMConfiguration::kCheckHolder" - - def _make_property_entry_check_cross_origin_access(property_, is_get=False, is_set=False): @@ -4339,21 +4362,15 @@ return constants[True] -def _make_property_entry_has_side_effect(property_): - if property_.extended_attributes.value_of("Affects") == "Nothing": - return "V8DOMConfiguration::kHasNoSideEffect" +def _make_property_entry_check_receiver(property_): + if ("LenientThis" in property_.extended_attributes + or (isinstance(property_, web_idl.Attribute) + and property_.idl_type.unwrap().is_promise) + or (isinstance(property_, web_idl.OverloadGroup) + and property_[0].return_type.unwrap().is_promise)): + return "V8DOMConfiguration::kDoNotCheckHolder" else: - return "V8DOMConfiguration::kHasSideEffect" - - -def _make_property_entry_world(world): - if world == CodeGenContext.MAIN_WORLD: - return "V8DOMConfiguration::kMainWorld" - if world == CodeGenContext.NON_MAIN_WORLDS: - return "V8DOMConfiguration::kNonMainWorlds" - if world == CodeGenContext.ALL_WORLDS: - return "V8DOMConfiguration::kAllWorlds" - assert False + return "V8DOMConfiguration::kCheckHolder" def _make_property_entry_constant_type_and_value_format(property_): @@ -4373,6 +4390,62 @@ assert False, "Unsupported type: {}".format(idl_type.syntactic_form) +def _make_property_entry_has_side_effect(property_): + if property_.extended_attributes.value_of("Affects") == "Nothing": + return "V8DOMConfiguration::kHasNoSideEffect" + else: + return "V8DOMConfiguration::kHasSideEffect" + + +def _make_property_entry_on_which_object(property_): + ON_INSTANCE = "V8DOMConfiguration::kOnInstance" + ON_PROTOTYPE = "V8DOMConfiguration::kOnPrototype" + ON_INTERFACE = "V8DOMConfiguration::kOnInterface" + if isinstance(property_, web_idl.Constant): + return ON_INTERFACE + if hasattr(property_, "is_static") and property_.is_static: + return ON_INTERFACE + if "Global" in property_.owner.extended_attributes: + return ON_INSTANCE + if "LegacyUnforgeable" in property_.extended_attributes: + return ON_INSTANCE + return ON_PROTOTYPE + + +def _make_property_entry_v8_c_function(entry): + if entry.no_alloc_direct_callback_name is None: + return None + return "v8::CFunction::Make({})".format( + entry.no_alloc_direct_callback_name) + + +def _make_property_entry_v8_property_attribute(property_): + values = [] + if "NotEnumerable" in property_.extended_attributes: + values.append("v8::DontEnum") + if "LegacyUnforgeable" in property_.extended_attributes: + if not isinstance(property_, web_idl.Attribute): + values.append("v8::ReadOnly") + values.append("v8::DontDelete") + if not values: + values.append("v8::None") + if len(values) == 1: + return values[0] + else: + return "static_cast<v8::PropertyAttribute>({})".format( + " | ".join(values)) + + +def _make_property_entry_world(world): + if world == CodeGenContext.MAIN_WORLD: + return "V8DOMConfiguration::kMainWorld" + if world == CodeGenContext.NON_MAIN_WORLDS: + return "V8DOMConfiguration::kNonMainWorlds" + if world == CodeGenContext.ALL_WORLDS: + return "V8DOMConfiguration::kAllWorlds" + assert False + + def _make_attribute_registration_table(table_name, attribute_entries): assert isinstance(table_name, str) assert isinstance(attribute_entries, (list, tuple)) @@ -4421,7 +4494,7 @@ entry_nodes.append(T(text)) return ListNode([ - T("static constexpr V8DOMConfiguration::AccessorConfiguration " + + T("static constexpr const V8DOMConfiguration::AccessorConfiguration " + table_name + "[] = {"), ListNode(entry_nodes), T("};"), @@ -4448,8 +4521,9 @@ entry_nodes.append(T(text)) return ListNode([ - T("static constexpr V8DOMConfiguration::ConstantCallbackConfiguration " - + table_name + "[] = {"), + T("static constexpr const " + "V8DOMConfiguration::ConstantCallbackConfiguration " + table_name + + "[] = {"), ListNode(entry_nodes), T("};"), ]) @@ -4484,7 +4558,7 @@ entry_nodes.append(T(text)) return ListNode([ - T("static constexpr V8DOMConfiguration::ConstantConfiguration " + + T("static constexpr const V8DOMConfiguration::ConstantConfiguration " + table_name + "[] = {"), ListNode(entry_nodes), T("};"), @@ -4522,8 +4596,8 @@ entry_nodes.append(T(text)) return ListNode([ - T("static constexpr V8DOMConfiguration::AttributeConfiguration " + - table_name + "[] = {"), + T("static constexpr const V8DOMConfiguration::AttributeConfiguration " + + table_name + "[] = {"), ListNode(entry_nodes), T("};"), ]) @@ -4538,6 +4612,14 @@ T = TextNode + no_alloc_direct_call_count = 0 + for entry in operation_entries: + if entry.no_alloc_direct_callback_name: + no_alloc_direct_call_count += 1 + assert (no_alloc_direct_call_count == 0 + or no_alloc_direct_call_count == len(operation_entries)) + no_alloc_direct_call_enabled = no_alloc_direct_call_count > 0 + entry_nodes = [] for entry in operation_entries: pattern = ("{{" @@ -4551,6 +4633,8 @@ "{has_side_effect}, " "{world}" "}}, ") + if no_alloc_direct_call_enabled: + pattern = "{{" + pattern + "{v8_c_function}}}, " text = _format( pattern, property_name=entry.property_.identifier, @@ -4567,12 +4651,17 @@ entry.property_)), has_side_effect=_make_property_entry_has_side_effect( entry.property_), - world=_make_property_entry_world(entry.world)) + world=_make_property_entry_world(entry.world), + v8_c_function=_make_property_entry_v8_c_function(entry)) entry_nodes.append(T(text)) + table_decl_before_name = ( + "static constexpr const V8DOMConfiguration::MethodConfiguration") + if no_alloc_direct_call_enabled: + table_decl_before_name = ("static const V8DOMConfiguration::" + "NoAllocDirectCallMethodConfiguration") return ListNode([ - T("static constexpr V8DOMConfiguration::MethodConfiguration " + - table_name + "[] = {"), + T(table_decl_before_name + " " + table_name + "[] = {"), ListNode(entry_nodes), T("};"), ]) @@ -4637,8 +4726,14 @@ class _PropEntryOperationGroup(_PropEntryBase): - def __init__(self, is_context_dependent, exposure_conditional, world, - operation_group, op_callback_name, op_func_length): + def __init__(self, + is_context_dependent, + exposure_conditional, + world, + operation_group, + op_callback_name, + op_func_length, + no_alloc_direct_callback_name=None): assert isinstance(op_callback_name, str) assert isinstance(op_func_length, (int, long)) @@ -4646,6 +4741,7 @@ exposure_conditional, world, operation_group) self.op_callback_name = op_callback_name self.op_func_length = op_func_length + self.no_alloc_direct_callback_name = no_alloc_direct_callback_name def _make_property_entries_and_callback_defs( @@ -4839,7 +4935,14 @@ cgc = cg_context.make_copy( operation_group=operation_group, for_world=world) op_callback_name = callback_function_name(cgc) - op_callback_node = make_operation_callback_def(cgc, op_callback_name) + no_alloc_direct_callback_name = ( + callback_function_name(cgc, no_alloc_direct_call=True) + if "NoAllocDirectCall" in operation_group.extended_attributes else + None) + op_callback_node = make_operation_callback_def( + cgc, + op_callback_name, + no_alloc_direct_callback_name=no_alloc_direct_callback_name) callback_def_nodes.extend([ op_callback_node, @@ -4853,7 +4956,8 @@ world=world, operation_group=operation_group, op_callback_name=op_callback_name, - op_func_length=operation_group.min_num_of_required_arguments)) + op_func_length=operation_group.min_num_of_required_arguments, + no_alloc_direct_callback_name=no_alloc_direct_callback_name)) def process_stringifier(_, is_context_dependent, exposure_conditional, world): @@ -5538,8 +5642,14 @@ "${instance_template}, ${prototype_template}, " "${interface_template}, ${signature}, " "kOperationTable, base::size(kOperationTable));") - install_properties(table_name, operation_entries, - _make_operation_registration_table, installer_call_text) + entries = filter(lambda entry: not entry.no_alloc_direct_callback_name, + operation_entries) + install_properties(table_name, entries, _make_operation_registration_table, + installer_call_text) + entries = filter(lambda entry: entry.no_alloc_direct_callback_name, + operation_entries) + install_properties(table_name, entries, _make_operation_registration_table, + installer_call_text) return func_decl, func_def, trampoline_def
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py b/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py index 63bc83f..d0d10a5 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py
@@ -518,8 +518,8 @@ def _propagate_extattrs_to_overload_group(self): ANY_OF = ('CrossOrigin', 'Custom', 'LegacyUnforgeable', 'LenientThis', - 'NotEnumerable', 'PerWorldBindings', 'SecureContext', - 'Unscopable') + 'NoAllocDirectCall', 'NotEnumerable', 'PerWorldBindings', + 'SecureContext', 'Unscopable') old_irs = self._ir_map.irs_of_kinds(IRMap.IR.Kind.INTERFACE, IRMap.IR.Kind.NAMESPACE)
diff --git a/third_party/blink/renderer/core/animation/BUILD.gn b/third_party/blink/renderer/core/animation/BUILD.gn index ed10902..a06ec21 100644 --- a/third_party/blink/renderer/core/animation/BUILD.gn +++ b/third_party/blink/renderer/core/animation/BUILD.gn
@@ -60,6 +60,8 @@ "css/css_animations.h", "css/css_keyframe_effect_model.cc", "css/css_keyframe_effect_model.h", + "css/css_scroll_timeline.cc", + "css/css_scroll_timeline.h", "css/css_timing_data.cc", "css/css_timing_data.h", "css/css_transition.cc",
diff --git a/third_party/blink/renderer/core/animation/animation_timeline.h b/third_party/blink/renderer/core/animation/animation_timeline.h index 2d68a4a..a86e00e 100644 --- a/third_party/blink/renderer/core/animation/animation_timeline.h +++ b/third_party/blink/renderer/core/animation/animation_timeline.h
@@ -42,6 +42,7 @@ virtual bool IsDocumentTimeline() const { return false; } virtual bool IsScrollTimeline() const { return false; } + virtual bool IsCSSScrollTimeline() const { return false; } virtual bool IsActive() const = 0; virtual double ZeroTimeInSeconds() = 0; // https://drafts.csswg.org/web-animations/#monotonically-increasing-timeline
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc index dd84051..559fe98 100644 --- a/third_party/blink/renderer/core/animation/css/css_animations.cc +++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -40,6 +40,7 @@ #include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.h" #include "third_party/blink/renderer/core/animation/css/css_animation.h" #include "third_party/blink/renderer/core/animation/css/css_keyframe_effect_model.h" +#include "third_party/blink/renderer/core/animation/css/css_scroll_timeline.h" #include "third_party/blink/renderer/core/animation/css/css_transition.h" #include "third_party/blink/renderer/core/animation/css_interpolation_types_map.h" #include "third_party/blink/renderer/core/animation/document_animations.h" @@ -51,13 +52,10 @@ #include "third_party/blink/renderer/core/animation/interpolation_type.h" #include "third_party/blink/renderer/core/animation/keyframe_effect.h" #include "third_party/blink/renderer/core/animation/keyframe_effect_model.h" -#include "third_party/blink/renderer/core/animation/scroll_timeline.h" #include "third_party/blink/renderer/core/animation/scroll_timeline_offset.h" #include "third_party/blink/renderer/core/animation/timing_calculations.h" #include "third_party/blink/renderer/core/animation/transition_interpolation.h" #include "third_party/blink/renderer/core/animation/worklet_animation_base.h" -#include "third_party/blink/renderer/core/css/css_id_selector_value.h" -#include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_keyframe_rule.h" #include "third_party/blink/renderer/core/css/css_property_equality.h" #include "third_party/blink/renderer/core/css/css_value_list.h" @@ -428,109 +426,15 @@ return iteration_duration * (iteration_boundary - iteration_start); } -bool IsIdentifier(const CSSValue* value, CSSValueID value_id) { - if (const auto* ident = DynamicTo<CSSIdentifierValue>(value)) - return ident->GetValueID() == value_id; - return false; -} - -bool IsAuto(const CSSValue* value) { - return IsIdentifier(value, CSSValueID::kAuto); -} - -bool IsNone(const CSSValue* value) { - return IsIdentifier(value, CSSValueID::kNone); -} - -const cssvalue::CSSIdSelectorValue* GetIdSelectorValue(const CSSValue* value) { - if (const auto* selector = DynamicTo<CSSFunctionValue>(value)) { - if (selector->FunctionType() != CSSValueID::kSelector) - return nullptr; - DCHECK_EQ(selector->length(), 1u); - return DynamicTo<cssvalue::CSSIdSelectorValue>(selector->Item(0)); - } - return nullptr; -} - -Element* ComputeScrollSource(Element* element, const CSSValue* value) { - if (const auto* id = GetIdSelectorValue(value)) - return element->GetDocument().getElementById(id->Id()); - if (IsNone(value)) - return nullptr; - DCHECK(!value || IsAuto(value)); - return element->GetDocument().scrollingElement(); -} - -ScrollTimeline::ScrollDirection ComputeScrollDirection(const CSSValue* value) { - CSSValueID value_id = CSSValueID::kAuto; - - if (const auto* identifier = DynamicTo<CSSIdentifierValue>(value)) - value_id = identifier->GetValueID(); - - switch (value_id) { - case CSSValueID::kInline: - return ScrollTimeline::Inline; - case CSSValueID::kHorizontal: - return ScrollTimeline::Horizontal; - case CSSValueID::kVertical: - return ScrollTimeline::Vertical; - case CSSValueID::kAuto: - case CSSValueID::kBlock: - default: - return ScrollTimeline::Block; - } -} - -ScrollTimelineOffset* ComputeScrollOffset(const CSSValue* value) { - if (auto* primitive_value = DynamicTo<CSSPrimitiveValue>(value)) - return MakeGarbageCollected<ScrollTimelineOffset>(primitive_value); - DCHECK(!value || IsAuto(value)); - return MakeGarbageCollected<ScrollTimelineOffset>(); -} - -HeapVector<Member<ScrollTimelineOffset>>* ComputeScrollOffsets( - const CSSValue* start, - const CSSValue* end) { - auto* offsets = - MakeGarbageCollected<HeapVector<Member<ScrollTimelineOffset>>>(); - offsets->push_back(ComputeScrollOffset(start)); - offsets->push_back(ComputeScrollOffset(end)); - return offsets; -} - -base::Optional<double> ComputeTimeRange(const CSSValue* value) { - if (auto* primitive = DynamicTo<CSSPrimitiveValue>(value)) - return primitive->ComputeSeconds() * 1000.0; - // TODO(crbug.com/1097041): Support 'auto' value. - return base::nullopt; -} - -struct CSSScrollTimelineOptions { - STACK_ALLOCATED(); - - public: - CSSScrollTimelineOptions(Element* element, StyleRuleScrollTimeline& rule) - : source(ComputeScrollSource(element, rule.GetSource())), - direction(ComputeScrollDirection(rule.GetOrientation())), - offsets(ComputeScrollOffsets(rule.GetStart(), rule.GetEnd())), - time_range(ComputeTimeRange(rule.GetTimeRange())) {} - - Element* source; - ScrollTimeline::ScrollDirection direction; - HeapVector<Member<ScrollTimelineOffset>>* offsets; - base::Optional<double> time_range; -}; - -ScrollTimeline* CreateScrollTimeline(Element* element, - StyleRuleScrollTimeline* rule) { +CSSScrollTimeline* CreateCSSScrollTimeline(Element* element, + StyleRuleScrollTimeline* rule) { if (!rule) return nullptr; - CSSScrollTimelineOptions options(element, *rule); - if (!options.time_range) + CSSScrollTimeline::Options options(element, *rule); + if (!options.IsValid()) return nullptr; - auto* scroll_timeline = MakeGarbageCollected<ScrollTimeline>( - &element->GetDocument(), options.source, options.direction, - options.offsets, *options.time_range); + auto* scroll_timeline = + MakeGarbageCollected<CSSScrollTimeline>(&element->GetDocument(), options); // It's is not allowed for a style resolve to create timelines that // needs timing updates (i.e. AnimationTimeline::NeedsAnimationTimingUpdate() // must return false). Servicing animations after creation preserves this @@ -541,12 +445,28 @@ } AnimationTimeline* ComputeTimeline(Element* element, + const StyleNameOrKeyword& timeline_name, StyleRuleScrollTimeline* rule) { + if (timeline_name.IsKeyword()) { + if (timeline_name.GetKeyword() == CSSValueID::kAuto) + return &element->GetDocument().Timeline(); + DCHECK_EQ(timeline_name.GetKeyword(), CSSValueID::kNone); + return nullptr; + } if (rule) { - if (auto* timeline = CreateScrollTimeline(element, rule)) + if (auto* timeline = CreateCSSScrollTimeline(element, rule)) return timeline; } - return &element->GetDocument().Timeline(); + return nullptr; +} + +StyleRuleScrollTimeline* FindScrollTimelineRule( + Document& document, + const StyleNameOrKeyword& timeline_name) { + if (timeline_name.IsKeyword()) + return nullptr; + return document.GetStyleEngine().FindScrollTimelineRule( + timeline_name.GetName().GetValue()); } } // namespace @@ -695,17 +615,11 @@ const StyleNameOrKeyword& timeline_name = animation_data->GetTimeline(i); - StyleRuleScrollTimeline* scroll_timeline_rule = nullptr; - - // TODO(crbug.com/1097046): Support 'none' keyword. - if (!timeline_name.IsKeyword()) { - scroll_timeline_rule = - element.GetDocument().GetStyleEngine().FindScrollTimelineRule( - timeline_name.GetName().GetValue()); - } + StyleRuleScrollTimeline* scroll_timeline_rule = + FindScrollTimelineRule(element.GetDocument(), timeline_name); AnimationTimeline* timeline = - ComputeTimeline(&element, scroll_timeline_rule); + ComputeTimeline(&element, timeline_name, scroll_timeline_rule); const RunningAnimation* existing_animation = nullptr; wtf_size_t existing_animation_index = 0; @@ -769,10 +683,14 @@ } else { DCHECK(!is_animation_style_change); base::Optional<TimelinePhase> inherited_phase; - base::Optional<double> inherited_time = 0; - if (timeline && timeline->IsScrollTimeline()) { - inherited_phase = base::make_optional(timeline->Phase()); - inherited_time = timeline->CurrentTimeSeconds(); + base::Optional<double> inherited_time; + if (timeline) { + if (timeline->IsMonotonicallyIncreasing()) { + inherited_time = 0; + } else { + inherited_phase = base::make_optional(timeline->Phase()); + inherited_time = timeline->CurrentTimeSeconds(); + } } update.StartAnimation( name, name_index, i, @@ -921,15 +839,9 @@ auto* effect = MakeGarbageCollected<KeyframeEffect>( element, inert_animation->Model(), inert_animation->SpecifiedTiming(), KeyframeEffect::kDefaultPriority, event_delegate); - - AnimationTimeline* timeline = entry.timeline; - // We always fall back to the DocumentTimeline at the moment, so the - // timeline can't be nullptr here. - // TODO(crbug.com/1097046): Support animation-timeline:none - DCHECK(timeline); auto* animation = MakeGarbageCollected<CSSAnimation>( - element->GetExecutionContext(), timeline, effect, entry.position_index, - entry.name); + element->GetExecutionContext(), entry.timeline, effect, + entry.position_index, entry.name); animation->play(); if (inert_animation->Paused()) animation->pause();
diff --git a/third_party/blink/renderer/core/animation/css/css_scroll_timeline.cc b/third_party/blink/renderer/core/animation/css/css_scroll_timeline.cc new file mode 100644 index 0000000..83e50cc --- /dev/null +++ b/third_party/blink/renderer/core/animation/css/css_scroll_timeline.cc
@@ -0,0 +1,113 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/animation/css/css_scroll_timeline.h" + +#include "third_party/blink/renderer/core/css/css_id_selector_value.h" +#include "third_party/blink/renderer/core/css/css_identifier_value.h" +#include "third_party/blink/renderer/core/css/css_value_list.h" +#include "third_party/blink/renderer/core/css/style_rule.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/element.h" + +namespace blink { + +namespace { + +bool IsIdentifier(const CSSValue* value, CSSValueID value_id) { + if (const auto* ident = DynamicTo<CSSIdentifierValue>(value)) + return ident->GetValueID() == value_id; + return false; +} + +bool IsAuto(const CSSValue* value) { + return IsIdentifier(value, CSSValueID::kAuto); +} + +bool IsNone(const CSSValue* value) { + return IsIdentifier(value, CSSValueID::kNone); +} + +const cssvalue::CSSIdSelectorValue* GetIdSelectorValue(const CSSValue* value) { + if (const auto* selector = DynamicTo<CSSFunctionValue>(value)) { + if (selector->FunctionType() != CSSValueID::kSelector) + return nullptr; + DCHECK_EQ(selector->length(), 1u); + return DynamicTo<cssvalue::CSSIdSelectorValue>(selector->Item(0)); + } + return nullptr; +} + +Element* ComputeScrollSource(Element* element, const CSSValue* value) { + if (const auto* id = GetIdSelectorValue(value)) + return element->GetDocument().getElementById(id->Id()); + if (IsNone(value)) + return nullptr; + DCHECK(!value || IsAuto(value)); + return element->GetDocument().scrollingElement(); +} + +ScrollTimeline::ScrollDirection ComputeScrollDirection(const CSSValue* value) { + CSSValueID value_id = CSSValueID::kAuto; + + if (const auto* identifier = DynamicTo<CSSIdentifierValue>(value)) + value_id = identifier->GetValueID(); + + switch (value_id) { + case CSSValueID::kInline: + return ScrollTimeline::Inline; + case CSSValueID::kHorizontal: + return ScrollTimeline::Horizontal; + case CSSValueID::kVertical: + return ScrollTimeline::Vertical; + case CSSValueID::kAuto: + case CSSValueID::kBlock: + default: + return ScrollTimeline::Block; + } +} + +ScrollTimelineOffset* ComputeScrollOffset(const CSSValue* value) { + if (auto* primitive_value = DynamicTo<CSSPrimitiveValue>(value)) + return MakeGarbageCollected<ScrollTimelineOffset>(primitive_value); + DCHECK(!value || IsAuto(value)); + return MakeGarbageCollected<ScrollTimelineOffset>(); +} + +HeapVector<Member<ScrollTimelineOffset>>* ComputeScrollOffsets( + const CSSValue* start, + const CSSValue* end) { + auto* offsets = + MakeGarbageCollected<HeapVector<Member<ScrollTimelineOffset>>>(); + offsets->push_back(ComputeScrollOffset(start)); + offsets->push_back(ComputeScrollOffset(end)); + return offsets; +} + +base::Optional<double> ComputeTimeRange(const CSSValue* value) { + if (auto* primitive = DynamicTo<CSSPrimitiveValue>(value)) + return primitive->ComputeSeconds() * 1000.0; + // TODO(crbug.com/1097041): Support 'auto' value. + return base::nullopt; +} + +} // anonymous namespace + +CSSScrollTimeline::Options::Options(Element* element, + StyleRuleScrollTimeline& rule) + : source_(ComputeScrollSource(element, rule.GetSource())), + direction_(ComputeScrollDirection(rule.GetOrientation())), + offsets_(ComputeScrollOffsets(rule.GetStart(), rule.GetEnd())), + time_range_(ComputeTimeRange(rule.GetTimeRange())) {} + +CSSScrollTimeline::CSSScrollTimeline(Document* document, const Options& options) + : ScrollTimeline(document, + options.source_, + options.direction_, + options.offsets_, + *options.time_range_) { + DCHECK(options.IsValid()); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css/css_scroll_timeline.h b/third_party/blink/renderer/core/animation/css/css_scroll_timeline.h new file mode 100644 index 0000000..2fb0946 --- /dev/null +++ b/third_party/blink/renderer/core/animation/css/css_scroll_timeline.h
@@ -0,0 +1,54 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_SCROLL_TIMELINE_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_SCROLL_TIMELINE_H_ + +#include "base/optional.h" +#include "third_party/blink/renderer/core/animation/scroll_timeline.h" + +namespace blink { + +class Document; +class Element; +class StyleRuleScrollTimeline; + +// A CSSScrollTimeline is like a ScrollTimeline, except it originates from +// an @scroll-timeline rule. +class CORE_EXPORT CSSScrollTimeline : public ScrollTimeline { + public: + struct Options { + STACK_ALLOCATED(); + + public: + Options(Element*, StyleRuleScrollTimeline&); + + // TODO(crbug.com/1097041): Support 'auto' value. + bool IsValid() const { return time_range_.has_value(); } + + private: + friend class CSSScrollTimeline; + + Element* source_; + ScrollTimeline::ScrollDirection direction_; + HeapVector<Member<ScrollTimelineOffset>>* offsets_; + base::Optional<double> time_range_; + }; + + CSSScrollTimeline(Document*, const Options&); + + // AnimationTimeline implementation. + bool IsCSSScrollTimeline() const override { return true; } +}; + +template <> +struct DowncastTraits<CSSScrollTimeline> { + static bool AllowFrom(const AnimationTimeline& value) { + return value.IsCSSScrollTimeline(); + } +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_SCROLL_TIMELINE_H_
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 4b8ab16..a92fb85 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -7135,7 +7135,7 @@ return true; } if (!GetFrame() || GetExecutionContext()->IsFeatureEnabled( - mojom::blink::FeaturePolicyFeature::kDocumentWrite, + mojom::blink::DocumentPolicyFeature::kDocumentWrite, ReportOptions::kReportOnFailure)) { return true; }
diff --git a/third_party/blink/renderer/core/feature_policy/document_policy_features.json5 b/third_party/blink/renderer/core/feature_policy/document_policy_features.json5 index 5d0f0936..b531a2bd 100644 --- a/third_party/blink/renderer/core/feature_policy/document_policy_features.json5 +++ b/third_party/blink/renderer/core/feature_policy/document_policy_features.json5
@@ -95,5 +95,12 @@ default_value: "true", depends_on: ["ExperimentalProductivityFeatures"], }, + { + name: "DocumentWrite", + document_policy_name: "document-write", + value_type: "Bool", + default_value: "true", + depends_on: ["ExperimentalProductivityFeatures"], + }, ], }
diff --git a/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5 b/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5 index 50cacd4..5a004c4 100644 --- a/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5 +++ b/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5
@@ -152,12 +152,6 @@ feature_default: "EnableForAll", }, { - name: "DocumentWrite", - feature_policy_name: "document-write", - feature_default: "EnableForAll", - depends_on: ["ExperimentalProductivityFeatures"], - }, - { name: "Downloads", feature_policy_name: "downloads", feature_default: "EnableForAll",
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box.cc b/third_party/blink/renderer/core/layout/layout_flexible_box.cc index cf82bf0..d28f0e9 100644 --- a/third_party/blink/renderer/core/layout/layout_flexible_box.cc +++ b/third_party/blink/renderer/core/layout/layout_flexible_box.cc
@@ -55,7 +55,8 @@ namespace blink { static bool HasAspectRatio(const LayoutBox& child) { - return child.IsImage() || child.IsCanvas() || IsA<LayoutVideo>(child); + return child.IsImage() || child.IsCanvas() || IsA<LayoutVideo>(child) || + child.StyleRef().AspectRatio(); } LayoutFlexibleBox::LayoutFlexibleBox(Element* element) @@ -736,7 +737,7 @@ bool LayoutFlexibleBox::UseChildAspectRatio(const LayoutBox& child) const { if (!HasAspectRatio(child)) return false; - if (child.IntrinsicSize().Height() == 0) { + if (!child.StyleRef().AspectRatio() && child.IntrinsicSize().Height() == 0) { // We can't compute a ratio in this case. return false; } @@ -749,7 +750,6 @@ const LayoutBox& child, const Length& cross_size_length) const { DCHECK(HasAspectRatio(child)); - DCHECK_NE(child.IntrinsicSize().Height(), 0); LayoutUnit cross_size; if (cross_size_length.IsFixed()) { @@ -762,9 +762,15 @@ ValueForLength(cross_size_length, ContentWidth())); } - const LayoutSize& child_intrinsic_size = child.IntrinsicSize(); - double ratio = child_intrinsic_size.Width().ToFloat() / - child_intrinsic_size.Height().ToFloat(); + LayoutSize aspect_ratio; + if (child.StyleRef().AspectRatio()) { + IntSize int_ratio = *child.StyleRef().AspectRatio(); + aspect_ratio = LayoutSize{int_ratio.Width(), int_ratio.Height()}; + } else { + aspect_ratio = child.IntrinsicSize(); + } + double ratio = + aspect_ratio.Width().ToFloat() / aspect_ratio.Height().ToFloat(); if (IsHorizontalFlow()) return LayoutUnit(cross_size * ratio); return LayoutUnit(cross_size / ratio);
diff --git a/third_party/blink/renderer/core/page/context_menu_controller.cc b/third_party/blink/renderer/core/page/context_menu_controller.cc index 7c9ab47..34bae4f 100644 --- a/third_party/blink/renderer/core/page/context_menu_controller.cc +++ b/third_party/blink/renderer/core/page/context_menu_controller.cc
@@ -248,17 +248,6 @@ PhysicalOffset(FlooredIntPoint(point))); } - // Store text selection when it happens as it might be cleared when the - // browser will request |TextFragmentSelectorGenerator| to generator selector. - if (!selected_frame->Selection().SelectedText().IsEmpty()) { - VisibleSelectionInFlatTree selection = - selected_frame->Selection().ComputeVisibleSelectionInFlatTree(); - EphemeralRangeInFlatTree selection_range(selection.Start(), - selection.End()); - page_->GetTextFragmentSelectorGenerator().UpdateSelection(selected_frame, - selection_range); - } - WebContextMenuData data; data.mouse_position = selected_frame->View()->FrameToViewport( result.RoundedPointInInnerNodeFrame()); @@ -433,6 +422,11 @@ << "]\nVisibleSelection: " << selected_frame->Selection() .ComputeVisibleSelectionInDOMTreeDeprecated(); + + // Store text selection when it happens as it might be cleared when the + // browser will request |TextFragmentSelectorGenerator| to generate + // selector. + UpdateTextFragmentSelectorGenerator(selected_frame); } if (result.IsContentEditable()) { @@ -528,4 +522,13 @@ return true; } +void ContextMenuController::UpdateTextFragmentSelectorGenerator( + LocalFrame* selected_frame) { + VisibleSelectionInFlatTree selection = + selected_frame->Selection().ComputeVisibleSelectionInFlatTree(); + EphemeralRangeInFlatTree selection_range(selection.Start(), selection.End()); + page_->GetTextFragmentSelectorGenerator().UpdateSelection(selected_frame, + selection_range); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/page/context_menu_controller.h b/third_party/blink/renderer/core/page/context_menu_controller.h index a88a26e..7c4c7e8 100644 --- a/third_party/blink/renderer/core/page/context_menu_controller.h +++ b/third_party/blink/renderer/core/page/context_menu_controller.h
@@ -74,6 +74,8 @@ const MouseEvent* mouse_event = nullptr); bool ShouldShowContextMenuFromTouch(const WebContextMenuData&); + void UpdateTextFragmentSelectorGenerator(LocalFrame*); + Member<Page> page_; Member<ContextMenuProvider> menu_provider_; HitTestResult hit_test_result_;
diff --git a/third_party/blink/renderer/core/timing/profiler.cc b/third_party/blink/renderer/core/timing/profiler.cc index bd4b3393..f4e347fb 100644 --- a/third_party/blink/renderer/core/timing/profiler.cc +++ b/third_party/blink/renderer/core/timing/profiler.cc
@@ -7,6 +7,7 @@ #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/timing/profiler_group.h" +#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h" namespace blink { @@ -32,6 +33,9 @@ ScriptPromise promise = resolver->Promise(); if (!stopped()) { + // Ensure that we don't synchronously invoke script when resolving + // (crbug.com/1119865). + ScriptForbiddenScope forbid_script; DCHECK(profiler_group_); profiler_group_->StopProfiler(script_state, this, resolver); profiler_group_ = nullptr;
diff --git a/third_party/blink/renderer/core/timing/profiler_group_test.cc b/third_party/blink/renderer/core/timing/profiler_group_test.cc index bc014b4..d3bd881 100644 --- a/third_party/blink/renderer/core/timing/profiler_group_test.cc +++ b/third_party/blink/renderer/core/timing/profiler_group_test.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/timing/profiler_group.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_profiler_init_options.h" #include "third_party/blink/renderer/core/timing/profiler.h" @@ -174,4 +175,36 @@ } } +TEST(ProfilerGroupTest, Bug1119865) { + class ExpectNoCallFunction : public ScriptFunction { + public: + static v8::Local<v8::Function> Create(ScriptState* state) { + return MakeGarbageCollected<ExpectNoCallFunction>(state) + ->BindToV8Function(); + } + + explicit ExpectNoCallFunction(ScriptState* state) : ScriptFunction(state) {} + + ScriptValue Call(ScriptValue) override { + EXPECT_FALSE(true) + << "Promise should not resolve without dispatching a task"; + return ScriptValue(); + } + }; + + V8TestingScope scope; + + ProfilerGroup* profiler_group = ProfilerGroup::From(scope.GetIsolate()); + + ProfilerInitOptions* init_options = ProfilerInitOptions::Create(); + init_options->setSampleInterval(0); + + auto* profiler = profiler_group->CreateProfiler( + scope.GetScriptState(), *init_options, base::TimeTicks(), + scope.GetExceptionState()); + + auto function = ExpectNoCallFunction::Create(scope.GetScriptState()); + profiler->stop(scope.GetScriptState()).Then(function); +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn index f3a094db..5d3b52e 100644 --- a/third_party/blink/renderer/modules/BUILD.gn +++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -323,6 +323,8 @@ "manifest/manifest_manager_unittest.cc", "manifest/manifest_parser_unittest.cc", "manifest/manifest_type_converters_unittest.cc", + "media/audio/mojo_audio_output_ipc_test.cc", + "media/audio/web_audio_output_ipc_factory_test.cc", "media/webmediaplayer_util_unittest.cc", "media_capabilities/media_capabilities_test.cc", "media_controls/elements/media_control_animated_arrow_container_element_test.cc",
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc index 86d91868..a7f4e69c 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -1768,14 +1768,6 @@ if (AriaRoleAttribute() == ax::mojom::blink::Role::kMenuBar) return AXObjectCache().GetOrCreate(layout_object_->Parent()); - // menuButton and its corresponding menu are DOM siblings, but Accessibility - // needs them to be parent/child. - if (AriaRoleAttribute() == ax::mojom::blink::Role::kMenu) { - AXObject* parent = MenuButtonForMenu(); - if (parent) - return parent; - } - if (GetNode()) return AXNodeObject::ComputeParent(); @@ -1799,14 +1791,6 @@ if (AriaRoleAttribute() == ax::mojom::blink::Role::kMenuBar) return AXObjectCache().Get(layout_object_->Parent()); - // menuButton and its corresponding menu are DOM siblings, but Accessibility - // needs them to be parent/child. - if (AriaRoleAttribute() == ax::mojom::blink::Role::kMenu) { - AXObject* parent = MenuButtonForMenuIfExists(); - if (parent) - return parent; - } - if (GetNode()) return AXNodeObject::ComputeParentIfExists();
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index 09b33e4..cb0bc6a 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -1090,32 +1090,6 @@ return false; } -AXObject* AXNodeObject::MenuButtonForMenu() const { - Element* menu_item = MenuItemElementForMenu(); - - if (menu_item) { - // ARIA just has generic menu items. AppKit needs to know if this is a top - // level items like MenuBarButton or MenuBarItem - AXObject* menu_item_ax = AXObjectCache().GetOrCreate(menu_item); - if (menu_item_ax && menu_item_ax->IsMenuButton()) - return menu_item_ax; - } - return nullptr; -} - -AXObject* AXNodeObject::MenuButtonForMenuIfExists() const { - Element* menu_item = MenuItemElementForMenu(); - - if (menu_item) { - // ARIA just has generic menu items. AppKit needs to know if this is a top - // level items like MenuBarButton or MenuBarItem - AXObject* menu_item_ax = AXObjectCache().Get(menu_item); - if (menu_item_ax && menu_item_ax->IsMenuButton()) - return menu_item_ax; - } - return nullptr; -} - static Element* SiblingWithAriaRole(String role, Node* node) { Node* parent = LayoutTreeBuilderTraversal::Parent(*node); if (!parent) @@ -3429,7 +3403,6 @@ case ax::mojom::blink::Role::kCheckBox: case ax::mojom::blink::Role::kImage: case ax::mojom::blink::Role::kListBoxOption: - case ax::mojom::blink::Role::kMenuButton: case ax::mojom::blink::Role::kMenuListOption: case ax::mojom::blink::Role::kMenuItem: case ax::mojom::blink::Role::kMenuItemCheckBox: @@ -3459,7 +3432,6 @@ case ax::mojom::blink::Role::kCheckBox: case ax::mojom::blink::Role::kListBoxOption: case ax::mojom::blink::Role::kMath: // role="math" is flat, unlike <math> - case ax::mojom::blink::Role::kMenuButton: case ax::mojom::blink::Role::kMenuListOption: case ax::mojom::blink::Role::kMenuItem: case ax::mojom::blink::Role::kMenuItemCheckBox:
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.h b/third_party/blink/renderer/modules/accessibility/ax_node_object.h index 320f5bd..fdecf9c 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.h
@@ -74,8 +74,6 @@ bool HasContentEditableAttributeSet() const; bool IsTextControl() const override; - AXObject* MenuButtonForMenu() const; - AXObject* MenuButtonForMenuIfExists() const; Element* MenuItemElementForMenu() const; Element* MouseButtonListener() const; bool IsNativeCheckboxOrRadio() const;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index e7bfd4a..b890343c 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -383,7 +383,6 @@ {ax::mojom::blink::Role::kMarquee, "Marquee"}, {ax::mojom::blink::Role::kMath, "Math"}, {ax::mojom::blink::Role::kMenuBar, "MenuBar"}, - {ax::mojom::blink::Role::kMenuButton, "MenuButton"}, {ax::mojom::blink::Role::kMenuItem, "MenuItem"}, {ax::mojom::blink::Role::kMenuItemCheckBox, "MenuItemCheckBox"}, {ax::mojom::blink::Role::kMenuItemRadio, "MenuItemRadio"}, @@ -459,7 +458,6 @@ {"button", ax::mojom::blink::Role::kToggleButton}, {"combobox", ax::mojom::blink::Role::kPopUpButton}, {"contentinfo", ax::mojom::blink::Role::kFooter}, - {"menuitem", ax::mojom::blink::Role::kMenuButton}, {"menuitem", ax::mojom::blink::Role::kMenuListOption}, {"progressbar", ax::mojom::blink::Role::kMeter}, {"region", ax::mojom::blink::Role::kSection}, @@ -976,10 +974,6 @@ return RoleValue() == ax::mojom::blink::Role::kMenu; } -bool AXObject::IsMenuButton() const { - return RoleValue() == ax::mojom::blink::Role::kMenuButton; -} - bool AXObject::IsCheckable() const { switch (RoleValue()) { case ax::mojom::blink::Role::kCheckBox: @@ -2365,7 +2359,6 @@ case ax::mojom::blink::Role::kListBox: case ax::mojom::blink::Role::kLink: case ax::mojom::blink::Role::kPopUpButton: - case ax::mojom::blink::Role::kMenuButton: case ax::mojom::blink::Role::kMenuItem: case ax::mojom::blink::Role::kMenuItemCheckBox: case ax::mojom::blink::Role::kMenuItemRadio: @@ -2621,11 +2614,6 @@ if (role == ax::mojom::blink::Role::kListBoxOption && parent_aria_role == ax::mojom::blink::Role::kMenu) return ax::mojom::blink::Role::kMenuItem; - // An aria "menuitem" may map to MenuButton or MenuItem depending on its - // parent. - if (role == ax::mojom::blink::Role::kMenuItem && - parent_aria_role == ax::mojom::blink::Role::kGroup) - return ax::mojom::blink::Role::kMenuButton; // If the parent had a different role, then we don't need to continue // searching up the chain. @@ -3997,7 +3985,6 @@ case ax::mojom::blink::Role::kLineBreak: case ax::mojom::blink::Role::kLink: case ax::mojom::blink::Role::kListBoxOption: - case ax::mojom::blink::Role::kMenuButton: case ax::mojom::blink::Role::kMenuItem: case ax::mojom::blink::Role::kMenuItemCheckBox: case ax::mojom::blink::Role::kMenuItemRadio:
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h index 164a3e94..7d10bfa 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -444,7 +444,6 @@ bool IsLink() const; virtual bool IsInPageLinkTarget() const; bool IsMenu() const; - bool IsMenuButton() const; bool IsMenuRelated() const; bool IsMeter() const; virtual bool IsNativeImage() const;
diff --git a/third_party/blink/renderer/modules/media/BUILD.gn b/third_party/blink/renderer/modules/media/BUILD.gn index 142e769..8cc957d 100644 --- a/third_party/blink/renderer/modules/media/BUILD.gn +++ b/third_party/blink/renderer/modules/media/BUILD.gn
@@ -5,5 +5,10 @@ import("//third_party/blink/renderer/modules/modules.gni") blink_modules_sources("media") { - sources = [ "webmediaplayer_util.cc" ] + sources = [ + "audio/mojo_audio_output_ipc.cc", + "audio/mojo_audio_output_ipc.h", + "audio/web_audio_output_ipc_factory.cc", + "webmediaplayer_util.cc", + ] }
diff --git a/third_party/blink/renderer/modules/media/audio/DEPS b/third_party/blink/renderer/modules/media/audio/DEPS new file mode 100644 index 0000000..a5811516 --- /dev/null +++ b/third_party/blink/renderer/modules/media/audio/DEPS
@@ -0,0 +1,19 @@ +include_rules = [ + # TODO(https://crbug.com/787252): Remove this include when WTF::HashMap. + # is used instead. + "+base/containers/flat_map.h", + + "+media/audio", + "+media/base/audio_parameters.h", + "+media/mojo", +] + +specific_include_rules = { + ".*test\.cc" : [ + "+base/message_loop/message_pump_type.h", + "+base/run_loop.h", + "+base/test/bind_test_util.h", + "+base/test/gtest_util.h", + "+base/threading/thread.h", + ], +}
diff --git a/content/renderer/media/audio/mojo_audio_output_ipc.cc b/third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc.cc similarity index 87% rename from content/renderer/media/audio/mojo_audio_output_ipc.cc rename to third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc.cc index 73611d3..ac3302b 100644 --- a/content/renderer/media/audio/mojo_audio_output_ipc.cc +++ b/third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc.cc
@@ -2,24 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/renderer/media/audio/mojo_audio_output_ipc.h" +#include "third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc.h" #include <utility> #include "base/bind.h" #include "base/metrics/histogram_macros.h" #include "media/audio/audio_device_description.h" -#include "media/mojo/mojom/audio_output_stream.mojom.h" +#include "media/mojo/mojom/audio_output_stream.mojom-blink.h" #include "mojo/public/cpp/bindings/callback_helpers.h" #include "mojo/public/cpp/system/platform_handle.h" -namespace content { +namespace blink { namespace { -void TrivialAuthorizedCallback(media::OutputDeviceStatus, +void TrivialAuthorizedCallback(media::mojom::blink::OutputDeviceStatus, const media::AudioParameters&, - const std::string&) {} + const String&) {} } // namespace @@ -57,8 +57,9 @@ mojo::WrapCallbackWithDefaultInvokeIfNotRun( base::BindOnce(&MojoAudioOutputIPC::ReceivedDeviceAuthorization, weak_factory_.GetWeakPtr(), base::TimeTicks::Now()), - media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL, - media::AudioParameters::UnavailableDeviceParams(), std::string())); + static_cast<media::mojom::blink::OutputDeviceStatus>( + media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL), + media::AudioParameters::UnavailableDeviceParams(), String())); } void MojoAudioOutputIPC::CreateStream( @@ -83,7 +84,7 @@ DCHECK_EQ(delegate_, delegate); // Since the creation callback won't fire if the provider receiver is gone // and |this| owns |stream_provider_|, unretained is safe. - mojo::PendingRemote<media::mojom::AudioOutputStreamProviderClient> + mojo::PendingRemote<media::mojom::blink::AudioOutputStreamProviderClient> client_remote; receiver_.Bind(client_remote.InitWithNewPipeAndPassReceiver()); // Unretained is safe because |this| owns |receiver_|. @@ -140,7 +141,7 @@ DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); DCHECK(delegate_); if (disconnect_reason == - static_cast<uint32_t>(media::mojom::AudioOutputStreamObserver:: + static_cast<uint32_t>(media::mojom::blink::AudioOutputStreamObserver:: DisconnectReason::kPlatformError)) { delegate_->OnError(); } @@ -157,7 +158,7 @@ return receiver_.is_bound(); } -mojo::PendingReceiver<media::mojom::AudioOutputStreamProvider> +mojo::PendingReceiver<media::mojom::blink::AudioOutputStreamProvider> MojoAudioOutputIPC::MakeProviderReceiver() { DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); DCHECK(!AuthorizationRequested()); @@ -203,14 +204,14 @@ MakeProviderReceiver(), session_id.is_empty() ? base::Optional<base::UnguessableToken>() : session_id, - device_id, std::move(callback)); + String::FromUTF8(device_id), std::move(callback)); } void MojoAudioOutputIPC::ReceivedDeviceAuthorization( base::TimeTicks auth_start_time, - media::OutputDeviceStatus status, + media::mojom::blink::OutputDeviceStatus status, const media::AudioParameters& params, - const std::string& device_id) const { + const String& device_id) const { DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); DCHECK(delegate_); @@ -221,12 +222,13 @@ base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromSeconds(15), 100); - delegate_->OnDeviceAuthorized(status, params, device_id); + delegate_->OnDeviceAuthorized(static_cast<media::OutputDeviceStatus>(status), + params, device_id.Utf8()); } void MojoAudioOutputIPC::Created( - mojo::PendingRemote<media::mojom::AudioOutputStream> pending_stream, - media::mojom::ReadWriteAudioDataPipePtr data_pipe) { + mojo::PendingRemote<media::mojom::blink::AudioOutputStream> pending_stream, + media::mojom::blink::ReadWriteAudioDataPipePtr data_pipe) { DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); DCHECK(delegate_); @@ -250,4 +252,4 @@ stream_->Play(); } -} // namespace content +} // namespace blink
diff --git a/content/renderer/media/audio/mojo_audio_output_ipc.h b/third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc.h similarity index 68% rename from content/renderer/media/audio/mojo_audio_output_ipc.h rename to third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc.h index e4295b74..475e75a 100644 --- a/content/renderer/media/audio/mojo_audio_output_ipc.h +++ b/third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc.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 CONTENT_RENDERER_MEDIA_AUDIO_MOJO_AUDIO_OUTPUT_IPC_H_ -#define CONTENT_RENDERER_MEDIA_AUDIO_MOJO_AUDIO_OUTPUT_IPC_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_AUDIO_MOJO_AUDIO_OUTPUT_IPC_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_AUDIO_MOJO_AUDIO_OUTPUT_IPC_H_ #include <string> @@ -13,27 +13,27 @@ #include "base/optional.h" #include "base/single_thread_task_runner.h" #include "base/time/time.h" -#include "content/common/content_export.h" #include "media/audio/audio_output_ipc.h" -#include "media/mojo/mojom/audio_data_pipe.mojom.h" -#include "media/mojo/mojom/audio_output_stream.mojom.h" +#include "media/mojo/mojom/audio_data_pipe.mojom-blink.h" +#include "media/mojo/mojom/audio_output_stream.mojom-blink.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" -#include "third_party/blink/public/mojom/media/renderer_audio_output_stream_factory.mojom.h" +#include "third_party/blink/public/mojom/media/renderer_audio_output_stream_factory.mojom-blink.h" +#include "third_party/blink/renderer/modules/modules_export.h" -namespace content { +namespace blink { // MojoAudioOutputIPC is a renderer-side class for handling creation, // initialization and control of an output stream. May only be used on a single // thread. -class CONTENT_EXPORT MojoAudioOutputIPC +class MODULES_EXPORT MojoAudioOutputIPC : public media::AudioOutputIPC, - public media::mojom::AudioOutputStreamProviderClient { + public media::mojom::blink::AudioOutputStreamProviderClient { public: using FactoryAccessorCB = base::RepeatingCallback< - blink::mojom::RendererAudioOutputStreamFactory*()>; + blink::mojom::blink::RendererAudioOutputStreamFactory*()>; // |factory_accessor| is required to provide a // RendererAudioOutputStreamFactory* if IPC is possible. @@ -58,14 +58,15 @@ void SetVolume(double volume) override; // media::mojom::AudioOutputStreamProviderClient implementation. - void Created(mojo::PendingRemote<media::mojom::AudioOutputStream> stream, - media::mojom::ReadWriteAudioDataPipePtr data_pipe) override; + void Created( + mojo::PendingRemote<media::mojom::blink::AudioOutputStream> stream, + media::mojom::blink::ReadWriteAudioDataPipePtr data_pipe) override; private: static constexpr double kDefaultVolume = 1.0; - using AuthorizationCB = blink::mojom::RendererAudioOutputStreamFactory:: - RequestDeviceAuthorizationCallback; + using AuthorizationCB = blink::mojom::blink:: + RendererAudioOutputStreamFactory::RequestDeviceAuthorizationCallback; bool AuthorizationRequested() const; bool StreamCreationRequested() const; @@ -73,7 +74,7 @@ void ProviderClientBindingDisconnected(uint32_t disconnect_reason, const std::string& description); - mojo::PendingReceiver<media::mojom::AudioOutputStreamProvider> + mojo::PendingReceiver<media::mojom::blink::AudioOutputStreamProvider> MakeProviderReceiver(); // Tries to acquire a RendererAudioOutputStreamFactory and requests device @@ -83,10 +84,11 @@ const std::string& device_id, AuthorizationCB callback); - void ReceivedDeviceAuthorization(base::TimeTicks auth_start_time, - media::OutputDeviceStatus status, - const media::AudioParameters& params, - const std::string& device_id) const; + void ReceivedDeviceAuthorization( + base::TimeTicks auth_start_time, + media::mojom::blink::OutputDeviceStatus status, + const media::AudioParameters& params, + const String& device_id) const; const FactoryAccessorCB factory_accessor_; @@ -95,9 +97,10 @@ enum { kPaused, kPlaying } expected_state_ = kPaused; base::Optional<double> volume_; - mojo::Receiver<media::mojom::AudioOutputStreamProviderClient> receiver_{this}; - mojo::Remote<media::mojom::AudioOutputStreamProvider> stream_provider_; - mojo::Remote<media::mojom::AudioOutputStream> stream_; + mojo::Receiver<media::mojom::blink::AudioOutputStreamProviderClient> + receiver_{this}; + mojo::Remote<media::mojom::blink::AudioOutputStreamProvider> stream_provider_; + mojo::Remote<media::mojom::blink::AudioOutputStream> stream_; media::AudioOutputIPCDelegate* delegate_ = nullptr; scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; @@ -108,6 +111,6 @@ DISALLOW_COPY_AND_ASSIGN(MojoAudioOutputIPC); }; -} // namespace content +} // namespace blink -#endif // CONTENT_RENDERER_MEDIA_AUDIO_MOJO_AUDIO_OUTPUT_IPC_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_AUDIO_MOJO_AUDIO_OUTPUT_IPC_H_
diff --git a/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc b/third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc_test.cc similarity index 85% rename from content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc rename to third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc_test.cc index 2aee416..26d1810 100644 --- a/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc +++ b/third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc_test.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 "content/renderer/media/audio/mojo_audio_output_ipc.h" +#include "third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc.h" #include <algorithm> #include <memory> @@ -13,7 +13,6 @@ #include "base/optional.h" #include "base/run_loop.h" #include "base/test/gtest_util.h" -#include "base/test/task_environment.h" #include "media/audio/audio_device_description.h" #include "media/base/audio_parameters.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -24,6 +23,7 @@ #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/renderer/platform/testing/io_task_runner_testing_platform_support.h" using testing::_; using testing::AtLeast; @@ -31,7 +31,7 @@ using testing::Mock; using testing::StrictMock; -namespace content { +namespace blink { namespace { @@ -46,14 +46,16 @@ MojoAudioOutputIPC::FactoryAccessorCB NullAccessor() { return base::BindRepeating( - []() -> blink::mojom::RendererAudioOutputStreamFactory* { + []() -> blink::mojom::blink::RendererAudioOutputStreamFactory* { return nullptr; }); } -class TestStreamProvider : public media::mojom::AudioOutputStreamProvider { +// TODO(https://crbug.com/787252): Convert the test away from using std::string. +class TestStreamProvider + : public media::mojom::blink::AudioOutputStreamProvider { public: - explicit TestStreamProvider(media::mojom::AudioOutputStream* stream) + explicit TestStreamProvider(media::mojom::blink::AudioOutputStream* stream) : stream_(stream) {} ~TestStreamProvider() override { @@ -64,13 +66,14 @@ void Acquire( const media::AudioParameters& params, - mojo::PendingRemote<media::mojom::AudioOutputStreamProviderClient> + mojo::PendingRemote<media::mojom::blink::AudioOutputStreamProviderClient> pending_provider_client) override { EXPECT_EQ(receiver_, base::nullopt); EXPECT_NE(stream_, nullptr); provider_client_.reset(); provider_client_.Bind(std::move(pending_provider_client)); - mojo::PendingRemote<media::mojom::AudioOutputStream> stream_pending_remote; + mojo::PendingRemote<media::mojom::blink::AudioOutputStream> + stream_pending_remote; receiver_.emplace(stream_, stream_pending_remote.InitWithNewPipeAndPassReceiver()); base::CancelableSyncSocket foreign_socket; @@ -84,20 +87,22 @@ void SignalErrorToProviderClient() { provider_client_.ResetWithReason( - static_cast<uint32_t>(media::mojom::AudioOutputStreamObserver:: + static_cast<uint32_t>(media::mojom::blink::AudioOutputStreamObserver:: DisconnectReason::kPlatformError), std::string()); } private: - media::mojom::AudioOutputStream* stream_; - mojo::Remote<media::mojom::AudioOutputStreamProviderClient> provider_client_; - base::Optional<mojo::Receiver<media::mojom::AudioOutputStream>> receiver_; + media::mojom::blink::AudioOutputStream* stream_; + mojo::Remote<media::mojom::blink::AudioOutputStreamProviderClient> + provider_client_; + base::Optional<mojo::Receiver<media::mojom::blink::AudioOutputStream>> + receiver_; base::CancelableSyncSocket socket_; }; class TestRemoteFactory - : public blink::mojom::RendererAudioOutputStreamFactory { + : public blink::mojom::blink::RendererAudioOutputStreamFactory { public: TestRemoteFactory() : expect_request_(false), @@ -106,24 +111,27 @@ ~TestRemoteFactory() override {} void RequestDeviceAuthorization( - mojo::PendingReceiver<media::mojom::AudioOutputStreamProvider> + mojo::PendingReceiver<media::mojom::blink::AudioOutputStreamProvider> stream_provider_receiver, const base::Optional<base::UnguessableToken>& session_id, - const std::string& device_id, + const String& device_id, RequestDeviceAuthorizationCallback callback) override { EXPECT_EQ(session_id, expected_session_id_); - EXPECT_EQ(device_id, expected_device_id_); + EXPECT_EQ(device_id.Utf8(), expected_device_id_); EXPECT_TRUE(expect_request_); if (provider_) { std::move(callback).Run( - media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK, Params(), - std::string(kReturnedDeviceId)); + static_cast<media::mojom::blink::OutputDeviceStatus>( + media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK), + Params(), String(kReturnedDeviceId)); provider_receiver_.emplace(provider_.get(), std::move(stream_provider_receiver)); } else { std::move(callback).Run( - media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED, - Params(), std::string("")); + static_cast<media::mojom::blink::OutputDeviceStatus>( + media::OutputDeviceStatus:: + OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED), + Params(), String("")); } expect_request_ = false; } @@ -168,7 +176,7 @@ } private: - blink::mojom::RendererAudioOutputStreamFactory* get() { + blink::mojom::blink::RendererAudioOutputStreamFactory* get() { return this_remote_.get(); } @@ -176,15 +184,16 @@ base::Optional<base::UnguessableToken> expected_session_id_; std::string expected_device_id_; - mojo::Remote<blink::mojom::RendererAudioOutputStreamFactory> this_remote_; - mojo::Receiver<blink::mojom::RendererAudioOutputStreamFactory> receiver_{ - this}; + mojo::Remote<blink::mojom::blink::RendererAudioOutputStreamFactory> + this_remote_; + mojo::Receiver<blink::mojom::blink::RendererAudioOutputStreamFactory> + receiver_{this}; std::unique_ptr<TestStreamProvider> provider_; - base::Optional<mojo::Receiver<media::mojom::AudioOutputStreamProvider>> + base::Optional<mojo::Receiver<media::mojom::blink::AudioOutputStreamProvider>> provider_receiver_; }; -class MockStream : public media::mojom::AudioOutputStream { +class MockStream : public media::mojom::blink::AudioOutputStream { public: MOCK_METHOD0(Play, void()); MOCK_METHOD0(Pause, void()); @@ -215,8 +224,8 @@ } // namespace TEST(MojoAudioOutputIPC, AuthorizeWithoutFactory_CallsAuthorizedWithError) { - base::test::SingleThreadTaskEnvironment task_environment( - base::test::SingleThreadTaskEnvironment::MainThreadType::IO); + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + const base::UnguessableToken session_id = base::UnguessableToken::Create(); StrictMock<MockDelegate> delegate; @@ -238,8 +247,8 @@ TEST(MojoAudioOutputIPC, CreateWithoutAuthorizationWithoutFactory_CallsAuthorizedWithError) { - base::test::SingleThreadTaskEnvironment task_environment( - base::test::SingleThreadTaskEnvironment::MainThreadType::IO); + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + StrictMock<MockDelegate> delegate; std::unique_ptr<media::AudioOutputIPC> ipc = @@ -256,8 +265,8 @@ } TEST(MojoAudioOutputIPC, DeviceAuthorized_Propagates) { - base::test::SingleThreadTaskEnvironment task_environment( - base::test::SingleThreadTaskEnvironment::MainThreadType::IO); + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + const base::UnguessableToken session_id = base::UnguessableToken::Create(); TestRemoteFactory stream_factory; StrictMock<MockDelegate> delegate; @@ -281,8 +290,8 @@ } TEST(MojoAudioOutputIPC, OnDeviceCreated_Propagates) { - base::test::SingleThreadTaskEnvironment task_environment( - base::test::SingleThreadTaskEnvironment::MainThreadType::IO); + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + const base::UnguessableToken session_id = base::UnguessableToken::Create(); TestRemoteFactory stream_factory; StrictMock<MockStream> stream; @@ -310,8 +319,8 @@ TEST(MojoAudioOutputIPC, CreateWithoutAuthorization_RequestsAuthorizationFirst) { - base::test::SingleThreadTaskEnvironment task_environment( - base::test::SingleThreadTaskEnvironment::MainThreadType::IO); + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + TestRemoteFactory stream_factory; StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; @@ -339,8 +348,8 @@ } TEST(MojoAudioOutputIPC, IsReusable) { - base::test::SingleThreadTaskEnvironment task_environment( - base::test::SingleThreadTaskEnvironment::MainThreadType::IO); + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + const base::UnguessableToken session_id = base::UnguessableToken::Create(); TestRemoteFactory stream_factory; StrictMock<MockStream> stream; @@ -372,8 +381,8 @@ } TEST(MojoAudioOutputIPC, IsReusableAfterError) { - base::test::SingleThreadTaskEnvironment task_environment( - base::test::SingleThreadTaskEnvironment::MainThreadType::IO); + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + const base::UnguessableToken session_id = base::UnguessableToken::Create(); TestRemoteFactory stream_factory; StrictMock<MockStream> stream; @@ -427,8 +436,8 @@ } TEST(MojoAudioOutputIPC, DeviceNotAuthorized_Propagates) { - base::test::SingleThreadTaskEnvironment task_environment( - base::test::SingleThreadTaskEnvironment::MainThreadType::IO); + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + const base::UnguessableToken session_id = base::UnguessableToken::Create(); TestRemoteFactory stream_factory; StrictMock<MockDelegate> delegate; @@ -460,8 +469,8 @@ // The authorization IPC message might be aborted by the remote end // disconnecting. In this case, the MojoAudioOutputIPC object must still // send a notification to unblock the AudioOutputIPCDelegate. - base::test::SingleThreadTaskEnvironment task_environment( - base::test::SingleThreadTaskEnvironment::MainThreadType::IO); + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + const base::UnguessableToken session_id = base::UnguessableToken::Create(); TestRemoteFactory stream_factory; StrictMock<MockDelegate> delegate; @@ -492,8 +501,8 @@ // This test makes sure that the MojoAudioOutputIPC doesn't callback for // authorization when the factory disconnects if it already got a callback // for authorization. - base::test::SingleThreadTaskEnvironment task_environment( - base::test::SingleThreadTaskEnvironment::MainThreadType::IO); + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + const base::UnguessableToken session_id = base::UnguessableToken::Create(); TestRemoteFactory stream_factory; stream_factory.PrepareProviderForAuthorization( @@ -520,8 +529,8 @@ } TEST(MojoAudioOutputIPC, AuthorizeNoClose_DCHECKs) { - base::test::SingleThreadTaskEnvironment task_environment( - base::test::SingleThreadTaskEnvironment::MainThreadType::IO); + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + TestRemoteFactory stream_factory; const base::UnguessableToken session_id = base::UnguessableToken::Create(); StrictMock<MockDelegate> delegate; @@ -542,8 +551,8 @@ } TEST(MojoAudioOutputIPC, CreateNoClose_DCHECKs) { - base::test::SingleThreadTaskEnvironment task_environment( - base::test::SingleThreadTaskEnvironment::MainThreadType::IO); + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + TestRemoteFactory stream_factory; StrictMock<MockDelegate> delegate; StrictMock<MockStream> stream; @@ -566,8 +575,8 @@ } TEST(MojoAudioOutputIPC, Play_Plays) { - base::test::SingleThreadTaskEnvironment task_environment( - base::test::SingleThreadTaskEnvironment::MainThreadType::IO); + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + TestRemoteFactory stream_factory; const base::UnguessableToken session_id = base::UnguessableToken::Create(); StrictMock<MockStream> stream; @@ -596,8 +605,8 @@ } TEST(MojoAudioOutputIPC, Pause_Pauses) { - base::test::SingleThreadTaskEnvironment task_environment( - base::test::SingleThreadTaskEnvironment::MainThreadType::IO); + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + TestRemoteFactory stream_factory; const base::UnguessableToken session_id = base::UnguessableToken::Create(); StrictMock<MockStream> stream; @@ -626,8 +635,8 @@ } TEST(MojoAudioOutputIPC, SetVolume_SetsVolume) { - base::test::SingleThreadTaskEnvironment task_environment( - base::test::SingleThreadTaskEnvironment::MainThreadType::IO); + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + TestRemoteFactory stream_factory; const base::UnguessableToken session_id = base::UnguessableToken::Create(); StrictMock<MockStream> stream; @@ -655,4 +664,4 @@ base::RunLoop().RunUntilIdle(); } -} // namespace content +} // namespace blink
diff --git a/third_party/blink/renderer/modules/media/audio/web_audio_output_ipc_factory.cc b/third_party/blink/renderer/modules/media/audio/web_audio_output_ipc_factory.cc new file mode 100644 index 0000000..49836e94 --- /dev/null +++ b/third_party/blink/renderer/modules/media/audio/web_audio_output_ipc_factory.cc
@@ -0,0 +1,146 @@ +// 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. + +#include "third_party/blink/public/web/modules/media/audio/web_audio_output_ipc_factory.h" + +#include <utility> + +#include "base/bind.h" +#include "base/check_op.h" +#include "base/containers/flat_map.h" +#include "base/single_thread_task_runner.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/mojom/media/renderer_audio_output_stream_factory.mojom-blink.h" +#include "third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc.h" + +namespace blink { + +WebAudioOutputIPCFactory* WebAudioOutputIPCFactory::instance_ = nullptr; + +class WebAudioOutputIPCFactory::Impl { + public: + using StreamFactoryMap = base::flat_map< + base::UnguessableToken, + mojo::Remote<mojom::blink::RendererAudioOutputStreamFactory>>; + + explicit Impl(scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) + : io_task_runner_(std::move(io_task_runner)) {} + ~Impl() { DCHECK(factory_remotes_.empty()); } + + mojom::blink::RendererAudioOutputStreamFactory* GetRemoteFactory( + const base::UnguessableToken& frame_token) const; + + void RegisterRemoteFactoryOnIOThread( + const base::UnguessableToken& frame_token, + mojo::PendingRemote<mojom::blink::RendererAudioOutputStreamFactory> + factory_pending_remote); + + void MaybeDeregisterRemoteFactoryOnIOThread( + const base::UnguessableToken& frame_token); + + // Maps frame id to the corresponding factory. + StreamFactoryMap factory_remotes_; + const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; + + private: + DISALLOW_COPY_AND_ASSIGN(Impl); +}; + +WebAudioOutputIPCFactory::WebAudioOutputIPCFactory( + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) + : impl_(std::make_unique<Impl>(std::move(io_task_runner))) { + DCHECK(!instance_); + instance_ = this; +} + +WebAudioOutputIPCFactory::~WebAudioOutputIPCFactory() { + // Allow destruction in tests. + DCHECK_EQ(instance_, this); + instance_ = nullptr; +} + +std::unique_ptr<media::AudioOutputIPC> +WebAudioOutputIPCFactory::CreateAudioOutputIPC( + const base::UnguessableToken& frame_token) const { + // Unretained is safe due to the contract at the top of the header file. + return std::make_unique<MojoAudioOutputIPC>( + base::BindRepeating(&WebAudioOutputIPCFactory::Impl::GetRemoteFactory, + base::Unretained(impl_.get()), frame_token), + io_task_runner()); +} + +void WebAudioOutputIPCFactory::RegisterRemoteFactory( + const base::UnguessableToken& frame_token, + blink::BrowserInterfaceBrokerProxy* interface_broker) { + mojo::PendingRemote<mojom::blink::RendererAudioOutputStreamFactory> + factory_remote; + interface_broker->GetInterface( + factory_remote.InitWithNewPipeAndPassReceiver()); + // Unretained is safe due to the contract at the top of the header file. + // It's safe to pass the |factory_remote| PendingRemote between threads. + io_task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + &WebAudioOutputIPCFactory::Impl::RegisterRemoteFactoryOnIOThread, + base::Unretained(impl_.get()), frame_token, + std::move(factory_remote))); +} + +void WebAudioOutputIPCFactory::MaybeDeregisterRemoteFactory( + const base::UnguessableToken& frame_token) { + io_task_runner()->PostTask( + FROM_HERE, base::BindOnce(&WebAudioOutputIPCFactory::Impl:: + MaybeDeregisterRemoteFactoryOnIOThread, + base::Unretained(impl_.get()), frame_token)); +} + +const scoped_refptr<base::SingleThreadTaskRunner>& +WebAudioOutputIPCFactory::io_task_runner() const { + return impl_->io_task_runner_; +} + +mojom::blink::RendererAudioOutputStreamFactory* +WebAudioOutputIPCFactory::Impl::GetRemoteFactory( + const base::UnguessableToken& frame_token) const { + DCHECK(io_task_runner_->BelongsToCurrentThread()); + auto it = factory_remotes_.find(frame_token); + return it == factory_remotes_.end() ? nullptr : it->second.get(); +} + +void WebAudioOutputIPCFactory::Impl::RegisterRemoteFactoryOnIOThread( + const base::UnguessableToken& frame_token, + mojo::PendingRemote<mojom::blink::RendererAudioOutputStreamFactory> + factory_pending_remote) { + DCHECK(io_task_runner_->BelongsToCurrentThread()); + std::pair<StreamFactoryMap::iterator, bool> emplace_result = + factory_remotes_.emplace(frame_token, std::move(factory_pending_remote)); + + DCHECK(emplace_result.second) << "Attempt to register a factory for a " + "frame which already has a factory " + "registered."; + + auto& emplaced_factory = emplace_result.first->second; + DCHECK(emplaced_factory.is_bound()) + << "Factory is not bound to a remote implementation."; + + // Unretained is safe because |this| owns the remote, so a connection error + // cannot trigger after destruction. + emplaced_factory.set_disconnect_handler(base::BindOnce( + &WebAudioOutputIPCFactory::Impl::MaybeDeregisterRemoteFactoryOnIOThread, + base::Unretained(this), frame_token)); +} + +void WebAudioOutputIPCFactory::Impl::MaybeDeregisterRemoteFactoryOnIOThread( + const base::UnguessableToken& frame_token) { + DCHECK(io_task_runner_->BelongsToCurrentThread()); + // This function can be called both by the frame and the connection error + // handler of the factory remote. Calling erase multiple times even though + // there is nothing to erase is safe, so we don't have to handle this in any + // particular way. + factory_remotes_.erase(frame_token); +} + +} // namespace blink
diff --git a/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc b/third_party/blink/renderer/modules/media/audio/web_audio_output_ipc_factory_test.cc similarity index 73% rename from content/renderer/media/audio/audio_output_ipc_factory_unittest.cc rename to third_party/blink/renderer/modules/media/audio/web_audio_output_ipc_factory_test.cc index 24514c3c..5a791edd 100644 --- a/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc +++ b/third_party/blink/renderer/modules/media/audio/web_audio_output_ipc_factory_test.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 "content/renderer/media/audio/audio_output_ipc_factory.h" +#include "third_party/blink/public/web/modules/media/audio/web_audio_output_ipc_factory.h" #include <string> #include <utility> @@ -12,7 +12,6 @@ #include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/test/bind_test_util.h" -#include "base/test/task_environment.h" #include "base/threading/thread.h" #include "media/audio/audio_output_ipc.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -21,10 +20,12 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/mojom/media/renderer_audio_output_stream_factory.mojom-blink.h" +#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" using ::testing::_; -namespace content { +namespace blink { namespace { @@ -45,20 +46,22 @@ } class FakeRemoteFactory - : public blink::mojom::RendererAudioOutputStreamFactory { + : public mojom::blink::RendererAudioOutputStreamFactory { public: FakeRemoteFactory() = default; ~FakeRemoteFactory() override {} void RequestDeviceAuthorization( - mojo::PendingReceiver<media::mojom::AudioOutputStreamProvider> + mojo::PendingReceiver<media::mojom::blink::AudioOutputStreamProvider> stream_provider, const base::Optional<base::UnguessableToken>& session_id, - const std::string& device_id, + const String& device_id, RequestDeviceAuthorizationCallback callback) override { std::move(callback).Run( - media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED, - media::AudioParameters::UnavailableDeviceParams(), std::string()); + static_cast<media::mojom::blink::OutputDeviceStatus>( + media::OutputDeviceStatus:: + OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED), + media::AudioParameters::UnavailableDeviceParams(), WTF::g_empty_string); EXPECT_FALSE(on_called_.is_null()); std::move(on_called_).Run(); } @@ -70,12 +73,12 @@ void Bind(mojo::ScopedMessagePipeHandle handle) { EXPECT_FALSE(receiver_.is_bound()); receiver_.Bind( - mojo::PendingReceiver<blink::mojom::RendererAudioOutputStreamFactory>( + mojo::PendingReceiver<mojom::blink::RendererAudioOutputStreamFactory>( std::move(handle))); } private: - mojo::Receiver<blink::mojom::RendererAudioOutputStreamFactory> receiver_{ + mojo::Receiver<mojom::blink::RendererAudioOutputStreamFactory> receiver_{ this}; base::OnceClosure on_called_; }; @@ -93,10 +96,10 @@ } // namespace -class AudioOutputIPCFactoryTest : public testing::Test { +class WebAudioOutputIPCFactoryTest : public testing::Test { public: - AudioOutputIPCFactoryTest() {} - ~AudioOutputIPCFactoryTest() override {} + WebAudioOutputIPCFactoryTest() = default; + ~WebAudioOutputIPCFactoryTest() override = default; void RequestAuthorizationOnIOThread( std::unique_ptr<media::AudioOutputIPC> output_ipc) { @@ -110,10 +113,10 @@ FakeAudioOutputIPCDelegate fake_delegate; }; -TEST_F(AudioOutputIPCFactoryTest, CallFactoryFromIOThread) { - // This test makes sure that AudioOutputIPCFactory correctly binds the +TEST_F(WebAudioOutputIPCFactoryTest, CallFactoryFromIOThread) { + // This test makes sure that WebAudioOutputIPCFactory correctly binds the // RendererAudioOutputStreamFactory to the IO thread. - base::test::SingleThreadTaskEnvironment task_environment; + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; base::RunLoop run_loop; auto io_thread = MakeIOThread(); @@ -122,11 +125,11 @@ auto& interface_broker = blink::GetEmptyBrowserInterfaceBroker(); interface_broker.SetBinderForTesting( - blink::mojom::RendererAudioOutputStreamFactory::Name_, + mojom::blink::RendererAudioOutputStreamFactory::Name_, base::BindRepeating(&FakeRemoteFactory::Bind, base::Unretained(&remote_factory))); - AudioOutputIPCFactory ipc_factory(io_thread->task_runner()); + WebAudioOutputIPCFactory ipc_factory(io_thread->task_runner()); ipc_factory.RegisterRemoteFactory(TokenFromInt(kRenderFrameId), &interface_broker); @@ -138,7 +141,7 @@ io_thread->task_runner()->PostTask( FROM_HERE, base::BindOnce( - &AudioOutputIPCFactoryTest::RequestAuthorizationOnIOThread, + &WebAudioOutputIPCFactoryTest::RequestAuthorizationOnIOThread, base::Unretained(this), ipc_factory.CreateAudioOutputIPC(TokenFromInt(kRenderFrameId)))); @@ -148,15 +151,15 @@ ipc_factory.MaybeDeregisterRemoteFactory(TokenFromInt(0)); interface_broker.SetBinderForTesting( - blink::mojom::RendererAudioOutputStreamFactory::Name_, {}); + mojom::blink::RendererAudioOutputStreamFactory::Name_, {}); io_thread.reset(); base::RunLoop().RunUntilIdle(); } -TEST_F(AudioOutputIPCFactoryTest, SeveralFactories) { +TEST_F(WebAudioOutputIPCFactoryTest, SeveralFactories) { // This test simulates having several frames being created and destructed. - base::test::SingleThreadTaskEnvironment task_environment; + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; auto io_thread = MakeIOThread(); const int n_factories = 5; @@ -165,7 +168,7 @@ auto& interface_broker = blink::GetEmptyBrowserInterfaceBroker(); interface_broker.SetBinderForTesting( - blink::mojom::RendererAudioOutputStreamFactory::Name_, + mojom::blink::RendererAudioOutputStreamFactory::Name_, base::BindLambdaForTesting([&](mojo::ScopedMessagePipeHandle handle) { static int factory_index = 0; DCHECK_LT(factory_index, n_factories); @@ -174,7 +177,7 @@ base::RunLoop().RunUntilIdle(); - AudioOutputIPCFactory ipc_factory(io_thread->task_runner()); + WebAudioOutputIPCFactory ipc_factory(io_thread->task_runner()); for (size_t i = 0; i < n_factories; i++) { ipc_factory.RegisterRemoteFactory(TokenFromInt(kRenderFrameId + i), @@ -186,7 +189,7 @@ io_thread->task_runner()->PostTask( FROM_HERE, base::BindOnce( - &AudioOutputIPCFactoryTest::RequestAuthorizationOnIOThread, + &WebAudioOutputIPCFactoryTest::RequestAuthorizationOnIOThread, base::Unretained(this), ipc_factory.CreateAudioOutputIPC(TokenFromInt(kRenderFrameId)))); run_loop.Run(); @@ -199,7 +202,7 @@ io_thread->task_runner()->PostTask( FROM_HERE, base::BindOnce( - &AudioOutputIPCFactoryTest::RequestAuthorizationOnIOThread, + &WebAudioOutputIPCFactoryTest::RequestAuthorizationOnIOThread, base::Unretained(this), ipc_factory.CreateAudioOutputIPC(TokenFromInt(kRenderFrameId + 2)))); run_loop2.Run(); @@ -211,40 +214,41 @@ } interface_broker.SetBinderForTesting( - blink::mojom::RendererAudioOutputStreamFactory::Name_, {}); + mojom::blink::RendererAudioOutputStreamFactory::Name_, {}); io_thread.reset(); base::RunLoop().RunUntilIdle(); } -TEST_F(AudioOutputIPCFactoryTest, RegisterDeregisterBackToBack_Deregisters) { +TEST_F(WebAudioOutputIPCFactoryTest, RegisterDeregisterBackToBack_Deregisters) { // This test makes sure that calling Register... followed by Deregister... // correctly sequences the registration before the deregistration. - base::test::SingleThreadTaskEnvironment task_environment; + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform; + auto io_thread = MakeIOThread(); FakeRemoteFactory remote_factory; auto& interface_broker = blink::GetEmptyBrowserInterfaceBroker(); interface_broker.SetBinderForTesting( - blink::mojom::RendererAudioOutputStreamFactory::Name_, + mojom::blink::RendererAudioOutputStreamFactory::Name_, base::BindRepeating(&FakeRemoteFactory::Bind, base::Unretained(&remote_factory))); - AudioOutputIPCFactory ipc_factory(io_thread->task_runner()); + WebAudioOutputIPCFactory ipc_factory(io_thread->task_runner()); ipc_factory.RegisterRemoteFactory(TokenFromInt(kRenderFrameId), &interface_broker); ipc_factory.MaybeDeregisterRemoteFactory(TokenFromInt(kRenderFrameId)); // That there is no factory remaining at destruction is DCHECKed in the - // AudioOutputIPCFactory destructor. + // WebAudioOutputIPCFactory destructor. base::RunLoop().RunUntilIdle(); interface_broker.SetBinderForTesting( - blink::mojom::RendererAudioOutputStreamFactory::Name_, {}); + mojom::blink::RendererAudioOutputStreamFactory::Name_, {}); io_thread.reset(); base::RunLoop().RunUntilIdle(); } -} // namespace content +} // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/BUILD.gn b/third_party/blink/renderer/modules/webcodecs/BUILD.gn index 497aa35..2b48c582 100644 --- a/third_party/blink/renderer/modules/webcodecs/BUILD.gn +++ b/third_party/blink/renderer/modules/webcodecs/BUILD.gn
@@ -15,6 +15,8 @@ "audio_frame.cc", "audio_frame.h", "codec_config_eval.h", + "codec_state_helper.cc", + "codec_state_helper.h", "decoder_selector.cc", "decoder_selector.h", "decoder_template.cc",
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl b/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl index 93c3efd..f985f84 100644 --- a/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl +++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl
@@ -57,4 +57,7 @@ // // Not recoverable: make a new AudioDecoder if needed. [RaisesException] void close(); + + // Which state the decoder is in, indicating which methods can be called. + readonly attribute CodecState state; };
diff --git a/third_party/blink/renderer/modules/webcodecs/codec_state.idl b/third_party/blink/renderer/modules/webcodecs/codec_state.idl new file mode 100644 index 0000000..3b503ca54 --- /dev/null +++ b/third_party/blink/renderer/modules/webcodecs/codec_state.idl
@@ -0,0 +1,11 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://github.com/WICG/web-codecs + +enum CodecState { + "unconfigured", + "configured", + "closed" +}; \ No newline at end of file
diff --git a/third_party/blink/renderer/modules/webcodecs/codec_state_helper.cc b/third_party/blink/renderer/modules/webcodecs/codec_state_helper.cc new file mode 100644 index 0000000..4aadc93 --- /dev/null +++ b/third_party/blink/renderer/modules/webcodecs/codec_state_helper.cc
@@ -0,0 +1,35 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/webcodecs/codec_state_helper.h" + +namespace blink { + +// static +bool ThrowIfCodecStateClosed(V8CodecState state, + String operation, + ExceptionState& exception_state) { + if (state.AsEnum() != V8CodecState::Enum::kClosed) + return false; + + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "Cannot call '" + operation + "' on a closed codec."); + return true; +} + +// static +bool ThrowIfCodecStateUnconfigured(V8CodecState state, + String operation, + ExceptionState& exception_state) { + if (state.AsEnum() != V8CodecState::Enum::kUnconfigured) + return false; + + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "Cannot call '" + operation + "' on an unconfigured codec."); + return true; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/codec_state_helper.h b/third_party/blink/renderer/modules/webcodecs/codec_state_helper.h new file mode 100644 index 0000000..f49cc3a --- /dev/null +++ b/third_party/blink/renderer/modules/webcodecs/codec_state_helper.h
@@ -0,0 +1,26 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_CODEC_STATE_HELPER_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_CODEC_STATE_HELPER_H_ + +#include "third_party/blink/renderer/bindings/modules/v8/v8_codec_state.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +// Returns true and sets the exception state if the passed CodecState is +// kClosed. The exception message is built from the |operation| name. +bool ThrowIfCodecStateClosed(V8CodecState, String operation, ExceptionState&); + +// Returns true and sets the exception state if the passed CodecState is +// kUnconfigured. The exception message is built from the |operation| name. +bool ThrowIfCodecStateUnconfigured(V8CodecState, + String operation, + ExceptionState&); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_CODEC_STATE_HELPER_H_
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc index c9b5d679..9762fa5 100644 --- a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc +++ b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
@@ -26,6 +26,7 @@ #include "third_party/blink/renderer/modules/webcodecs/audio_decoder.h" #include "third_party/blink/renderer/modules/webcodecs/audio_frame.h" #include "third_party/blink/renderer/modules/webcodecs/codec_config_eval.h" +#include "third_party/blink/renderer/modules/webcodecs/codec_state_helper.h" #include "third_party/blink/renderer/modules/webcodecs/video_decoder.h" #include "third_party/blink/renderer/modules/webcodecs/video_frame.h" #include "third_party/blink/renderer/platform/bindings/exception_code.h" @@ -42,7 +43,7 @@ DecoderTemplate<Traits>::DecoderTemplate(ScriptState* script_state, const InitType* init, ExceptionState& exception_state) - : script_state_(script_state) { + : script_state_(script_state), state_(V8CodecState::Enum::kUnconfigured) { DVLOG(1) << __func__; DCHECK(init->hasOutput()); DCHECK(init->hasError()); @@ -61,14 +62,16 @@ } template <typename Traits> +bool DecoderTemplate<Traits>::IsClosed() { + return state_ == V8CodecState::Enum::kClosed; +} + +template <typename Traits> void DecoderTemplate<Traits>::configure(const ConfigType* config, ExceptionState& exception_state) { DVLOG(1) << __func__; - if (is_closed_) { - exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, - "Cannot configure a closed codec."); + if (ThrowIfCodecStateClosed(state_, "decode", exception_state)) return; - } auto media_config = std::make_unique<MediaConfigType>(); String console_message; @@ -88,6 +91,8 @@ break; } + state_ = V8CodecState(V8CodecState::Enum::kConfigured); + Request* request = MakeGarbageCollected<Request>(); request->type = Request::Type::kConfigure; request->media_config = std::move(media_config); @@ -99,11 +104,11 @@ void DecoderTemplate<Traits>::decode(const InputType* chunk, ExceptionState& exception_state) { DVLOG(3) << __func__; - if (is_closed_) { - exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, - "Cannot decode with a closed codec."); + if (ThrowIfCodecStateClosed(state_, "decode", exception_state)) return; - } + + if (ThrowIfCodecStateUnconfigured(state_, "decode", exception_state)) + return; Request* request = MakeGarbageCollected<Request>(); request->type = Request::Type::kDecode; @@ -116,11 +121,11 @@ template <typename Traits> ScriptPromise DecoderTemplate<Traits>::flush(ExceptionState& exception_state) { DVLOG(3) << __func__; - if (is_closed_) { - exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, - "Cannot flush a closed codec."); + if (ThrowIfCodecStateClosed(state_, "flush", exception_state)) return ScriptPromise(); - } + + if (ThrowIfCodecStateUnconfigured(state_, "flush", exception_state)) + return ScriptPromise(); Request* request = MakeGarbageCollected<Request>(); request->type = Request::Type::kFlush; @@ -135,11 +140,13 @@ template <typename Traits> void DecoderTemplate<Traits>::reset(ExceptionState& exception_state) { DVLOG(3) << __func__; - if (is_closed_) { - exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, - "Cannot reset a closed codec."); + if (ThrowIfCodecStateClosed(state_, "reset", exception_state)) return; - } + + if (state_ == V8CodecState::Enum::kUnconfigured) + return; + + state_ = V8CodecState(V8CodecState::Enum::kUnconfigured); Request* request = MakeGarbageCollected<Request>(); request->type = Request::Type::kReset; @@ -151,18 +158,16 @@ template <typename Traits> void DecoderTemplate<Traits>::close(ExceptionState& exception_state) { DVLOG(3) << __func__; - if (is_closed_) { - exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, - "Codec is already closed."); + if (ThrowIfCodecStateClosed(state_, "close", exception_state)) return; - } + Shutdown(false); } template <typename Traits> void DecoderTemplate<Traits>::ProcessRequests() { DVLOG(3) << __func__; - DCHECK(!is_closed_); + DCHECK(!IsClosed()); while (!pending_request_ && !requests_.IsEmpty()) { Request* request = requests_.front(); switch (request->type) { @@ -190,7 +195,7 @@ template <typename Traits> bool DecoderTemplate<Traits>::ProcessConfigureRequest(Request* request) { DVLOG(3) << __func__; - DCHECK(!is_closed_); + DCHECK(!IsClosed()); DCHECK(!pending_request_); DCHECK_EQ(request->type, Request::Type::kConfigure); DCHECK(request->media_config); @@ -242,7 +247,7 @@ template <typename Traits> bool DecoderTemplate<Traits>::ProcessDecodeRequest(Request* request) { DVLOG(3) << __func__; - DCHECK(!is_closed_); + DCHECK_EQ(state_, V8CodecState::Enum::kConfigured); DCHECK(!pending_request_); DCHECK_EQ(request->type, Request::Type::kDecode); DCHECK_GT(requested_decodes_, 0); @@ -285,7 +290,7 @@ template <typename Traits> bool DecoderTemplate<Traits>::ProcessFlushRequest(Request* request) { DVLOG(3) << __func__; - DCHECK(!is_closed_); + DCHECK(!IsClosed()); DCHECK(!pending_request_); DCHECK_EQ(request->type, Request::Type::kFlush); @@ -315,7 +320,7 @@ template <typename Traits> bool DecoderTemplate<Traits>::ProcessResetRequest(Request* request) { DVLOG(3) << __func__; - DCHECK(!is_closed_); + DCHECK(!IsClosed()); DCHECK(!pending_request_); DCHECK_EQ(request->type, Request::Type::kReset); DCHECK_GT(requested_resets_, 0); @@ -331,7 +336,7 @@ template <typename Traits> void DecoderTemplate<Traits>::HandleError() { DVLOG(1) << __func__; - if (is_closed_) + if (IsClosed()) return; Shutdown(true); @@ -340,14 +345,14 @@ template <typename Traits> void DecoderTemplate<Traits>::Shutdown(bool is_error) { DVLOG(3) << __func__; - DCHECK(!is_closed_); + DCHECK(!IsClosed()); // Store the error callback so that we can use it after clearing state. V8WebCodecsErrorCallback* error_cb = error_cb_.Get(); // Prevent any new public API calls during teardown. // This should make it safe to call into JS synchronously. - is_closed_ = true; + state_ = V8CodecState(V8CodecState::Enum::kClosed); // Prevent any late callbacks running. output_cb_.Release(); @@ -379,7 +384,7 @@ template <typename Traits> void DecoderTemplate<Traits>::OnConfigureFlushDone(media::DecodeStatus status) { DVLOG(3) << __func__; - if (is_closed_) + if (IsClosed()) return; DCHECK(pending_request_); @@ -400,7 +405,7 @@ template <typename Traits> void DecoderTemplate<Traits>::OnInitializeDone(media::Status status) { DVLOG(3) << __func__; - if (is_closed_) + if (IsClosed()) return; DCHECK(pending_request_); @@ -423,7 +428,7 @@ void DecoderTemplate<Traits>::OnDecodeDone(uint32_t id, media::DecodeStatus status) { DVLOG(3) << __func__; - if (is_closed_) + if (IsClosed()) return; if (status != media::DecodeStatus::OK && @@ -441,7 +446,7 @@ template <typename Traits> void DecoderTemplate<Traits>::OnFlushDone(media::DecodeStatus status) { DVLOG(3) << __func__; - if (is_closed_) + if (IsClosed()) return; DCHECK(pending_request_); @@ -459,7 +464,7 @@ template <typename Traits> void DecoderTemplate<Traits>::OnResetDone() { DVLOG(3) << __func__; - if (is_closed_) + if (IsClosed()) return; DCHECK(pending_request_); @@ -472,8 +477,9 @@ template <typename Traits> void DecoderTemplate<Traits>::OnOutput(scoped_refptr<MediaOutputType> output) { DVLOG(3) << __func__; - if (is_closed_) + if (state_.AsEnum() != V8CodecState::Enum::kConfigured) return; + output_cb_->InvokeAndReportException( nullptr, MakeGarbageCollected<OutputType>(output)); }
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_template.h b/third_party/blink/renderer/modules/webcodecs/decoder_template.h index 43732fc..6369944e 100644 --- a/third_party/blink/renderer/modules/webcodecs/decoder_template.h +++ b/third_party/blink/renderer/modules/webcodecs/decoder_template.h
@@ -13,6 +13,7 @@ #include "media/base/status.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_codec_state.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_codecs_error_callback.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/webcodecs/codec_config_eval.h" @@ -45,6 +46,7 @@ ScriptPromise flush(ExceptionState&); void reset(ExceptionState&); void close(ExceptionState&); + String state() const { return state_; } // GarbageCollected override. void Trace(Visitor*) const override; @@ -103,6 +105,9 @@ void OnResetDone(); void OnOutput(scoped_refptr<MediaOutputType>); + // Helper function making it easier to check |state_|. + bool IsClosed(); + Member<ScriptState> script_state_; Member<OutputCallbackType> output_cb_; Member<V8WebCodecsErrorCallback> error_cb_; @@ -111,6 +116,9 @@ int32_t requested_decodes_ = 0; int32_t requested_resets_ = 0; + // Which state the codec is in, determining which calls we can receive. + V8CodecState state_; + // An in-flight, mutually-exclusive request. // Could be a configure, flush, or reset. Decodes go in |pending_decodes_|. Member<Request> pending_request_; @@ -121,7 +129,6 @@ // duplicates can be elided. std::unique_ptr<MediaDecoderType> decoder_; bool initializing_sync_ = false; - bool is_closed_ = false; // TODO(sandersd): Can this just be a HashSet by ptr comparison? uint32_t pending_decode_id_ = 0;
diff --git a/third_party/blink/renderer/modules/webcodecs/idls.gni b/third_party/blink/renderer/modules/webcodecs/idls.gni index 4045608..b97d8fa 100644 --- a/third_party/blink/renderer/modules/webcodecs/idls.gni +++ b/third_party/blink/renderer/modules/webcodecs/idls.gni
@@ -41,6 +41,8 @@ "video_track_writer_parameters.idl", ] +modules_typedefs_enums_only_idl_files = [ "codec_state.idl" ] + # IDL files that either define partial interfaces or target (right side of) # `includes`. modules_dependency_idl_files = []
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder.idl b/third_party/blink/renderer/modules/webcodecs/video_decoder.idl index c396dbc3..181e46cd 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_decoder.idl +++ b/third_party/blink/renderer/modules/webcodecs/video_decoder.idl
@@ -18,7 +18,7 @@ // |init| includes an |output| callback for emitting VideoFrames and an // |error| callback for emitting decode errors. // - // When in an error state, methods other than reset() will fail. + // When in an closed state, all methods will fail. // // TODO(sandersd): Consider adding a state or last error attribute. [CallWith=ScriptState, RaisesException] constructor(VideoDecoderInit init); @@ -73,4 +73,7 @@ // // Not recoverable: make a new VideoDecoder if needed. [RaisesException] void close(); + + // Which state the decoder is in, indicating which methods can be called. + readonly attribute CodecState state; };
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc index da98d4d..6eb8b9b1 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc +++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
@@ -31,6 +31,7 @@ #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/streams/readable_stream.h" #include "third_party/blink/renderer/core/streams/writable_stream.h" +#include "third_party/blink/renderer/modules/webcodecs/codec_state_helper.h" #include "third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h" #include "third_party/blink/renderer/modules/webcodecs/encoded_video_metadata.h" #include "third_party/blink/renderer/platform/bindings/enumeration_base.h" @@ -106,7 +107,7 @@ VideoEncoder::VideoEncoder(ScriptState* script_state, const VideoEncoderInit* init, ExceptionState& exception_state) - : script_state_(script_state) { + : state_(V8CodecState::Enum::kUnconfigured), script_state_(script_state) { output_callback_ = init->output(); if (init->hasError()) error_callback_ = init->error(); @@ -229,6 +230,9 @@ ExceptionState& exception_state) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (ThrowIfCodecStateClosed(state_, "configure", exception_state)) + return; + auto parsed_config = ParseConfig(config, exception_state); if (!parsed_config) { @@ -244,6 +248,8 @@ // TODO(https://crbug.com/1119892): flush |media_encoder_| if it already // exists, otherwise might could lose frames in flight. + state_ = V8CodecState(V8CodecState::Enum::kConfigured); + Request* request = MakeGarbageCollected<Request>(); request->type = Request::Type::kConfigure; request->config = std::move(parsed_config); @@ -254,11 +260,12 @@ const VideoEncoderEncodeOptions* opts, ExceptionState& exception_state) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!media_encoder_) { - exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, - "Encoder is not configured yet."); + + if (ThrowIfCodecStateClosed(state_, "encode", exception_state)) return; - } + + if (ThrowIfCodecStateUnconfigured(state_, "encode", exception_state)) + return; // This will fail if |frame| is already destroyed. auto* internal_frame = frame->clone(exception_state); @@ -296,22 +303,25 @@ void VideoEncoder::close(ExceptionState& exception_state) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!media_encoder_) + + if (ThrowIfCodecStateClosed(state_, "close", exception_state)) return; - reset(exception_state); + state_ = V8CodecState(V8CodecState::Enum::kClosed); + + ClearRequests(); media_encoder_.reset(); output_callback_.Clear(); error_callback_.Clear(); } -ScriptPromise VideoEncoder::flush(ExceptionState&) { +ScriptPromise VideoEncoder::flush(ExceptionState& exception_state) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!media_encoder_) { - auto* ex = MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, "Encoder is not configured yet."); - return ScriptPromise::RejectWithDOMException(script_state_, ex); - } + if (ThrowIfCodecStateClosed(state_, "flush", exception_state)) + return ScriptPromise(); + + if (ThrowIfCodecStateUnconfigured(state_, "flush", exception_state)) + return ScriptPromise(); Request* request = MakeGarbageCollected<Request>(); request->resolver = @@ -321,10 +331,19 @@ return request->resolver->Promise(); } -void VideoEncoder::reset(ExceptionState&) { +void VideoEncoder::reset(ExceptionState& exception_state) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // TODO: Not fully implemented yet + if (ThrowIfCodecStateClosed(state_, "reset", exception_state)) + return; + ClearRequests(); + + state_ = V8CodecState(V8CodecState::Enum::kUnconfigured); +} + +void VideoEncoder::ClearRequests() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); while (!requests_.empty()) { Request* pending_req = requests_.TakeFirst(); DCHECK(pending_req); @@ -337,7 +356,8 @@ } void VideoEncoder::CallOutputCallback(EncodedVideoChunk* chunk) { - if (!script_state_->ContextIsValid() || !output_callback_) + if (!script_state_->ContextIsValid() || !output_callback_ || + state_.AsEnum() != V8CodecState::Enum::kConfigured) return; ScriptState::Scope scope(script_state_); output_callback_->InvokeAndReportException(nullptr, chunk); @@ -347,6 +367,10 @@ // Save a temp before we clear the callback. V8WebCodecsErrorCallback* error_callback = error_callback_.Get(); + state_ = V8CodecState(V8CodecState::Enum::kClosed); + + ClearRequests(); + // Errors are permanent. Shut everything down. error_callback_.Clear(); media_encoder_.reset(); @@ -391,6 +415,8 @@ void VideoEncoder::ProcessEncode(Request* request) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK_EQ(state_, V8CodecState::Enum::kConfigured); + DCHECK(media_encoder_); DCHECK_EQ(request->type, Request::Type::kEncode); DCHECK_GT(requested_encodes_, 0); @@ -406,11 +432,6 @@ self->ProcessRequests(); }; - if (!media_encoder_) { - HandleError(DOMExceptionCode::kOperationError, "Encoder is not configured"); - return; - } - scoped_refptr<media::VideoFrame> frame = request->frame->frame(); if (frame->storage_type() == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER) { frame = ConvertToI420Frame(frame); @@ -432,6 +453,7 @@ } void VideoEncoder::ProcessConfigure(Request* request) { + DCHECK_NE(state_.AsEnum(), V8CodecState::Enum::kClosed); DCHECK(request->config); DCHECK_EQ(request->type, Request::Type::kConfigure); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -481,6 +503,8 @@ void VideoEncoder::ProcessFlush(Request* request) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK_EQ(state_, V8CodecState::Enum::kConfigured); + DCHECK(media_encoder_); DCHECK_EQ(request->type, Request::Type::kFlush); auto done_callback = [](VideoEncoder* self, Request* req, @@ -502,14 +526,6 @@ self->ProcessRequests(); }; - if (!media_encoder_) { - auto* ex = MakeGarbageCollected<DOMException>( - DOMExceptionCode::kOperationError, "Encoder is not configured"); - HandleError(ex); - request->resolver.Release()->Reject(ex); - return; - } - stall_request_processing_ = true; media_encoder_->Flush(WTF::Bind(done_callback, WrapWeakPersistent(this), WrapPersistentIfNeeded(request)));
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.h b/third_party/blink/renderer/modules/webcodecs/video_encoder.h index e338e6f..5d5b863 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_encoder.h +++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.h
@@ -13,6 +13,7 @@ #include "media/base/video_color_space.h" #include "media/base/video_encoder.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_codec_state.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_output_callback.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_codecs_error_callback.h" #include "third_party/blink/renderer/modules/modules_export.h" @@ -58,6 +59,8 @@ void close(ExceptionState&); + String state() { return state_; } + // GarbageCollected override. void Trace(Visitor*) const override; @@ -103,6 +106,8 @@ void ProcessConfigure(Request* request); void ProcessFlush(Request* request); + void ClearRequests(); + void MediaEncoderOutputCallback(media::VideoEncoderOutput output); std::unique_ptr<ParsedConfig> ParseConfig(const VideoEncoderConfig*, @@ -112,6 +117,8 @@ gfx::Size frame_size_; std::unique_ptr<media::VideoEncoder> media_encoder_; + V8CodecState state_; + Member<ScriptState> script_state_; Member<V8VideoEncoderOutputCallback> output_callback_; Member<V8WebCodecsErrorCallback> error_callback_;
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.idl b/third_party/blink/renderer/modules/webcodecs/video_encoder.idl index 3ce6a0c1..41860e1 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_encoder.idl +++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.idl
@@ -54,4 +54,7 @@ // rejected. [RaisesException] void close(); + + // Which state the decoder is in, indicating which methods can be called. + readonly attribute CodecState state; };
diff --git a/third_party/blink/renderer/platform/bindings/wrapper_type_info.h b/third_party/blink/renderer/platform/bindings/wrapper_type_info.h index 96ee0295..3ad83fdb 100644 --- a/third_party/blink/renderer/platform/bindings/wrapper_type_info.h +++ b/third_party/blink/renderer/platform/bindings/wrapper_type_info.h
@@ -187,6 +187,13 @@ wrapper->GetAlignedPointerFromInternalField(offset)); } +template <typename T, int offset> +inline T* GetInternalField(v8::Object* wrapper) { + DCHECK_LT(offset, wrapper->InternalFieldCount()); + return reinterpret_cast<T*>( + wrapper->GetAlignedPointerFromInternalField(offset)); +} + // The return value can be null if |wrapper| is a global proxy, which points to // nothing while a navigation. inline ScriptWrappable* ToScriptWrappable( @@ -203,6 +210,10 @@ return GetInternalField<ScriptWrappable, kV8DOMWrapperObjectIndex>(wrapper); } +inline ScriptWrappable* ToScriptWrappable(v8::Object* wrapper) { + return GetInternalField<ScriptWrappable, kV8DOMWrapperObjectIndex>(wrapper); +} + inline CustomWrappable* ToCustomWrappable( const v8::PersistentBase<v8::Object>& wrapper) { return GetInternalField<CustomWrappable, kV8DOMWrapperObjectIndex>(wrapper);
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index ac930690..efdea67 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -717,6 +717,10 @@ RuntimeEnabledFeatures::SetRestrictGamepadAccessEnabled(enable); } +void WebRuntimeFeatures::EnableCompositeSVG(bool enable) { + RuntimeEnabledFeatures::SetCompositeSVGEnabled(enable); +} + void WebRuntimeFeatures::EnableCompositingOptimizations(bool enable) { RuntimeEnabledFeatures::SetCompositingOptimizationsEnabled(enable); }
diff --git a/third_party/blink/renderer/platform/text/character.cc b/third_party/blink/renderer/platform/text/character.cc index 3832e4ca..20e18546 100644 --- a/third_party/blink/renderer/platform/text/character.cc +++ b/third_party/blink/renderer/platform/text/character.cc
@@ -268,4 +268,28 @@ hint_char_script != USCRIPT_COMMON; } +// https://mathml-refresh.github.io/mathml-core/#stretchy-operator-axis +static const UChar stretchy_operator_with_inline_axis[]{ + 0x003D, 0x005E, 0x005F, 0x007E, 0x00AF, 0x02C6, 0x02C7, 0x02C9, 0x02CD, + 0x02DC, 0x02F7, 0x0302, 0x0332, 0x203E, 0x20D0, 0x20D1, 0x20D6, 0x20D7, + 0x20E1, 0x2190, 0x2192, 0x2194, 0x2198, 0x2199, 0x219C, 0x219D, 0x219E, + 0x21A0, 0x21A2, 0x21A3, 0x21A4, 0x21A6, 0x21A9, 0x21AA, 0x21AB, 0x21AC, + 0x21AD, 0x21B4, 0x21B9, 0x21BC, 0x21BD, 0x21C0, 0x21C1, 0x21C4, 0x21C6, + 0x21C7, 0x21C9, 0x21CB, 0x21CC, 0x21D0, 0x21D2, 0x21D4, 0x21DA, 0x21DB, + 0x21DC, 0x21DD, 0x21E0, 0x21E2, 0x21E4, 0x21E5, 0x21E6, 0x21E8, 0x21F0, + 0x21F6, 0x21FD, 0x21FE, 0x21FF, 0x23B4, 0x23B5, 0x23DC, 0x23DD, 0x23DE, + 0x23DF, 0x23E0, 0x23E1, 0x2500, 0x27F5, 0x27F6, 0x27F7, 0x27F8, 0x27F9, + 0x27FA, 0x27FB, 0x27FC, 0x27FD, 0x27FE, 0x27FF, 0x290C, 0x290D, 0x290E, + 0x290F, 0x2910, 0x294E, 0x2950, 0x2952, 0x2953, 0x2956, 0x2957, 0x295A, + 0x295B, 0x295E, 0x295F, 0x2B45, 0x2B46, 0xFE35, 0xFE36, 0xFE37, 0xFE38}; + +bool Character::IsVerticalMathCharacter(UChar32 text_content) { + return text_content != kArabicMathematicalOperatorMeemWithHahWithTatweel && + text_content != kArabicMathematicalOperatorHahWithDal && + !std::binary_search(stretchy_operator_with_inline_axis, + stretchy_operator_with_inline_axis + + base::size(stretchy_operator_with_inline_axis), + text_content); +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/text/character.h b/third_party/blink/renderer/platform/text/character.h index 9604a26..3a177dbc 100644 --- a/third_party/blink/renderer/platform/text/character.h +++ b/third_party/blink/renderer/platform/text/character.h
@@ -202,6 +202,8 @@ return (c - (0x1C90 - 0x10D0)); } + static bool IsVerticalMathCharacter(UChar32); + private: static bool IsCJKIdeographOrSymbolSlow(UChar32); static bool IsHangulSlow(UChar32);
diff --git a/third_party/blink/renderer/platform/text/character_test.cc b/third_party/blink/renderer/platform/text/character_test.cc index 1870ae9..acf6e2fb 100644 --- a/third_party/blink/renderer/platform/text/character_test.cc +++ b/third_party/blink/renderer/platform/text/character_test.cc
@@ -411,4 +411,36 @@ } } +TEST(CharacterTest, IsVerticalMathCharacter) { + // https://mathml-refresh.github.io/mathml-core/#stretchy-operator-axis + const UChar stretchy_operator_with_inline_axis[]{ + 0x003D, 0x005E, 0x005F, 0x007E, 0x00AF, 0x02C6, 0x02C7, 0x02C9, 0x02CD, + 0x02DC, 0x02F7, 0x0302, 0x0332, 0x203E, 0x20D0, 0x20D1, 0x20D6, 0x20D7, + 0x20E1, 0x2190, 0x2192, 0x2194, 0x2198, 0x2199, 0x219C, 0x219D, 0x219E, + 0x21A0, 0x21A2, 0x21A3, 0x21A4, 0x21A6, 0x21A9, 0x21AA, 0x21AB, 0x21AC, + 0x21AD, 0x21B4, 0x21B9, 0x21BC, 0x21BD, 0x21C0, 0x21C1, 0x21C4, 0x21C6, + 0x21C7, 0x21C9, 0x21CB, 0x21CC, 0x21D0, 0x21D2, 0x21D4, 0x21DA, 0x21DB, + 0x21DC, 0x21DD, 0x21E0, 0x21E2, 0x21E4, 0x21E5, 0x21E6, 0x21E8, 0x21F0, + 0x21F6, 0x21FD, 0x21FE, 0x21FF, 0x23B4, 0x23B5, 0x23DC, 0x23DD, 0x23DE, + 0x23DF, 0x23E0, 0x23E1, 0x2500, 0x27F5, 0x27F6, 0x27F7, 0x27F8, 0x27F9, + 0x27FA, 0x27FB, 0x27FC, 0x27FD, 0x27FE, 0x27FF, 0x290C, 0x290D, 0x290E, + 0x290F, 0x2910, 0x294E, 0x2950, 0x2952, 0x2953, 0x2956, 0x2957, 0x295A, + 0x295B, 0x295E, 0x295F, 0x2B45, 0x2B46, 0xFE35, 0xFE36, 0xFE37, 0xFE38}; + + for (UChar32 test_char = 0; test_char < kMaxCodepoint; test_char++) { + if (test_char == kArabicMathematicalOperatorMeemWithHahWithTatweel) { + EXPECT_FALSE(Character::IsVerticalMathCharacter(test_char)); + } else if (test_char == kArabicMathematicalOperatorHahWithDal) { + EXPECT_FALSE(Character::IsVerticalMathCharacter(test_char)); + } else { + bool in_vertical = !std::binary_search( + stretchy_operator_with_inline_axis, + stretchy_operator_with_inline_axis + + base::size(stretchy_operator_with_inline_axis), + test_char); + EXPECT_TRUE(Character::IsVerticalMathCharacter(test_char) == in_vertical); + } + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/wtf/text/character_names.h b/third_party/blink/renderer/platform/wtf/text/character_names.h index d1a7a2f7..19b0b44 100644 --- a/third_party/blink/renderer/platform/wtf/text/character_names.h +++ b/third_party/blink/renderer/platform/wtf/text/character_names.h
@@ -41,6 +41,8 @@ const UChar32 kAegeanWordSeparatorLineCharacter = 0x10100; const UChar32 kAegeanWordSeparatorDotCharacter = 0x10101; const UChar kArabicLetterMarkCharacter = 0x061C; +const UChar32 kArabicMathematicalOperatorMeemWithHahWithTatweel = 0x1EEF0; +const UChar32 kArabicMathematicalOperatorHahWithDal = 0x1EEF1; const UChar kBlackCircleCharacter = 0x25CF; const UChar kBlackSquareCharacter = 0x25A0; const UChar kBlackUpPointingTriangleCharacter = 0x25B2; @@ -184,6 +186,8 @@ using WTF::unicode::kAegeanWordSeparatorDotCharacter; using WTF::unicode::kAegeanWordSeparatorLineCharacter; using WTF::unicode::kArabicLetterMarkCharacter; +using WTF::unicode::kArabicMathematicalOperatorHahWithDal; +using WTF::unicode::kArabicMathematicalOperatorMeemWithHahWithTatweel; using WTF::unicode::kBlackCircleCharacter; using WTF::unicode::kBlackSquareCharacter; using WTF::unicode::kBlackUpPointingTriangleCharacter;
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py index ce4de99..ae15d72 100755 --- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py +++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -831,6 +831,20 @@ }, { 'paths': [ + 'third_party/blink/renderer/modules/media/audio/', + ], + 'allowed': [ + # TODO(https://crbug.com/787252): Remove most of the entries below, + # once the directory is fully Onion soup'ed. + 'base::flat_map', + 'base::Bind.*', + 'base::Unretained', + 'mojo::WrapCallbackWithDefaultInvokeIfNotRun', + 'base::ScopedPlatformFile', + ] + }, + { + 'paths': [ 'third_party/blink/renderer/modules/imagecapture/', ], 'allowed': [
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng index e9837e3..f6a1415b 100644 --- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng +++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -122,10 +122,6 @@ crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-026.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-027.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-028.tentative.html [ Failure ] -crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-001.tentative.html [ Failure ] -crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-002.tentative.html [ Failure ] -crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-004.tentative.html [ Failure ] -crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-005.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-008.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-009.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/intrinsic-size-001.tentative.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index fac130f8c..797bd3fa 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -915,8 +915,6 @@ crbug.com/591099 fast/selectors/shadow-host-div-with-text.html [ Failure ] crbug.com/591099 virtual/text-antialias/selection/inline-block-in-selection-root.html [ Failure ] crbug.com/591099 paint/invalidation/media-audio-no-spurious-repaints.html [ Failure Timeout ] -crbug.com/591099 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-list-item-002.html [ Failure ] -crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/border-radius-clipped-layer.html [ Failure ] crbug.com/591099 editing/selection/paint-hyphen.html [ Failure Pass ] crbug.com/591099 external/wpt/dom/ranges/Range-compareBoundaryPoints.html [ Timeout Failure Pass ] crbug.com/591099 external/wpt/dom/ranges/Range-set.html [ Failure Timeout ] @@ -965,12 +963,6 @@ # If they are not also fixed, reinstate them when removing these lines. crbug.com/982211 fast/events/before-unload-return-value-from-listener.html [ Pass Crash Timeout ] -# Crashes/asserts due to inline item reuse. -crbug.com/636993 virtual/layout_ng_block_frag/fast/multicol/dynamic/remove-inline-and-spanner-after-spanner-foreignObject.html [ Pass Crash Timeout ] - -crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/flowthread-with-floats-destroyed-crash.html [ Crash Pass ] - - ### With LayoutNGFragmentItem enabled crbug.com/982194 [ Win ] external/wpt/css/CSS2/linebox/empty-inline-002.xht [ Failure ] crbug.com/982194 [ Win ] external/wpt/css/css-text/white-space/line-edge-white-space-collapse-001.html [ Failure ] @@ -992,36 +984,59 @@ crbug.com/982194 [ Win10 ] paint/invalidation/outline/focus-ring-on-continuation-move.html [ Failure ] crbug.com/982194 [ Win10 ] paint/invalidation/outline/focus-ring-on-inline-continuation-move.html [ Failure ] +### Tests passing with LayoutNGBlockFragmentation enabled: +virtual/layout_ng_block_frag/external/wpt/css/css-break/avoid-border-break.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/borders-000.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/borders-001.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/borders-002.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/borders-003.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/borders-004.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/borders-005.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/break-at-end-container-edge-000.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/break-at-end-container-edge-001.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/break-at-end-container-edge-002.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/break-at-end-container-edge-004.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/break-between-avoid-000.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/break-between-avoid-001.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/break-between-avoid-003.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/break-between-avoid-004.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/forced-break-at-fragmentainer-start-000.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/overflowed-block-with-no-room-after-000.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/overflowed-block-with-no-room-after-001.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/tall-line-in-short-fragmentainer-000.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/tall-line-in-short-fragmentainer-001.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/tall-line-in-short-fragmentainer-002.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/trailing-child-margin-000.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/trailing-child-margin-002.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-006.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-007.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-008.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-fieldset-001.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-margin-bottom-001.xht [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-float-001.xht [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-multicol/nested-with-too-tall-line.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-multicol/non-adjacent-spanners-000.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-multicol/spanner-fragmentation-001.html [ Pass ] +virtual/layout_ng_block_frag/fast/multicol/newmulticol/hide-box-vertical-lr.html [ Pass ] +virtual/layout_ng_block_frag/fast/multicol/span/vertical-lr.html [ Pass ] +virtual/layout_ng_block_frag/fast/multicol/vertical-lr/abspos-auto-position-on-line.html [ Pass ] +virtual/layout_ng_block_frag/fast/multicol/vertical-lr/column-break-with-balancing.html [ Pass ] +virtual/layout_ng_block_frag/fast/multicol/vertical-lr/column-count-with-rules.html [ Pass ] +virtual/layout_ng_block_frag/fast/multicol/vertical-lr/column-rules.html [ Pass ] +virtual/layout_ng_block_frag/fast/multicol/vertical-lr/float-big-line.html [ Pass ] +virtual/layout_ng_block_frag/fast/multicol/vertical-lr/float-break.html [ Pass ] +virtual/layout_ng_block_frag/fast/multicol/vertical-lr/float-content-break.html [ Pass ] +virtual/layout_ng_block_frag/fast/multicol/vertical-lr/float-edge.html [ Pass ] +virtual/layout_ng_block_frag/fast/multicol/vertical-lr/float-paginate.html [ Pass ] +virtual/layout_ng_block_frag/fast/multicol/vertical-lr/unsplittable-inline-block.html [ Pass ] -### With LayoutNGBlockFragmentation enabled: - +### Tests failing with LayoutNGBlockFragmentation enabled: crbug.com/1079031 virtual/layout_ng_block_frag/external/wpt/css/css-break/block-end-aligned-abspos-nested.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/block-end-aligned-abspos-with-overflow.html [ Failure ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/borders-000.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/borders-001.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/borders-002.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/borders-003.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/borders-004.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/borders-005.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/break-at-end-container-edge-000.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/break-at-end-container-edge-001.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/break-at-end-container-edge-002.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/break-at-end-container-edge-004.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/break-between-avoid-000.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/break-between-avoid-001.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/break-between-avoid-003.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/break-between-avoid-004.html [ Pass ] crbug.com/1028595 virtual/layout_ng_block_frag/external/wpt/css/css-break/fieldset-001.html [ Failure ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/forced-break-at-fragmentainer-start-000.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/overflowed-block-with-no-room-after-001.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/overflowed-block-with-no-room-after-000.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/tall-line-in-short-fragmentainer-000.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/tall-line-in-short-fragmentainer-001.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/tall-line-in-short-fragmentainer-002.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/trailing-child-margin-000.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/trailing-child-margin-002.html [ Pass ] crbug.com/1066380 virtual/layout_ng_block_frag/external/wpt/css/css-break/widows-orphans-002.html [ Failure ] crbug.com/1066380 virtual/layout_ng_block_frag/external/wpt/css/css-break/widows-orphans-004.html [ Failure ] +crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/widows-orphans-005.html [ Failure ] crbug.com/875235 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-size-breaks-001.html [ Crash Failure ] crbug.com/875235 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-size-monolithic-001.html [ Crash Failure ] crbug.com/875235 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-size-multicol-001.html [ Failure ] @@ -1070,14 +1085,13 @@ crbug.com/874051 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-fieldset-002.html [ Failure Crash ] crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-fieldset-003.html [ Crash Failure ] crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-list-item-001.html [ Failure ] +crbug.com/591099 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-list-item-002.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-001.xht [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-002.xht [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-003.xht [ Crash Failure Timeout ] crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-004.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-ch-001.xht [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-small-001.xht [ Failure ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/non-adjacent-spanners-000.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/spanner-fragmentation-001.html [ Pass ] crbug.com/875235 virtual/layout_ng_block_frag/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-size-multicol-002.html [ Failure ] crbug.com/875235 virtual/layout_ng_block_frag/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-size-multicol-003.html [ Failure ] crbug.com/875235 virtual/layout_ng_block_frag/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-multicol.html [ Failure ] @@ -1088,6 +1102,8 @@ crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/balance-line-overflow.html [ Failure ] crbug.com/994172 virtual/layout_ng_block_frag/fast/multicol/balance-line-underflow-1.html [ Pass Crash ] crbug.com/994172 virtual/layout_ng_block_frag/fast/multicol/balance-line-underflow-2.html [ Pass Crash ] +crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/border-radius-clipped-layer.html [ Failure ] +crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/border-radius-clipped-layer-second-column.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/break-before-first-line-in-first-child.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/caret-range-anonymous-block.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/caret-range-anonymous-block-rtl.html [ Failure ] @@ -1110,20 +1126,24 @@ crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/dynamic/insert-spanner-into-stf-unconstrained-width.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/dynamic/relpos-becomes-static-has-abspos.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/dynamic/remove-column-content-next-to-abspos-between-spanners.html [ Failure ] +crbug.com/636993 virtual/layout_ng_block_frag/fast/multicol/dynamic/remove-inline-and-spanner-after-spanner-foreignObject.html [ Pass Crash Timeout ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/dynamic/static-becomes-relpos-has-abspos.html [ Crash Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/event-offset-in-nested.html [ Failure ] crbug.com/875235 virtual/layout_ng_block_frag/fast/multicol/fieldset-as-multicol.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/file-upload-as-multicol.html [ Failure ] +crbug.com/1061423 virtual/layout_ng_block_frag/fast/multicol/flipped-blocks-hit-test.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/float-after-break-after.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/float-avoidance.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/float-margin-at-row-boundary.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/float-margin-at-row-boundary-fixed-multicol-height.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/float-moved-by-child-line-and-unbreakable.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/float-paginate-empty-lines.html [ Failure ] +crbug.com/1061423 virtual/layout_ng_block_frag/fast/multicol/float-truncation.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/float-with-margin-moved-by-child-block-and-unbreakable.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/float-with-margin-moved-by-child-block.html [ Failure Timeout ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/float-with-margin-moved-by-child-line-and-unbreakable.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/float-with-margin-moved-by-child-line.html [ Failure ] +crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/flowthread-with-floats-destroyed-crash.html [ Crash Pass ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/forced-break-in-nested-columns.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/forced-break-too-short-column.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/hit-test-above-or-below.html [ Failure ] @@ -1199,10 +1219,8 @@ crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/client-rects-crossing-boundaries-nested.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/float-avoidance.html [ Crash Failure ] -crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/float-big-line.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/float-break.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/float-content-break.html [ Pass ] -crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/float-paginate.html [ Pass ] +crbug.com/1061423 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/float-truncation.html [ Failure ] +crbug.com/1061423 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/float-truncation.html [ Failure ] crbug.com/467477 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/nested-columns.html [ Crash Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/offset-top-and-left-at-boundaries-nested.html [ Failure ] crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/offset-top-and-left-nested.html [ Failure ] @@ -1224,42 +1242,8 @@ crbug.com/829028 virtual/layout_ng_block_frag/printing/frameset.html [ Failure ] crbug.com/829804 virtual/layout_ng_block_frag/printing/webgl-oversized-printing.html [ Skip ] -### With LayoutNGBlockFragmentation and LayoutNGFragmentItem enabled: -crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-break/widows-orphans-005.html [ Failure ] -crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/border-radius-clipped-layer-second-column.html [ Failure ] -crbug.com/1061423 virtual/layout_ng_block_frag/fast/multicol/flipped-blocks-hit-test.html [ Failure ] -crbug.com/1061423 virtual/layout_ng_block_frag/fast/multicol/float-truncation.html [ Failure ] -crbug.com/1061423 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/float-truncation.html [ Failure ] -crbug.com/1061423 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/float-truncation.html [ Failure ] - -### Tests passing with LayoutNGBlockFragmentation -virtual/layout_ng_block_frag/external/wpt/css/css-break/avoid-border-break.html [ Pass ] -virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-006.html [ Pass ] -virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-007.html [ Pass ] -virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-008.html [ Pass ] -virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-fieldset-001.html [ Pass ] -virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-margin-bottom-001.xht [ Pass ] -virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-float-001.xht [ Pass ] -virtual/layout_ng_block_frag/external/wpt/css/css-multicol/nested-with-too-tall-line.html [ Pass ] -virtual/layout_ng_block_frag/fast/multicol/newmulticol/hide-box-vertical-lr.html [ Pass ] -virtual/layout_ng_block_frag/fast/multicol/span/vertical-lr.html [ Pass ] -virtual/layout_ng_block_frag/fast/multicol/vertical-lr/abspos-auto-position-on-line.html [ Pass ] -virtual/layout_ng_block_frag/fast/multicol/vertical-lr/column-break-with-balancing.html [ Pass ] -virtual/layout_ng_block_frag/fast/multicol/vertical-lr/column-count-with-rules.html [ Pass ] -virtual/layout_ng_block_frag/fast/multicol/vertical-lr/column-rules.html [ Pass ] -virtual/layout_ng_block_frag/fast/multicol/vertical-lr/float-edge.html [ Pass ] -virtual/layout_ng_block_frag/fast/multicol/vertical-lr/unsplittable-inline-block.html [ Pass ] - ### With LayoutNGFragmentTraversal (and LayoutNGFragmentItem) enabled: -virtual/layout_ng_fragment_traversal/external/wpt/css/CSS2/linebox/inline-formatting-context-023.xht [ Pass ] -virtual/layout_ng_fragment_traversal/external/wpt/css/CSS2/linebox/line-height-126.xht [ Pass ] -virtual/layout_ng_fragment_traversal/external/wpt/css/CSS2/normal-flow/max-height-applies-to-012.xht [ Pass ] -virtual/layout_ng_fragment_traversal/external/wpt/css/CSS2/normal-flow/max-width-applies-to-012.xht [ Pass ] -virtual/layout_ng_fragment_traversal/external/wpt/css/CSS2/normal-flow/min-height-applies-to-012.xht [ Pass ] -virtual/layout_ng_fragment_traversal/external/wpt/css/CSS2/normal-flow/min-width-applies-to-012.xht [ Pass ] -virtual/layout_ng_fragment_traversal/external/wpt/css/CSS2/normal-flow/width-applies-to-012.xht [ Pass ] - crbug.com/982194 [ Mac ] virtual/layout_ng_fragment_traversal/fast/table/027-vertical.html [ Failure ] crbug.com/982194 [ Mac ] virtual/layout_ng_fragment_traversal/fast/table/border-collapsing/003-vertical.html [ Failure ]
diff --git a/third_party/blink/web_tests/WPTOverrideExpectations b/third_party/blink/web_tests/WPTOverrideExpectations index 4d74e90..11f9a2c 100644 --- a/third_party/blink/web_tests/WPTOverrideExpectations +++ b/third_party/blink/web_tests/WPTOverrideExpectations
@@ -946,11 +946,6 @@ external/wpt/orientation-sensor/RelativeOrientationSensor-iframe-access.https.html [ Pass ] # wpt_subtest_failure external/wpt/orientation-sensor/RelativeOrientationSensor.https.html [ Pass ] # wpt_subtest_failure external/wpt/paint-timing/sibling-painting-first-image.html [ Failure Pass ] # wpt_subtest_failure -external/wpt/payment-request/payment-is-showing.https.html [ Failure ] # wpt_subtest_failure -external/wpt/payment-request/payment-request-canmakepayment-method-protection.https.html [ Pass ] # wpt_subtest_failure -external/wpt/payment-request/payment-request-canmakepayment-method.https.html [ Failure ] -external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https.html [ Failure ] # wpt_subtest_failure -external/wpt/payment-request/payment-request-show-method.https.html [ Failure ] external/wpt/picture-in-picture/css-selector.html [ Pass ] # wpt_subtest_failure external/wpt/picture-in-picture/disable-picture-in-picture.html [ Pass ] # wpt_subtest_failure external/wpt/picture-in-picture/enter-picture-in-picture.html [ Pass ] # wpt_subtest_failure
diff --git a/third_party/blink/web_tests/android/ChromiumWPTExpectations b/third_party/blink/web_tests/android/ChromiumWPTExpectations index efed7a7..d1556508 100644 --- a/third_party/blink/web_tests/android/ChromiumWPTExpectations +++ b/third_party/blink/web_tests/android/ChromiumWPTExpectations
@@ -1877,7 +1877,7 @@ crbug.com/1050754 external/wpt/eventsource/shared-worker/eventsource-onopen.htm [ Failure ] crbug.com/1050754 external/wpt/eventsource/shared-worker/eventsource-prototype.htm [ Failure ] crbug.com/1050754 external/wpt/eventsource/shared-worker/eventsource-url.htm [ Failure ] -crbug.com/1050754 external/wpt/feature-policy/experimental-features/document-write.tentative.html [ Failure ] +crbug.com/1050754 external/wpt/document-policy/experimental-features/document-write.tentative.html [ Failure ] crbug.com/1050754 external/wpt/feature-policy/experimental-features/focus-without-user-activation-disabled-tentative.html [ Failure ] crbug.com/1050754 external/wpt/feature-policy/experimental-features/focus-without-user-activation-enabled-tentative.sub.html [ Timeout ] crbug.com/1050754 external/wpt/feature-policy/experimental-features/sync-script.tentative.https.sub.html [ Failure ] @@ -1902,8 +1902,8 @@ crbug.com/1050754 external/wpt/feature-policy/picture-in-picture-supported-by-feature-policy.html [ Failure ] crbug.com/1050754 external/wpt/feature-policy/reporting/camera-report-only.https.html [ Timeout ] crbug.com/1050754 external/wpt/feature-policy/reporting/camera-reporting.https.html [ Timeout ] -crbug.com/1050754 external/wpt/feature-policy/reporting/document-write-report-only.html [ Timeout ] -crbug.com/1050754 external/wpt/feature-policy/reporting/document-write-reporting.html [ Failure ] +crbug.com/1050754 external/wpt/document-policy/reporting/document-write-report-only-tentative.html [ Timeout ] +crbug.com/1050754 external/wpt/document-policy/reporting/document-write-reporting-tentative.html [ Failure ] crbug.com/1050754 external/wpt/feature-policy/reporting/encrypted-media-report-only.https.html [ Timeout ] crbug.com/1050754 external/wpt/feature-policy/reporting/encrypted-media-reporting.https.html [ Timeout ] crbug.com/1050754 external/wpt/feature-policy/reporting/fullscreen-report-only.html [ Timeout ]
diff --git a/third_party/blink/web_tests/android/WeblayerWPTExpectations b/third_party/blink/web_tests/android/WeblayerWPTExpectations index 3ac1604..88f2020 100644 --- a/third_party/blink/web_tests/android/WeblayerWPTExpectations +++ b/third_party/blink/web_tests/android/WeblayerWPTExpectations
@@ -1777,7 +1777,7 @@ crbug.com/1050754 external/wpt/eventsource/shared-worker/eventsource-onopen.htm [ Failure ] crbug.com/1050754 external/wpt/eventsource/shared-worker/eventsource-prototype.htm [ Failure ] crbug.com/1050754 external/wpt/eventsource/shared-worker/eventsource-url.htm [ Failure ] -crbug.com/1050754 external/wpt/feature-policy/experimental-features/document-write.tentative.html [ Failure ] +crbug.com/1050754 external/wpt/document-policy/experimental-features/document-write.tentative.html [ Failure ] crbug.com/1050754 external/wpt/feature-policy/experimental-features/focus-without-user-activation-disabled-tentative.html [ Failure ] crbug.com/1050754 external/wpt/feature-policy/experimental-features/focus-without-user-activation-enabled-tentative.sub.html [ Timeout ] crbug.com/1050754 external/wpt/feature-policy/experimental-features/sync-script.tentative.https.sub.html [ Failure ] @@ -1803,8 +1803,8 @@ crbug.com/1050754 external/wpt/feature-policy/picture-in-picture-supported-by-feature-policy.html [ Failure ] crbug.com/1050754 external/wpt/feature-policy/reporting/camera-report-only.https.html [ Timeout ] crbug.com/1050754 external/wpt/feature-policy/reporting/camera-reporting.https.html [ Timeout ] -crbug.com/1050754 external/wpt/feature-policy/reporting/document-write-report-only.html [ Timeout ] -crbug.com/1050754 external/wpt/feature-policy/reporting/document-write-reporting.html [ Failure ] +crbug.com/1050754 external/wpt/document-policy/reporting/document-write-report-only-tentative.html [ Timeout ] +crbug.com/1050754 external/wpt/document-policy/reporting/document-write-reporting-tentative.html [ Failure ] crbug.com/1050754 external/wpt/feature-policy/reporting/encrypted-media-report-only.https.html [ Timeout ] crbug.com/1050754 external/wpt/feature-policy/reporting/encrypted-media-reporting.https.html [ Timeout ] crbug.com/1050754 external/wpt/feature-policy/reporting/fullscreen-report-only.html [ Failure Timeout ]
diff --git a/third_party/blink/web_tests/android/WebviewWPTExpectations b/third_party/blink/web_tests/android/WebviewWPTExpectations index a990eb5b..f70fea0 100644 --- a/third_party/blink/web_tests/android/WebviewWPTExpectations +++ b/third_party/blink/web_tests/android/WebviewWPTExpectations
@@ -1924,7 +1924,7 @@ crbug.com/1050754 external/wpt/eventsource/shared-worker/eventsource-onopen.htm [ Failure ] crbug.com/1050754 external/wpt/eventsource/shared-worker/eventsource-prototype.htm [ Failure ] crbug.com/1050754 external/wpt/eventsource/shared-worker/eventsource-url.htm [ Failure ] -crbug.com/1050754 external/wpt/feature-policy/experimental-features/document-write.tentative.html [ Failure ] +crbug.com/1050754 external/wpt/document-policy/experimental-features/document-write.tentative.html [ Failure ] crbug.com/1050754 external/wpt/feature-policy/experimental-features/focus-without-user-activation-disabled-tentative.html [ Failure ] crbug.com/1050754 external/wpt/feature-policy/experimental-features/focus-without-user-activation-enabled-tentative.sub.html [ Timeout ] crbug.com/1050754 external/wpt/feature-policy/experimental-features/sync-script.tentative.https.sub.html [ Failure ] @@ -1951,8 +1951,8 @@ crbug.com/1050754 external/wpt/feature-policy/picture-in-picture-supported-by-feature-policy.html [ Failure ] crbug.com/1050754 external/wpt/feature-policy/reporting/camera-report-only.https.html [ Timeout ] crbug.com/1050754 external/wpt/feature-policy/reporting/camera-reporting.https.html [ Timeout ] -crbug.com/1050754 external/wpt/feature-policy/reporting/document-write-report-only.html [ Timeout ] -crbug.com/1050754 external/wpt/feature-policy/reporting/document-write-reporting.html [ Failure ] +crbug.com/1050754 external/wpt/document-policy/reporting/document-write-report-only-tentative.html [ Timeout ] +crbug.com/1050754 external/wpt/document-policy/reporting/document-write-reporting-tentative.html [ Failure ] crbug.com/1050754 external/wpt/feature-policy/reporting/encrypted-media-report-only.https.html [ Timeout ] crbug.com/1050754 external/wpt/feature-policy/reporting/encrypted-media-reporting.https.html [ Timeout ] crbug.com/1050754 external/wpt/feature-policy/reporting/fullscreen-report-only.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 0bd04ae3..93813a0d 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -207272,6 +207272,10 @@ ] }, "the-offscreen-canvas": { + "offscreencanvas.commit-expected.txt": [ + "15d774a7fea1b183bf8e87740b8ba8cee46071c0", + [] + ], "offscreencanvas.transferrable-expected.txt": [ "c03435e3c6ab6f3c0fa274b6d7063a1848a2a302", [] @@ -208143,11 +208147,15 @@ [] ], "common.js": [ - "8a3cd133734dc38d18c190c77c8ebc947c260030", + "5a1744cd9ceaa438bdc2e50dea3f66acb8657eb3", [] ], "coop-coep.py": [ - "dd232e601bf7182bd2ac07e15791973d60f587e8", + "285b961e9969175161ffe51791c20afec5c4fdbb", + [] + ], + "coop-same-origin-repeated.asis": [ + "082478e1599eb8974319a31334e41f46ab0fb91d", [] ], "iframe-popup.sub.html": [ @@ -218869,7 +218877,7 @@ [] ], "console.idl": [ - "3cd3c06b54b022c61857a6a29e8e97bf4fa9b47b", + "01e155e443d8d5a313e6e5048a4a4a510d6dbbb2", [] ], "construct-stylesheets.idl": [ @@ -219429,7 +219437,7 @@ [] ], "webauthn.idl": [ - "607c4765485041e5a8e5fe65571469bedf1d6fd0", + "ed6437751e17814dc0cec756ea136d9ec7eee857", [] ], "webdriver.idl": [ @@ -225828,7 +225836,11 @@ [] ], "animation-timeline-in-keyframe-expected.txt": [ - "0af056bbffc521c1ad6615ff3beed9d0a9a3bc0f", + "e714ac78cda2f6e8d04efcb295911dd97ebc7a36", + [] + ], + "animation-timeline-none-expected.txt": [ + "3b56d986e1b02045d758b25bb301a129702fafcf", [] ], "animation-timeline-parsing-expected.txt": [ @@ -235721,7 +235733,7 @@ [] ], "README.md": [ - "277cbe550c065782b0e315de04651c9e068cb3ad", + "8684f2cc7ee36960ef3ba9a7dafeef8db591a6f7", [] ], "example": { @@ -235766,7 +235778,7 @@ [] ], "echo_client.py": [ - "e4459a19bc68c7879a174f572122382914e6f7dd", + "dafda059b1139935a571b811daa5a10d4158c61b", [] ], "echo_noext_wsh.py": [ @@ -235836,7 +235848,7 @@ [] ], "extensions.py": [ - "344539f6fce14bee65d7fa7a583acbb65f023aff", + "314a949d4550ab6ff5500f5254387d2b35cae535", [] ], "fast_masking.i": [ @@ -235858,7 +235870,7 @@ ] }, "http_header_util.py": [ - "ded90b247b8ded9f254daba70909cbc8ff3c82d6", + "21fde59af10c3b6e373fc2d64f19401c6ed7dc38", [] ], "memorizingfile.py": [ @@ -235870,7 +235882,7 @@ [] ], "request_handler.py": [ - "e038d9f43acd37bf5a1b10a0ce5585bd51ed602d", + "5e9c875dc7daff9929a47d448afcb5aa5bad1b2c", [] ], "server_util.py": [ @@ -235878,7 +235890,7 @@ [] ], "standalone.py": [ - "1042c496c58a23b6ce4c23eee0ba462095452671", + "b075d989f052bb08d15a5a83b6222457da94821c", [] ], "stream.py": [ @@ -235922,7 +235934,7 @@ ] }, "client_for_testing.py": [ - "450a6acd5376223c603abe264b967796832fb573", + "f9aa8119e342a25ccf39a37db64921c67e8e0545", [] ], "mock.py": [ @@ -235930,19 +235942,19 @@ [] ], "run_all.py": [ - "f622015539e47fdf518875158f6bd6f36994faba", + "ea52223cea6d1458adc39dcd2f8b956c885fb419", [] ], "set_sys_path.py": [ - "9fce7b34b6751d635dcda6e0d4a5711951a0a33b", + "48d0e116a5843c1adfedb8cc4c5918c5c2003277", [] ], "test_dispatch.py": [ - "ae63980f2581f9f6136e85dc16bb64ccbe373dc9", + "132dd92d76cef648e2516702e3530e918fb6f4b9", [] ], "test_endtoend.py": [ - "445d29c67ddf07b3f123245977f95cfe0148c83a", + "8d457ff68595feb59a70d0c3e0145d567202444d", [] ], "test_extensions.py": [ @@ -235970,7 +235982,7 @@ [] ], "test_msgutil.py": [ - "943f21b8d297668770cb91c501c2b2fc8258b9eb", + "1122c281b7874bfb3dc1a93f55c4ed3062107825", [] ], "test_stream.py": [ @@ -235978,7 +235990,7 @@ [] ], "test_util.py": [ - "20347941051455ebee58823b4b0be93762912b0a", + "bf4bd32bbac30c52d99997fecc7bbb83cf7516ad", [] ], "testdata": { @@ -238912,6 +238924,10 @@ "cb762eff806849df46dc758ef7b98b63f27f54c9", [] ], + "classic_script.js": [ + "db69b96188d7ca20b8bb12b429aead8fcfdc7b64", + [] + ], "resource1.js": [ "7bd437364a24b6e94493c2acca939991b15cd41c", [] @@ -238930,6 +238946,10 @@ ] }, "dynamic1": { + "classic_script.js": [ + "5fcf045906c1ab151512a3e425b7c5c6f79cee59", + [] + ], "resource1.js": [ "6fd1de600e5599bfe4740b06da6d089e65838f55", [] @@ -238948,6 +238968,10 @@ ] }, "dynamic2": { + "classic_script.js": [ + "546d8a503d90f4de7ca4f45098c8753160c0b169", + [] + ], "resource1.js": [ "c6f751cec49ebe67e3a9a827ef3764ab730a6f17", [] @@ -238995,15 +239019,15 @@ [] ], "dynamic1-crossorigin.wbn": [ - "a35e12aa0a2cb5b6757a9efabb1f3a657a456835", + "5ebb86178e9bf5cccfa09878210c7866f9d80478", [] ], "dynamic1.wbn": [ - "22db19e7ce14d40cc4ba87d120486c24da1a4070", + "9e69e1fd89834bd2d238859413fc8e09d8b6b181", [] ], "dynamic2.wbn": [ - "44c4b1ee86662af2b474447335267cf7b274e62b", + "e4d04d60c2aa9050c6454ad9f88af407a844669d", [] ], "location.wbn": [ @@ -240241,7 +240265,7 @@ [] ], "RTCRtpTransceiver.https-expected.txt": [ - "b0e1b21f7e884b1be93b6dd0d5b40290d5e30861", + "71f96185ebfbc893db80491752604d518432372d", [] ], "RTCStats-helper.js": [ @@ -315384,7 +315408,7 @@ ] ], "request-structure.html": [ - "806606cf627c115aad4c3fd89d4cc2377a3c8a61", + "e137a7ea5120ff24de310020fe330a6725cdb9d7", [ null, {} @@ -331943,7 +331967,7 @@ }, "the-offscreen-canvas": { "offscreencanvas.commit.html": [ - "35cba368116db58cbcb3cdcb9e244a18dbda8650", + "fa0e2ac5fc8b73d316599d8147c039751fd1da3d", [ null, {} @@ -337652,6 +337676,13 @@ {} ] ], + "header-parsing.https.html": [ + "2839c381b807efa2ab934b2ff66c932d5f179e9f", + [ + null, + {} + ] + ], "historical": { "coep-navigate-popup-unsafe-inherit.https.html": [ "21feef73ddf2a9cdfffc58ef2d17d45773fb2b7d", @@ -337981,6 +338012,15 @@ ], "reporting": { "access-reporting": { + "access-to-coop-page-from-other_coop-ro.https.html": [ + "c349b9a708e7cb579db921cc1d574869dc0b081c", + [ + null, + { + "timeout": "long" + } + ] + ], "openee-accessed_openee-coop-ro.https.html": [ "ef969738c33f8cacc8a269f5159e60900f98a7c7", [ @@ -380826,7 +380866,14 @@ ] ], "animation-timeline-in-keyframe.html": [ - "bdf40e0747ff96d58cabdfc820373434cd5e2fd8", + "75483331390d9fb6571307c3158cc37adcd893ee", + [ + null, + {} + ] + ], + "animation-timeline-none.html": [ + "d5d585366c9e3c451f9d19f0c573798d1413644e", [ null, {} @@ -382897,7 +382944,7 @@ ] ], "fetch-request-resources.https.html": [ - "fe227d9ce2f4943ec8a2aa936882f7b46daca28f", + "50864ca78955ea2d52b8e6f71abe2dd6dfef431a", [ null, {} @@ -400775,7 +400822,7 @@ ] ], "subresource-loading-from-web-bundle.tentative.html": [ - "3ab6d7a23e57201eb67833c87283819103193665", + "1e0e78a320403e67d447a6df99ef819bd85c0106", [ null, {} @@ -405627,7 +405674,7 @@ ] ], "RTCRtpTransceiver.https.html": [ - "487774982298376b7ce27a2cbfaea7ad3c716e28", + "45c8664429fc44cb0caf67145641c4cd61052bb7", [ null, { @@ -410297,7 +410344,7 @@ ] ], "set.window.js": [ - "228ce60296697a21520b8c635bd352ed1fbefb2c", + "1c20907939ad0b7b42987f9b2c573e4a17c10707", [ "webstorage/set.window.html", {}
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/document-write.tentative.html b/third_party/blink/web_tests/external/wpt/document-policy/experimental-features/document-write.tentative.html similarity index 88% rename from third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/document-write.tentative.html rename to third_party/blink/web_tests/external/wpt/document-policy/experimental-features/document-write.tentative.html index 7e09ef7e7..551703c6 100644 --- a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/document-write.tentative.html +++ b/third_party/blink/web_tests/external/wpt/document-policy/experimental-features/document-write.tentative.html
@@ -2,7 +2,7 @@ <title>'document-write' tests</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="/feature-policy/experimental-features/resources/common.js"></script> +<script src="/document-policy/experimental-features/resources/common.js"></script> <style> html, body { height: 100%; @@ -20,7 +20,8 @@ } let iframeElement = document.querySelector("iframe"); - let url = url_base + "document-write.html"; + const allowed_url = url_base + "document-write-allowed.html"; + const disallowed_url = url_base + "document-write-disallowed.html"; let text_to_write = "<div>FOO<\/div>"; let test_cases = [{ @@ -49,7 +50,7 @@ test_cases.forEach((tc) => { promise_test(async() => { let iframeElement = newIframe(); - await loadUrlInIframe(iframeElement, url); + await loadUrlInIframe(iframeElement, allowed_url); await sendMessageAndGetResponse(iframeElement.contentWindow, tc).then((response) => { assert_false( response.did_throw_exception, @@ -70,8 +71,7 @@ test_cases.forEach((tc) => { promise_test(async() => { let iframeElement = newIframe(); - setFeatureState(iframeElement, "document-write", "'none'"); - await loadUrlInIframe(iframeElement, url); + await loadUrlInIframe(iframeElement, disallowed_url); await sendMessageAndGetResponse(iframeElement.contentWindow, tc).then((response) => { assert_true( response.did_throw_exception,
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/resources/document-write.html b/third_party/blink/web_tests/external/wpt/document-policy/experimental-features/resources/document-write-allowed.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/resources/document-write.html rename to third_party/blink/web_tests/external/wpt/document-policy/experimental-features/resources/document-write-allowed.html
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/resources/document-write.html b/third_party/blink/web_tests/external/wpt/document-policy/experimental-features/resources/document-write-disallowed.html similarity index 100% copy from third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/resources/document-write.html copy to third_party/blink/web_tests/external/wpt/document-policy/experimental-features/resources/document-write-disallowed.html
diff --git a/third_party/blink/web_tests/external/wpt/document-policy/experimental-features/resources/document-write-disallowed.html.headers b/third_party/blink/web_tests/external/wpt/document-policy/experimental-features/resources/document-write-disallowed.html.headers new file mode 100644 index 0000000..32846f7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/document-policy/experimental-features/resources/document-write-disallowed.html.headers
@@ -0,0 +1 @@ +Document-Policy: document-write=?0 \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/document-write-report-only.html b/third_party/blink/web_tests/external/wpt/document-policy/reporting/document-write-report-only-tentative.html similarity index 83% rename from third_party/blink/web_tests/external/wpt/feature-policy/reporting/document-write-report-only.html rename to third_party/blink/web_tests/external/wpt/document-policy/reporting/document-write-report-only-tentative.html index 69ce9f8..bf17807 100644 --- a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/document-write-report-only.html +++ b/third_party/blink/web_tests/external/wpt/document-policy/reporting/document-write-report-only-tentative.html
@@ -8,7 +8,7 @@ <script> var check_report_format = ([reports, observer]) => { let report = reports[0]; - assert_equals(report.type, "feature-policy-violation"); + assert_equals(report.type, "document-policy-violation"); assert_equals(report.body.featureId, "document-write"); assert_equals(report.body.disposition, "report"); }; @@ -16,7 +16,7 @@ promise_test(async t => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy-violation']}).observe(); + {types: ['document-policy-violation']}).observe(); }); document.write("This should be written into the document"); check_report_format(await report);
diff --git a/third_party/blink/web_tests/external/wpt/document-policy/reporting/document-write-report-only-tentative.html.headers b/third_party/blink/web_tests/external/wpt/document-policy/reporting/document-write-report-only-tentative.html.headers new file mode 100644 index 0000000..924dac8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/document-policy/reporting/document-write-report-only-tentative.html.headers
@@ -0,0 +1 @@ +Document-Policy-Report-Only: document-write=?0
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/document-write-reporting.html b/third_party/blink/web_tests/external/wpt/document-policy/reporting/document-write-reporting-tentative.html similarity index 86% rename from third_party/blink/web_tests/external/wpt/feature-policy/reporting/document-write-reporting.html rename to third_party/blink/web_tests/external/wpt/document-policy/reporting/document-write-reporting-tentative.html index 50af640..65a584c 100644 --- a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/document-write-reporting.html +++ b/third_party/blink/web_tests/external/wpt/document-policy/reporting/document-write-reporting-tentative.html
@@ -10,7 +10,7 @@ var check_report_format = (reports, observer) => { let report = reports[0]; - assert_equals(report.type, "feature-policy-violation"); + assert_equals(report.type, "document-policy-violation"); assert_equals(report.url, document.location.href); assert_equals(report.body.featureId, "document-write"); assert_equals(report.body.sourceFile, document.location.href); @@ -20,7 +20,7 @@ }; new ReportingObserver(t.step_func_done(check_report_format), - {types: ['feature-policy-violation']}).observe(); + {types: ['document-policy-violation']}).observe(); t.step_func(() => { assert_throws_dom('NotAllowedError',
diff --git a/third_party/blink/web_tests/external/wpt/document-policy/reporting/document-write-reporting-tentative.html.headers b/third_party/blink/web_tests/external/wpt/document-policy/reporting/document-write-reporting-tentative.html.headers new file mode 100644 index 0000000..6d05e96 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/document-policy/reporting/document-write-reporting-tentative.html.headers
@@ -0,0 +1 @@ +Document-Policy: document-write=?0
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/document-write-report-only.html.headers b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/document-write-report-only.html.headers deleted file mode 100644 index bd14187..0000000 --- a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/document-write-report-only.html.headers +++ /dev/null
@@ -1 +0,0 @@ -Feature-Policy-Report-Only: document-write 'none'
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/document-write-reporting.html.headers b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/document-write-reporting.html.headers deleted file mode 100644 index 57102d5..0000000 --- a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/document-write-reporting.html.headers +++ /dev/null
@@ -1 +0,0 @@ -Feature-Policy: document-write 'none'
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/request/request-structure.html b/third_party/blink/web_tests/external/wpt/fetch/api/request/request-structure.html index 806606c..e137a7e 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/api/request/request-structure.html +++ b/third_party/blink/web_tests/external/wpt/fetch/api/request/request-structure.html
@@ -58,7 +58,7 @@ break; case "destination": - defaultValue = "empty"; + defaultValue = ""; newValue = "worker"; break;
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.commit-expected.txt b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.commit-expected.txt new file mode 100644 index 0000000..15d774a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.commit-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +FAIL Test that calling OffscreenCanvas's commit pushes its contents to its placeholder. assert_equals: Green channel of the pixel at (5, 5) expected 255 but got 0 +PASS Test that calling commit on an OffscreenCanvas that is not transferred from a HTMLCanvasElement is a noop. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.commit.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.commit.html index 35cba36..fa0e2ac 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.commit.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.commit.html
@@ -14,7 +14,7 @@ _assertPixel(canvas, 5,5, expectedR, expectedG, expectedB, expectedA, "5,5", expectedClrStr); } -test(function() { +async_test(function(t) { var placeholder = document.createElement('canvas'); placeholder.width = placeholder.height = 10; var offscreenCanvas = placeholder.transferControlToOffscreen(); @@ -25,8 +25,9 @@ // place holder contents should still be transparent black at this moment. verifyPlaceholder(placeholder, 0,0,0,0, "0,0,0,0"); // Set timeout acts as a sync barrier to allow commit to propagate - setTimeout(function() { + t.step_timeout(function() { verifyPlaceholder(placeholder, 0,255,0,255, "0,255,0,255"); + t.done(); }, 0); }, "Test that calling OffscreenCanvas's commit pushes its contents to its placeholder.");
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/header-parsing.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/header-parsing.https.html new file mode 100644 index 0000000..2839c381 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/header-parsing.https.html
@@ -0,0 +1,52 @@ +<!doctype html> +<meta charset=utf-8> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="resources/common.js"></script> + +<div id=log></div> +<script> + +let tests = [ + // popup Origin, popup COOP, expect opener + + // None of the following should be recognized as "same-origin" (hence the + // "expected opener" value of `true`). + [SAME_ORIGIN, { percentEncoded: "same%FForigin" }, true], // non-ASCII byte + [SAME_ORIGIN, "same-origin;", true], + [SAME_ORIGIN, "\u000bsame-origin\u000b", true], // vertical tab + [SAME_ORIGIN, "\u000csame-origin\u000c", true], // form feed + [SAME_ORIGIN, "\u000dsame-origin\u000d", true], // carriage return + [SAME_ORIGIN, "Same-origin", true], + [SAME_ORIGIN, "same-origin;\tfoo=bar", true], + [SAME_ORIGIN, "same-origin ;foo=bar", true], + [SAME_ORIGIN, "same-origin; foo=bar;", true], + [SAME_ORIGIN, "\"same-origin\"", true], // HTTP structured fields "string" item + [SAME_ORIGIN, ":c2FtZS1vcmlnaW4=:", true], // HTTP structured fields "byte sequence" item + [SAME_ORIGIN, "?1", true], // HTTP structured fields "boolean" item + [SAME_ORIGIN, "1", true], // HTTP structured fields "integer or decimal" item + [SAME_ORIGIN, "$same-origin", true], // the item type is unrecognized + [SAME_ORIGIN, "same-origin same-origin", true], + [SAME_ORIGIN, "same-origin,same-origin", true], + [SAME_ORIGIN, "*same-origin ", true], + + // All of the following should be recognized as "same-origin" (hence the + // "expected opener" value of `false`). + [SAME_ORIGIN, " same-origin", false], + [SAME_ORIGIN, "same-origin ", false], + [SAME_ORIGIN, "\tsame-origin", false], + [SAME_ORIGIN, "same-origin\t", false], + [SAME_ORIGIN, "same-origin;same-origin", false], + [SAME_ORIGIN, "same-origin; foo=bar", false], +]; + +run_coop_tests("unspecified", tests); + +async_test((t) => { + const channelName = `none_to_${SAME_ORIGIN.name}_duplicated-header`; + const url = `${SAME_ORIGIN.origin}/html/cross-origin-opener-policy/resources/coop-same-origin-repeated.asis?channel=${channelName}`; + + url_test(t, url, channelName, true); +}, `unspecified document opening popup to ${SAME_ORIGIN.origin} with repeated COOP header`); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/common.js b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/common.js index 8a3cd133..5a1744c 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/common.js +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/common.js
@@ -49,8 +49,16 @@ }); } +function percent_encode(objectOrString) { + if (typeof objectOrString === "object") { + return objectOrString.percentEncoded; + } + return encodeURIComponent(objectOrString); +} + function coop_coep_test(t, host, coop, coep, channelName, hasOpener, openerDOMAccess, callback) { - url_test(t, `${host.origin}/html/cross-origin-opener-policy/resources/coop-coep.py?coop=${encodeURIComponent(coop)}&coep=${coep}&channel=${channelName}`, channelName, hasOpener, openerDOMAccess, callback); + const coopPercentEncoded = percent_encode(coop); + url_test(t, `${host.origin}/html/cross-origin-opener-policy/resources/coop-coep.py?coop=${coopPercentEncoded}&coep=${coep}&channel=${encodeURIComponent(channelName)}`, channelName, hasOpener, openerDOMAccess, callback); } function coop_test(t, host, coop, channelName, hasOpener, callback) { @@ -59,11 +67,12 @@ function run_coop_tests(documentCOOPValueTitle, testArray) { for (const test of testArray) { + let coopName = typeof test[1] === "object" ? test[1].percentEncoded : test[1]; async_test(t => { coop_test(t, test[0], test[1], - `${documentCOOPValueTitle}_to_${test[0].name}_${test[1].replace(/ /g,"-")}`, + `${documentCOOPValueTitle}_to_${test[0].name}_${coopName.replace(/ /g,"-")}`, test[2], () => { t.done(); }); - }, `${documentCOOPValueTitle} document opening popup to ${test[0].origin} with COOP: "${test[1]}"`); + }, `${documentCOOPValueTitle} document opening popup to ${test[0].origin} with COOP: ${format_value(coopName)}`); } } @@ -91,5 +100,5 @@ assert_equals(payload.name, expects_name? name:"", 'name'); }); document.body.append(frame); - }, `${documentTitle} with ${iframe_origin.name} iframe opening popup a ${popup_origin.name} with COOP: ${popup_coop}`); -} \ No newline at end of file + }, `${documentTitle} with ${iframe_origin.name} iframe opening popup a ${popup_origin.name} with COOP: ${format_value(popup_coop)}`); +}
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/coop-coep.py b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/coop-coep.py index dd232e6..285b961 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/coop-coep.py +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/coop-coep.py
@@ -70,7 +70,7 @@ iframe.contentWindow.postMessage(payload, "*"); }; const channelName = new URL(location).searchParams.get("channel"); - iframe.src = `${get_host_info().HTTPS_ORIGIN}/html/cross-origin-opener-policy/resources/postback.html?channel=${channelName}`; + iframe.src = `${get_host_info().HTTPS_ORIGIN}/html/cross-origin-opener-policy/resources/postback.html?channel=${encodeURIComponent(channelName)}`; document.body.appendChild(iframe); } </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/coop-same-origin-repeated.asis b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/coop-same-origin-repeated.asis new file mode 100644 index 0000000..082478e1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/coop-same-origin-repeated.asis
@@ -0,0 +1,24 @@ +HTTP/1.1 200 OK +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Opener-Policy: same-origin +Server: BaseHTTP/0.3 Python/2.7.15+ +Date: Wed, 18 Dec 2019 00:47:08 GMT + +<!doctype html> +<meta charset=utf-8> +<script src="/common/get-host-info.sub.js"></script> +<iframe></iframe> +<script> + const navigate = new URL(location).searchParams.get("navigate"); + if (navigate !== null) { + self.location = navigate; + } else { + const iframe = document.querySelector("iframe"); + iframe.onload = () => { + const payload = { name: self.name, opener: !!self.opener }; + iframe.contentWindow.postMessage(payload, "*"); + }; + const channelName = new URL(location).searchParams.get("channel"); + iframe.src = `${get_host_info().HTTPS_ORIGIN}/html/cross-origin-opener-policy/resources/postback.html?channel=${channelName}`; + } +</script>
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/console.idl b/third_party/blink/web_tests/external/wpt/interfaces/console.idl index 3cd3c06..01e155e 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/console.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/console.idl
@@ -6,29 +6,29 @@ [Exposed=(Window,Worker,Worklet)] namespace console { // but see namespace object requirements below // Logging - void assert(optional boolean condition = false, any... data); - void clear(); - void debug(any... data); - void error(any... data); - void info(any... data); - void log(any... data); - void table(optional any tabularData, optional sequence<DOMString> properties); - void trace(any... data); - void warn(any... data); - void dir(optional any item, optional object? options); - void dirxml(any... data); + undefined assert(optional boolean condition = false, any... data); + undefined clear(); + undefined debug(any... data); + undefined error(any... data); + undefined info(any... data); + undefined log(any... data); + undefined table(optional any tabularData, optional sequence<DOMString> properties); + undefined trace(any... data); + undefined warn(any... data); + undefined dir(optional any item, optional object? options); + undefined dirxml(any... data); // Counting - void count(optional DOMString label = "default"); - void countReset(optional DOMString label = "default"); + undefined count(optional DOMString label = "default"); + undefined countReset(optional DOMString label = "default"); // Grouping - void group(any... data); - void groupCollapsed(any... data); - void groupEnd(); + undefined group(any... data); + undefined groupCollapsed(any... data); + undefined groupEnd(); // Timing - void time(optional DOMString label = "default"); - void timeLog(optional DOMString label = "default", any... data); - void timeEnd(optional DOMString label = "default"); + undefined time(optional DOMString label = "default"); + undefined timeLog(optional DOMString label = "default", any... data); + undefined timeEnd(optional DOMString label = "default"); };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webauthn.idl b/third_party/blink/web_tests/external/wpt/interfaces/webauthn.idl index 607c476..ed64377 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/webauthn.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/webauthn.idl
@@ -77,8 +77,8 @@ dictionary AuthenticatorSelectionCriteria { DOMString authenticatorAttachment; - boolean requireResidentKey = false; DOMString residentKey; + boolean requireResidentKey = false; DOMString userVerification = "preferred"; };
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-in-keyframe-expected.txt b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-in-keyframe-expected.txt index 0af056b..e714ac78 100644 --- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-in-keyframe-expected.txt +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-in-keyframe-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL The animation-timeline property may not be used in keyframes assert_equals: expected (string) "bar" but got (undefined) undefined +FAIL The animation-timeline property may not be used in keyframes assert_equals: expected (string) "auto" but got (undefined) undefined Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-in-keyframe.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-in-keyframe.html index bdf40e0..7548333 100644 --- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-in-keyframe.html +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-in-keyframe.html
@@ -7,11 +7,10 @@ <style> @keyframes test { from { width: 100px; animation-timeline: foo; } - to { width: 100px: animation-timeline: foo; } + to { width: 100px; animation-timeline: foo; } } #target { width: 50px; - animation-timeline: bar; animation-name: test; animation-duration: 1s; animation-play-state: paused; @@ -23,6 +22,6 @@ let style = getComputedStyle(document.getElementById('target')); // Checking 'width' verifies that the animation is applied at all. assert_equals(style.width, '100px'); - assert_equals(style.animationTimeline, 'bar'); + assert_equals(style.animationTimeline, 'auto'); }, 'The animation-timeline property may not be used in keyframes'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-none-expected.txt b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-none-expected.txt new file mode 100644 index 0000000..3b56d98 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-none-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +FAIL Animation with animation-timeline:none has no effect value assert_equals: expected "0px" but got "100px" +FAIL Animation with unknown timeline name has no effect value assert_equals: expected "0px" but got "100px" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-none.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-none.html new file mode 100644 index 0000000..d5d5853 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-none.html
@@ -0,0 +1,46 @@ +<!DOCTYPE html> +<link rel="help" src="https://drafts.csswg.org/css-animations-2/#typedef-timeline-name"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/web-animations/testcommon.js"></script> +<style> + @keyframes expand { + from { width: 100px; } + to { width: 200px; } + } + + .test, #ref { + width: 0px; + animation-name: expand; + animation-duration: 10s; + animation-play-state: paused; + } + + #element_timeline_none { + animation-timeline: none; + } + #element_unknown_timeline { + animation-timeline: unknown_timeline; + } + +</style> +<div class=test id=element_timeline_none></div> +<div class=test id=element_unknown_timeline></div> +<div id=ref></div> +<script> + promise_test(async (t) => { + assert_equals(getComputedStyle(element_timeline_none).width, '0px'); + assert_equals(getComputedStyle(ref).width, '100px'); + await waitForNextFrame(); + assert_equals(getComputedStyle(element_timeline_none).width, '0px'); + assert_equals(getComputedStyle(ref).width, '100px'); + }, 'Animation with animation-timeline:none has no effect value'); + + promise_test(async (t) => { + assert_equals(getComputedStyle(element_unknown_timeline).width, '0px'); + assert_equals(getComputedStyle(ref).width, '100px'); + await waitForNextFrame(); + assert_equals(getComputedStyle(element_unknown_timeline).width, '0px'); + assert_equals(getComputedStyle(ref).width, '100px'); + }, 'Animation with unknown timeline name has no effect value'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html index fe227d9..50864ca 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html
@@ -117,7 +117,7 @@ credentials: expected_credentials, redirect: 'follow', integrity: '', - destination: 'empty', + destination: '', message: `fetch (url:${actual_url} mode:${mode} ` + `credentials:${credentials})` };
diff --git a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/README.md b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/README.md index 277cbe5..8684f2cc 100644 --- a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/README.md +++ b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/README.md
@@ -10,7 +10,7 @@ $ pydoc mod_pywebsocket ``` -Please see [Wiki](../../wiki) for more details. +Please see [Wiki](https://github.com/GoogleChromeLabs/pywebsocket3/wiki) for more details. # INSTALL #
diff --git a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/example/echo_client.py b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/example/echo_client.py index e4459a19..dafda059b 100755 --- a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/example/echo_client.py +++ b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/example/echo_client.py
@@ -51,7 +51,7 @@ import codecs from hashlib import sha1 import logging -from optparse import OptionParser +import argparse import os import random import re @@ -602,76 +602,78 @@ if six.PY2: sys.stdout = codecs.getwriter('utf-8')(sys.stdout) - parser = OptionParser() + parser = argparse.ArgumentParser() # We accept --command_line_flag style flags which is the same as Google # gflags in addition to common --command-line-flag style flags. - parser.add_option('-s', - '--server-host', - '--server_host', - dest='server_host', - type='string', - default='localhost', - help='server host') - parser.add_option('-p', - '--server-port', - '--server_port', - dest='server_port', - type='int', - default=_UNDEFINED_PORT, - help='server port') - parser.add_option('-o', - '--origin', - dest='origin', - type='string', - default=None, - help='origin') - parser.add_option('-r', - '--resource', - dest='resource', - type='string', - default='/echo', - help='resource path') - parser.add_option('-m', - '--message', - dest='message', - type='string', - help=('comma-separated messages to send. ' - '%s will force close the connection from server.' % - _GOODBYE_MESSAGE)) - parser.add_option('-q', - '--quiet', - dest='verbose', - action='store_false', - default=True, - help='suppress messages') - parser.add_option('-t', - '--tls', - dest='use_tls', - action='store_true', - default=False, - help='use TLS (wss://).') - parser.add_option('-k', - '--socket-timeout', - '--socket_timeout', - dest='socket_timeout', - type='int', - default=_TIMEOUT_SEC, - help='Timeout(sec) for sockets') - parser.add_option('--use-permessage-deflate', - '--use_permessage_deflate', - dest='use_permessage_deflate', - action='store_true', - default=False, - help='Use the permessage-deflate extension.') - parser.add_option('--log-level', - '--log_level', - type='choice', - dest='log_level', - default='warn', - choices=['debug', 'info', 'warn', 'error', 'critical'], - help='Log level.') + parser.add_argument('-s', + '--server-host', + '--server_host', + dest='server_host', + type=six.text_type, + default='localhost', + help='server host') + parser.add_argument('-p', + '--server-port', + '--server_port', + dest='server_port', + type=int, + default=_UNDEFINED_PORT, + help='server port') + parser.add_argument('-o', + '--origin', + dest='origin', + type=six.text_type, + default=None, + help='origin') + parser.add_argument('-r', + '--resource', + dest='resource', + type=six.text_type, + default='/echo', + help='resource path') + parser.add_argument( + '-m', + '--message', + dest='message', + type=six.text_type, + default=u'Hello,\u65e5\u672c', + help=('comma-separated messages to send. ' + '%s will force close the connection from server.' % + _GOODBYE_MESSAGE)) + parser.add_argument('-q', + '--quiet', + dest='verbose', + action='store_false', + default=True, + help='suppress messages') + parser.add_argument('-t', + '--tls', + dest='use_tls', + action='store_true', + default=False, + help='use TLS (wss://).') + parser.add_argument('-k', + '--socket-timeout', + '--socket_timeout', + dest='socket_timeout', + type=int, + default=_TIMEOUT_SEC, + help='Timeout(sec) for sockets') + parser.add_argument('--use-permessage-deflate', + '--use_permessage_deflate', + dest='use_permessage_deflate', + action='store_true', + default=False, + help='Use the permessage-deflate extension.') + parser.add_argument('--log-level', + '--log_level', + type=six.text_type, + dest='log_level', + default='warn', + choices=['debug', 'info', 'warn', 'error', 'critical'], + help='Log level.') - (options, unused_args) = parser.parse_args() + options = parser.parse_args() logging.basicConfig(level=logging.getLevelName(options.log_level.upper())) @@ -682,11 +684,6 @@ else: options.server_port = common.DEFAULT_WEB_SOCKET_PORT - # optparse doesn't seem to handle non-ascii default values. - # Set default message here. - if not options.message: - options.message = u'Hello,\u65e5\u672c' # "Japan" in Japanese - EchoClient(options).run()
diff --git a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/extensions.py b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/extensions.py index 344539f6..314a949 100644 --- a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/extensions.py +++ b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/extensions.py
@@ -273,6 +273,7 @@ If this method has been called with True and an offer without the client_max_window_bits extension parameter is received, + - (When processing the permessage-deflate extension) this processor declines the request. - (When processing the permessage-compress extension) this processor
diff --git a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/http_header_util.py b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/http_header_util.py index ded90b2..21fde59 100644 --- a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/http_header_util.py +++ b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/http_header_util.py
@@ -120,7 +120,7 @@ def consume_lwses(state): - """Consumes *LWS from the head.""" + r"""Consumes \*LWS from the head.""" while consume_lws(state): pass
diff --git a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/request_handler.py b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/request_handler.py index e038d9f..5e9c875 100644 --- a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/request_handler.py +++ b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/request_handler.py
@@ -208,7 +208,7 @@ return False if self._options.use_basic_auth: - auth = self.headers.getheader('Authorization') + auth = self.headers.get('Authorization') if auth != self._options.basic_auth_credential: self.send_response(401) self.send_header('WWW-Authenticate',
diff --git a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/standalone.py b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/standalone.py index 1042c496..b075d98 100755 --- a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/standalone.py +++ b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/mod_pywebsocket/standalone.py
@@ -157,8 +157,9 @@ from six.moves import configparser import base64 import logging -import optparse +import argparse import os +import six import sys import traceback @@ -174,188 +175,192 @@ def _build_option_parser(): - parser = optparse.OptionParser() + parser = argparse.ArgumentParser() - parser.add_option('--config', - dest='config_file', - type='string', - default=None, - help=('Path to configuration file. See the file comment ' - 'at the top of this file for the configuration ' - 'file format')) - parser.add_option('-H', - '--server-host', - '--server_host', - dest='server_host', - default='', - help='server hostname to listen to') - parser.add_option('-V', - '--validation-host', - '--validation_host', - dest='validation_host', - default=None, - help='server hostname to validate in absolute path.') - parser.add_option('-p', - '--port', - dest='port', - type='int', - default=common.DEFAULT_WEB_SOCKET_PORT, - help='port to listen to') - parser.add_option('-P', - '--validation-port', - '--validation_port', - dest='validation_port', - type='int', - default=None, - help='server port to validate in absolute path.') - parser.add_option('-w', - '--websock-handlers', - '--websock_handlers', - dest='websock_handlers', - default='.', - help=('The root directory of WebSocket handler files. ' - 'If the path is relative, --document-root is used ' - 'as the base.')) - parser.add_option('-m', - '--websock-handlers-map-file', - '--websock_handlers_map_file', - dest='websock_handlers_map_file', - default=None, - help=('WebSocket handlers map file. ' - 'Each line consists of alias_resource_path and ' - 'existing_resource_path, separated by spaces.')) - parser.add_option('-s', - '--scan-dir', - '--scan_dir', - dest='scan_dir', - default=None, - help=('Must be a directory under --websock-handlers. ' - 'Only handlers under this directory are scanned ' - 'and registered to the server. ' - 'Useful for saving scan time when the handler ' - 'root directory contains lots of files that are ' - 'not handler file or are handler files but you ' - 'don\'t want them to be registered. ')) - parser.add_option('--allow-handlers-outside-root-dir', - '--allow_handlers_outside_root_dir', - dest='allow_handlers_outside_root_dir', - action='store_true', - default=False, - help=('Scans WebSocket handlers even if their canonical ' - 'path is not under --websock-handlers.')) - parser.add_option('-d', - '--document-root', - '--document_root', - dest='document_root', - default='.', - help='Document root directory.') - parser.add_option('-x', - '--cgi-paths', - '--cgi_paths', - dest='cgi_paths', - default=None, - help=('CGI paths relative to document_root.' - 'Comma-separated. (e.g -x /cgi,/htbin) ' - 'Files under document_root/cgi_path are handled ' - 'as CGI programs. Must be executable.')) - parser.add_option('-t', - '--tls', - dest='use_tls', - action='store_true', - default=False, - help='use TLS (wss://)') - parser.add_option('-k', - '--private-key', - '--private_key', - dest='private_key', - default='', - help='TLS private key file.') - parser.add_option('-c', - '--certificate', - dest='certificate', - default='', - help='TLS certificate file.') - parser.add_option('--tls-client-auth', - dest='tls_client_auth', - action='store_true', - default=False, - help='Requests TLS client auth on every connection.') - parser.add_option('--tls-client-cert-optional', - dest='tls_client_cert_optional', - action='store_true', - default=False, - help=('Makes client certificate optional even though ' - 'TLS client auth is enabled.')) - parser.add_option('--tls-client-ca', - dest='tls_client_ca', - default='', - help=('Specifies a pem file which contains a set of ' - 'concatenated CA certificates which are used to ' - 'validate certificates passed from clients')) - parser.add_option('--basic-auth', - dest='use_basic_auth', - action='store_true', - default=False, - help='Requires Basic authentication.') - parser.add_option('--basic-auth-credential', - dest='basic_auth_credential', - default='test:test', - help='Specifies the credential of basic authentication ' - 'by username:password pair (e.g. test:test).') - parser.add_option('-l', - '--log-file', - '--log_file', - dest='log_file', - default='', - help='Log file.') + parser.add_argument( + '--config', + dest='config_file', + type=six.text_type, + default=None, + help=('Path to configuration file. See the file comment ' + 'at the top of this file for the configuration ' + 'file format')) + parser.add_argument('-H', + '--server-host', + '--server_host', + dest='server_host', + default='', + help='server hostname to listen to') + parser.add_argument('-V', + '--validation-host', + '--validation_host', + dest='validation_host', + default=None, + help='server hostname to validate in absolute path.') + parser.add_argument('-p', + '--port', + dest='port', + type=int, + default=common.DEFAULT_WEB_SOCKET_PORT, + help='port to listen to') + parser.add_argument('-P', + '--validation-port', + '--validation_port', + dest='validation_port', + type=int, + default=None, + help='server port to validate in absolute path.') + parser.add_argument( + '-w', + '--websock-handlers', + '--websock_handlers', + dest='websock_handlers', + default='.', + help=('The root directory of WebSocket handler files. ' + 'If the path is relative, --document-root is used ' + 'as the base.')) + parser.add_argument('-m', + '--websock-handlers-map-file', + '--websock_handlers_map_file', + dest='websock_handlers_map_file', + default=None, + help=('WebSocket handlers map file. ' + 'Each line consists of alias_resource_path and ' + 'existing_resource_path, separated by spaces.')) + parser.add_argument('-s', + '--scan-dir', + '--scan_dir', + dest='scan_dir', + default=None, + help=('Must be a directory under --websock-handlers. ' + 'Only handlers under this directory are scanned ' + 'and registered to the server. ' + 'Useful for saving scan time when the handler ' + 'root directory contains lots of files that are ' + 'not handler file or are handler files but you ' + 'don\'t want them to be registered. ')) + parser.add_argument( + '--allow-handlers-outside-root-dir', + '--allow_handlers_outside_root_dir', + dest='allow_handlers_outside_root_dir', + action='store_true', + default=False, + help=('Scans WebSocket handlers even if their canonical ' + 'path is not under --websock-handlers.')) + parser.add_argument('-d', + '--document-root', + '--document_root', + dest='document_root', + default='.', + help='Document root directory.') + parser.add_argument('-x', + '--cgi-paths', + '--cgi_paths', + dest='cgi_paths', + default=None, + help=('CGI paths relative to document_root.' + 'Comma-separated. (e.g -x /cgi,/htbin) ' + 'Files under document_root/cgi_path are handled ' + 'as CGI programs. Must be executable.')) + parser.add_argument('-t', + '--tls', + dest='use_tls', + action='store_true', + default=False, + help='use TLS (wss://)') + parser.add_argument('-k', + '--private-key', + '--private_key', + dest='private_key', + default='', + help='TLS private key file.') + parser.add_argument('-c', + '--certificate', + dest='certificate', + default='', + help='TLS certificate file.') + parser.add_argument('--tls-client-auth', + dest='tls_client_auth', + action='store_true', + default=False, + help='Requests TLS client auth on every connection.') + parser.add_argument('--tls-client-cert-optional', + dest='tls_client_cert_optional', + action='store_true', + default=False, + help=('Makes client certificate optional even though ' + 'TLS client auth is enabled.')) + parser.add_argument('--tls-client-ca', + dest='tls_client_ca', + default='', + help=('Specifies a pem file which contains a set of ' + 'concatenated CA certificates which are used to ' + 'validate certificates passed from clients')) + parser.add_argument('--basic-auth', + dest='use_basic_auth', + action='store_true', + default=False, + help='Requires Basic authentication.') + parser.add_argument( + '--basic-auth-credential', + dest='basic_auth_credential', + default='test:test', + help='Specifies the credential of basic authentication ' + 'by username:password pair (e.g. test:test).') + parser.add_argument('-l', + '--log-file', + '--log_file', + dest='log_file', + default='', + help='Log file.') # Custom log level: # - FINE: Prints status of each frame processing step - parser.add_option('--log-level', - '--log_level', - type='choice', - dest='log_level', - default='warn', - choices=[ - 'fine', 'debug', 'info', 'warning', 'warn', 'error', - 'critical' - ], - help='Log level.') - parser.add_option( + parser.add_argument('--log-level', + '--log_level', + type=six.text_type, + dest='log_level', + default='warn', + choices=[ + 'fine', 'debug', 'info', 'warning', 'warn', + 'error', 'critical' + ], + help='Log level.') + parser.add_argument( '--deflate-log-level', '--deflate_log_level', - type='choice', + type=six.text_type, dest='deflate_log_level', default='warn', choices=['debug', 'info', 'warning', 'warn', 'error', 'critical'], help='Log level for _Deflater and _Inflater.') - parser.add_option('--thread-monitor-interval-in-sec', - '--thread_monitor_interval_in_sec', - dest='thread_monitor_interval_in_sec', - type='int', - default=-1, - help=('If positive integer is specified, run a thread ' - 'monitor to show the status of server threads ' - 'periodically in the specified inteval in ' - 'second. If non-positive integer is specified, ' - 'disable the thread monitor.')) - parser.add_option('--log-max', - '--log_max', - dest='log_max', - type='int', - default=_DEFAULT_LOG_MAX_BYTES, - help='Log maximum bytes') - parser.add_option('--log-count', - '--log_count', - dest='log_count', - type='int', - default=_DEFAULT_LOG_BACKUP_COUNT, - help='Log backup count') - parser.add_option('-q', - '--queue', - dest='request_queue_size', - type='int', - default=_DEFAULT_REQUEST_QUEUE_SIZE, - help='request queue size') + parser.add_argument('--thread-monitor-interval-in-sec', + '--thread_monitor_interval_in_sec', + dest='thread_monitor_interval_in_sec', + type=int, + default=-1, + help=('If positive integer is specified, run a thread ' + 'monitor to show the status of server threads ' + 'periodically in the specified inteval in ' + 'second. If non-positive integer is specified, ' + 'disable the thread monitor.')) + parser.add_argument('--log-max', + '--log_max', + dest='log_max', + type=int, + default=_DEFAULT_LOG_MAX_BYTES, + help='Log maximum bytes') + parser.add_argument('--log-count', + '--log_count', + dest='log_count', + type=int, + default=_DEFAULT_LOG_BACKUP_COUNT, + help='Log backup count') + parser.add_argument('-q', + '--queue', + dest='request_queue_size', + type=int, + default=_DEFAULT_REQUEST_QUEUE_SIZE, + help='request queue size') return parser @@ -364,7 +369,7 @@ parser = _build_option_parser() # First, parse options without configuration file. - temporary_options, temporary_args = parser.parse_args(args=args) + temporary_options, temporary_args = parser.parse_known_args(args=args) if temporary_args: logging.critical('Unrecognized positional arguments: %r', temporary_args) @@ -390,7 +395,7 @@ args = args_from_config else: args = args_from_config + args - return parser.parse_args(args=args) + return parser.parse_known_args(args=args) else: return temporary_options, temporary_args
diff --git a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/client_for_testing.py b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/client_for_testing.py index 450a6ac..f9aa811 100755 --- a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/client_for_testing.py +++ b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/client_for_testing.py
@@ -316,6 +316,11 @@ fields.append(u'Sec-WebSocket-Version: %d\r\n' % self._options.version) + if self._options.use_basic_auth: + credential = 'Basic ' + base64.b64encode( + self._options.basic_auth_credential.encode('UTF-8')).decode() + fields.append(u'Authorization: %s\r\n' % credential) + # Setting up extensions. if len(self._options.extensions) > 0: fields.append(u'Sec-WebSocket-Extensions: %s\r\n' % @@ -609,6 +614,8 @@ self.server_port = -1 self.socket_timeout = 1000 self.use_tls = False + self.use_basic_auth = False + self.basic_auth_credential = 'test:test' self.extensions = []
diff --git a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/run_all.py b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/run_all.py index f6220155..ea52223c 100755 --- a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/run_all.py +++ b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/run_all.py
@@ -43,9 +43,10 @@ from __future__ import absolute_import import logging -import optparse +import argparse import os import re +import six import sys import unittest @@ -64,19 +65,19 @@ def _suite(): loader = unittest.TestLoader() return loader.loadTestsFromNames( - _list_test_modules(os.path.join(os.path.split(__file__)[0], '.'))) + _list_test_modules(os.path.dirname(__file__))) if __name__ == '__main__': - parser = optparse.OptionParser() - parser.add_option( + parser = argparse.ArgumentParser() + parser.add_argument( '--log-level', '--log_level', - type='choice', + type=six.text_type, dest='log_level', default='warning', choices=['debug', 'info', 'warning', 'warn', 'error', 'critical']) - options, args = parser.parse_args() + options, args = parser.parse_known_args() logging.basicConfig(level=logging.getLevelName(options.log_level.upper()), format='%(levelname)s %(asctime)s ' '%(filename)s:%(lineno)d] '
diff --git a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/set_sys_path.py b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/set_sys_path.py index 9fce7b3..48d0e116 100644 --- a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/set_sys_path.py +++ b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/set_sys_path.py
@@ -36,6 +36,6 @@ import sys # Add the parent directory to sys.path to enable importing mod_pywebsocket. -sys.path.insert(0, os.path.join(os.path.split(__file__)[0], '..')) +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) # vi:sts=4 sw=4 et
diff --git a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_dispatch.py b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_dispatch.py index ae63980..132dd92 100755 --- a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_dispatch.py +++ b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_dispatch.py
@@ -41,8 +41,8 @@ from test import mock from six.moves import zip -_TEST_HANDLERS_DIR = os.path.join( - os.path.split(__file__)[0], 'testdata', 'handlers') +_TEST_HANDLERS_DIR = os.path.join(os.path.dirname(__file__), 'testdata', + 'handlers') _TEST_HANDLERS_SUB_DIR = os.path.join(_TEST_HANDLERS_DIR, 'sub')
diff --git a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_endtoend.py b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_endtoend.py index 445d29c..8d457ff6 100755 --- a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_endtoend.py +++ b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_endtoend.py
@@ -113,6 +113,18 @@ client.assert_connection_closed() +def _check_handshake_with_basic_auth(client): + client.connect() + + client.send_message(_GOODBYE_MESSAGE) + client.assert_receive(_GOODBYE_MESSAGE) + + client.assert_receive_close() + client.send_close() + + client.assert_connection_closed() + + class EndToEndTestBase(unittest.TestCase): """Base class for end-to-end tests that launch pywebsocket standalone server as a separate process, connect to it using the client_for_testing @@ -121,7 +133,7 @@ """ def setUp(self): self.server_stderr = None - self.top_dir = os.path.join(os.path.split(__file__)[0], '..') + self.top_dir = os.path.join(os.path.dirname(__file__), '..') os.putenv('PYTHONPATH', os.path.pathsep.join(sys.path)) self.standalone_command = os.path.join(self.top_dir, 'mod_pywebsocket', 'standalone.py') @@ -146,7 +158,7 @@ stdout=stdout, stderr=stderr) - def _run_server(self): + def _run_server(self, extra_args=[]): args = [ self.standalone_command, '-H', 'localhost', '-V', 'localhost', '-p', @@ -161,6 +173,8 @@ args.append('--log-level') args.append(logging.getLevelName(log_level).lower()) + args += extra_args + return self._run_python_command(args, stderr=self.server_stderr) def _close_server(self, server): @@ -187,8 +201,11 @@ def setUp(self): EndToEndTestBase.setUp(self) - def _run_test_with_client_options(self, test_function, options): - server = self._run_server() + def _run_test_with_options(self, + test_function, + options, + server_options=[]): + server = self._run_server(server_options) try: # TODO(tyoshino): add some logic to poll the server until it # becomes ready @@ -203,7 +220,7 @@ self._close_server(server) def _run_test(self, test_function): - self._run_test_with_client_options(test_function, self._options) + self._run_test_with_options(test_function, self._options) def _run_permessage_deflate_test(self, offer, response_checker, test_function): @@ -227,8 +244,11 @@ finally: self._close_server(server) - def _run_close_with_code_and_reason_test(self, test_function, code, - reason): + def _run_close_with_code_and_reason_test(self, + test_function, + code, + reason, + server_options=[]): server = self._run_server() try: time.sleep(_SERVER_WARMUP_IN_SEC) @@ -528,16 +548,21 @@ self._run_test(test_function) - # TODO(toyoshim): Add tests to verify invalid absolute uri handling like - # host unmatch, port unmatch and invalid port description (':' without port - # number). - def test_absolute_uri(self): """Tests absolute uri request.""" options = self._options options.resource = 'ws://localhost:%d/echo' % options.server_port - self._run_test_with_client_options(_echo_check_procedure, options) + self._run_test_with_options(_echo_check_procedure, options) + + def test_invalid_absolute_uri(self): + """Tests invalid absolute uri request.""" + + options = self._options + options.resource = 'ws://invalidlocalhost:%d/echo' % options.server_port + options.server_stderr = subprocess.PIPE + + self._run_http_fallback_test(options, 404) def test_origin_check(self): """Tests http fallback on origin check fail.""" @@ -549,6 +574,24 @@ self.server_stderr = subprocess.PIPE self._run_http_fallback_test(options, 403) + def test_invalid_resource(self): + """Tests invalid resource path.""" + + options = self._options + options.resource = '/no_resource' + + self.server_stderr = subprocess.PIPE + self._run_http_fallback_test(options, 404) + + def test_fragmentized_resource(self): + """Tests resource name with fragment""" + + options = self._options + options.resource = '/echo#fragment' + + self.server_stderr = subprocess.PIPE + self._run_http_fallback_test(options, 400) + def test_version_check(self): """Tests http fallback on version check fail.""" @@ -556,6 +599,32 @@ options.version = 99 self._run_http_fallback_test(options, 400) + def test_basic_auth_connection(self): + """Test successful basic auth""" + + options = self._options + options.use_basic_auth = True + + self.server_stderr = subprocess.PIPE + self._run_test_with_options(_check_handshake_with_basic_auth, + options, + server_options=['--basic-auth']) + + def test_invalid_basic_auth_connection(self): + """Tests basic auth with invalid credentials""" + + options = self._options + options.use_basic_auth = True + options.basic_auth_credential = 'invalid:test' + + self.server_stderr = subprocess.PIPE + + with self.assertRaises(client_for_testing.HttpStatusException) as e: + self._run_test_with_options(_check_handshake_with_basic_auth, + options, + server_options=['--basic-auth']) + self.assertEqual(101, e.exception.status) + class EndToEndTestWithEchoClient(EndToEndTestBase): def setUp(self):
diff --git a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_msgutil.py b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_msgutil.py index 943f21b..1122c28 100755 --- a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_msgutil.py +++ b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_msgutil.py
@@ -552,7 +552,6 @@ compressed_empty = compressed_empty[:-4] expected += b'\x80%c' % len(compressed_empty) expected += compressed_empty - print('%r' % expected) self.assertEqual(expected, request.connection.written_data()) def test_send_message_fragmented_empty_last_frame(self): @@ -732,7 +731,6 @@ frame_count += 1 - print("Chunk sizes: %r" % chunk_sizes) self.assertTrue(len(chunk_sizes) > 10) # Close frame @@ -834,9 +832,7 @@ compress = None finish_used = True - print("Chunk sizes: %r" % chunk_sizes) self.assertTrue(len(chunk_sizes) > 10) - print("Methods: %r" % methods) self.assertTrue(sync_used) self.assertTrue(finish_used)
diff --git a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_util.py b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_util.py index 20347941..bf4bd32 100755 --- a/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_util.py +++ b/third_party/blink/web_tests/external/wpt/tools/third_party/pywebsocket3/test/test_util.py
@@ -45,7 +45,7 @@ from six import PY3 from six import int2byte -_TEST_DATA_DIR = os.path.join(os.path.split(__file__)[0], 'testdata') +_TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), 'testdata') class UtilTest(unittest.TestCase): @@ -167,7 +167,6 @@ [int2byte(random.randint(0, 255)) for i in range(100 * 1024)]) chunked_input = get_random_section(source, 10) - print("Input chunk sizes: %r" % [len(c) for c in chunked_input]) deflater = util._Deflater(15) compressed = [] @@ -176,8 +175,6 @@ compressed.append(deflater.compress_and_finish(b'')) chunked_expectation = get_random_section(source, 10) - print("Expectation chunk sizes: %r" % - [len(c) for c in chunked_expectation]) inflater = util._Inflater(15) inflater.append(b''.join(compressed))
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/audio-decoder.html b/third_party/blink/web_tests/external/wpt/webcodecs/audio-decoder.html index 78450c3..af82b2cd 100644 --- a/third_party/blink/web_tests/external/wpt/webcodecs/audio-decoder.html +++ b/third_party/blink/web_tests/external/wpt/webcodecs/audio-decoder.html
@@ -34,6 +34,8 @@ numberOfChannels: 2 } + assert_equals(decoder.state, "unconfigured"); + // Empty codec rejected. config.codec = ''; assert_throws_js(TypeError, () => { decoder.configure(config); }); @@ -54,7 +56,101 @@ config.codec = 'opus'; decoder.configure(config); + assert_equals(decoder.state, "configured"); + + // Test we can configure after a reset. + decoder.reset() + assert_equals(decoder.state, "unconfigured"); + + decoder.configure(config); + assert_equals(decoder.state, "configured"); + asyncDone(t); }, 'Test AudioDecoder.configure() codec validity'); + +function getFakeChunk() { + return new EncodedAudioChunk({ + type:'key', + timestamp:0, + data:Uint8Array.of(0) + }); +} + +promise_test(t => { + let decoder = new AudioDecoder({ + output(frame) { + t.step(() => { + throw "unexpected output"; + }); + }, + error(e) { + t.step(() => { + throw "unexpected error"; + }); + } + }); + + decoder.close(); + + assert_equals(decoder.state, "closed"); + + let config = { + sampleRate: 48000, + numberOfChannels: 2, + codec: 'opus' + } + + let fakeChunk = getFakeChunk(); + + assert_throws_dom("InvalidStateError", + () => decoder.configure(config), + "configure"); + assert_throws_dom("InvalidStateError", + () => decoder.decode(fakeChunk), + "decode"); + assert_throws_dom("InvalidStateError", + () => decoder.reset(), + "reset"); + assert_throws_dom("InvalidStateError", + () => decoder.close(), + "close"); + return promise_rejects_dom(t, 'InvalidStateError', decoder.flush(), 'flush'); +}, 'Closed decoder'); + +promise_test(t => { + let decoder = new AudioDecoder({ + output(frame) { + t.step(() => { + throw "unexpected output"; + }); + }, + error(e) { + t.step(() => { + throw "unexpected error"; + }); + } + }); + + assert_equals(decoder.state, "unconfigured"); + + // Reseting an unconfigured encoder is a no-op. + decoder.reset(); + assert_equals(decoder.state, "unconfigured"); + + let config = { + sampleRate: 48000, + numberOfChannels: 2, + codec: 'opus' + } + + let fakeChunk = getFakeChunk(); + + assert_throws_dom("InvalidStateError", + () => decoder.decode(fakeChunk), + "decode"); + return promise_rejects_dom(t, 'InvalidStateError', decoder.flush(), 'flush'); +}, 'Unconfigured decoder'); + + </script> </html>
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/video-decoder.html b/third_party/blink/web_tests/external/wpt/webcodecs/video-decoder.html index 79f6256..7a37fed 100644 --- a/third_party/blink/web_tests/external/wpt/webcodecs/video-decoder.html +++ b/third_party/blink/web_tests/external/wpt/webcodecs/video-decoder.html
@@ -68,6 +68,8 @@ error(error) { t.unreached_func("Unexpected error:" + error).call(); }, }); + assert_equals(decoder.state, "unconfigured"); + asyncDone(t); }, 'Test VideoDecoder construction'); @@ -77,7 +79,6 @@ error(error) { t.unreached_func("Unexpected error:" + error).call(); }, }); - let config = {}; // Bogus codec rejected. @@ -100,6 +101,27 @@ config.codec = 'vp09.00.10.08'; decoder.configure(config); + assert_equals(decoder.state, "configured"); + + // Verify a failed reconfigure does not affect the current configuration. + config.codec = 'bogus'; + assert_throws_js(TypeError, () => { decoder.configure(config); }); + + assert_equals(decoder.state, "configured"); + + // Verify we can reconfigure. + config.codec = 'vp09.00.10.08'; + decoder.configure(config); + + assert_equals(decoder.state, "configured"); + + // Test we can configure after a reset. + decoder.reset() + assert_equals(decoder.state, "unconfigured"); + + decoder.configure(config); + assert_equals(decoder.state, "configured"); + asyncDone(t); }, 'Test VideoDecoder.configure() codec validity'); @@ -152,13 +174,15 @@ decoder.close(); + assert_equals(decoder.state, "closed"); + let fakeChunk = getFakeChunk(); assert_throws_dom("InvalidStateError", () => decoder.configure({codec: vp9.codec}), "configure"); assert_throws_dom("InvalidStateError", () => decoder.decode(fakeChunk), - "reset"); + "decode"); assert_throws_dom("InvalidStateError", () => decoder.reset(), "reset"); @@ -169,7 +193,6 @@ }, 'Closed decoder'); promise_test(t => { - let numErrors = 0; let decoder = new VideoDecoder({ output(frame) { t.step(() => { @@ -177,17 +200,24 @@ }); }, error(e) { - numErrors++; + t.step(() => { + throw "unexpected error"; + }); } }); - let fakeChunk = getFakeChunk(); - decoder.decode(fakeChunk); + assert_equals(decoder.state, "unconfigured"); - return decoder.flush().then( - () => { throw "flush succeeded unexpectedly"; }, - () => { assert_equals(numErrors, 1, "errors"); }); -}, 'Decode without configure'); + // Reseting an unconfigured encoder is a no-op. + decoder.reset(); + assert_equals(decoder.state, "unconfigured"); + + let fakeChunk = getFakeChunk(); + assert_throws_dom("InvalidStateError", + () => decoder.decode(fakeChunk), + "decode"); + return promise_rejects_dom(t, 'InvalidStateError', decoder.flush(), 'flush'); +}, 'Unconfigured decoder'); promise_test(t => { let numErrors = 0; @@ -209,7 +239,10 @@ return decoder.flush().then( () => { throw "flush succeeded unexpectedly"; }, - () => { assert_equals(numErrors, 1, "errors"); }); + () => { + assert_equals(numErrors, 1, "errors"); + assert_equals(decoder.state, "closed"); + }); }, 'Decode corrupt VP9 frame'); promise_test(t => {
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/video-encoder.html b/third_party/blink/web_tests/external/wpt/webcodecs/video-encoder.html index b56e7d1..368789b 100644 --- a/third_party/blink/web_tests/external/wpt/webcodecs/video-encoder.html +++ b/third_party/blink/web_tests/external/wpt/webcodecs/video-encoder.html
@@ -9,6 +9,13 @@ <script src="/common/media.js"></script> <script> +const defaultConfig = { + codec: 'vp8', + framerate: 25, + width: 640, + height: 480 +}; + async function generateBitmap(width, height) { return createImageBitmap(document.getElementById('frame_image'), { resizeWidth: width, @@ -34,6 +41,9 @@ output(chunk) { t.unreached_func("Unexpected output").call(); }, error(error) { t.unreached_func("Unexpected error:" + error).call(); }, }); + + assert_equals(encoder.state, "unconfigured"); + encoder.close(); asyncDone(t); @@ -45,25 +55,23 @@ error(error) { t.unreached_func("Unexpected error:" + error).call(); }, }); - const requiredConfigPairs = { - codec: 'vp8', - framerate: 25, - width: 640, - height: 480 - }; + const requiredConfigPairs = defaultConfig; let incrementalConfig = {}; for (let key in requiredConfigPairs) { // Configure should fail while required keys are missing. assert_throws_js(TypeError, () => { encoder.configure(incrementalConfig); }); incrementalConfig[key] = requiredConfigPairs[key]; + assert_equals(encoder.state, "unconfigured"); } // Configure should pass once incrementalConfig meets all requirements. encoder.configure(incrementalConfig); + assert_equals(encoder.state, "configured"); // We should be able to reconfigure the encoder. encoder.configure(incrementalConfig); + assert_equals(encoder.state, "configured"); let config = incrementalConfig; @@ -83,6 +91,16 @@ config.codec = 'video/webm; codecs="vp9"'; assert_throws_js(TypeError, () => { encoder.configure(config); }); + // The failed configures should not affect the current config. + assert_equals(encoder.state, "configured"); + + // Test we can configure after a reset. + encoder.reset() + assert_equals(encoder.state, "unconfigured"); + + encoder.configure(defaultConfig); + assert_equals(encoder.state, "configured"); + encoder.close(); asyncDone(t); @@ -120,13 +138,7 @@ // No encodes yet. assert_equals(encoder.encodeQueueSize, 0); - const config = { - codec: 'vp8', - framerate: 25, - width: 640, - height: 480 - }; - encoder.configure(config); + encoder.configure(defaultConfig); // Still no encodes. assert_equals(encoder.encodeQueueSize, 0); @@ -165,12 +177,8 @@ // No encodes yet. assert_equals(encoder.encodeQueueSize, 0); - const config = { - codec: 'vp8', - framerate: 25, - width: 640, - height: 480 - }; + let config = defaultConfig; + encoder.configure(config); let frame1 = await createVideoFrame(640, 480, 0); @@ -238,13 +246,7 @@ // No encodes yet. assert_equals(encoder.encodeQueueSize, 0); - const config = { - codec: 'vp8', - framerate: 25, - width: 640, - height: 480 - }; - encoder.configure(config); + encoder.configure(defaultConfig); encoder.encode(frame); @@ -257,5 +259,68 @@ asyncDone(t); }, 'Test encoder consumes (destroys) frames.'); +promise_test(async t => { + let encoder = new VideoEncoder({ + output(frame) { + t.step(() => { + throw "unexpected output"; + }); + }, + error(e) { + t.step(() => { + throw "unexpected error"; + }); + } + }); + + encoder.close(); + + assert_equals(encoder.state, "closed") + + let frame = await createVideoFrame(640, 480, 0); + + assert_throws_dom("InvalidStateError", + () => encoder.configure(defaultConfig), + "configure"); + assert_throws_dom("InvalidStateError", + () => encoder.encode(frame), + "encode"); + assert_throws_dom("InvalidStateError", + () => encoder.reset(), + "reset"); + assert_throws_dom("InvalidStateError", + () => encoder.close(), + "close"); + return promise_rejects_dom(t, 'InvalidStateError', encoder.flush(), 'flush'); +}, 'Closed encoder'); + +promise_test(async t => { + let encoder = new VideoEncoder({ + output(frame) { + t.step(() => { + throw "unexpected output"; + }); + }, + error(e) { + t.step(() => { + throw "unexpected error"; + }); + } + }); + + assert_equals(encoder.state, "unconfigured"); + + let frame = await createVideoFrame(640, 480, 0); + + // Resetting an unconfigured encoder is a no-op. + encoder.reset(); + assert_equals(encoder.state, "unconfigured"); + + assert_throws_dom("InvalidStateError", + () => encoder.encode(frame), + "encode"); + return promise_rejects_dom(t, 'InvalidStateError', encoder.flush(), 'flush'); +}, 'Unconfigured encoder'); + </script> </html>
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index b6406a0..41643a4 100644 --- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -17,6 +17,7 @@ interface AudioDecoder attribute @@toStringTag getter decodeQueueSize + getter state method close method configure method constructor
diff --git a/third_party/blink/web_tests/virtual/css-scroll-timeline/external/wpt/scroll-animations/css/animation-timeline-none-expected.txt b/third_party/blink/web_tests/virtual/css-scroll-timeline/external/wpt/scroll-animations/css/animation-timeline-none-expected.txt new file mode 100644 index 0000000..8f1d1d7 --- /dev/null +++ b/third_party/blink/web_tests/virtual/css-scroll-timeline/external/wpt/scroll-animations/css/animation-timeline-none-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS Animation with animation-timeline:none has no effect value +PASS Animation with unknown timeline name has no effect value +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt b/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt index 49d979ba..d00c758 100644 --- a/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt +++ b/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt
@@ -24,7 +24,6 @@ clipboard-write cross-origin-isolated document-domain -document-write downloads encrypted-media execution-while-not-rendered
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt index 1f7b39c2..1543525 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -18,6 +18,7 @@ [Worker] interface AudioDecoder [Worker] attribute @@toStringTag [Worker] getter decodeQueueSize +[Worker] getter state [Worker] method close [Worker] method configure [Worker] method constructor
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index c535addb..01f9c19c8 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -271,6 +271,7 @@ interface AudioDecoder attribute @@toStringTag getter decodeQueueSize + getter state method close method configure method constructor @@ -8802,6 +8803,7 @@ interface VideoDecoder attribute @@toStringTag getter decodeQueueSize + getter state method close method configure method constructor @@ -8811,6 +8813,7 @@ interface VideoEncoder attribute @@toStringTag getter encodeQueueSize + getter state method close method configure method constructor
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt index 32346cd..d145bab2 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -18,6 +18,7 @@ [Worker] interface AudioDecoder [Worker] attribute @@toStringTag [Worker] getter decodeQueueSize +[Worker] getter state [Worker] method close [Worker] method configure [Worker] method constructor
diff --git a/third_party/closure_compiler/externs/automation.js b/third_party/closure_compiler/externs/automation.js index 239347b..866f773 100644 --- a/third_party/closure_compiler/externs/automation.js +++ b/third_party/closure_compiler/externs/automation.js
@@ -210,7 +210,6 @@ MATH: 'math', MENU: 'menu', MENU_BAR: 'menuBar', - MENU_BUTTON: 'menuButton', MENU_ITEM: 'menuItem', MENU_ITEM_CHECK_BOX: 'menuItemCheckBox', MENU_ITEM_RADIO: 'menuItemRadio',
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 2cda02d..d93130e 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -3340,6 +3340,8 @@ <int value="4" label="M_TO_P"/> <int value="5" label="N_TO_P"/> <int value="6" label="P_TO_Q"/> + <int value="7" label="N_TO_R"/> + <int value="8" label="P_TO_R"/> </enum> <enum name="ArcShareFilesOnExit"> @@ -16996,6 +16998,7 @@ <int value="6" label="OversizedImages"/> <int value="7" label="UnsizedMedia"/> <int value="8" label="LayoutAnimations"/> + <int value="9" label="DocumentWrite"/> </enum> <enum name="DocumentScanSaneBackend"> @@ -64991,6 +64994,20 @@ <int value="10" label="Undo">The sync was aborted with an undo button.</int> </enum> +<enum name="SigninInterceptHeuristicOutcome"> + <int value="0" label="Intercept: profile switch"/> + <int value="1" label="Intercept: multi-user"/> + <int value="2" label="Intercept: enterprise"/> + <int value="3" label="Abort: Sync signin"/> + <int value="4" label="Abort: intercept in progress"/> + <int value="5" label="Abort: account not new"/> + <int value="6" label="Abort: single account"/> + <int value="7" label="Abort: account info fetch timeout"/> + <int value="8" label="Abort: account info not compatible"/> + <int value="9" label="Abort: profile creation disallowed"/> + <int value="10" label="Abort: shut down"/> +</enum> + <enum name="SigninInterceptResult"> <int value="0" label="Accepted"/> <int value="1" label="Declined"/> @@ -68795,9 +68812,11 @@ <enum name="SyncErrorInfobarTypes"> <summary>Possible errors that can trigger a sync error infobar.</summary> <int value="1" label="Sign in needs update"/> - <int value="2" label="Service unavailable"/> + <int value="2" label="Service unavailable (deprecated)"/> <int value="3" label="Needs passphrase"/> <int value="4" label="Unrecoverable error"/> + <int value="5" label="Sync settings not confirmed"/> + <int value="6" label="Sync needs trusted vault key"/> </enum> <!-- This must be kept current with @@ -69289,6 +69308,17 @@ <int value="2" label="Not loaded on creation"/> </enum> +<enum name="TabbedPaintPreviewCompositorFailureReason"> + <int value="0" label="OK"/> + <int value="1" label="URL Mismatch"/> + <int value="2" label="Compositor Service Disconnected"/> + <int value="3" label="Compositor Client Disconnected"/> + <int value="4" label="Protobuf Deserialization Error"/> + <int value="5" label="Compositor Deserialization Error"/> + <int value="6" label="Invalid Root Frame SKP"/> + <int value="7" label="Invalid Request"/> +</enum> + <enum name="TabbedPaintPreviewExitCause"> <int value="0" label="Pull to Refresh"/> <int value="1" label="Actionbar Action"/> @@ -75038,6 +75068,20 @@ <int value="13" label="android_asset or android_res"/> </enum> +<enum name="WebViewUserAgentType"> + <int value="0" label="Valid"/> + <int value="1" label="Invalid - contains one or more nulls"/> + <int value="2" + label="Invalid - but could be extra headers (with correct line endings)"/> + <int value="3" + label="Invalid - but could be extra headers (but with wrong line + endings)"/> + <int value="4" + label="Invalid - but could be attempting to terminate headers"/> + <int value="5" + label="Invalid - none of the above; random garbage or an unknown case"/> +</enum> + <enum name="WebViewVisibility"> <int value="0" label="Visible"/> <int value="1" label="NotVisible"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index f7c64bb..e1c874b 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -5317,6 +5317,17 @@ </summary> </histogram> +<histogram name="Android.WebView.ExtraHeaders.Valid" enum="BooleanValid" + expires_after="2021-01-14"> + <owner>torne@chromium.org</owner> + <owner>src/android_webview/OWNERS</owner> + <summary> + Recorded when an app passes extra headers to + WebView.loadUrl(url,extra_headers). We check if the header names and values + are valid. + </summary> +</histogram> + <histogram name="Android.WebView.ExtraHeadersRedirect" enum="WebViewExtraHeadersRedirect" expires_after="2020-12-01"> <owner>torne@chromium.org</owner> @@ -5716,6 +5727,17 @@ </summary> </histogram> +<histogram name="Android.WebView.UserAgent.Valid" enum="WebViewUserAgentType" + expires_after="2021-01-14"> + <owner>torne@chromium.org</owner> + <owner>src/android_webview/OWNERS</owner> + <summary> + Recorded when an app passes a custom user agent to + WebSettings.setUserAgentString. We check if the UA is valid, and if not we + try to interpret it in several ways and record which (if any) made sense. + </summary> +</histogram> + <histogram name="Android.WebView.VariationsEnableState" enum="AndroidWebViewVariationsEnableState" expires_after="M69"> <obsolete> @@ -7476,7 +7498,7 @@ </histogram> <histogram name="Apps.AppListPlayStoreQueryState" - enum="AppListPlayStoreQueryState" expires_after="2020-10-25"> + enum="AppListPlayStoreQueryState" expires_after="2021-02-21"> <owner>hejq@chromium.org</owner> <summary>The state of a Play Store app search request.</summary> </histogram> @@ -20955,7 +20977,7 @@ </histogram> <histogram name="Blink.PrePaint.UpdateTime" units="microseconds" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> @@ -24039,6 +24061,18 @@ </summary> </histogram> +<histogram name="Browser.PaintPreview.TabbedPlayer.CompositorFailureReason" + enum="TabbedPaintPreviewCompositorFailureReason" expires_after="2021-02-21"> + <owner>ckitagawa@chromium.org</owner> + <owner>mahmoudi@chromium.org</owner> + <owner>fredmello@chromium.org</owner> + <summary> + Records the the reason for exiting the compositor process for the + TabbedPaintPreviewPlayer. Recorded when the compositor returns an error or + disconnects. + </summary> +</histogram> + <histogram name="Browser.PaintPreview.TabbedPlayer.ExitCause" enum="TabbedPaintPreviewExitCause" expires_after="2021-02-14"> <owner>ckitagawa@chromium.org</owner> @@ -28504,7 +28538,7 @@ </histogram> <histogram name="Compositing.Browser.LayersUpdateTime" units="microseconds" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>schenney@chromium.org</owner> <owner>animations-dev@chromium.org</owner> <summary> @@ -28520,7 +28554,7 @@ </histogram> <histogram name="Compositing.Browser.LayerTreeImpl.CalculateDrawPropertiesUs" - units="microseconds" expires_after="2020-12-20"> + units="microseconds" expires_after="2021-02-21"> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <summary> @@ -36134,7 +36168,7 @@ </histogram> <histogram name="Cryptohome.AsyncDBusRequest" units="ms" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>zuan@chromium.org</owner> <owner>cros-hwsec+uma@chromium.org</owner> <summary> @@ -53205,7 +53239,7 @@ </histogram> <histogram name="Event.Latency.ScrollBegin.Wheel.TimeToScrollUpdateSwapBegin4" - units="microseconds" expires_after="2020-12-20"> + units="microseconds" expires_after="2021-02-21"> <owner>tdresser@chromium.org</owner> <summary> Time between initial creation of a wheel event and the start of the frame @@ -54055,7 +54089,7 @@ </histogram> <histogram name="Event.Latency.ScrollUpdate.Wheel.TimeToScrollUpdateSwapBegin4" - units="microseconds" expires_after="2020-12-20"> + units="microseconds" expires_after="2021-02-21"> <owner>tdresser@chromium.org</owner> <summary> Time between initial creation of a wheel event and start of the frame swap @@ -165354,6 +165388,35 @@ </summary> </histogram> +<histogram name="Signin.Intercept.AccountInfoFetchDuration" units="ms" + expires_after="2021-08-12"> + <owner>alexilin@chromium.org</owner> + <owner>droger@chromium.org</owner> + <summary> + Records the duration of the account info fetch after signin interception. + </summary> +</histogram> + +<histogram name="Signin.Intercept.HeuristicOutcome" + enum="SigninInterceptHeuristicOutcome" expires_after="2021-08-12"> + <owner>droger@chromium.org</owner> + <owner>alexilin@chromium.org</owner> + <summary> + Records the outcome of the signin interception heuristic, which runs for + each signin interception. + </summary> +</histogram> + +<histogram name="Signin.Intercept.ProfileCreationDuration" units="ms" + expires_after="2021-08-12"> + <owner>alexilin@chromium.org</owner> + <owner>droger@chromium.org</owner> + <summary> + Records the duration of the signed-in profile creation after signin + interception. + </summary> +</histogram> + <histogram base="true" name="Signin.InterceptResult" enum="SigninInterceptResult" expires_after="2021-08-12"> <!-- Name completed by histogram_suffixes name="SigninInterceptType" --> @@ -176759,7 +176822,7 @@ </histogram> <histogram base="true" name="Sync.ModelTypeConfigurationTime.Ephemeral" - units="ms" expires_after="2020-12-20"> + units="ms" expires_after="2021-02-21"> <owner>jkrcal@chromium.org</owner> <owner>mastiz@chromium.org</owner> <summary> @@ -178111,10 +178174,9 @@ </histogram> <histogram name="Sync.SyncErrorInfobarDisplayed" enum="SyncErrorInfobarTypes" - expires_after="2020-09-27"> - <owner>droger@chromium.org</owner> - <owner>mastiz@chromium.org</owner> - <owner>treib@chromium.org</owner> + expires_after="2021-08-24"> + <owner>fernandex@chromium.org</owner> + <owner>chrome-signin-team@google.com</owner> <summary> Enumeration of error conditions that displays an infobar to the user. iOS only. @@ -184789,7 +184851,7 @@ </histogram> <histogram name="UKM.UnsentLogs.DroppedSize" units="bytes" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>rkaplow@chromium.org</owner> <owner>ukm-team@google.com</owner> <summary> @@ -193288,7 +193350,7 @@ </histogram> <histogram name="WebFont.LocalFontUsed" enum="BooleanUsage" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>hajimehoshi@chromium.org</owner> <owner>kenjibaheux@chromium.org</owner> <owner>kouhei@chromium.org</owner> @@ -194262,7 +194324,7 @@ </histogram> <histogram name="WebRTC.Audio.ReceiverDeviceDelayMs" units="ms" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>hlundin@chromium.org</owner> <summary> The sound card's buffering delay for the receiving side. Sampled once every @@ -194271,7 +194333,7 @@ </histogram> <histogram name="WebRTC.Audio.ReceiverJitterBufferDelayMs" units="ms" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>hlundin@chromium.org</owner> <summary> The jitter buffer delay for the receiving side. Sampled once every 10 ms @@ -194584,7 +194646,7 @@ </histogram> <histogram name="WebRTC.Call.AudioBitrateReceivedInKbps" units="kbps" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>holmer@chromium.org</owner> <summary> Average audio bitrate received during a call, counted from first packet @@ -194594,7 +194656,7 @@ </histogram> <histogram name="WebRTC.Call.BitrateReceivedInKbps" units="kbps" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>holmer@chromium.org</owner> <summary> Average total bitrate received during a call (audio + video + RTCP), counted @@ -194622,7 +194684,7 @@ </histogram> <histogram name="WebRTC.Call.PacerBitrateInKbps" units="kbps" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>holmer@chromium.org</owner> <summary> Average pacer bitrate during a call, counted from first packet sent until @@ -194632,7 +194694,7 @@ </histogram> <histogram name="WebRTC.Call.RtcpBitrateReceivedInBps" units="bits/s" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>holmer@chromium.org</owner> <summary> Average RTCP bitrate received during a call, counted from first packet @@ -194681,7 +194743,7 @@ </histogram> <histogram name="WebRTC.Call.VideoBitrateReceivedInKbps" units="kbps" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>holmer@chromium.org</owner> <summary> Average video bitrate received during a call, counted from first packet @@ -195452,7 +195514,7 @@ </histogram> <histogram name="WebRTC.Video.AverageRoundTripTimeInMilliseconds" units="ms" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>holmer@chromium.org</owner> <summary> The average round-trip time of a WebRTC call in milliseconds. Recorded when @@ -195461,7 +195523,7 @@ </histogram> <histogram name="WebRTC.Video.AVSyncOffsetInMs" units="ms" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>asapersson@chromium.org</owner> <summary> The absolute value of the sync offset between a rendered video frame and the @@ -195564,7 +195626,7 @@ </histogram> <histogram name="WebRTC.Video.CurrentDelayInMs" units="ms" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>asapersson@chromium.org</owner> <summary> Average current delay for a received video stream. This is the actual delay @@ -195838,7 +195900,7 @@ </histogram> <histogram name="WebRTC.Video.InputHeightInPixels" units="pixels" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>asapersson@chromium.org</owner> <summary> The average input height per frame (for incoming frames to video engine) for @@ -195847,7 +195909,7 @@ </histogram> <histogram name="WebRTC.Video.InputWidthInPixels" units="pixels" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>asapersson@chromium.org</owner> <summary> The average input width per frame (for incoming frames to video engine) for @@ -195886,7 +195948,7 @@ </histogram> <histogram name="WebRTC.Video.JitterBufferDelayInMs" units="ms" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>asapersson@chromium.org</owner> <summary> Average jitter buffer delay for a received video stream. Recorded when a @@ -195895,7 +195957,7 @@ </histogram> <histogram name="WebRTC.Video.KeyFramesReceivedInPermille" units="permille" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>asapersson@chromium.org</owner> <summary> Permille of frames that are key frames for a received video stream. Recorded @@ -196020,7 +196082,7 @@ </histogram> <histogram name="WebRTC.Video.PaddingBitrateSentInKbps" units="kbps" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>asapersson@chromium.org</owner> <summary> The number of sent padding bits per second for a sent video stream. Recorded @@ -196039,7 +196101,7 @@ </histogram> <histogram name="WebRTC.Video.PliPacketsReceivedPerMinute" - units="packets/minute" expires_after="2020-12-20"> + units="packets/minute" expires_after="2021-02-21"> <owner>asapersson@chromium.org</owner> <summary> The number of received RTCP PLI packets per minute for a sent video stream. @@ -196765,7 +196827,7 @@ </histogram> <histogram name="WebRTC.Video.SentHeightInPixels" units="pixels" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>asapersson@chromium.org</owner> <summary> The average sent height per frame for a sent video stream. Recorded when a @@ -196794,7 +196856,7 @@ </histogram> <histogram name="WebRTC.Video.SentWidthInPixels" units="pixels" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>asapersson@chromium.org</owner> <summary> The average sent width per frame for a sent video stream. Recorded when a @@ -196803,7 +196865,7 @@ </histogram> <histogram name="WebRTC.Video.TargetDelayInMs" units="ms" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>asapersson@chromium.org</owner> <summary> Average target delay (jitter delay + decode time + render delay) for a @@ -196832,7 +196894,7 @@ </histogram> <histogram name="WebRTC.Video.UniqueNackRequestsReceivedInPercent" units="%" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>asapersson@chromium.org</owner> <summary> Percentage of unique RTCP NACK requests that are received in response to a @@ -196841,7 +196903,7 @@ </histogram> <histogram name="WebRTC.Video.UniqueNackRequestsSentInPercent" units="%" - expires_after="2020-12-20"> + expires_after="2021-02-21"> <owner>asapersson@chromium.org</owner> <summary> Percentage of unique RTCP NACK requests that are sent in response to a
diff --git a/tools/metrics/histograms/histograms_xml/UMA/histograms.xml b/tools/metrics/histograms/histograms_xml/UMA/histograms.xml index 04dec668..ee2cf57 100644 --- a/tools/metrics/histograms/histograms_xml/UMA/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/UMA/histograms.xml
@@ -385,7 +385,7 @@ </histogram> <histogram name="UMA.PersistentHistograms.InitResult" - enum="PersistentHistogramsInitResult" expires_after="2020-12-20"> + enum="PersistentHistogramsInitResult" expires_after="2021-02-21"> <owner>bcwhite@chromium.org</owner> <owner>src/base/metrics/OWNERS</owner> <summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 5999033e..8eed525 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,11 +6,11 @@ }, "mac": { "hash": "856218c5e01964b2e9d6b1643de0909de34f5e01", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/cd8de1d295b4bedf5b0b00a6655575881df8696a/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/mac/41db2fb64914bb8c4cd2261f8ecedf1ef3b28942/trace_processor_shell" }, "linux": { "hash": "9898e7dd58b976adcc52b6b910d711f8ab130b3f", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/cd8de1d295b4bedf5b0b00a6655575881df8696a/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/linux/41db2fb64914bb8c4cd2261f8ecedf1ef3b28942/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/win/IdleWakeups/README.md b/tools/win/IdleWakeups/README.md index 841df0a..0bf16e1 100644 --- a/tools/win/IdleWakeups/README.md +++ b/tools/win/IdleWakeups/README.md
@@ -10,12 +10,14 @@ IdleWakeups.exe can then be found in src/tools/win/IdleWakeups/x64/Debug/. # Usage -"IdleWakeups.exe" to match all Chrome processes. -"IdleWakeups.exe Firefox" to match all Firefox processes. -"IdleWakeups.exe msedge" to match all Edge processes. +`IdleWakeups.exe` to match all Chrome processes. + +`IdleWakeups.exe Firefox` to match all Firefox processes. + +`IdleWakeups.exe msedge` to match all Edge processes. The process matching the provided parameter is identified by case-sensitive -string prefix, e.g., "some_process" and "some_process.exe" would both work. +string prefix, e.g., `some_process` and `some_process.exe` would both work. When the tool starts it begins gathering and aggregating CPU usage, private working set size, number of context switches / sec, and power usage for all @@ -25,5 +27,5 @@ CPU usage is normalized to one CPU core, with 100% meaning one CPU core is fully utilized. -Intel Power Gadget is required to allow IdleWakeups tool to query power usage. -https://software.intel.com/en-us/articles/intel-power-gadget-20 +[Intel Power Gadget](https://software.intel.com/en-us/articles/intel-power-gadget-20) +is required to allow IdleWakeups tool to query power usage.
diff --git a/tools/xdisplaycheck/BUILD.gn b/tools/xdisplaycheck/BUILD.gn deleted file mode 100644 index 1dc067c..0000000 --- a/tools/xdisplaycheck/BUILD.gn +++ /dev/null
@@ -1,9 +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. - -executable("xdisplaycheck") { - sources = [ "xdisplaycheck.cc" ] - - configs += [ "//build/config/linux:x11" ] -}
diff --git a/tools/xdisplaycheck/xdisplaycheck.cc b/tools/xdisplaycheck/xdisplaycheck.cc deleted file mode 100644 index 2e901ee..0000000 --- a/tools/xdisplaycheck/xdisplaycheck.cc +++ /dev/null
@@ -1,119 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// This is a small program that tries to connect to the X server. It -// continually retries until it connects or 30 seconds pass. If it fails -// to connect to the X server or fails to find needed functiona, it returns -// an error code of -1. -// -// This is to help verify that a useful X server is available before we start -// start running tests on the build bots. - -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <X11/Xlib.h> - -#if defined(USE_AURA) -#include <X11/extensions/XInput2.h> -#endif - -void Sleep(int duration_ms) { - struct timespec sleep_time, remaining; - - // Contains the portion of duration_ms >= 1 sec. - sleep_time.tv_sec = duration_ms / 1000; - duration_ms -= sleep_time.tv_sec * 1000; - - // Contains the portion of duration_ms < 1 sec. - sleep_time.tv_nsec = duration_ms * 1000 * 1000; // nanoseconds. - - while (nanosleep(&sleep_time, &remaining) == -1 && errno == EINTR) - sleep_time = remaining; -} - -class XScopedDisplay { - public: - XScopedDisplay() : display_(nullptr) {} - ~XScopedDisplay() { - if (display_) XCloseDisplay(display_); - } - - void set(Display* display) { display_ = display; } - Display* display() { return display_; } - - private: - Display* display_; -}; - -int main(int argc, char* argv[]) { - XScopedDisplay scoped_display; - if (argv[1] && strcmp(argv[1], "--noserver") == 0) { - scoped_display.set(XOpenDisplay(NULL)); - if (scoped_display.display()) { - fprintf(stderr, "Found unexpected connectable display %s\n", - XDisplayName(NULL)); - } - // Return success when we got an unexpected display so that the code - // without the --noserver is the same, but slow, rather than inverted. - return !scoped_display.display(); - } - - int kNumTries = 78; // 78*77/2 * 10 = 30s of waiting - int tries; - for (tries = 0; tries < kNumTries; ++tries) { - scoped_display.set(XOpenDisplay(NULL)); - if (scoped_display.display()) - break; - Sleep(10 * tries); - } - - if (!scoped_display.display()) { - fprintf(stderr, "Failed to connect to %s\n", XDisplayName(NULL)); - return -1; - } - - fprintf(stderr, "Connected after %d retries\n", tries); - -#if defined(USE_AURA) - // Check for XInput2 - int opcode, event, err; - if (!XQueryExtension(scoped_display.display(), "XInputExtension", &opcode, - &event, &err)) { - fprintf(stderr, - "Failed to get XInputExtension on %s.\n", XDisplayName(NULL)); - return -2; - } - - int major = 2, minor = 0; - if (XIQueryVersion(scoped_display.display(), &major, &minor) == BadRequest) { - fprintf(stderr, - "Server does not have XInput2 on %s.\n", XDisplayName(NULL)); - return -3; - } - - // Ask for the list of devices. This can cause some Xvfb to crash. - int count = 0; - XIDeviceInfo* devices = - XIQueryDevice(scoped_display.display(), XIAllDevices, &count); - if (devices) - XIFreeDeviceInfo(devices); - - fprintf(stderr, - "XInput2 verified initially sane on %s.\n", XDisplayName(NULL)); -#endif - return 0; -} - -#if defined(LEAK_SANITIZER) -// XOpenDisplay leaks memory if it takes more than one try to connect. This -// causes LSan bots to fail. We don't care about memory leaks in xdisplaycheck -// anyway, so just disable LSan completely. -// This function isn't referenced from the executable itself. Make sure it isn't -// stripped by the linker. -__attribute__((used)) -__attribute__((visibility("default"))) -extern "C" int __lsan_is_turned_off() { return 1; } -#endif
diff --git a/ui/accessibility/ax_assistant_structure.cc b/ui/accessibility/ax_assistant_structure.cc index a1b09d27..1d34198 100644 --- a/ui/accessibility/ax_assistant_structure.cc +++ b/ui/accessibility/ax_assistant_structure.cc
@@ -459,7 +459,6 @@ return kAXDialogClassname; case ax::mojom::Role::kRootWebArea: return has_parent ? kAXViewClassname : kAXWebViewClassname; - case ax::mojom::Role::kMenuButton: case ax::mojom::Role::kMenuItem: case ax::mojom::Role::kMenuItemCheckBox: case ax::mojom::Role::kMenuItemRadio:
diff --git a/ui/accessibility/ax_enum_util.cc b/ui/accessibility/ax_enum_util.cc index f0f11cb..f17e077 100644 --- a/ui/accessibility/ax_enum_util.cc +++ b/ui/accessibility/ax_enum_util.cc
@@ -518,8 +518,6 @@ return "menu"; case ax::mojom::Role::kMenuBar: return "menuBar"; - case ax::mojom::Role::kMenuButton: - return "menuButton"; case ax::mojom::Role::kMenuItem: return "menuItem"; case ax::mojom::Role::kMenuItemCheckBox: @@ -904,8 +902,6 @@ return ax::mojom::Role::kMenu; if (0 == strcmp(role, "menuBar")) return ax::mojom::Role::kMenuBar; - if (0 == strcmp(role, "menuButton")) - return ax::mojom::Role::kMenuButton; if (0 == strcmp(role, "menuItem")) return ax::mojom::Role::kMenuItem; if (0 == strcmp(role, "menuItemCheckBox"))
diff --git a/ui/accessibility/ax_enums.mojom b/ui/accessibility/ax_enums.mojom index 53b114e2..ff5def8f 100644 --- a/ui/accessibility/ax_enums.mojom +++ b/ui/accessibility/ax_enums.mojom
@@ -242,7 +242,6 @@ kMath, kMenu, kMenuBar, - kMenuButton, // TODO: kMenuButton is not used anywhere, consider removal. kMenuItem, kMenuItemCheckBox, kMenuItemRadio,
diff --git a/ui/accessibility/ax_node_data_unittest.cc b/ui/accessibility/ax_node_data_unittest.cc index 492bf6a..90a96af 100644 --- a/ui/accessibility/ax_node_data_unittest.cc +++ b/ui/accessibility/ax_node_data_unittest.cc
@@ -174,7 +174,6 @@ ax::mojom::Role::kLink, ax::mojom::Role::kListBox, ax::mojom::Role::kListBoxOption, - ax::mojom::Role::kMenuButton, ax::mojom::Role::kMenuItem, ax::mojom::Role::kMenuItemCheckBox, ax::mojom::Role::kMenuItemRadio,
diff --git a/ui/accessibility/ax_role_properties.cc b/ui/accessibility/ax_role_properties.cc index b9756d9..f776bb6 100644 --- a/ui/accessibility/ax_role_properties.cc +++ b/ui/accessibility/ax_role_properties.cc
@@ -83,7 +83,6 @@ case ax::mojom::Role::kLink: case ax::mojom::Role::kListBox: case ax::mojom::Role::kListBoxOption: - case ax::mojom::Role::kMenuButton: case ax::mojom::Role::kMenuItem: case ax::mojom::Role::kMenuItemCheckBox: case ax::mojom::Role::kMenuItemRadio: @@ -152,7 +151,6 @@ case ax::mojom::Role::kListGrid: case ax::mojom::Role::kMenu: case ax::mojom::Role::kMenuBar: - case ax::mojom::Role::kMenuButton: case ax::mojom::Role::kMenuItem: case ax::mojom::Role::kMenuItemCheckBox: case ax::mojom::Role::kMenuItemRadio: @@ -381,7 +379,6 @@ switch (role) { case ax::mojom::Role::kMenu: case ax::mojom::Role::kMenuBar: - case ax::mojom::Role::kMenuButton: case ax::mojom::Role::kMenuItem: case ax::mojom::Role::kMenuItemCheckBox: case ax::mojom::Role::kMenuItemRadio:
diff --git a/ui/accessibility/extensions/chromevoxclassic/cvox2/background/automation_predicate.js b/ui/accessibility/extensions/chromevoxclassic/cvox2/background/automation_predicate.js index 312d926c..1ed1ca2 100644 --- a/ui/accessibility/extensions/chromevoxclassic/cvox2/background/automation_predicate.js +++ b/ui/accessibility/extensions/chromevoxclassic/cvox2/background/automation_predicate.js
@@ -86,7 +86,6 @@ case 'details': case 'disclosureTriangle': case 'form': - case 'menuButton': case 'menuListPopup': case 'popUpButton': case 'radioButton':
diff --git a/ui/accessibility/platform/atk_util_auralinux.cc b/ui/accessibility/platform/atk_util_auralinux.cc index 3fd67575..9cfbdf8 100644 --- a/ui/accessibility/platform/atk_util_auralinux.cc +++ b/ui/accessibility/platform/atk_util_auralinux.cc
@@ -5,6 +5,7 @@ #include <atk/atk.h> #include <map> #include <memory> +#include <set> #include <string> #include <utility> @@ -53,7 +54,7 @@ return *active_key_snoop_functions; } -using AXPlatformNodeSet = std::unordered_set<ui::AXPlatformNodeAuraLinux*>; +using AXPlatformNodeSet = std::set<ui::AXPlatformNodeAuraLinux*>; static AXPlatformNodeSet& GetNodesWithPostponedEvents() { static base::NoDestructor<AXPlatformNodeSet> nodes_with_postponed_events_list; return *nodes_with_postponed_events_list;
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc index b1293b4c..fd8dfd2 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -2854,8 +2854,6 @@ return ATK_ROLE_MARQUEE; case ax::mojom::Role::kMenu: return ATK_ROLE_MENU; - case ax::mojom::Role::kMenuButton: - return ATK_ROLE_MENU_ITEM; case ax::mojom::Role::kMenuBar: return ATK_ROLE_MENU_BAR; case ax::mojom::Role::kMenuItem:
diff --git a/ui/accessibility/platform/ax_platform_node_mac.mm b/ui/accessibility/platform/ax_platform_node_mac.mm index 5bc70451..96d46d4 100644 --- a/ui/accessibility/platform/ax_platform_node_mac.mm +++ b/ui/accessibility/platform/ax_platform_node_mac.mm
@@ -159,7 +159,6 @@ {ax::mojom::Role::kMath, NSAccessibilityGroupRole}, {ax::mojom::Role::kMenu, NSAccessibilityMenuRole}, {ax::mojom::Role::kMenuBar, NSAccessibilityMenuBarRole}, - {ax::mojom::Role::kMenuButton, NSAccessibilityMenuButtonRole}, {ax::mojom::Role::kMenuItem, NSAccessibilityMenuItemRole}, {ax::mojom::Role::kMenuItemCheckBox, NSAccessibilityMenuItemRole}, {ax::mojom::Role::kMenuItemRadio, NSAccessibilityMenuItemRole},
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index 64e997a..5aec80f 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -5315,21 +5315,16 @@ case ax::mojom::Role::kMenuBar: return ROLE_SYSTEM_MENUBAR; - case ax::mojom::Role::kMenuButton: case ax::mojom::Role::kMenuItem: case ax::mojom::Role::kMenuItemCheckBox: case ax::mojom::Role::kMenuItemRadio: return ROLE_SYSTEM_MENUITEM; case ax::mojom::Role::kMenuListPopup: - if (IsAncestorComboBox()) - return ROLE_SYSTEM_LIST; - return ROLE_SYSTEM_MENUPOPUP; + return ROLE_SYSTEM_LIST; case ax::mojom::Role::kMenuListOption: - if (IsAncestorComboBox()) - return ROLE_SYSTEM_LISTITEM; - return ROLE_SYSTEM_MENUITEM; + return ROLE_SYSTEM_LISTITEM; case ax::mojom::Role::kMeter: return ROLE_SYSTEM_PROGRESSBAR; @@ -6143,7 +6138,6 @@ case ax::mojom::Role::kMenuBar: return L"menubar"; - case ax::mojom::Role::kMenuButton: case ax::mojom::Role::kMenuItem: return L"menuitem"; @@ -6154,14 +6148,10 @@ return L"menuitemradio"; case ax::mojom::Role::kMenuListPopup: - if (IsAncestorComboBox()) - return L"list"; - return L"menu"; + return L"list"; case ax::mojom::Role::kMenuListOption: - if (IsAncestorComboBox()) - return L"listitem"; - return L"menuitem"; + return L"listitem"; case ax::mojom::Role::kMeter: return L"progressbar"; @@ -6810,7 +6800,6 @@ case ax::mojom::Role::kMenuBar: return UIA_MenuBarControlTypeId; - case ax::mojom::Role::kMenuButton: case ax::mojom::Role::kMenuItem: return UIA_MenuItemControlTypeId; @@ -6821,14 +6810,10 @@ return UIA_RadioButtonControlTypeId; case ax::mojom::Role::kMenuListPopup: - if (IsAncestorComboBox()) - return UIA_ListControlTypeId; - return UIA_MenuControlTypeId; + return UIA_ListControlTypeId; case ax::mojom::Role::kMenuListOption: - if (IsAncestorComboBox()) - return UIA_ListItemControlTypeId; - return UIA_MenuItemControlTypeId; + return UIA_ListItemControlTypeId; case ax::mojom::Role::kMeter: return UIA_ProgressBarControlTypeId; @@ -7811,18 +7796,6 @@ return S_OK; } -// TODO(dmazzoni): Remove this function once combo box refactoring is -// complete. -bool AXPlatformNodeWin::IsAncestorComboBox() { - auto* parent = - static_cast<AXPlatformNodeWin*>(FromNativeViewAccessible(GetParent())); - if (!parent) - return false; - if (parent->MSAARole() == ROLE_SYSTEM_COMBOBOX) - return true; - return parent->IsAncestorComboBox(); -} - bool AXPlatformNodeWin::IsPlaceholderText() const { if (GetData().role != ax::mojom::Role::kStaticText) return false;
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index ec14b8b8..696b1ad5 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -220,7 +220,7 @@ ] } -android_library("ui_full_java") { +android_library("ui_no_recycler_view_java") { sources = [ "java/src/org/chromium/ui/AsyncViewProvider.java", "java/src/org/chromium/ui/AsyncViewStub.java", @@ -298,11 +298,7 @@ "java/src/org/chromium/ui/modelutil/PropertyModel.java", "java/src/org/chromium/ui/modelutil/PropertyModelChangeProcessor.java", "java/src/org/chromium/ui/modelutil/PropertyObservable.java", - "java/src/org/chromium/ui/modelutil/RecyclerViewAdapter.java", "java/src/org/chromium/ui/modelutil/SimpleList.java", - "java/src/org/chromium/ui/modelutil/SimpleRecyclerViewAdapter.java", - "java/src/org/chromium/ui/modelutil/SimpleRecyclerViewMcp.java", - "java/src/org/chromium/ui/modelutil/SimpleRecyclerViewMcpBase.java", "java/src/org/chromium/ui/resources/HandleViewResources.java", "java/src/org/chromium/ui/resources/LayoutResource.java", "java/src/org/chromium/ui/resources/Resource.java", @@ -349,11 +345,12 @@ ":ui_utils_java", "//base:base_java", "//base:jni_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:androidx_appcompat_appcompat_java", "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//third_party/android_deps:androidx_asynclayoutinflater_asynclayoutinflater_java", - "//third_party/android_deps:androidx_recyclerview_recyclerview_java", + "//third_party/android_deps:androidx_core_core_java", + "//third_party/android_deps:androidx_vectordrawable_vectordrawable_animated_java", "//ui/base/cursor/mojom:cursor_type_java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] @@ -361,6 +358,28 @@ resources_package = "org.chromium.ui" } +android_library("ui_recycler_view_java") { + sources = [ + "java/src/org/chromium/ui/modelutil/RecyclerViewAdapter.java", + "java/src/org/chromium/ui/modelutil/SimpleRecyclerViewAdapter.java", + "java/src/org/chromium/ui/modelutil/SimpleRecyclerViewMcp.java", + "java/src/org/chromium/ui/modelutil/SimpleRecyclerViewMcpBase.java", + ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] + deps = [ + ":ui_no_recycler_view_java", + "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:androidx_recyclerview_recyclerview_java", + ] +} + +java_group("ui_full_java") { + deps = [ + ":ui_no_recycler_view_java", + ":ui_recycler_view_java", + ] +} + android_library("ui_java_test_support") { testonly = true sources = [
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/ListModelChangeProcessor.java b/ui/android/java/src/org/chromium/ui/modelutil/ListModelChangeProcessor.java index d0c5f126..1affc49 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/ListModelChangeProcessor.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/ListModelChangeProcessor.java
@@ -5,15 +5,14 @@ package org.chromium.ui.modelutil; import androidx.annotation.Nullable; -import androidx.recyclerview.widget.RecyclerView; /** * A model change processor for use with a {@link ListObservable} model. The * {@link ListModelChangeProcessor} should be registered as a list observer of the model. * Internally uses a view binder to bind model properties to a view like a TabLayout. * - * Do not use this class to fill {@link RecyclerView}s - consider using the - * {@link SimpleRecyclerViewMcp} which was specifically designed for that use case! + * Do not use this class to fill {@link androidx.recyclerview.widget.RecyclerView}s - consider using + * the {@link SimpleRecyclerViewMcp} which was specifically designed for that use case! * * @param <M> The {@link ListObservable} model. * @param <V> The view object that is changing. @@ -65,4 +64,4 @@ assert source == mModel; mViewBinder.onItemsChanged(mModel, mView, index, count); } -} \ No newline at end of file +}
diff --git a/ui/base/cocoa/command_dispatcher.h b/ui/base/cocoa/command_dispatcher.h index 1203c0a..c2e437dc 100644 --- a/ui/base/cocoa/command_dispatcher.h +++ b/ui/base/cocoa/command_dispatcher.h
@@ -86,6 +86,11 @@ // the event to be passed to the MainMenu, which will handle the key // equivalent. kPassToMainMenu, + + // The CommandDispatcherDelegate determined the event should not be handled. + // This can occur when an event has been sent via key repeat that we've + // determined should not be triggered via repeat. + kDrop, }; } // namespace ui
diff --git a/ui/base/cocoa/command_dispatcher.mm b/ui/base/cocoa/command_dispatcher.mm index 1ae7b17..c905b6be 100644 --- a/ui/base/cocoa/command_dispatcher.mm +++ b/ui/base/cocoa/command_dispatcher.mm
@@ -130,7 +130,8 @@ // First, give the delegate an opportunity to consume this event. ui::PerformKeyEquivalentResult result = [_delegate prePerformKeyEquivalent:event window:_owner]; - if (result == ui::PerformKeyEquivalentResult::kHandled) + if (result == ui::PerformKeyEquivalentResult::kHandled || + result == ui::PerformKeyEquivalentResult::kDrop) return YES; if (result == ui::PerformKeyEquivalentResult::kPassToMainMenu) return NO;
diff --git a/ui/base/models/simple_menu_model.h b/ui/base/models/simple_menu_model.h index 5f1116b..3166989 100644 --- a/ui/base/models/simple_menu_model.h +++ b/ui/base/models/simple_menu_model.h
@@ -27,6 +27,9 @@ // The breadth of MenuModel is not exposed through this API. class COMPONENT_EXPORT(UI_BASE) SimpleMenuModel : public MenuModel { public: + // Default icon size to be used for context menus. + static constexpr int kDefaultIconSize = 16; + class COMPONENT_EXPORT(UI_BASE) Delegate : public AcceleratorProvider { public: ~Delegate() override {}
diff --git a/ui/base/x/xwmstartupcheck/BUILD.gn b/ui/base/x/xwmstartupcheck/BUILD.gn index debd8fa..50f34ca6 100644 --- a/ui/base/x/xwmstartupcheck/BUILD.gn +++ b/ui/base/x/xwmstartupcheck/BUILD.gn
@@ -7,7 +7,10 @@ sources = [ "xwmstartupcheck.cc" ] - deps = [ "//base" ] + deps = [ + "//base", + "//ui/gfx/x", + ] configs += [ "//build/config/linux:x11" ] }
diff --git a/ui/base/x/xwmstartupcheck/xwmstartupcheck.cc b/ui/base/x/xwmstartupcheck/xwmstartupcheck.cc index 09ef42f..3a18a8e 100644 --- a/ui/base/x/xwmstartupcheck/xwmstartupcheck.cc +++ b/ui/base/x/xwmstartupcheck/xwmstartupcheck.cc
@@ -7,12 +7,15 @@ // BEFORE the Wm starts. // +#include <time.h> + #include <cerrno> #include <cstdio> -#include <time.h> - -#include <X11/Xlib.h> +#include "base/command_line.h" +#include "ui/gfx/x/connection.h" +#include "ui/gfx/x/x11.h" +#include "ui/gfx/x/xproto.h" void CalculateTimeout(const timespec& now, const timespec& deadline, @@ -24,53 +27,37 @@ timeout->tv_sec = 0; } -class XScopedDisplay { - public: - explicit XScopedDisplay(Display* display) : display_(display) {} - ~XScopedDisplay() { - if (display_) - XCloseDisplay(display_); - } - - Display* display() const { return display_; } - - private: - Display* const display_; -}; - int main(int argc, char* argv[]) { - // Connects to a display specified in the current process' env value DISPLAY. - XScopedDisplay scoped_display(XOpenDisplay(nullptr)); + base::CommandLine::Init(argc, argv); + + // Connects to a X server specified in the current process' env value DISPLAY. + x11::Connection connection; // No display found - fail early. - if (!scoped_display.display()) { - fprintf(stderr, "Couldn't connect to a display.\n"); + if (!connection.Ready()) { + fprintf(stderr, "Couldn't connect to the X11 server.\n"); return 1; } - auto* xdisplay = scoped_display.display(); - - auto root_window = DefaultRootWindow(xdisplay); - if (!root_window) { - fprintf(stderr, "Couldn't find root window.\n"); - return 1; - } - - auto dummmy_window = XCreateSimpleWindow( - xdisplay, root_window, 0 /*x*/, 0 /*y*/, 1 /*width*/, 1 /*height*/, - 0 /*border width*/, 0 /*border*/, 0 /*background*/); - if (!dummmy_window) { + auto dummy_window = connection.GenerateId<x11::Window>(); + auto req = connection.CreateWindow({ + .wid = dummy_window, + .parent = connection.default_root(), + .width = 1, + .height = 1, + // We are only interested in the ReparentNotify events that are sent + // whenever our dummy window is reparented because of a wm start. + .event_mask = x11::EventMask::StructureNotify, + }); + if (req.Sync().error) { fprintf(stderr, "Couldn't create a dummy window."); return 1; } - XMapWindow(xdisplay, dummmy_window); - // We are only interested in the ReparentNotify events that are sent whenever - // our dummy window is reparented because of a wm start. - XSelectInput(xdisplay, dummmy_window, StructureNotifyMask); - XFlush(xdisplay); + connection.MapWindow({dummy_window}); + connection.Flush(); - int display_fd = ConnectionNumber(xdisplay); + int display_fd = ConnectionNumber(connection.display()); // Set deadline as 30s. struct timespec now, deadline; @@ -82,7 +69,6 @@ struct timeval tv; CalculateTimeout(now, deadline, &tv); - XEvent ev; do { fd_set in_fds; FD_ZERO(&in_fds); @@ -95,14 +81,14 @@ break; } } else if (ret > 0) { - while (XPending(xdisplay)) { - XNextEvent(xdisplay, &ev); + connection.ReadResponses(); + for (const auto& event : connection.events()) { // If we got ReparentNotify, a wm has started up and we can stop // execution. - if (ev.type == ReparentNotify) { + if (event.As<x11::ReparentNotifyEvent>()) return 0; - } } + connection.events().clear(); } // Calculate next timeout. If it's less or equal to 0, give up. clock_gettime(CLOCK_REALTIME, &now); @@ -114,7 +100,7 @@ #if defined(LEAK_SANITIZER) // XOpenDisplay leaks memory if it takes more than one try to connect. This -// causes LSan bots to fail. We don't care about memory leaks in xdisplaycheck +// causes LSan bots to fail. We don't care about memory leaks in xwmstartupcheck // anyway, so just disable LSan completely. // This function isn't referenced from the executable itself. Make sure it isn't // stripped by the linker.
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc index 12f75f8..9434c6e7 100644 --- a/ui/compositor/layer.cc +++ b/ui/compositor/layer.cc
@@ -273,6 +273,7 @@ clone->SetMasksToBounds(GetMasksToBounds()); clone->SetOpacity(GetTargetOpacity()); clone->SetVisible(GetTargetVisibility()); + clone->SetClipRect(GetTargetClipRect()); clone->SetAcceptEvents(accept_events()); clone->SetFillsBoundsOpaquely(fills_bounds_opaquely_); clone->SetFillsBoundsCompletely(fills_bounds_completely_); @@ -497,6 +498,14 @@ return cc_layer_->masks_to_bounds(); } +gfx::Rect Layer::GetTargetClipRect() const { + if (animator_ && + animator_->IsAnimatingProperty(LayerAnimationElement::CLIP)) { + return animator_->GetTargetClipRect(); + } + return clip_rect(); +} + void Layer::SetClipRect(const gfx::Rect& clip_rect) { GetAnimator()->SetClipRect(clip_rect); }
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h index b3f6b8bc..8290f3f 100644 --- a/ui/compositor/layer.h +++ b/ui/compositor/layer.h
@@ -203,6 +203,7 @@ // Sets/gets the clip rect for the layer. |clip_rect| is in layer space and // relative to |this| layer. Prefer SetMasksToBounds() to set the clip to the // bounds of |this| layer. This clips the subtree rooted at |this| layer. + gfx::Rect GetTargetClipRect() const; void SetClipRect(const gfx::Rect& clip_rect); gfx::Rect clip_rect() const { return cc_layer_->clip_rect(); }
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc index 57c280b7..5e477daf 100644 --- a/ui/compositor/layer_unittest.cc +++ b/ui/compositor/layer_unittest.cc
@@ -746,11 +746,14 @@ transform.Scale(2, 1); transform.Translate(10, 5); + gfx::Rect clip_rect(1, 1, 2, 2); + layer->SetTransform(transform); layer->SetColor(SK_ColorRED); layer->SetLayerInverted(true); layer->AddCacheRenderSurfaceRequest(); layer->AddTrilinearFilteringRequest(); + layer->SetClipRect(clip_rect); layer->SetRoundedCornerRadius({1, 2, 4, 5}); layer->SetIsFastRoundedCorner(true); @@ -767,12 +770,14 @@ // Cloning should not preserve trilinear_filtering flag. EXPECT_NE(layer->cc_layer_for_testing()->trilinear_filtering(), clone->cc_layer_for_testing()->trilinear_filtering()); + EXPECT_EQ(clip_rect, clone->clip_rect()); EXPECT_EQ(layer->rounded_corner_radii(), clone->rounded_corner_radii()); EXPECT_EQ(layer->is_fast_rounded_corner(), clone->is_fast_rounded_corner()); layer->SetTransform(gfx::Transform()); layer->SetColor(SK_ColorGREEN); layer->SetLayerInverted(false); + layer->SetClipRect(gfx::Rect(10, 10, 10, 10)); layer->SetIsFastRoundedCorner(false); layer->SetRoundedCornerRadius({3, 6, 9, 12}); @@ -781,6 +786,7 @@ EXPECT_EQ(SK_ColorRED, clone->background_color()); EXPECT_EQ(SK_ColorRED, clone->GetTargetColor()); EXPECT_TRUE(clone->layer_inverted()); + EXPECT_EQ(clip_rect, clone->clip_rect()); EXPECT_FALSE(layer->is_fast_rounded_corner()); EXPECT_TRUE(clone->is_fast_rounded_corner()); EXPECT_NE(layer->rounded_corner_radii(), clone->rounded_corner_radii());
diff --git a/ui/gl/gl_image_shared_memory_unittest.cc b/ui/gl/gl_image_shared_memory_unittest.cc index 1208405..7df0ea3 100644 --- a/ui/gl/gl_image_shared_memory_unittest.cc +++ b/ui/gl/gl_image_shared_memory_unittest.cc
@@ -51,7 +51,7 @@ GLImageSharedMemoryTestDelegate<gfx::BufferFormat::RGBX_8888>, GLImageSharedMemoryTestDelegate<gfx::BufferFormat::RGBA_8888>, GLImageSharedMemoryTestDelegate<gfx::BufferFormat::BGRX_8888>, -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // Fails on Win nVidia and linux android: the test writes nothing (we read // back the color used to clear the buffer). // TODO(mcasas): enable those paltforms https://crbug.com/803451.
diff --git a/ui/ozone/platform/scenic/ozone_platform_scenic.cc b/ui/ozone/platform/scenic/ozone_platform_scenic.cc index ec639a6..b7c7dae 100644 --- a/ui/ozone/platform/scenic/ozone_platform_scenic.cc +++ b/ui/ozone/platform/scenic/ozone_platform_scenic.cc
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_pump_type.h" +#include "base/no_destructor.h" #include "base/notreached.h" #include "base/task/current_thread.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -43,14 +44,6 @@ namespace { -constexpr OzonePlatform::PlatformProperties kScenicPlatformProperties{ - .needs_view_token = true, - .custom_frame_pref_default = false, - .use_system_title_bar = false, - .message_pump_type_for_gpu = base::MessagePumpType::IO, - .supports_vulkan_swap_chain = true, -}; - class ScenicPlatformEventSource : public ui::PlatformEventSource { public: ScenicPlatformEventSource() = default; @@ -105,7 +98,17 @@ } const PlatformProperties& GetPlatformProperties() override { - return kScenicPlatformProperties; + static base::NoDestructor<OzonePlatform::PlatformProperties> properties; + static bool initialised = false; + if (!initialised) { + properties->needs_view_token = true; + properties->message_pump_type_for_gpu = base::MessagePumpType::IO; + properties->supports_vulkan_swap_chain = true; + + initialised = true; + } + + return *properties; } std::unique_ptr<display::NativeDisplayDelegate> CreateNativeDisplayDelegate()
diff --git a/ui/ozone/platform/wayland/ozone_platform_wayland.cc b/ui/ozone/platform/wayland/ozone_platform_wayland.cc index 8de40eb6..6d19339d 100644 --- a/ui/ozone/platform/wayland/ozone_platform_wayland.cc +++ b/ui/ozone/platform/wayland/ozone_platform_wayland.cc
@@ -12,6 +12,7 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_pump_type.h" +#include "base/no_destructor.h" #include "base/threading/sequenced_task_runner_handle.h" #include "ui/base/buildflags.h" #include "ui/base/cursor/cursor_factory.h" @@ -63,23 +64,6 @@ namespace { -constexpr OzonePlatform::PlatformProperties kWaylandPlatformProperties = { - // Supporting server-side decorations requires a support of - // xdg-decorations. But this protocol has been accepted into the upstream - // recently, and it will take time before it is taken by compositors. For - // now, always use custom frames and disallow switching to server-side - // frames. - // https://github.com/wayland-project/wayland-protocols/commit/76d1ae8c65739eff3434ef219c58a913ad34e988 - .custom_frame_pref_default = true, - - // Wayland doesn't provide clients with global screen coordinates. Instead, - // it forces clients to position windows relative to their top level windows - // if the have child-parent relationship. In case of toplevel windows, - // clients simply don't know their position on screens and always assume - // they are located at some arbitrary position. - .ignore_screen_bounds_for_menus = true, -}; - constexpr OzonePlatform::InitializedHostProperties kWaylandInitializedHostProperties = { /*supports_overlays=*/false, @@ -232,7 +216,29 @@ } const PlatformProperties& GetPlatformProperties() override { - return kWaylandPlatformProperties; + static base::NoDestructor<OzonePlatform::PlatformProperties> properties; + static bool initialised = false; + if (!initialised) { + // Supporting server-side decorations requires a support of + // xdg-decorations. But this protocol has been accepted into the upstream + // recently, and it will take time before it is taken by compositors. For + // now, always use custom frames and disallow switching to server-side + // frames. + // https://github.com/wayland-project/wayland-protocols/commit/76d1ae8c65739eff3434ef219c58a913ad34e988 + properties->custom_frame_pref_default = true; + + // Wayland doesn't provide clients with global screen coordinates. + // Instead, it forces clients to position windows relative to their top + // level windows if the have child-parent relationship. In case of + // toplevel windows, clients simply don't know their position on screens + // and always assume they are located at some arbitrary position. + properties->ignore_screen_bounds_for_menus = true; + properties->app_modal_dialogs_use_event_blocker = true; + + initialised = true; + } + + return *properties; } const InitializedHostProperties& GetInitializedHostProperties() override {
diff --git a/ui/ozone/platform/x11/ozone_platform_x11.cc b/ui/ozone/platform/x11/ozone_platform_x11.cc index 182c556d..322a7cb 100644 --- a/ui/ozone/platform/x11/ozone_platform_x11.cc +++ b/ui/ozone/platform/x11/ozone_platform_x11.cc
@@ -9,6 +9,7 @@ #include "base/message_loop/message_pump_type.h" #include "base/metrics/histogram_functions.h" +#include "base/no_destructor.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "ui/base/buildflags.h" @@ -64,30 +65,12 @@ namespace { -static OzonePlatform::PlatformProperties kX11PlatformProperties{ - .needs_view_token = false, - .custom_frame_pref_default = false, - .use_system_title_bar = true, - - // When the Ozone X11 backend is running, use a UI loop to grab Expose - // events. See GLSurfaceGLX and https://crbug.com/326995. - .message_pump_type_for_gpu = base::MessagePumpType::UI, - // When the Ozone X11 backend is running, use a UI loop to dispatch - // SHM completion events. - .message_pump_type_for_viz_compositor = base::MessagePumpType::UI, - .supports_vulkan_swap_chain = true, - .platform_shows_drag_image = false, - .supports_global_application_menus = true}; - // Singleton OzonePlatform implementation for X11 platform. class OzonePlatformX11 : public OzonePlatform, public ui::OSExchangeDataProviderFactoryOzone { public: OzonePlatformX11() { SetInstance(this); - - kX11PlatformProperties.custom_frame_pref_default = - ui::GetCustomFramePrefDefault(); } ~OzonePlatformX11() override {} @@ -170,7 +153,28 @@ } const PlatformProperties& GetPlatformProperties() override { - return kX11PlatformProperties; + static base::NoDestructor<OzonePlatform::PlatformProperties> properties; + static bool initialised = false; + if (!initialised) { + properties->custom_frame_pref_default = ui::GetCustomFramePrefDefault(); + properties->use_system_title_bar = true; + + // When the Ozone X11 backend is running, use a UI loop to grab Expose + // events. See GLSurfaceGLX and https://crbug.com/326995. + properties->message_pump_type_for_gpu = base::MessagePumpType::UI; + // When the Ozone X11 backend is running, use a UI loop to dispatch + // SHM completion events. + properties->message_pump_type_for_viz_compositor = + base::MessagePumpType::UI; + properties->supports_vulkan_swap_chain = true; + properties->platform_shows_drag_image = false; + properties->supports_global_application_menus = true; + properties->app_modal_dialogs_use_event_blocker = true; + + initialised = true; + } + + return *properties; } void InitializeUI(const InitParams& params) override {
diff --git a/ui/ozone/public/ozone_platform.cc b/ui/ozone/public/ozone_platform.cc index c7027b2..bcc577c5 100644 --- a/ui/ozone/public/ozone_platform.cc +++ b/ui/ozone/public/ozone_platform.cc
@@ -36,6 +36,9 @@ } // namespace +OzonePlatform::PlatformProperties::PlatformProperties() = default; +OzonePlatform::PlatformProperties::~PlatformProperties() = default; + OzonePlatform::OzonePlatform() { DCHECK(!g_instance) << "There should only be a single OzonePlatform."; g_instance = this;
diff --git a/ui/ozone/public/ozone_platform.h b/ui/ozone/public/ozone_platform.h index 797c79d0..764945e 100644 --- a/ui/ozone/public/ozone_platform.h +++ b/ui/ozone/public/ozone_platform.h
@@ -70,6 +70,11 @@ // Struct used to indicate platform properties. struct PlatformProperties { + PlatformProperties(); + PlatformProperties(const PlatformProperties& other) = delete; + PlatformProperties& operator=(const PlatformProperties& other) = delete; + ~PlatformProperties(); + // Fuchsia only: set to true when the platforms requires |view_token| field // in PlatformWindowInitProperties when creating a window. bool needs_view_token = false; @@ -105,6 +110,10 @@ // Linux only, but see a TODO in BrowserDesktopWindowTreeHostLinux. // Determines whether the platform supports the global application menu. bool supports_global_application_menus = false; + + // Determines if the application modal dialogs should use the event blocker + // to allow the only browser window receiving UI events. + bool app_modal_dialogs_use_event_blocker = false; }; // Properties available in the host process after initialization.
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index 97205b1..cf2df50 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -905,8 +905,6 @@ "test/scoped_views_test_helper.h", "test/slider_test_api.cc", "test/slider_test_api.h", - "test/test_ax_event_observer.cc", - "test/test_ax_event_observer.h", "test/test_layout_manager.cc", "test/test_layout_manager.h", "test/test_layout_provider.cc",
diff --git a/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc b/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc index 1a742163..8806f523 100644 --- a/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc +++ b/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc
@@ -75,7 +75,12 @@ return should_show_close_button_; } - void set_title_view(View* title_view) { title_view_.reset(title_view); } + template <typename T> + T* set_title_view(std::unique_ptr<T> title_view) { + T* const ret = title_view.get(); + title_view_ = std::move(title_view); + return ret; + } void show_close_button() { should_show_close_button_ = true; } void hide_buttons() { should_show_close_button_ = false; @@ -404,8 +409,8 @@ TestBubbleDialogDelegateView* bubble_delegate = new TestBubbleDialogDelegateView(anchor_widget->GetContentsView()); constexpr int kTitleHeight = 20; - View* title_view = new StaticSizedView(gfx::Size(10, kTitleHeight)); - bubble_delegate->set_title_view(title_view); + View* title_view = bubble_delegate->set_title_view( + std::make_unique<StaticSizedView>(gfx::Size(10, kTitleHeight))); Widget* bubble_widget = BubbleDialogDelegateView::CreateBubble(bubble_delegate); bubble_widget->Show(); @@ -480,8 +485,9 @@ CreateTestWidget(Widget::InitParams::TYPE_WINDOW); TestBubbleDialogDelegateView* bubble_delegate = new TestBubbleDialogDelegateView(anchor_widget->GetContentsView()); - StyledLabel* title_view = new StyledLabel(base::ASCIIToUTF16("123"), nullptr); - bubble_delegate->set_title_view(title_view); + StyledLabel* title_view = + bubble_delegate->set_title_view(std::make_unique<StyledLabel>()); + title_view->SetText(base::ASCIIToUTF16("123")); Widget* bubble_widget = BubbleDialogDelegateView::CreateBubble(bubble_delegate);
diff --git a/ui/views/controls/button/button_unittest.cc b/ui/views/controls/button/button_unittest.cc index d57aa9a..b2e72b78 100644 --- a/ui/views/controls/button/button_unittest.cc +++ b/ui/views/controls/button/button_unittest.cc
@@ -37,7 +37,7 @@ #include "ui/views/controls/link.h" #include "ui/views/controls/textfield/textfield.h" #include "ui/views/style/platform_style.h" -#include "ui/views/test/test_ax_event_observer.h" +#include "ui/views/test/ax_event_counter.h" #include "ui/views/test/view_metadata_test_utils.h" #include "ui/views/test/views_test_base.h" #include "ui/views/widget/widget_utils.h" @@ -962,10 +962,10 @@ // Verifies setting the tooltip text will call NotifyAccessibilityEvent. TEST_F(ButtonTest, SetTooltipTextNotifiesAccessibilityEvent) { base::string16 test_tooltip_text = base::ASCIIToUTF16("Test Tooltip Text"); - test::TestAXEventObserver observer; - EXPECT_EQ(0, observer.text_changed_event_count()); + test::AXEventCounter counter(views::AXEventManager::Get()); + EXPECT_EQ(0, counter.GetCount(ax::mojom::Event::kTextChanged)); button()->SetTooltipText(test_tooltip_text); - EXPECT_EQ(1, observer.text_changed_event_count()); + EXPECT_EQ(1, counter.GetCount(ax::mojom::Event::kTextChanged)); EXPECT_EQ(test_tooltip_text, button()->GetTooltipText(gfx::Point())); ui::AXNodeData data; button()->GetAccessibleNodeData(&data);
diff --git a/ui/views/controls/button/checkbox_unittest.cc b/ui/views/controls/button/checkbox_unittest.cc index bb554d2..2f9983a 100644 --- a/ui/views/controls/button/checkbox_unittest.cc +++ b/ui/views/controls/button/checkbox_unittest.cc
@@ -52,7 +52,8 @@ TEST_F(CheckboxTest, AccessibilityTest) { const base::string16 label_text = base::ASCIIToUTF16("Some label"); - StyledLabel label(label_text, nullptr); + StyledLabel label; + label.SetText(label_text); checkbox()->SetAssociatedLabel(&label); ui::AXNodeData ax_data;
diff --git a/ui/views/controls/combobox/combobox_unittest.cc b/ui/views/controls/combobox/combobox_unittest.cc index 1581b5f6..3737d9b 100644 --- a/ui/views/controls/combobox/combobox_unittest.cc +++ b/ui/views/controls/combobox/combobox_unittest.cc
@@ -31,8 +31,8 @@ #include "ui/events/types/event_type.h" #include "ui/views/controls/combobox/combobox_listener.h" #include "ui/views/style/platform_style.h" +#include "ui/views/test/ax_event_counter.h" #include "ui/views/test/combobox_test_api.h" -#include "ui/views/test/test_ax_event_observer.h" #include "ui/views/test/view_metadata_test_utils.h" #include "ui/views/test/views_test_base.h" #include "ui/views/widget/unique_widget_ptr.h" @@ -830,10 +830,10 @@ TEST_F(ComboboxTest, SetTooltipTextNotifiesAccessibilityEvent) { InitCombobox(nullptr); base::string16 test_tooltip_text = ASCIIToUTF16("Test Tooltip Text"); - test::TestAXEventObserver observer; - EXPECT_EQ(0, observer.text_changed_event_count()); + test::AXEventCounter counter(views::AXEventManager::Get()); + EXPECT_EQ(0, counter.GetCount(ax::mojom::Event::kTextChanged)); combobox_->SetTooltipText(test_tooltip_text); - EXPECT_EQ(1, observer.text_changed_event_count()); + EXPECT_EQ(1, counter.GetCount(ax::mojom::Event::kTextChanged)); EXPECT_EQ(test_tooltip_text, combobox_->GetAccessibleName()); ui::AXNodeData data; combobox_->GetAccessibleNodeData(&data);
diff --git a/ui/views/controls/image_view_unittest.cc b/ui/views/controls/image_view_unittest.cc index e5d9479..f7dfecc 100644 --- a/ui/views/controls/image_view_unittest.cc +++ b/ui/views/controls/image_view_unittest.cc
@@ -20,7 +20,7 @@ #include "ui/gfx/image/image_skia.h" #include "ui/views/border.h" #include "ui/views/layout/box_layout.h" -#include "ui/views/test/test_ax_event_observer.h" +#include "ui/views/test/ax_event_counter.h" #include "ui/views/test/views_test_base.h" #include "ui/views/widget/widget.h" @@ -151,10 +151,10 @@ // Verifies setting the accessible name will be call NotifyAccessibilityEvent. TEST_P(ImageViewTest, SetAccessibleNameNotifiesAccessibilityEvent) { base::string16 test_tooltip_text = base::ASCIIToUTF16("Test Tooltip Text"); - test::TestAXEventObserver observer; - EXPECT_EQ(0, observer.text_changed_event_count()); + test::AXEventCounter counter(views::AXEventManager::Get()); + EXPECT_EQ(0, counter.GetCount(ax::mojom::Event::kTextChanged)); image_view()->SetAccessibleName(test_tooltip_text); - EXPECT_EQ(1, observer.text_changed_event_count()); + EXPECT_EQ(1, counter.GetCount(ax::mojom::Event::kTextChanged)); EXPECT_EQ(test_tooltip_text, image_view()->GetAccessibleName()); ui::AXNodeData data; image_view()->GetAccessibleNodeData(&data);
diff --git a/ui/views/controls/styled_label.cc b/ui/views/controls/styled_label.cc index a494af8..96dfd7d 100644 --- a/ui/views/controls/styled_label.cc +++ b/ui/views/controls/styled_label.cc
@@ -78,11 +78,7 @@ std::vector<std::unique_ptr<View>> owned_views; }; -StyledLabel::StyledLabel(const base::string16& text, - StyledLabelListener* listener) - : listener_(listener) { - base::TrimWhitespace(text, base::TRIM_TRAILING, &text_); -} +StyledLabel::StyledLabel(StyledLabelListener* listener) : listener_(listener) {} StyledLabel::~StyledLabel() = default; @@ -90,7 +86,11 @@ return text_; } -void StyledLabel::SetText(const base::string16& text) { +void StyledLabel::SetText(base::string16 text) { + // Failing to trim trailing whitespace will cause later confusion when the + // text elider tries to do so internally. There's no obvious reason to + // preserve trailing whitespace anyway. + base::TrimWhitespace(std::move(text), base::TRIM_TRAILING, &text); if (text_ == text) return;
diff --git a/ui/views/controls/styled_label.h b/ui/views/controls/styled_label.h index b12461b..b87ca92 100644 --- a/ui/views/controls/styled_label.h +++ b/ui/views/controls/styled_label.h
@@ -105,18 +105,18 @@ // smaller width than this will force a recomputation. gfx::Size total_size; - // The sizes of each line of child views. |size| can be computed directly - // from these values and is kept separately just for convenience. + // The sizes of each line of child views. |total_size| can be computed + // directly from these values and is kept separately just for convenience. std::vector<gfx::Size> line_sizes; }; - // Note that any trailing whitespace in |text| will be trimmed. - StyledLabel(const base::string16& text, StyledLabelListener* listener); + explicit StyledLabel(StyledLabelListener* listener = nullptr); ~StyledLabel() override; - // Sets the text to be displayed, and clears any previous styling. + // Sets the text to be displayed, and clears any previous styling. Trailing + // whitespace is trimmed from the text. const base::string16& GetText() const; - void SetText(const base::string16& text); + void SetText(base::string16 text); // Returns the FontList that should be used. |style_info| is an optional // argument that takes precedence over the default values.
diff --git a/ui/views/controls/styled_label_unittest.cc b/ui/views/controls/styled_label_unittest.cc index c42c1452..5f805656 100644 --- a/ui/views/controls/styled_label_unittest.cc +++ b/ui/views/controls/styled_label_unittest.cc
@@ -54,7 +54,8 @@ } void InitStyledLabel(const std::string& ascii_text) { - styled_ = std::make_unique<StyledLabel>(ASCIIToUTF16(ascii_text), this); + styled_ = std::make_unique<StyledLabel>(this); + styled_->SetText(ASCIIToUTF16(ascii_text)); styled_->set_owned_by_client(); } @@ -330,7 +331,8 @@ // Sanity check that |bold_text| with normal font style would fit on a single // line in a styled label with width |styled_width|. - StyledLabel unstyled(ASCIIToUTF16(bold_text), this); + StyledLabel unstyled(this); + unstyled.SetText(ASCIIToUTF16(bold_text)); unstyled.SetBounds(0, 0, styled_width, pref_height); unstyled.Layout(); EXPECT_EQ(1u, unstyled.children().size());
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc index e331133..c3c9b52 100644 --- a/ui/views/controls/textfield/textfield_unittest.cc +++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -51,7 +51,7 @@ #include "ui/views/controls/textfield/textfield_test_api.h" #include "ui/views/focus/focus_manager.h" #include "ui/views/style/platform_style.h" -#include "ui/views/test/test_ax_event_observer.h" +#include "ui/views/test/ax_event_counter.h" #include "ui/views/test/test_views_delegate.h" #include "ui/views/test/views_test_base.h" #include "ui/views/test/widget_test.h" @@ -3474,10 +3474,10 @@ TEST_F(TextfieldTest, SetAccessibleNameNotifiesAccessibilityEvent) { InitTextfield(); base::string16 test_tooltip_text = ASCIIToUTF16("Test Accessible Name"); - test::TestAXEventObserver observer; - EXPECT_EQ(0, observer.text_changed_event_count()); + test::AXEventCounter counter(views::AXEventManager::Get()); + EXPECT_EQ(0, counter.GetCount(ax::mojom::Event::kTextChanged)); textfield_->SetAccessibleName(test_tooltip_text); - EXPECT_EQ(1, observer.text_changed_event_count()); + EXPECT_EQ(1, counter.GetCount(ax::mojom::Event::kTextChanged)); EXPECT_EQ(test_tooltip_text, textfield_->GetAccessibleName()); ui::AXNodeData data; textfield_->GetAccessibleNodeData(&data);
diff --git a/ui/views/metadata/metadata_impl_macros.h b/ui/views/metadata/metadata_impl_macros.h index 1cf40b5..6a54f1ef 100644 --- a/ui/views/metadata/metadata_impl_macros.h +++ b/ui/views/metadata/metadata_impl_macros.h
@@ -27,25 +27,25 @@ // This will fail to compile if the property accessors aren't in the form of // SetXXXX and GetXXXX. #define ADD_PROPERTY_METADATA(class_name, property_type, property_name) \ - std::unique_ptr<METADATA_PROPERTY_TYPE_INTERNAL(class_name, property_type, \ + std::unique_ptr<METADATA_PROPERTY_TYPE_INTERNAL(property_type, \ property_name)> \ property_name##_prop = std::make_unique<METADATA_PROPERTY_TYPE_INTERNAL( \ - class_name, property_type, property_name)>(); \ + property_type, property_name)>(); \ property_name##_prop->SetMemberName(#property_name); \ property_name##_prop->SetMemberType(#property_type); \ AddMemberData(std::move(property_name##_prop)); // This will fail to compile if the property accessor isn't in the form of // GetXXXX. -#define ADD_READONLY_PROPERTY_METADATA(class_name, property_type, \ - property_name) \ - std::unique_ptr<METADATA_READONLY_PROPERTY_TYPE_INTERNAL( \ - class_name, property_type, property_name)> \ - property_name##_prop = \ - std::make_unique<METADATA_READONLY_PROPERTY_TYPE_INTERNAL( \ - class_name, property_type, property_name)>(); \ - property_name##_prop->SetMemberName(#property_name); \ - property_name##_prop->SetMemberType(#property_type); \ +#define ADD_READONLY_PROPERTY_METADATA(class_name, property_type, \ + property_name) \ + std::unique_ptr<METADATA_READONLY_PROPERTY_TYPE_INTERNAL(property_type, \ + property_name)> \ + property_name##_prop = \ + std::make_unique<METADATA_READONLY_PROPERTY_TYPE_INTERNAL( \ + property_type, property_name)>(); \ + property_name##_prop->SetMemberName(#property_name); \ + property_name##_prop->SetMemberType(#property_type); \ AddMemberData(std::move(property_name##_prop)); #endif // UI_VIEWS_METADATA_METADATA_IMPL_MACROS_H_
diff --git a/ui/views/metadata/metadata_macros_internal.h b/ui/views/metadata/metadata_macros_internal.h index 59da36d..eb2b753f 100644 --- a/ui/views/metadata/metadata_macros_internal.h +++ b/ui/views/metadata/metadata_macros_internal.h
@@ -37,32 +37,34 @@ class METADATA_CLASS_NAME_INTERNAL(class_name) \ : public views::metadata::ClassMetaData { \ public: \ + using ViewClass = class_name; \ explicit METADATA_CLASS_NAME_INTERNAL(class_name)() \ : ClassMetaData(file, line) { \ BuildMetaData(); \ } \ + METADATA_CLASS_NAME_INTERNAL(class_name) \ + (const METADATA_CLASS_NAME_INTERNAL(class_name) &) = delete; \ + METADATA_CLASS_NAME_INTERNAL(class_name) & operator=( \ + const METADATA_CLASS_NAME_INTERNAL(class_name) &) = delete; \ \ private: \ friend class class_name; \ virtual void BuildMetaData(); \ static views::metadata::ClassMetaData* meta_data_ ALLOW_UNUSED_TYPE; \ - DISALLOW_COPY_AND_ASSIGN(METADATA_CLASS_NAME_INTERNAL(class_name)); \ } -#define METADATA_PROPERTY_TYPE_INTERNAL(class_name, property_type, \ - property_name) \ - views::metadata::ClassPropertyMetaData< \ - class_name, property_type, decltype(&class_name::Set##property_name), \ - &class_name::Set##property_name, \ - decltype(std::declval<class_name>().Get##property_name()), \ - &class_name::Get##property_name> +#define METADATA_PROPERTY_TYPE_INTERNAL(property_type, property_name) \ + views::metadata::ClassPropertyMetaData< \ + ViewClass, property_type, decltype(&ViewClass::Set##property_name), \ + &ViewClass::Set##property_name, \ + decltype(std::declval<ViewClass>().Get##property_name()), \ + &ViewClass::Get##property_name> -#define METADATA_READONLY_PROPERTY_TYPE_INTERNAL(class_name, property_type, \ - property_name) \ - views::metadata::ClassPropertyReadOnlyMetaData< \ - class_name, property_type, \ - decltype(std::declval<class_name>().Get##property_name()), \ - &class_name::Get##property_name> +#define METADATA_READONLY_PROPERTY_TYPE_INTERNAL(property_type, property_name) \ + views::metadata::ClassPropertyReadOnlyMetaData< \ + ViewClass, property_type, \ + decltype(std::declval<ViewClass>().Get##property_name()), \ + &ViewClass::Get##property_name> #define BEGIN_METADATA_INTERNAL(class_name) \ views::metadata::ClassMetaData* class_name::METADATA_CLASS_NAME_INTERNAL( \
diff --git a/ui/views/test/test_ax_event_observer.cc b/ui/views/test/test_ax_event_observer.cc deleted file mode 100644 index 1fbaec0..0000000 --- a/ui/views/test/test_ax_event_observer.cc +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/test/test_ax_event_observer.h" - -#include "ui/accessibility/ax_enums.mojom.h" -#include "ui/views/accessibility/ax_event_manager.h" -#include "ui/views/accessibility/ax_event_observer.h" - -namespace views { -namespace test { - -TestAXEventObserver::TestAXEventObserver() { - AXEventManager::Get()->AddObserver(this); -} - -TestAXEventObserver::~TestAXEventObserver() { - AXEventManager::Get()->RemoveObserver(this); -} - -void TestAXEventObserver::OnViewEvent(View* view, ax::mojom::Event event_type) { - if (event_type == ax::mojom::Event::kTextChanged) - ++text_changed_event_count_; -} - -} // namespace test -} // namespace views
diff --git a/ui/views/test/test_ax_event_observer.h b/ui/views/test/test_ax_event_observer.h deleted file mode 100644 index 718974c..0000000 --- a/ui/views/test/test_ax_event_observer.h +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_TEST_TEST_AX_EVENT_OBSERVER_H_ -#define UI_VIEWS_TEST_TEST_AX_EVENT_OBSERVER_H_ - -#include "ui/views/accessibility/ax_event_observer.h" - -namespace views { -namespace test { - -// Observes all Views accessibility events for tests. -class TestAXEventObserver : public AXEventObserver { - public: - TestAXEventObserver(); - TestAXEventObserver(const TestAXEventObserver&) = delete; - TestAXEventObserver& operator=(const TestAXEventObserver&) = delete; - ~TestAXEventObserver() override; - - // AXEventObserver: - void OnViewEvent(View* view, ax::mojom::Event event_type) override; - - int text_changed_event_count() const { return text_changed_event_count_; } - - private: - int text_changed_event_count_ = 0; -}; - -} // namespace test -} // namespace views - -#endif // UI_VIEWS_TEST_TEST_AX_EVENT_OBSERVER_H_