diff --git a/DEPS b/DEPS index 44c4a51..9ca28a7 100644 --- a/DEPS +++ b/DEPS
@@ -222,11 +222,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': 'b5cd95b58fba65d22518edbfd2982c82da358fe4', + 'skia_revision': '5caab8eea6e6e236bd1df2834ac43e95e10260f2', # 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': '10df900d12a671fb7a17514c0b62203df2ebaf2b', + 'v8_revision': 'd44c0c48b9644c3e085a42a7dbb97b5fdb38fc1d', # 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. @@ -234,7 +234,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '011ef7edf24c5ba8304a82d8bb83486ae49759b9', + 'angle_revision': 'e635f6c2f6f8aea77e5ec42df9615a9f5257d0cb', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -242,7 +242,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '60a7195a9b42b5f27b13fff2a9173ad797ce958c', + 'pdfium_revision': '178a16eb4c3cdd7fd2c821e2e6bbc506a50086dd', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -269,7 +269,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling NaCl # and whatever else without interference from each other. - 'nacl_revision': '99d0376791a10d3e8d16d0884b0222853567d7cc', + 'nacl_revision': '04380f47fa1839317e3c27c0bc087061231bc1a2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -301,7 +301,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': '853239d9237c4febd78a1103dcce4a313ead9553', + 'devtools_frontend_revision': 'd2002ce81eb3ea19488b73979c07e5632c863261', # 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. @@ -341,11 +341,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': 'cfd5ebb2f2ad1a9d57fe83437ea11aa477e351ea', + 'dawn_revision': '67035040f687fddbf38b7675c4ab23fa20b1fdaf', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'quiche_revision': '80f93811e1e6b737feb1324eddbe0ef8e435b78d', + 'quiche_revision': 'b69b653883363564d8cd93cbed561bb859d9bfc1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -369,7 +369,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling nearby # and whatever else without interference from each other. - 'nearby_revision': '258403118d3bd98ec6c52eeb6db0d626af05249d', + 'nearby_revision': '7c1f423014003e2bf4ed2feb7520b3355c834fed', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling securemessage # and whatever else without interference from each other. @@ -408,7 +408,7 @@ 'libcxx_revision': '79a2e924d96e2fc1e4b937c42efd08898fa472d7', # GN CIPD package version. - 'gn_version': 'git_revision:61a0153b5e60f11100a04e51393cae15268d1ee3', + 'gn_version': 'git_revision:d565aa3e72dd9e81da9595ee8c9d7b24cb45c48b', } # Only these hosts are allowed for dependencies in this DEPS file. @@ -651,7 +651,7 @@ 'packages': [ { 'package': 'chromium/rts/model/linux-amd64', - 'version': 'uYn940FBk_ICotJoTOu1E1AteY-XUIF8XcFnT5dmWMkC', + 'version': 'YJC4scXTq0Y8HjJ2pr8FDtf-_5_6kcggHIJyNN9Z4MwC', }, ], 'dep_type': 'cipd', @@ -662,7 +662,7 @@ 'packages': [ { 'package': 'chromium/rts/model/mac-amd64', - 'version': 'qWsm2aW_77qIRj_oOPKdUX0ule-VVZqY45g-K64y408C', + 'version': 'nDQeTu3Klh29HLZKRIyxAwcTWZcuElS6TY3yRB12f7sC', }, ], 'dep_type': 'cipd', @@ -673,7 +673,7 @@ 'packages': [ { 'package': 'chromium/rts/model/windows-amd64', - 'version': 'uuHcKSIrpBg-xESipDyzMpTv8BF0j9HXwOJtIAPZOoYC', + 'version': '2pZY3jtknnojIbHl4QL7TP8USEoMSwdv8nv6HSghfe4C', }, ], 'dep_type': 'cipd', @@ -738,7 +738,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': '3LEkAxvMyv3fgl0tjQXjlDeT_bwP9wCnOly8fNQlZQkC', + 'version': 'ak5sLJWTzTXot5KoqTvJsoSbbL-L5TYYMVsXEzVZDVsC', }, ], 'condition': 'checkout_android', @@ -954,7 +954,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '3a7b7a26d93e82da511142a1284c6488ffa9babe', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'f203f97cdc2be1d07151386f6f036fb23b3ffe46', 'condition': 'checkout_chromeos', }, @@ -1360,7 +1360,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '56537d0732d7cda6c26453cc60eee9e63a7f106a', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '99063db35d93f47568a608d87e3f3912db59d3dd', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1592,7 +1592,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'f19dd8595c4cc6058ec47db576b292d072353e5e', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '9e09831767995531ae1c2804e1c15fa2be4053f2', + Var('webrtc_git') + '/src.git' + '@' + '3b35fbcb66fee8af58b0c0990527833f1dcbcd7b', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1653,7 +1653,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c13f153ff608dde3400ae192a1dfecff244431e3', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@d776a052b8a501d8c2bf5d5ca5503f0da5cd44ef', 'condition': 'checkout_src_internal', }, @@ -1661,7 +1661,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/eche_app/app', - 'version': '6Y3z4rxrZpZwwidihDX3mul97QzeR6ZggWONNIYto1sC', + 'version': 'VZRj2PzW9IXHskymVfyKGRcnFTxPhSAkTbgc12beEckC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1672,7 +1672,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'vNRb2vKdknUwfwzzhwzJo4sSETdJYnu_Wy_F91-fOSAC', + 'version': 'oaXK5N5cXxFJ_nE5koGGPT1IQumi_tYTc7suEbL2nOgC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1683,7 +1683,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'WKUUwJJeT2Bz7DjwRD1mT4PNedG8Cr89EQRvQBrSlnMC', + 'version': '9kKuyr-hCQ0u1-4ohi2CMmkAwb1X7llLGb57NXYyZYEC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/ash/public/cpp/login_types.h b/ash/public/cpp/login_types.h index ec44b46..1da1a918 100644 --- a/ash/public/cpp/login_types.h +++ b/ash/public/cpp/login_types.h
@@ -69,6 +69,9 @@ // Showing user creation screen. USER_CREATION = 15, + + // Showing enrollment screen with the possibility to cancel. + ENROLLMENT_CANCEL_ENABLED = 16, }; // Supported multi-profile user behavior values.
diff --git a/ash/shelf/login_shelf_view.cc b/ash/shelf/login_shelf_view.cc index f0bbd9fe..f6e0e13 100644 --- a/ash/shelf/login_shelf_view.cc +++ b/ash/shelf/login_shelf_view.cc
@@ -92,6 +92,7 @@ LoginShelfView::kBrowseAsGuest, LoginShelfView::kAddUser, LoginShelfView::kEnterpriseEnrollment, + LoginShelfView::kSignIn, LoginShelfView::kOsInstall, }; @@ -295,6 +296,7 @@ bool ShutdownButtonHidden(OobeDialogState state) { return state == OobeDialogState::MIGRATION || state == OobeDialogState::ENROLLMENT || + state == OobeDialogState::ENROLLMENT_CANCEL_ENABLED || state == OobeDialogState::ONBOARDING || state == OobeDialogState::KIOSK_LAUNCH || state == OobeDialogState::PASSWORD_CHANGED; @@ -571,6 +573,12 @@ base::Unretained(Shell::Get()->login_screen_controller()), ash::LoginAcceleratorAction::kStartEnrollment), IDS_ASH_ENTERPRISE_ENROLLMENT_BUTTON, chromeos::kEnterpriseIcon); + add_button(kSignIn, + base::BindRepeating( + &LoginScreenController::HandleAccelerator, + base::Unretained(Shell::Get()->login_screen_controller()), + ash::LoginAcceleratorAction::kCancelScreenAction), + IDS_ASH_SHELF_SIGNIN_BUTTON, kShelfAddPersonButtonIcon); add_button(kOsInstall, base::BindRepeating( &LoginScreenController::ShowOsInstallScreen, @@ -830,6 +838,7 @@ GetViewByID(kBrowseAsGuest)->SetVisible(ShouldShowGuestButton()); GetViewByID(kEnterpriseEnrollment) ->SetVisible(ShouldShowEnterpriseEnrollmentButton()); + GetViewByID(kSignIn)->SetVisible(ShouldShowSignInButton()); // Show add user button when it's in login screen and Oobe UI dialog is not // visible. The button should not appear if the device is not connected to a @@ -869,6 +878,7 @@ static_cast<LoginShelfButton*>(GetViewByID(kAddUser))->UpdateButtonColors(); static_cast<LoginShelfButton*>(GetViewByID(kEnterpriseEnrollment)) ->UpdateButtonColors(); + static_cast<LoginShelfButton*>(GetViewByID(kSignIn))->UpdateButtonColors(); static_cast<LoginShelfButton*>(GetViewByID(kOsInstall))->UpdateButtonColors(); kiosk_apps_button_->UpdateButtonColors(); } @@ -939,6 +949,13 @@ dialog_state_ == OobeDialogState::USER_CREATION; } +bool LoginShelfView::ShouldShowSignInButton() const { + const SessionState session_state = + Shell::Get()->session_controller()->GetSessionState(); + return session_state == SessionState::OOBE && + dialog_state_ == OobeDialogState::ENROLLMENT_CANCEL_ENABLED; +} + bool LoginShelfView::ShouldShowAppsButton() const { if (!ShouldShowGuestAndAppsButtons()) return false;
diff --git a/ash/shelf/login_shelf_view.h b/ash/shelf/login_shelf_view.h index 3e7c581..9ad5b60 100644 --- a/ash/shelf/login_shelf_view.h +++ b/ash/shelf/login_shelf_view.h
@@ -58,6 +58,7 @@ kApps, // Show list of available kiosk apps. kParentAccess, // Unlock child device with Parent Access Code. kEnterpriseEnrollment, // Start enterprise enrollment flow. + kSignIn, // Start signin. kOsInstall, // Start OS Install flow. }; @@ -174,6 +175,8 @@ bool ShouldShowEnterpriseEnrollmentButton() const; + bool ShouldShowSignInButton() const; + bool ShouldShowAppsButton() const; bool ShouldShowGuestAndAppsButtons() const;
diff --git a/ash/system/bluetooth/tray_bluetooth_helper_legacy.cc b/ash/system/bluetooth/tray_bluetooth_helper_legacy.cc index f62cd2f..1864370 100644 --- a/ash/system/bluetooth/tray_bluetooth_helper_legacy.cc +++ b/ash/system/bluetooth/tray_bluetooth_helper_legacy.cc
@@ -69,7 +69,7 @@ error_code ? absl::make_optional(GetConnectionFailureReason(*error_code)) : absl::nullopt, - device::BluetoothUiSurface::kSystemTray); + device::UserInitiatedReconnectionUISurfaces::kSystemTray); } if (error_code) { LOG(ERROR) << "Failed to connect to device, error code [" @@ -230,7 +230,7 @@ if (!discovery_start_timestamp_.is_null()) { device::RecordDeviceSelectionDuration( base::DefaultClock::GetInstance()->Now() - discovery_start_timestamp_, - device::BluetoothUiSurface::kSystemTray, device->IsPaired(), + device::DeviceSelectionUISurfaces::kSystemTray, device->IsPaired(), device->GetType()); discovery_start_timestamp_ = base::Time(); } @@ -244,7 +244,7 @@ if (!device->IsConnectable()) { device::RecordUserInitiatedReconnectionAttemptResult( device::ConnectionFailureReason::kNotConnectable, - device::BluetoothUiSurface::kSystemTray); + device::UserInitiatedReconnectionUISurfaces::kSystemTray); return; }
diff --git a/ash/webui/diagnostics_ui/diagnostics_ui.cc b/ash/webui/diagnostics_ui/diagnostics_ui.cc index 23ffad32..ab002c14 100644 --- a/ash/webui/diagnostics_ui/diagnostics_ui.cc +++ b/ash/webui/diagnostics_ui/diagnostics_ui.cc
@@ -110,6 +110,8 @@ {"httpFirewallRoutineText", IDS_NETWORK_DIAGNOSTICS_HTTP_FIREWALL}, {"httpsFirewallRoutineText", IDS_NETWORK_DIAGNOSTICS_HTTPS_FIREWALL}, {"httpsLatencyRoutineText", IDS_NETWORK_DIAGNOSTICS_HTTPS_LATENCY}, + {"ipConfigInfoDrawerTitle", + IDS_NETWORK_DIAGNOSTICS_IP_CONFIG_INFO_DRAWER_TITLE}, {"lanConnectivityRoutineText", IDS_NETWORK_DIAGNOSTICS_LAN_CONNECTIVITY}, {"learnMore", IDS_DIANOSTICS_LEARN_MORE_LABEL}, {"learnMoreShort", IDS_DIAGNOSTICS_LEARN_MORE_LABEL_SHORT},
diff --git a/ash/webui/diagnostics_ui/resources/BUILD.gn b/ash/webui/diagnostics_ui/resources/BUILD.gn index 724e5074..0c964c6b6 100644 --- a/ash/webui/diagnostics_ui/resources/BUILD.gn +++ b/ash/webui/diagnostics_ui/resources/BUILD.gn
@@ -176,6 +176,8 @@ deps = [ ":diagnostics_types", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_button:cr_button.m", + "//ui/webui/resources/js:i18n_behavior.m", ] }
diff --git a/ash/webui/diagnostics_ui/resources/ip_config_info_drawer.html b/ash/webui/diagnostics_ui/resources/ip_config_info_drawer.html index 2e95ca3..2da16b0f9 100644 --- a/ash/webui/diagnostics_ui/resources/ip_config_info_drawer.html +++ b/ash/webui/diagnostics_ui/resources/ip_config_info_drawer.html
@@ -1,3 +1,8 @@ <style include="diagnostics-shared diagnostics-fonts"> </style> -<div id="ipConfigInfoElement"></div> +<cr-expand-button expanded="{{expanded_}}"> + <span aria-hidden="true">[[i18n('ipConfigInfoDrawerTitle')]]</span> +</cr-expand-button> +<template is="dom-if" if="[[expanded_]]"> + <div id="ipConfigInfoElement"></div> +</template>
diff --git a/ash/webui/diagnostics_ui/resources/ip_config_info_drawer.js b/ash/webui/diagnostics_ui/resources/ip_config_info_drawer.js index b9601b5..e2117637 100644 --- a/ash/webui/diagnostics_ui/resources/ip_config_info_drawer.js +++ b/ash/webui/diagnostics_ui/resources/ip_config_info_drawer.js
@@ -5,6 +5,8 @@ import './diagnostics_fonts_css.js'; import './diagnostics_shared_css.js'; +import 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.m.js'; +import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; /** @@ -17,5 +19,16 @@ _template: html`{__html_template__}`, - properties: {}, + behaviors: [I18nBehavior], + + properties: { + /** + * @protected + * @type {boolean} + */ + expanded_: { + type: Boolean, + value: false, + }, + }, });
diff --git a/base/BUILD.gn b/base/BUILD.gn index 576bd49..0c47ed7 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -221,6 +221,7 @@ "containers/cxx20_erase_unordered_map.h", "containers/cxx20_erase_unordered_set.h", "containers/cxx20_erase_vector.h", + "containers/extend.h", "containers/fixed_flat_map.h", "containers/fixed_flat_set.h", "containers/flat_map.h", @@ -2877,6 +2878,7 @@ "containers/contains_unittest.cc", "containers/contiguous_iterator_unittest.cc", "containers/erase_unittest.cc", + "containers/extend_unittest.cc", "containers/fixed_flat_map_unittest.cc", "containers/fixed_flat_set_unittest.cc", "containers/flat_map_unittest.cc",
diff --git a/base/android/build_info.cc b/base/android/build_info.cc index be91430..5d8a138e 100644 --- a/base/android/build_info.cc +++ b/base/android/build_info.cc
@@ -86,5 +86,11 @@ return Singleton<BuildInfo, BuildInfoSingletonTraits >::get(); } +// static +bool BuildInfo::IsAtLeastS() { + JNIEnv* env = AttachCurrentThread(); + return Java_BuildInfo_isAtLeastS(env); +} + } // namespace android } // namespace base
diff --git a/base/android/build_info.h b/base/android/build_info.h index 92f730a..f75e8cf 100644 --- a/base/android/build_info.h +++ b/base/android/build_info.h
@@ -51,6 +51,10 @@ // should only be one instance of BuildInfo ever created. static BuildInfo* GetInstance(); + // Checks if the device is running on a pre-release version of Android S or a + // release version of Android S or newer. + bool IsAtLeastS(); + // Const char* is used instead of std::strings because these values must be // available even if the process is in a crash state. Sadly // std::string.c_str() doesn't guarantee that memory won't be allocated when
diff --git a/base/android/java/src/org/chromium/base/BuildInfo.java b/base/android/java/src/org/chromium/base/BuildInfo.java index 7693702..deca13f 100644 --- a/base/android/java/src/org/chromium/base/BuildInfo.java +++ b/base/android/java/src/org/chromium/base/BuildInfo.java
@@ -243,6 +243,7 @@ * * @return {@code true} if S APIs are available for use, {@code false} otherwise */ + @CalledByNative @ChecksSdkIntAtLeast(api = 31, codename = "S") public static boolean isAtLeastS() { return VERSION.SDK_INT >= 31 || isAtLeastPreReleaseCodename("S", VERSION.CODENAME);
diff --git a/base/containers/extend.h b/base/containers/extend.h new file mode 100644 index 0000000..b4f1c12 --- /dev/null +++ b/base/containers/extend.h
@@ -0,0 +1,31 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_CONTAINERS_EXTEND_H_ +#define BASE_CONTAINERS_EXTEND_H_ + +#include <iterator> +#include <vector> + +namespace base { + +// Append to |dst| all elements of |src| by std::move-ing them out of |src|. +// After this operation, |src| will be empty. +template <typename T> +void Extend(std::vector<T>& dst, std::vector<T>&& src) { + dst.insert(dst.end(), std::make_move_iterator(src.begin()), + std::make_move_iterator(src.end())); + src.clear(); +} + +// Append to |dst| all elements of |src| by copying them out of |src|. |src| is +// not changed. +template <typename T> +void Extend(std::vector<T>& dst, const std::vector<T>& src) { + dst.insert(dst.end(), src.begin(), src.end()); +} + +} // namespace base + +#endif // BASE_CONTAINERS_EXTEND_H_
diff --git a/base/containers/extend_unittest.cc b/base/containers/extend_unittest.cc new file mode 100644 index 0000000..ec69936 --- /dev/null +++ b/base/containers/extend_unittest.cc
@@ -0,0 +1,102 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/containers/extend.h" + +#include <initializer_list> +#include <type_traits> +#include <utility> +#include <vector> + +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { + +namespace { + +struct NonCopyable { + char c_; + explicit NonCopyable(char c) : c_(c) {} + NonCopyable(NonCopyable&&) = default; + NonCopyable& operator=(NonCopyable&& other) = default; + + NonCopyable(const NonCopyable&) = delete; + NonCopyable& operator=(const NonCopyable&) = delete; +}; + +bool operator==(const NonCopyable& a, const NonCopyable& b) { + return a.c_ == b.c_; +} + +static_assert(std::is_move_constructible<NonCopyable>::value, ""); +static_assert(!std::is_copy_constructible<NonCopyable>::value, ""); + +struct CopyableMovable { + bool copied_; + char c_; + explicit CopyableMovable(char c) : copied_(false), c_(c) {} + CopyableMovable(const CopyableMovable& other) : copied_(true), c_(other.c_) {} + + CopyableMovable& operator=(const CopyableMovable&) = default; + CopyableMovable(CopyableMovable&&) = default; + CopyableMovable& operator=(CopyableMovable&& other) = default; +}; + +bool operator==(const CopyableMovable& a, const CopyableMovable& b) { + return a.c_ == b.c_; +} + +} // namespace + +TEST(ExtendTest, ExtendWithMove) { + std::vector<NonCopyable> dst; + for (char c : {'a', 'b', 'c', 'd'}) + dst.emplace_back(c); + std::vector<NonCopyable> src; + for (char c : {'e', 'f', 'g'}) + src.emplace_back(c); + std::vector<NonCopyable> expected; + for (char c : {'a', 'b', 'c', 'd', 'e', 'f', 'g'}) + expected.emplace_back(c); + + Extend(dst, std::move(src)); + EXPECT_EQ(dst, expected); + EXPECT_TRUE(src.empty()); +} + +TEST(ExtendTest, ExtendCopyableWithMove) { + std::vector<CopyableMovable> dst; + for (char c : {'a', 'b', 'c', 'd'}) + dst.emplace_back(c); + std::vector<CopyableMovable> src; + for (char c : {'e', 'f', 'g'}) + src.emplace_back(c); + std::vector<CopyableMovable> expected; + for (char c : {'a', 'b', 'c', 'd', 'e', 'f', 'g'}) + expected.emplace_back(c); + + Extend(dst, std::move(src)); + EXPECT_EQ(dst, expected); + EXPECT_TRUE(src.empty()); +} + +TEST(ExtendTest, ExtendWithCopy) { + std::vector<CopyableMovable> dst; + for (char c : {'a', 'b', 'c', 'd'}) + dst.emplace_back(c); + std::vector<CopyableMovable> src; + for (char c : {'e', 'f', 'g'}) + src.emplace_back(c); + std::vector<CopyableMovable> expected; + for (char c : {'a', 'b', 'c', 'd', 'e', 'f', 'g'}) + expected.emplace_back(c); + + EXPECT_FALSE(dst[0].copied_); + Extend(dst, src); + EXPECT_EQ(dst, expected); + EXPECT_FALSE(dst[0].copied_); + EXPECT_TRUE(dst[dst.size() - 1].copied_); +} + +} // namespace base
diff --git a/base/trace_event/trace_event_memory_overhead.cc b/base/trace_event/trace_event_memory_overhead.cc index 9f316739..977600d9 100644 --- a/base/trace_event/trace_event_memory_overhead.cc +++ b/base/trace_event/trace_event_memory_overhead.cc
@@ -114,7 +114,7 @@ case Value::Type::DICTIONARY: Add(kBaseValue, sizeof(Value)); - for (const auto& pair : value.DictItems()) { + for (const auto pair : value.DictItems()) { AddString(pair.first); AddValue(pair.second); }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index ede07d1..5dedf5d 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1216,12 +1216,18 @@ # different build directory like "out/feature_a" and "out/feature_b" if # we build same files with same compile flag. # Other paths are already given in relative, no need to normalize them. - cflags += [ - "-Xclang", - "-fdebug-compilation-dir", - "-Xclang", - ".", - ] + if (is_nacl) { + cflags += [ + "-Xclang", + "-fdebug-compilation-dir", + "-Xclang", + ".", + ] + } else { + # -ffile-compilation-dir is an alias for both -fdebug-compilation-dir= + # and -fcoverage-compilation-dir=. + cflags += [ "-ffile-compilation-dir=." ] + } if (!is_win) { # We don't use clang -cc1as on Windows (yet? https://crbug.com/762167) asmflags = [ "-Wa,-fdebug-compilation-dir,." ] @@ -1576,8 +1582,7 @@ if (is_clang) { cflags += [ - # TODO(thakis): Consider -Wloop-analysis (turns on - # -Wrange-loop-analysis too). + "-Wloop-analysis", # TODO(thakis): This used to be implied by -Wno-unused-function, # which we no longer use. Check if it makes sense to remove @@ -2382,6 +2387,16 @@ # gcc nacl is is_nacl && !is_clang, pnacl and nacl-clang are && is_clang. if (!is_nacl || is_clang) { cflags += [ "-g2" ] + + # gcc generates dwarf-aranges by default on -g1 and -g2. On clang it has + # to be manually enabled. + # + # It is skipped in tsan and asan because enabling it causes some + # formatting changes in the output which would require fixing bunches + # of expectation regexps. + if (is_clang && !is_tsan && !is_asan) { + cflags += [ "-gdwarf-aranges" ] + } } if (is_apple) { @@ -2474,6 +2489,11 @@ # gcc nacl is is_nacl && !is_clang, pnacl and nacl-clang are && is_clang. if (!is_nacl || is_clang) { cflags += [ "-g1" ] + + # See comment for -gdwarf-aranges in config("symbols"). + if (is_clang && !is_tsan && !is_asan) { + cflags += [ "-gdwarf-aranges" ] + } } ldflags = [] if (is_android && is_clang) {
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni index 8c259c36..642319b 100644 --- a/build/config/compiler/compiler.gni +++ b/build/config/compiler/compiler.gni
@@ -225,11 +225,8 @@ # deterministic builds to reduce compile times, so this is less relevant for # official builders. strip_absolute_paths_from_debug_symbols_default = - # TODO(crbug.com/1010267): remove '!use_clang_coverage', coverage build has - # dependency to absolute path of source files. - !use_clang_coverage && - (is_android || is_fuchsia || is_nacl || (is_win && use_lld) || is_linux || - is_chromeos || (is_apple && !enable_dsyms)) + is_android || is_fuchsia || is_nacl || (is_win && use_lld) || is_linux || + is_chromeos || (is_apple && !enable_dsyms) # If the platform uses stripped absolute paths by default, then we don't expose # it as a configuration option. If this is causing problems, please file a bug.
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 03d58272..1cf70b2f 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -5.20210719.3.1 +5.20210720.1.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 758829b..1cf70b2f 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -5.20210719.2.1 +5.20210720.1.1
diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc index 4cec1f3..d0546a6 100644 --- a/cc/layers/heads_up_display_layer_impl.cc +++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -380,7 +380,8 @@ constexpr GLuint msaa_sample_count = -1; constexpr bool can_use_lcd_text = true; ri->BeginRasterCHROMIUM(background_color, needs_clear, msaa_sample_count, - can_use_lcd_text, gfx::ColorSpace::CreateSRGB(), + gpu::raster::kNoMSAA, can_use_lcd_text, + gfx::ColorSpace::CreateSRGB(), backing->mailbox.name); gfx::Vector2dF post_translate(0.f, 0.f); gfx::Vector2dF post_scale(1.f, 1.f);
diff --git a/cc/paint/oop_pixeltest.cc b/cc/paint/oop_pixeltest.cc index 4bb65676..841a912 100644 --- a/cc/paint/oop_pixeltest.cc +++ b/cc/paint/oop_pixeltest.cc
@@ -179,11 +179,16 @@ raster_implementation->WaitSyncTokenCHROMIUM( sii->GenUnverifiedSyncToken().GetConstData()); + // Assume legacy MSAA if sample count is positive. + gpu::raster::MsaaMode msaa_mode = options.msaa_sample_count > 0 + ? gpu::raster::kMSAA + : gpu::raster::kNoMSAA; + if (options.preclear) { raster_implementation->BeginRasterCHROMIUM( options.preclear_color, /*needs_clear=*/options.preclear, - options.msaa_sample_count, options.use_lcd_text, options.color_space, - mailbox.name); + options.msaa_sample_count, msaa_mode, options.use_lcd_text, + options.color_space, mailbox.name); raster_implementation->EndRasterCHROMIUM(); } @@ -193,8 +198,8 @@ // cleared, so set |needs_clear| to false here. raster_implementation->BeginRasterCHROMIUM( options.background_color, /*needs_clear=*/!options.preclear, - options.msaa_sample_count, options.use_lcd_text, options.color_space, - mailbox.name); + options.msaa_sample_count, msaa_mode, options.use_lcd_text, + options.color_space, mailbox.name); size_t max_op_size_limit = gpu::raster::RasterInterface::kDefaultMaxOpSizeHint; raster_implementation->RasterCHROMIUM(
diff --git a/cc/raster/gpu_raster_buffer_provider.cc b/cc/raster/gpu_raster_buffer_provider.cc index ded09504..2af2773 100644 --- a/cc/raster/gpu_raster_buffer_provider.cc +++ b/cc/raster/gpu_raster_buffer_provider.cc
@@ -78,10 +78,15 @@ ri->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); } + // Assume legacy MSAA if sample count is positive. + gpu::raster::MsaaMode msaa_mode = playback_settings.msaa_sample_count > 0 + ? gpu::raster::kMSAA + : gpu::raster::kNoMSAA; + ri->BeginRasterCHROMIUM( raster_source->background_color(), mailbox_needs_clear, - playback_settings.msaa_sample_count, playback_settings.use_lcd_text, - color_space, mailbox->name); + playback_settings.msaa_sample_count, msaa_mode, + playback_settings.use_lcd_text, color_space, mailbox->name); gfx::Vector2dF recording_to_raster_scale = transform.scale(); recording_to_raster_scale.Scale(1 / raster_source->recording_scale_factor()); gfx::Size content_size = raster_source->GetContentSize(transform.scale());
diff --git a/cc/raster/raster_buffer_provider_unittest.cc b/cc/raster/raster_buffer_provider_unittest.cc index 0c37113..9ba0950 100644 --- a/cc/raster/raster_buffer_provider_unittest.cc +++ b/cc/raster/raster_buffer_provider_unittest.cc
@@ -176,6 +176,7 @@ void BeginRasterCHROMIUM(GLuint sk_color, GLboolean needs_clear, GLuint msaa_sample_count, + gpu::raster::MsaaMode msaa_mode, GLboolean can_use_lcd_text, const gfx::ColorSpace& color_space, const GLbyte* mailbox) override {}
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni index 599227d..3f07afc 100644 --- a/chrome/android/chrome_java_resources.gni +++ b/chrome/android/chrome_java_resources.gni
@@ -758,7 +758,6 @@ "java/res/values-v26/styles.xml", "java/res/values-v27/styles.xml", "java/res/values-v28/styles.xml", - "java/res/values-v31/styles.xml", "java/res/values-xhdpi/dimens.xml", "java/res/values-xlarge/dimens.xml", "java/res/values/attrs.xml",
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java index cfdef45..985a593 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
@@ -177,6 +177,7 @@ @Test @MediumTest + @DisabledTest(message = "crbug.com/1231024") public void testBackPressCloseDialog() { final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); createTabs(cta, false, 2); @@ -211,6 +212,7 @@ @Test @MediumTest + @DisabledTest(message = "crbug.com/1231024") public void testClickScrimCloseDialog() throws ExecutionException { final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); createTabs(cta, false, 2); @@ -340,7 +342,7 @@ @Test @MediumTest - @DisableIf.Build(supported_abis_includes = "x86", message = "https://crbug.com/1121363") + @DisabledTest(message = "crbug.com/1231024 and https://crbug.com/1121363") public void testUndoClosureInDialog_DialogUndoBar() throws ExecutionException { final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); createTabs(cta, false, 2); @@ -597,6 +599,7 @@ @Test @MediumTest @Features.EnableFeatures(ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID) + @DisabledTest(message = "crbug.com/1231024") public void testTabGroupNaming() throws ExecutionException { final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); createTabs(cta, false, 2); @@ -635,6 +638,7 @@ // clang-format off @Features.EnableFeatures({ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID + "<Study"}) @CommandLineFlags.Add({"force-fieldtrials=Study/Group", TAB_GROUP_LAUNCH_POLISH_PARAMS}) + @DisabledTest(message = "crbug.com/1231024") public void testTabGroupNaming_KeyboardVisibility() throws ExecutionException { // clang-format on final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); @@ -979,6 +983,7 @@ @Test @MediumTest + @DisabledTest(message = "crbug.com/1231024") public void testCreateTabInDialog() { final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); createTabs(cta, false, 2);
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java index 1675f4b..04c61d4 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
@@ -15,6 +15,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; @@ -89,6 +90,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.JniMocker; +import org.chromium.build.BuildConfig; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.endpoint_fetcher.EndpointFetcher; import org.chromium.chrome.browser.endpoint_fetcher.EndpointFetcherJni; @@ -1706,9 +1708,16 @@ assertEquals(TabProperties.UiType.DIVIDER, mModel.get(1).type); } - @Test(expected = AssertionError.class) + @Test public void addSpecialItem_withoutTabListModelProperties() { - mMediator.addSpecialItemToModel(0, TabProperties.UiType.DIVIDER, new PropertyModel()); + if (!BuildConfig.ENABLE_ASSERTS) return; + + try { + mMediator.addSpecialItemToModel(0, TabProperties.UiType.DIVIDER, new PropertyModel()); + } catch (AssertionError e) { + return; + } + fail("PropertyModel#validateKey() assert should have failed."); } @Test
diff --git a/chrome/android/java/res/values-sw600dp-v27/styles.xml b/chrome/android/java/res/values-sw600dp-v27/styles.xml index ee0ebc6..0a208fb 100644 --- a/chrome/android/java/res/values-sw600dp-v27/styles.xml +++ b/chrome/android/java/res/values-sw600dp-v27/styles.xml
@@ -5,6 +5,6 @@ <resources> <style name="Theme.Chromium.WithWindowAnimation" - parent="Base.Theme.Chromium.WithWindowAnimation" /> - <style name="Base.V27.Theme.Chromium.DialogWhenLarge" parent="Base.Theme.Chromium.DialogWhenLarge" /> + parent="Base.Theme.Chromium.WithWindowAnimation"/> + <style name="Theme.Chromium.DialogWhenLarge" parent="Base.Theme.Chromium.DialogWhenLarge"/> </resources>
diff --git a/chrome/android/java/res/values-v27/styles.xml b/chrome/android/java/res/values-v27/styles.xml index 63bc0f0..2ddbe83 100644 --- a/chrome/android/java/res/values-v27/styles.xml +++ b/chrome/android/java/res/values-v27/styles.xml
@@ -14,7 +14,7 @@ <item name="android:navigationBarDividerColor">@color/bottom_system_nav_divider_color</item> <item name="android:windowLightNavigationBar">@bool/window_light_navigation_bar</item> </style> - <style name="Base.V27.Theme.Chromium.DialogWhenLarge" parent="Base.Theme.Chromium.DialogWhenLarge" > + <style name="Theme.Chromium.DialogWhenLarge" parent="Base.Theme.Chromium.DialogWhenLarge"> <item name="android:navigationBarColor">@color/bottom_system_nav_color</item> <item name="android:navigationBarDividerColor">@color/bottom_system_nav_divider_color</item> <item name="android:windowLightNavigationBar">@bool/window_light_navigation_bar</item>
diff --git a/chrome/android/java/res/values-v31/styles.xml b/chrome/android/java/res/values-v31/styles.xml deleted file mode 100644 index 0cdc95c..0000000 --- a/chrome/android/java/res/values-v31/styles.xml +++ /dev/null
@@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2021 The Chromium Authors. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. --> - -<resources> - <style name="Theme.Chromium.DialogWhenLarge" parent="Base.V27.Theme.Chromium.DialogWhenLarge" > - <!-- TODO(https://crbug.com/1201349): Disable overscroll on S due to - consistency issues between browser and web platform. --> - <item name="android:overScrollMode">never</item> - </style> -</resources>
diff --git a/chrome/android/java/res/values/styles.xml b/chrome/android/java/res/values/styles.xml index b90ad9278..e747561 100644 --- a/chrome/android/java/res/values/styles.xml +++ b/chrome/android/java/res/values/styles.xml
@@ -134,11 +134,9 @@ <item name="windowNoTitle">true</item> <item name="windowActionBar">false</item> </style> - <!-- TODO(https://crbug.com/933438): Move v29 override to upstream. --> <style name="Base.Theme.Chromium.DialogWhenLarge" parent="Base.V17.Theme.Chromium.DialogWhenLarge" /> - <style name="Base.V27.Theme.Chromium.DialogWhenLarge" parent="Base.Theme.Chromium.DialogWhenLarge" /> - <style name="Theme.Chromium.DialogWhenLarge" parent="Base.V27.Theme.Chromium.DialogWhenLarge" /> + <style name="Theme.Chromium.DialogWhenLarge" parent="Base.Theme.Chromium.DialogWhenLarge" /> <style name="DimmingDialog" parent="Base.Theme.Chromium.DialogWhenLarge"> <item name="android:windowLightNavigationBar" tools:targetApi="28">false</item> </style> @@ -491,4 +489,8 @@ <style name="ColorOverlay.ChromiumAndroid.DayNight" parent="ColorOverlay"> <!-- TODO(https://crbug.com/1216642): Move color attributes here. --> </style> + + <style name="ThemeOverlay.DisableOverscroll" parent=""> + <item name="android:overScrollMode">never</item> + </style> </resources>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java index 38d5c725..f2e83ac 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java
@@ -16,6 +16,7 @@ import androidx.annotation.StyleRes; import androidx.appcompat.app.AppCompatActivity; +import org.chromium.base.BuildInfo; import org.chromium.base.ContextUtils; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; @@ -178,6 +179,16 @@ if (CachedFeatureFlags.isEnabled(ChromeFeatureList.DYNAMIC_COLOR_ANDROID)) { new ColorDelegateImpl().applyDynamicColorsIfAvailable(this); } + // Try to enable browser overscroll when content overscroll is enabled for consistency. This + // needs to be in a cached feature because activity startup happens before native is + // initialized. Unfortunately content overscroll is read in renderer threads, and these two + // are not synchronized. Typically the first time overscroll is enabled, the following will + // use the old value and then content will pick up the enabled value, causing one execution + // of inconsistency. + if (BuildInfo.isAtLeastS() + && !CachedFeatureFlags.isEnabled(ChromeFeatureList.ELASTIC_OVERSCROLL)) { + setTheme(R.style.ThemeOverlay_DisableOverscroll); + } } // NightModeStateProvider.Observer implementation.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java index e7675d4..bd461886 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -82,6 +82,7 @@ add(ChromeFeatureList.DOWNLOADS_AUTO_RESUMPTION_NATIVE); add(ChromeFeatureList.DYNAMIC_COLOR_ANDROID); add(ChromeFeatureList.EARLY_LIBRARY_LOAD); + add(ChromeFeatureList.ELASTIC_OVERSCROLL); add(ChromeFeatureList.IMMERSIVE_UI_MODE); add(ChromeFeatureList.INSTANT_START); add(ChromeFeatureList.INTEREST_FEED_V2);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedPromoRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedPromoRenderTest.java index 5fb7571..5fc63958 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedPromoRenderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedPromoRenderTest.java
@@ -33,10 +33,9 @@ import org.chromium.chrome.test.util.BookmarkTestRule; import org.chromium.chrome.test.util.BookmarkTestUtil; import org.chromium.chrome.test.util.ChromeRenderTestRule; -import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule; -import org.chromium.components.signin.test.util.FakeProfileDataSource; +import org.chromium.components.signin.test.util.FakeAccountInfoService; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.NightModeTestUtils; import org.chromium.ui.test.util.UiDisableIf; @@ -47,14 +46,12 @@ @RunWith(ParameterizedRunner.class) @ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -@DisableFeatures({ChromeFeatureList.DEPRECATE_MENAGERIE_API}) -@EnableFeatures({ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY_PROMOS}) +@EnableFeatures({ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY_PROMOS, + ChromeFeatureList.DEPRECATE_MENAGERIE_API}) @DisableIf.Device(type = {UiDisableIf.TABLET}) public class BookmarkPersonalizedPromoRenderTest { - // FakeProfileDataSource is required to create the ProfileDataCache entry with sync_off badge - // for Sync promo. private final AccountManagerTestRule mAccountManagerTestRule = - new AccountManagerTestRule(new FakeProfileDataSource()); + new AccountManagerTestRule(new FakeAccountInfoService()); private final ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java index 9b1c844..2a4d4228 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java
@@ -73,7 +73,7 @@ import org.chromium.chrome.test.util.browser.suggestions.mostvisited.FakeMostVisitedSites; import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; import org.chromium.components.embedder_support.util.UrlConstants; -import org.chromium.components.signin.test.util.FakeProfileDataSource; +import org.chromium.components.signin.test.util.FakeAccountInfoService; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.test.util.KeyUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; @@ -103,8 +103,9 @@ @CommandLineFlags. Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, "disable-features=IPH_FeedHeaderMenu"}) @Features.DisableFeatures({ChromeFeatureList.EXPLORE_SITES, ChromeFeatureList.QUERY_TILES, - ChromeFeatureList.VIDEO_TUTORIALS, ChromeFeatureList.DEPRECATE_MENAGERIE_API}) -@Features.EnableFeatures({ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY_PROMOS}) + ChromeFeatureList.VIDEO_TUTORIALS}) +@Features.EnableFeatures({ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY_PROMOS, + ChromeFeatureList.DEPRECATE_MENAGERIE_API}) public class NewTabPageTest { private static final int ARTICLE_SECTION_HEADER_POSITION = 1; private static final int SIGNIN_PROMO_POSITION = 2; @@ -117,7 +118,7 @@ public SuggestionsDependenciesRule mSuggestionsDeps = new SuggestionsDependenciesRule(); @Rule public AccountManagerTestRule mAccountManagerTestRule = - new AccountManagerTestRule(new FakeProfileDataSource()); + new AccountManagerTestRule(new FakeAccountInfoService()); @Rule public final DisableAnimationsTestRule mNoAnimationRule = new DisableAnimationsTestRule(); @@ -199,8 +200,8 @@ @SmallTest @Feature({"NewTabPage", "FeedNewTabPage", "RenderTest"}) public void testRender_SignInPromoWithAccount() throws Exception { - mAccountManagerTestRule.addAccount(mAccountManagerTestRule.createProfileDataFromName( - AccountManagerTestRule.TEST_ACCOUNT_EMAIL)); + mAccountManagerTestRule.addAccountWithNameAndAvatar( + AccountManagerTestRule.TEST_ACCOUNT_EMAIL); // Scroll to the sign in promo in case it is not visible. onView(withId(R.id.feed_stream_recycler_view)) .perform(RecyclerViewActions.scrollToPosition(SIGNIN_PROMO_POSITION));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java index 9d5179a6..b92ffa0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java
@@ -29,11 +29,10 @@ import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeRenderTestRule; import org.chromium.chrome.test.util.RecentTabsPageTestUtils; -import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule; import org.chromium.components.embedder_support.util.UrlConstants; -import org.chromium.components.signin.test.util.FakeProfileDataSource; +import org.chromium.components.signin.test.util.FakeAccountInfoService; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.common.ContentUrlConstants; import org.chromium.url.GURL; @@ -47,14 +46,14 @@ */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -@DisableFeatures({ChromeFeatureList.DEPRECATE_MENAGERIE_API}) -@EnableFeatures({ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY_PROMOS}) +@EnableFeatures({ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY_PROMOS, + ChromeFeatureList.DEPRECATE_MENAGERIE_API}) public class RecentTabsPageTest { - // FakeProfileDataSource is required to create the ProfileDataCache entry with sync_off badge + // FakeAccountInfoService is required to create the ProfileDataCache entry with sync_off badge // for Sync promo. @Rule public final AccountManagerTestRule mAccountManagerTestRule = - new AccountManagerTestRule(new FakeProfileDataSource()); + new AccountManagerTestRule(new FakeAccountInfoService()); @Rule public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); @@ -103,8 +102,8 @@ @LargeTest @Feature("RenderTest") public void testPersonalizedSigninPromoInRecentTabsPage() throws Exception { - mAccountManagerTestRule.addAccount(mAccountManagerTestRule.createProfileDataFromName( - AccountManagerTestRule.TEST_ACCOUNT_EMAIL)); + mAccountManagerTestRule.addAccountWithNameAndAvatar( + AccountManagerTestRule.TEST_ACCOUNT_EMAIL); mPage = loadRecentTabsPage(); mRenderTestRule.render(mPage.getView(), "personalized_signin_promo_recent_tabs_page"); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java index 8088d84..8e14c3f6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java
@@ -74,7 +74,8 @@ @MediumTest public void testFragmentWhenChoosingAnotherAccount() { mAccountManagerTestRule.addAccount(TEST_EMAIL1, FULL_NAME1, GIVEN_NAME1, null); - mAccountManagerTestRule.addAccount(TEST_EMAIL2); + mAccountManagerTestRule.addAccount( + TEST_EMAIL2, /* fullName= */ null, /* givenName= */ null, /* avatar= */ null); launchActivityWithFragment(); onView(withText(TEST_EMAIL1)).perform(click());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncErrorCardPreferenceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncErrorCardPreferenceTest.java index 832dae3..c57d70f0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncErrorCardPreferenceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncErrorCardPreferenceTest.java
@@ -31,10 +31,10 @@ import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeRenderTestRule; -import org.chromium.chrome.test.util.browser.Features.DisableFeatures; +import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule; import org.chromium.components.signin.base.GoogleServiceAuthError; -import org.chromium.components.signin.test.util.FakeProfileDataSource; +import org.chromium.components.signin.test.util.FakeAccountInfoService; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.NightModeTestUtils; @@ -44,13 +44,13 @@ @RunWith(ParameterizedRunner.class) @ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -@DisableFeatures({ChromeFeatureList.DEPRECATE_MENAGERIE_API}) +@EnableFeatures({ChromeFeatureList.DEPRECATE_MENAGERIE_API}) public class SyncErrorCardPreferenceTest { // FakeProfileDataSource is required to create the ProfileDataCache entry with sync_error badge // for Sync error card. @Rule public final AccountManagerTestRule mAccountManagerTestRule = - new AccountManagerTestRule(new FakeProfileDataSource()); + new AccountManagerTestRule(new FakeAccountInfoService()); @Rule public final ChromeTabbedActivityTestRule mActivityTestRule =
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerImplTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerImplTest.java index a2836ba..b493758 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerImplTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerImplTest.java
@@ -34,6 +34,7 @@ import org.chromium.components.signin.base.AccountInfo; import org.chromium.components.signin.base.CoreAccountId; import org.chromium.components.signin.base.CoreAccountInfo; +import org.chromium.components.signin.identitymanager.AccountInfoServiceProvider; import org.chromium.components.signin.identitymanager.AccountTrackerService; import org.chromium.components.signin.identitymanager.ConsentLevel; import org.chromium.components.signin.identitymanager.IdentityManager; @@ -50,7 +51,7 @@ /** Tests for {@link SigninManagerImpl}. */ @RunWith(BaseRobolectricTestRunner.class) -@Features.DisableFeatures({ChromeFeatureList.DEPRECATE_MENAGERIE_API}) +@Features.EnableFeatures({ChromeFeatureList.DEPRECATE_MENAGERIE_API}) public class SigninManagerImplTest { private static final long NATIVE_SIGNIN_MANAGER = 10001L; private static final long NATIVE_IDENTITY_MANAGER = 10002L; @@ -106,6 +107,7 @@ @After public void tearDown() { mSigninManager.destroy(); + AccountInfoServiceProvider.resetForTests(); } @Test
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 24da81a..0af03fc 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-93.0.4577.5_rc-r1-merged.afdo.bz2 +chromeos-chrome-amd64-93.0.4577.6_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/app-Info.plist b/chrome/app/app-Info.plist index c162513e..4b5e163 100644 --- a/chrome/app/app-Info.plist +++ b/chrome/app/app-Info.plist
@@ -382,8 +382,6 @@ </array> <key>NSUserNotificationAlertStyle</key> <string>banner</string> - <key>NSRequiresAquaSystemAppearance</key> - <false/> <key>GPUEjectPolicy</key> <string>wait</string> </dict>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 475164b..e0f4950 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -2533,15 +2533,22 @@ <message name="IDS_WEBAPP_UPDATE_EXPLANATION" desc="The text at the top of the dialog, explaining what to do when an app changes its identity." formatter_data="android_java"> If this web app is trying to trick you into thinking it's a different app, uninstall it. </message> - <message name="IDS_WEBAPP_UPDATE_NEGATIVE_BUTTON" desc="The text for the negative button (aka. cancel button), allowing the user to uninstall the app and report it to the abuse team." formatter_data="android_java"> - Uninstall app - </message> <message name="IDS_WEBAPP_UPDATE_CURRENT_ICON" desc="The accessibility string explaining which icon is the current icon." formatter_data="android_java"> Current icon </message> <message name="IDS_WEBAPP_UPDATE_NEW_ICON" desc="The accessibility string explaining which icon is the new icon." formatter_data="android_java"> New icon </message> + <if expr="not use_titlecase"> + <message name="IDS_WEBAPP_UPDATE_NEGATIVE_BUTTON" desc="The text for the negative button (aka. cancel button), allowing the user to uninstall the app and report it to the abuse team (sentence casing)." formatter_data="android_java"> + Uninstall app + </message> + </if> + <if expr="use_titlecase"> + <message name="IDS_WEBAPP_UPDATE_NEGATIVE_BUTTON" desc="The text for the negative button (aka. cancel button), allowing the user to uninstall the app and report it to the abuse team (title casing)."> + Uninstall App + </message> + </if> <!-- Finish policy app installation dialog --> <message name="IDS_FINISH_POLICY_WEB_APP_INSTALLATION" desc="Main text for the Finish Policy Web App Installation dialog. This is a dialog message that appears on the first launch of an app after it was remotely installed by an enterprise administrator. The app has some cosmetic factors (like the app icon) that can only be fixed if the user launches and then restarts the app. After the initial launch, this dialog encourages users to restart the app to complete the installation.">
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index c4401342..67d4165a 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -4780,6 +4780,10 @@ kNtpDriveModuleVariations, "DesktopNtpModules")}, + {"ntp-photos-module", flag_descriptions::kNtpPhotosModuleName, + flag_descriptions::kNtpPhotosModuleDescription, kOsDesktop, + FEATURE_VALUE_TYPE(ntp_features::kNtpPhotosModule)}, + {"ntp-recipe-tasks-module", flag_descriptions::kNtpRecipeTasksModuleName, flag_descriptions::kNtpRecipeTasksModuleDescription, kOsDesktop, FEATURE_WITH_PARAMS_VALUE_TYPE(ntp_features::kNtpRecipeTasksModule,
diff --git a/chrome/browser/android/explore_sites/get_catalog_task_unittest.cc b/chrome/browser/android/explore_sites/get_catalog_task_unittest.cc index 0e3f405b..9e7324e5 100644 --- a/chrome/browser/android/explore_sites/get_catalog_task_unittest.cc +++ b/chrome/browser/android/explore_sites/get_catalog_task_unittest.cc
@@ -360,7 +360,7 @@ SetDownloadingAndCurrentVersion("1234", ""); ExecuteSync(base::BindLambdaForTesting([&](sql::Database* db) { sql::Statement cat_count(db->GetUniqueStatement( - "DELETE FROM categories where version_token <> \"1234\";")); + "DELETE FROM categories where version_token <> '1234'")); return cat_count.Run(); })); auto callback = base::BindLambdaForTesting(
diff --git a/chrome/browser/android/explore_sites/increment_shown_count_task_unittest.cc b/chrome/browser/android/explore_sites/increment_shown_count_task_unittest.cc index dab3e6e..56ca932 100644 --- a/chrome/browser/android/explore_sites/increment_shown_count_task_unittest.cc +++ b/chrome/browser/android/explore_sites/increment_shown_count_task_unittest.cc
@@ -59,13 +59,15 @@ void ExploreSitesIncrementShownCountTaskTest::PopulateCategories() { ExecuteSync(base::BindLambdaForTesting([&](sql::Database* db) { - sql::Statement insert_categories(db->GetUniqueStatement(R"( -INSERT INTO categories -(category_id, version_token, type, label, ntp_shown_count) -VALUES -(1, "1234", 1, "label_1", 5), -(2, "1234", 2, "label_2", 2) - )")); + static constexpr char kSql[] = + // clang-format off + "INSERT INTO categories" + "(category_id, version_token, type, label, ntp_shown_count)" + "VALUES " + "(1, '1234', 1, 'label_1', 5)," + "(2, '1234', 2, 'label_2', 2)"; + // clang-format on + sql::Statement insert_categories(db->GetUniqueStatement(kSql)); return insert_categories.Run(); })); }
diff --git a/chrome/browser/android/search_permissions/search_permissions_service.cc b/chrome/browser/android/search_permissions/search_permissions_service.cc index 33f41930..51f5581d 100644 --- a/chrome/browser/android/search_permissions/search_permissions_service.cc +++ b/chrome/browser/android/search_permissions/search_permissions_service.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/callback.h" +#include "base/feature_list.h" #include "base/values.h" #include "chrome/browser/android/search_permissions/search_geolocation_disclosure_tab_helper.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" @@ -20,6 +21,7 @@ #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings_types.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/permissions/features.h" #include "components/permissions/permission_decision_auto_blocker.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" @@ -247,7 +249,8 @@ ContentSetting SearchPermissionsService::RestoreOldSettingAndReturnPrevious( const GURL& dse_origin, ContentSettingsType type, - ContentSetting setting_to_restore) { + ContentSetting setting_to_restore, + bool preserve_block_setting) { // Read the current value of the old DSE. This is the DSE setting that we want // to try to apply to the new DSE origin. ContentSetting dse_setting = GetContentSetting(dse_origin, type); @@ -261,6 +264,10 @@ dse_setting = CONTENT_SETTING_BLOCK; } + // If `preserve_block_setting` is set we don't restore a "BLOCK" setting. + if (dse_setting == CONTENT_SETTING_BLOCK && preserve_block_setting) + setting_to_restore = CONTENT_SETTING_BLOCK; + // Restore the setting for the old origin. If the user has changed the setting // since the origin became the DSE, we reset the setting so the user will be // prompted. @@ -282,7 +289,8 @@ ->RemoveEmbargoAndResetCounts(new_dse_origin, type); ContentSetting dse_setting = RestoreOldSettingAndReturnPrevious( - old_dse_origin, type, old_dse_setting_to_restore); + old_dse_origin, type, old_dse_setting_to_restore, + false /* preserve_block_setting */); ContentSetting new_dse_setting_to_restore = GetContentSetting(new_dse_origin, type); @@ -313,21 +321,26 @@ void SearchPermissionsService::InitializeSettingsIfNeeded() { GURL dse_origin = delegate_->GetDSEOrigin().GetURL(); - // This can happen in tests or if the DSE is disabled by policy. If that's - // the case, we restore the old settings and erase the pref. - if (!dse_origin.is_valid()) { + // `dse_origin` can be invalid in tests or if the DSE is disabled by policy. + // If that's the case or if `RevertDSEAutomaticPermissions` is enabled, we + // restore the old settings and erase the pref. + const bool disabled_by_policy = !dse_origin.is_valid(); + if (disabled_by_policy || + base::FeatureList::IsEnabled( + permissions::features::kRevertDSEAutomaticPermissions)) { if (pref_service_->HasPrefPath(prefs::kDSEPermissionsSettings)) { - pref_service_->SetBoolean(prefs::kDSEWasDisabledByPolicy, true); + if (disabled_by_policy) + pref_service_->SetBoolean(prefs::kDSEWasDisabledByPolicy, true); PrefValue pref = GetDSEPref(); GURL old_dse_origin(pref.dse_origin); - RestoreOldSettingAndReturnPrevious(old_dse_origin, - ContentSettingsType::GEOLOCATION, - pref.geolocation_setting_to_restore); + RestoreOldSettingAndReturnPrevious( + old_dse_origin, ContentSettingsType::GEOLOCATION, + pref.geolocation_setting_to_restore, !disabled_by_policy); if (pref.notifications_setting_to_restore != CONTENT_SETTING_DEFAULT) { RestoreOldSettingAndReturnPrevious( old_dse_origin, ContentSettingsType::NOTIFICATIONS, - pref.notifications_setting_to_restore); + pref.notifications_setting_to_restore, !disabled_by_policy); } pref_service_->ClearPref(prefs::kDSEPermissionsSettings); }
diff --git a/chrome/browser/android/search_permissions/search_permissions_service.h b/chrome/browser/android/search_permissions/search_permissions_service.h index 3df7b2c..91d0f39 100644 --- a/chrome/browser/android/search_permissions/search_permissions_service.h +++ b/chrome/browser/android/search_permissions/search_permissions_service.h
@@ -120,7 +120,8 @@ ContentSetting RestoreOldSettingAndReturnPrevious( const GURL& dse_origin, ContentSettingsType type, - ContentSetting setting_to_restore); + ContentSetting setting_to_restore, + bool preserve_block_setting); // Helper function for OnDSEChanged which transitions the DSE setting for a // specific permission. It returns the content setting to be restored later
diff --git a/chrome/browser/android/search_permissions/search_permissions_service_unittest.cc b/chrome/browser/android/search_permissions/search_permissions_service_unittest.cc index 2d6338a..ed5be3b6 100644 --- a/chrome/browser/android/search_permissions/search_permissions_service_unittest.cc +++ b/chrome/browser/android/search_permissions/search_permissions_service_unittest.cc
@@ -9,13 +9,17 @@ #include "base/callback.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/android/search_permissions/search_geolocation_disclosure_tab_helper.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/permissions/permission_decision_auto_blocker_factory.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_profile.h" #include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/content_settings/core/common/content_settings.h" +#include "components/content_settings/core/common/content_settings_types.h" #include "components/content_settings/core/common/pref_names.h" +#include "components/permissions/features.h" #include "components/permissions/permission_decision_auto_blocker.h" #include "components/permissions/permission_result.h" #include "components/prefs/pref_service.h" @@ -77,7 +81,9 @@ void SetUp() override { profile_ = std::make_unique<TestingProfile>(); - ClearNotificationsChannels(); + // Because notification channel settings aren't tied to the profile, they + // will persist across tests. We need to make sure they're clean here. + ClearContentSettings(ContentSettingsType::NOTIFICATIONS); auto test_delegate = std::make_unique<TestSearchEngineDelegate>(); test_delegate_ = test_delegate.get(); @@ -88,22 +94,18 @@ void TearDown() override { test_delegate_ = nullptr; - ClearNotificationsChannels(); + // Because notification channel settings aren't tied to the profile, they + // will persist across tests. We need to make sure they're reset here. + ClearContentSettings(ContentSettingsType::NOTIFICATIONS); profile_.reset(); } - void ClearNotificationsChannels() { - // Because notification channel settings aren't tied to the profile, they - // will persist across tests. We need to make sure they're reset here. - SetContentSetting(kGoogleURL, ContentSettingsType::NOTIFICATIONS, - CONTENT_SETTING_DEFAULT); - SetContentSetting(kGoogleAusURL, ContentSettingsType::NOTIFICATIONS, - CONTENT_SETTING_DEFAULT); - SetContentSetting(kGoogleHTTPURL, ContentSettingsType::NOTIFICATIONS, - CONTENT_SETTING_DEFAULT); - SetContentSetting(kExampleURL, ContentSettingsType::NOTIFICATIONS, - CONTENT_SETTING_DEFAULT); + void ClearContentSettings(ContentSettingsType type) { + SetContentSetting(kGoogleURL, type, CONTENT_SETTING_DEFAULT); + SetContentSetting(kGoogleAusURL, type, CONTENT_SETTING_DEFAULT); + SetContentSetting(kGoogleHTTPURL, type, CONTENT_SETTING_DEFAULT); + SetContentSetting(kExampleURL, type, CONTENT_SETTING_DEFAULT); } TestingProfile* profile() { return profile_.get(); } @@ -637,3 +639,345 @@ EXPECT_EQ(CONTENT_SETTING_BLOCK, GetContentSetting(kGoogleURL, ContentSettingsType::GEOLOCATION)); } + +// Setting the `RevertDSEAutomaticPermissions` feature disables DSE permissions. +TEST_F(SearchPermissionsServiceTest, DSEPermissionsCanBeDisabledByFeature) { + constexpr struct { + ContentSetting initial_setting; + ContentSetting expected_setting_after_autogrant; + ContentSetting expected_setting_after_autogrant_reverted; + } kTests[] = { + {CONTENT_SETTING_DEFAULT, CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK}, + {CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW}, + {CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK}, + {CONTENT_SETTING_ASK, CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK}, + }; + + test_delegate()->ChangeDSEOrigin(kGoogleURL); + + for (const auto& test : kTests) { + for (const auto type : {ContentSettingsType::NOTIFICATIONS, + ContentSettingsType::GEOLOCATION}) { + // Notifications can not be set to ASK. + if (test.initial_setting == CONTENT_SETTING_ASK && + type == ContentSettingsType::NOTIFICATIONS) { + continue; + } + + ClearContentSettings(type); + SetContentSetting(kGoogleURL, type, test.initial_setting); + + // Initialize DSE and verify the expected setting. + ReinitializeService(true /* clear_pref */); + EXPECT_EQ(test.expected_setting_after_autogrant, + GetContentSetting(kGoogleURL, type)); + + // Enable `RevertDSEAutomaticPermissions`. DSE stops being controlled by + // the SearchPermissionsService. + { + base::test::ScopedFeatureList features( + permissions::features::kRevertDSEAutomaticPermissions); + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(test.expected_setting_after_autogrant_reverted, + GetContentSetting(kGoogleURL, type)); + } + + // If the feature is disabled again, DSE starts being controlled by the + // SearchPermissionsService. + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(test.expected_setting_after_autogrant, + GetContentSetting(kGoogleURL, type)); + } + } +} + +// Change the permission state for the DSE origin while DSE is active. Also test +// how the `RevertDSEAutomaticPermissions` feature interacts with this scenario. +TEST_F(SearchPermissionsServiceTest, + DSEOriginPermissionsChangeBeforeFeatureIsEnabled) { + constexpr struct { + ContentSetting initial_setting; + ContentSetting expected_setting_after_autogrant; + ContentSetting updated_setting; + ContentSetting expected_setting_after_update; + ContentSetting expected_setting_after_autogrant_reverted; + ContentSetting expected_setting_after_autogrant_reverted_disabled; + } kTests[] = { + {CONTENT_SETTING_DEFAULT, CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW, + CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK, CONTENT_SETTING_ALLOW}, + // Critical journey: if the user decided to change the DSE origin's + // setting to BLOCK then disabling DSE should still keep it at BLOCK. + {CONTENT_SETTING_DEFAULT, CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK, + CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK}, + {CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW, + CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW}, + // Critical journey: if the user decided to change the DSE origin's + // setting to BLOCK then disabling DSE should still keep it at BLOCK. + {CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK, + CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK}, + {CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK, CONTENT_SETTING_ALLOW, + CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK, CONTENT_SETTING_ALLOW}, + {CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK, + CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK}, + {CONTENT_SETTING_ASK, CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW, + CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK, CONTENT_SETTING_ALLOW}, + // Critical journey: if the user decided to change the DSE origin's + // setting to BLOCK then disabling DSE should still keep it at BLOCK. + {CONTENT_SETTING_ASK, CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK, + CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK}, + }; + + for (const auto& test : kTests) { + for (const auto type : {ContentSettingsType::NOTIFICATIONS, + ContentSettingsType::GEOLOCATION}) { + // Notifications can not be set to ASK on Android as notification channels + // explicitly rely on the state being only BLOCK/ALLOW/DEFAULT. + if (test.initial_setting == CONTENT_SETTING_ASK && + type == ContentSettingsType::NOTIFICATIONS) { + continue; + } + + ClearContentSettings(type); + SetContentSetting(kGoogleURL, type, test.initial_setting); + + // Initialize DSE and verify the expected setting. + ReinitializeService(true /* clear_pref */); + EXPECT_EQ(test.expected_setting_after_autogrant, + GetContentSetting(kGoogleURL, type)); + + // Change the setting of the DSE origin and verify the result. + SetContentSetting(kGoogleURL, type, test.updated_setting); + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(test.expected_setting_after_update, + GetContentSetting(kGoogleURL, type)); + + // Enable `RevertDSEAutomaticPermissions`. DSE stops being controlled by + // the SearchPermissionsService. + { + base::test::ScopedFeatureList features( + permissions::features::kRevertDSEAutomaticPermissions); + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(test.expected_setting_after_autogrant_reverted, + GetContentSetting(kGoogleURL, type)); + } + + // If the feature is disabled again, DSE starts being controlled by the + // SearchPermissionsService. + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(test.expected_setting_after_autogrant_reverted_disabled, + GetContentSetting(kGoogleURL, type)); + } + } +} + +// Change the permission state for the DSE origin while the +// `RevertDSEAutomaticPermissions` feature is active. Also test how disabling +// the feature again afterwards will affect the permission. +TEST_F(SearchPermissionsServiceTest, + DSEOriginPermissionsChangeAfterFeatureIsEnabled) { + constexpr struct { + ContentSetting initial_setting; + ContentSetting expected_setting_after_autogrant; + ContentSetting expected_setting_after_autogrant_reverted; + } kTestsBeforeSettingUpdate[] = { + {CONTENT_SETTING_DEFAULT, CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK}, + {CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW}, + {CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK}, + {CONTENT_SETTING_ASK, CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK}, + }; + + constexpr struct { + ContentSetting updated_setting; + ContentSetting expected_setting_after_update; + ContentSetting expected_setting_after_autogrant_reverted_disabled; + } kTestsAfterSettingUpdate[] = { + {CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW}, + {CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK}, + {CONTENT_SETTING_ASK, CONTENT_SETTING_ASK, CONTENT_SETTING_ALLOW}, + {CONTENT_SETTING_DEFAULT, CONTENT_SETTING_ASK, CONTENT_SETTING_ALLOW}, + }; + + // The test cases are split into two halves. Every combination of + // `kTestsBeforeSettingUpdate` and `kTestsBeforeSettingUpdate` entries + // produces a test case. + for (const auto& test_before : kTestsBeforeSettingUpdate) { + for (const auto& test_after : kTestsAfterSettingUpdate) { + for (const auto type : {ContentSettingsType::NOTIFICATIONS, + ContentSettingsType::GEOLOCATION}) { + // Notifications can not be set to ASK on Android as notification + // channels explicitly rely on the state being only BLOCK/ALLOW/DEFAULT. + if (test_before.initial_setting == CONTENT_SETTING_ASK && + type == ContentSettingsType::NOTIFICATIONS) { + continue; + } + + ClearContentSettings(type); + SetContentSetting(kGoogleURL, type, test_before.initial_setting); + + // Initialize DSE and verify the expected setting. + ReinitializeService(true /* clear_pref */); + EXPECT_EQ(test_before.expected_setting_after_autogrant, + GetContentSetting(kGoogleURL, type)); + + // Enable `RevertDSEAutomaticPermissions`. DSE stops being controlled by + // the SearchPermissionsService. + { + base::test::ScopedFeatureList features( + permissions::features::kRevertDSEAutomaticPermissions); + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(test_before.expected_setting_after_autogrant_reverted, + GetContentSetting(kGoogleURL, type)); + + // Notifications can not be set to ASK on Android as notification + // channels explicitly rely on the state being only + // BLOCK/ALLOW/DEFAULT. + if (test_after.updated_setting == CONTENT_SETTING_ASK && + type == ContentSettingsType::NOTIFICATIONS) { + continue; + } + + // Change the setting of the DSE origin and verify the result. This + // means that the user made a decision for the DSE origin while DSE + // is inactive. + SetContentSetting(kGoogleURL, type, test_after.updated_setting); + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(test_after.expected_setting_after_update, + GetContentSetting(kGoogleURL, type)); + } + + // If the feature is disabled again, DSE starts being controlled by the + // SearchPermissionsService. Test how it handles the user's setting + // change while DSE was inactive. + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(test_after.expected_setting_after_autogrant_reverted_disabled, + GetContentSetting(kGoogleURL, type)); + } + } + } +} + +// Tests the scenario in which the permission is disabled by default for all +// origins. +TEST_F(SearchPermissionsServiceTest, PermissionsDisabledByDefault) { + HostContentSettingsMap* hcsm = + HostContentSettingsMapFactory::GetForProfile(profile()); + + for (const auto type : + {ContentSettingsType::GEOLOCATION, ContentSettingsType::NOTIFICATIONS}) { + ClearContentSettings(type); + hcsm->SetDefaultContentSetting(type, CONTENT_SETTING_BLOCK); + + // Global setting should still apply. + ReinitializeService(true /* clear_pref */); + EXPECT_EQ(CONTENT_SETTING_BLOCK, GetContentSetting(kGoogleURL, type)); + + // Enable `RevertDSEAutomaticPermissions`. DSE stops being controlled by the + // SearchPermissionsService. + { + base::test::ScopedFeatureList features( + permissions::features::kRevertDSEAutomaticPermissions); + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(CONTENT_SETTING_BLOCK, GetContentSetting(kGoogleURL, type)); + } + + // If the feature is disabled again, DSE starts being controlled by the + // SearchPermissionsService. + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(CONTENT_SETTING_BLOCK, GetContentSetting(kGoogleURL, type)); + } +} + +// Tests the scenario in which the permission is disabled by default for all +// origins after DSE has granted permission. +TEST_F(SearchPermissionsServiceTest, + PermissionsDisabledByDefaultAfterAutogrant) { + HostContentSettingsMap* hcsm = + HostContentSettingsMapFactory::GetForProfile(profile()); + + for (const auto type : + {ContentSettingsType::GEOLOCATION, ContentSettingsType::NOTIFICATIONS}) { + ClearContentSettings(type); + ReinitializeService(true /* clear_pref */); + EXPECT_EQ(CONTENT_SETTING_ALLOW, GetContentSetting(kGoogleURL, type)); + + // Set the default content setting after the DSE has been applied. + hcsm->SetDefaultContentSetting(type, CONTENT_SETTING_BLOCK); + EXPECT_EQ(CONTENT_SETTING_ALLOW, GetContentSetting(kGoogleURL, type)); + + // Enable `RevertDSEAutomaticPermissions`. DSE stops being controlled by the + // SearchPermissionsService. + { + base::test::ScopedFeatureList features( + permissions::features::kRevertDSEAutomaticPermissions); + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(CONTENT_SETTING_BLOCK, GetContentSetting(kGoogleURL, type)); + } + + // If the feature is disabled again, DSE starts being controlled by the + // SearchPermissionsService. + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(CONTENT_SETTING_BLOCK, GetContentSetting(kGoogleURL, type)); + } +} + +// Test repeatedly enabling and disabling the `RevertDSEAutomaticPermissions` +// feature. +TEST_F(SearchPermissionsServiceTest, + DSEPermissionsRepeatedlyDisabledByFeature) { + for (const auto type : + {ContentSettingsType::GEOLOCATION, ContentSettingsType::NOTIFICATIONS}) { + ClearContentSettings(type); + ReinitializeService(true /* clear_pref */); + EXPECT_EQ(CONTENT_SETTING_ALLOW, GetContentSetting(kGoogleURL, type)); + + int num_repetitions = 5; + while (num_repetitions--) { + // Enable `RevertDSEAutomaticPermissions`. DSE stops being controlled by + // the SearchPermissionsService. + { + base::test::ScopedFeatureList features( + permissions::features::kRevertDSEAutomaticPermissions); + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(CONTENT_SETTING_ASK, GetContentSetting(kGoogleURL, type)); + } + + // If the feature is disabled again, DSE starts being controlled by the + // SearchPermissionsService. + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(CONTENT_SETTING_ALLOW, GetContentSetting(kGoogleURL, type)); + } + } +} + +// Test disabling DSE via the `RevertDSEAutomaticPermissions` feature after the +// DSE origin has changed at least once. +TEST_F(SearchPermissionsServiceTest, DSEDisabledAfterOriginChange) { + for (const auto type : + {ContentSettingsType::GEOLOCATION, ContentSettingsType::NOTIFICATIONS}) { + test_delegate()->ChangeDSEOrigin(kGoogleURL); + ClearContentSettings(type); + ReinitializeService(true /* clear_pref */); + EXPECT_EQ(CONTENT_SETTING_ALLOW, GetContentSetting(kGoogleURL, type)); + + // Change DSE origin and make sure the setting is correctly updated. + test_delegate()->ChangeDSEOrigin(kGoogleAusURL); + EXPECT_EQ(CONTENT_SETTING_ALLOW, GetContentSetting(kGoogleAusURL, type)); + EXPECT_EQ(CONTENT_SETTING_ASK, GetContentSetting(kGoogleURL, type)); + + // Enable `RevertDSEAutomaticPermissions`. DSE stops being controlled by + // the SearchPermissionsService. + { + base::test::ScopedFeatureList features( + permissions::features::kRevertDSEAutomaticPermissions); + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(CONTENT_SETTING_ASK, GetContentSetting(kGoogleAusURL, type)); + EXPECT_EQ(CONTENT_SETTING_ASK, GetContentSetting(kGoogleURL, type)); + } + + // If the feature is disabled again, DSE starts being controlled by the + // SearchPermissionsService. + ReinitializeService(false /* clear_pref */); + EXPECT_EQ(CONTENT_SETTING_ALLOW, GetContentSetting(kGoogleAusURL, type)); + EXPECT_EQ(CONTENT_SETTING_ASK, GetContentSetting(kGoogleURL, type)); + } +}
diff --git a/chrome/browser/ash/arc/auth/arc_auth_service.cc b/chrome/browser/ash/arc/auth/arc_auth_service.cc index 830944e..1df4be3 100644 --- a/chrome/browser/ash/arc/auth/arc_auth_service.cc +++ b/chrome/browser/ash/arc/auth/arc_auth_service.cc
@@ -39,6 +39,7 @@ #include "components/arc/arc_prefs.h" #include "components/arc/arc_service_manager.h" #include "components/arc/arc_util.h" +#include "components/arc/enterprise/arc_data_snapshotd_manager.h" #include "components/arc/session/arc_bridge_service.h" #include "components/arc/session/arc_management_transition.h" #include "components/prefs/pref_service.h" @@ -655,6 +656,16 @@ std::string() /* auth_name */, mojom::ChromeAccountType::OFFLINE_DEMO_ACCOUNT, true /* is_managed */)); + } else if (arc::data_snapshotd::ArcDataSnapshotdManager::Get()->state() == + arc::data_snapshotd::ArcDataSnapshotdManager::State::kRunning) { + // If MGS is running with a snapshotted data/, it could be offline. + const std::string& full_account_id = GetAccountName(profile_); + std::move(callback).Run( + mojom::ArcAuthCodeStatus::SUCCESS, + CreateAccountInfo(false /* is_enforced */, + std::string() /* auth_info */, full_account_id, + GetAccountType(profile_), + policy_util::IsAccountManaged(profile_))); } else { // Send error to ARC. std::move(callback).Run(
diff --git a/chrome/browser/ash/child_accounts/child_user_service_factory.h b/chrome/browser/ash/child_accounts/child_user_service_factory.h index f21bb695..cf3f4d2 100644 --- a/chrome/browser/ash/child_accounts/child_user_service_factory.h +++ b/chrome/browser/ash/child_accounts/child_user_service_factory.h
@@ -40,9 +40,4 @@ } // namespace ash -// TODO(https://crbug.com/1164001): remove when ChromOS code migration is done. -namespace chromeos { -using ::ash::ChildUserServiceFactory; -} // namespace chromeos - #endif // CHROME_BROWSER_ASH_CHILD_ACCOUNTS_CHILD_USER_SERVICE_FACTORY_H_
diff --git a/chrome/browser/ash/child_accounts/secondary_account_consent_logger.cc b/chrome/browser/ash/child_accounts/secondary_account_consent_logger.cc index e02a336..abea9f95 100644 --- a/chrome/browser/ash/child_accounts/secondary_account_consent_logger.cc +++ b/chrome/browser/ash/child_accounts/secondary_account_consent_logger.cc
@@ -32,6 +32,7 @@ #include "services/network/public/mojom/url_response_head.mojom.h" #include "url/gurl.h" +namespace ash { namespace { constexpr char kConsentApiPath[] = @@ -74,10 +75,10 @@ })"); std::string GetOrCreateEduCoexistenceId(PrefService* pref_service) { - std::string id = pref_service->GetString(ash::prefs::kEduCoexistenceId); + std::string id = pref_service->GetString(prefs::kEduCoexistenceId); if (id.empty()) { id = base::GenerateGUID(); - pref_service->SetString(ash::prefs::kEduCoexistenceId, id); + pref_service->SetString(prefs::kEduCoexistenceId, id); } return id; } @@ -87,10 +88,10 @@ // static void SecondaryAccountConsentLogger::RegisterPrefs( PrefRegistrySimple* registry) { - registry->RegisterStringPref(ash::prefs::kEduCoexistenceId, + registry->RegisterStringPref(prefs::kEduCoexistenceId, std::string() /* default_value */); registry->RegisterStringPref( - ash::prefs::kEduCoexistenceSecondaryAccountsInvalidationVersion, + prefs::kEduCoexistenceSecondaryAccountsInvalidationVersion, "iv2153049" /* default_value, the first invalidation version */); } @@ -220,3 +221,5 @@ std::move(callback_).Run(Result::kSuccess); } + +} // namespace ash
diff --git a/chrome/browser/ash/child_accounts/secondary_account_consent_logger.h b/chrome/browser/ash/child_accounts/secondary_account_consent_logger.h index 1b0dac8..b717df7 100644 --- a/chrome/browser/ash/child_accounts/secondary_account_consent_logger.h +++ b/chrome/browser/ash/child_accounts/secondary_account_consent_logger.h
@@ -32,6 +32,8 @@ class SharedURLLoaderFactory; } // namespace network +namespace ash { + // Logs parental consent for addition of secondary EDU account. // Firstly fetches access token with "kid.management.privileged" scope. Then // logs consent with provided parent id, rapt, coexistence id and text version. @@ -103,4 +105,12 @@ SEQUENCE_CHECKER(sequence_checker_); }; +} // namespace ash + +// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos +// source code migration is finished. +namespace chromeos { +using ::ash::SecondaryAccountConsentLogger; +} + #endif // CHROME_BROWSER_ASH_CHILD_ACCOUNTS_SECONDARY_ACCOUNT_CONSENT_LOGGER_H_
diff --git a/chrome/browser/ash/child_accounts/secondary_account_consent_logger_unittest.cc b/chrome/browser/ash/child_accounts/secondary_account_consent_logger_unittest.cc index c8fcc0e..845bb4b 100644 --- a/chrome/browser/ash/child_accounts/secondary_account_consent_logger_unittest.cc +++ b/chrome/browser/ash/child_accounts/secondary_account_consent_logger_unittest.cc
@@ -25,7 +25,9 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +namespace ash { namespace { + constexpr char kAccountEmail[] = "user@gmail.com"; constexpr char kSecondaryEmail[] = "secondary@gmail.com"; constexpr char kParentObfuscatedGaiaId[] = "parent-obfuscated-gaia-id"; @@ -67,7 +69,7 @@ void SetUp() { SecondaryAccountConsentLogger::RegisterPrefs(local_state_.registry()); - local_state_.SetUserPref(ash::prefs::kEduCoexistenceId, + local_state_.SetUserPref(prefs::kEduCoexistenceId, std::make_unique<base::Value>(kChromeSyncId)); } @@ -225,3 +227,5 @@ base::DictionaryValue request_body = CreateRequestBody(); EXPECT_EQ(test_request_body.value(), request_body); } + +} // namespace ash
diff --git a/chrome/browser/ash/child_accounts/time_limits/web_time_calculation_browsertest.cc b/chrome/browser/ash/child_accounts/time_limits/web_time_calculation_browsertest.cc index a711f84..68df2b5 100644 --- a/chrome/browser/ash/child_accounts/time_limits/web_time_calculation_browsertest.cc +++ b/chrome/browser/ash/child_accounts/time_limits/web_time_calculation_browsertest.cc
@@ -44,6 +44,7 @@ #include "ui/base/window_open_disposition.h" #include "url/gurl.h" +namespace ash { namespace { constexpr char kExampleHost1[] = "www.example.com"; @@ -69,7 +70,7 @@ const std::string& url_in, WindowOpenDisposition disposition); - ash::app_time::ChromeAppActivityState GetChromeAppActivityState(); + app_time::ChromeAppActivityState GetChromeAppActivityState(); private: void UpdatePolicy(); @@ -78,7 +79,7 @@ base::test::ScopedFeatureList scoped_feature_list_; - ash::app_time::AppTimeLimitsAllowlistPolicyBuilder builder_; + app_time::AppTimeLimitsAllowlistPolicyBuilder builder_; chromeos::LoggedInUserMixin logged_in_user_mixin_{ &mixin_host_, chromeos::LoggedInUserMixin::LogInType::kChild, @@ -104,11 +105,10 @@ // During tests, AppService doesn't notify AppActivityRegistry that chrome app // is installed. Mark chrome as installed here. - ash::ChildUserService* service = - ash::ChildUserServiceFactory::GetForBrowserContext(profile_); - ash::ChildUserService::TestApi test_api(service); + auto* service = ChildUserServiceFactory::GetForBrowserContext(profile_); + ChildUserService::TestApi test_api(service); test_api.app_time_controller()->app_registry()->OnAppInstalled( - ash::app_time::GetChromeAppId()); + app_time::GetChromeAppId()); } void WebTimeCalculationBrowserTest::TearDown() { @@ -141,11 +141,10 @@ return params.navigated_or_inserted_contents; } -ash::app_time::ChromeAppActivityState +app_time::ChromeAppActivityState WebTimeCalculationBrowserTest::GetChromeAppActivityState() { - ash::ChildUserService* service = - chromeos::ChildUserServiceFactory::GetForBrowserContext(profile_); - ash::ChildUserService::TestApi test_api(service); + auto* service = ChildUserServiceFactory::GetForBrowserContext(profile_); + ChildUserService::TestApi test_api(service); auto* web_time_activity_provider = test_api.app_time_controller()->web_time_activity_provider(); return web_time_activity_provider->chrome_app_activty_state(); @@ -173,11 +172,11 @@ // Create a new tab and navigate it to some url. Navigate(browser(), kExampleHost2, WindowOpenDisposition::NEW_FOREGROUND_TAB); - EXPECT_EQ(ash::app_time::ChromeAppActivityState::kActive, + EXPECT_EQ(app_time::ChromeAppActivityState::kActive, GetChromeAppActivityState()); browser()->tab_strip_model()->ActivateTabAt(0); - EXPECT_EQ(ash::app_time::ChromeAppActivityState::kActiveAllowlisted, + EXPECT_EQ(app_time::ChromeAppActivityState::kActiveAllowlisted, GetChromeAppActivityState()); bool destroyed = browser()->tab_strip_model()->CloseWebContentsAt( @@ -186,7 +185,7 @@ base::RunLoop().RunUntilIdle(); - EXPECT_EQ(ash::app_time::ChromeAppActivityState::kActive, + EXPECT_EQ(app_time::ChromeAppActivityState::kActive, GetChromeAppActivityState()); } @@ -200,12 +199,12 @@ browser()->tab_strip_model()->ActivateTabAt(0); - EXPECT_EQ(ash::app_time::ChromeAppActivityState::kActiveAllowlisted, + EXPECT_EQ(app_time::ChromeAppActivityState::kActiveAllowlisted, GetChromeAppActivityState()); Browser* new_browser = DetachTabToNewBrowser(browser(), 1); - EXPECT_EQ(ash::app_time::ChromeAppActivityState::kActive, + EXPECT_EQ(app_time::ChromeAppActivityState::kActive, GetChromeAppActivityState()); // Now we have two browser windows. One hosting a allowlisted url and the @@ -214,16 +213,18 @@ 0, TabStripModel::CloseTypes::CLOSE_USER_GESTURE)); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(ash::app_time::ChromeAppActivityState::kActiveAllowlisted, + EXPECT_EQ(app_time::ChromeAppActivityState::kActiveAllowlisted, GetChromeAppActivityState()); EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt( 0, TabStripModel::CloseTypes::CLOSE_USER_GESTURE)); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(ash::app_time::ChromeAppActivityState::kInactive, + EXPECT_EQ(app_time::ChromeAppActivityState::kInactive, GetChromeAppActivityState()); } // TODO(yilkal): Write test to check that going to a URL in the current tab of // the first browser will result in chrome being active or active allowlisted. + +} // namespace ash
diff --git a/chrome/browser/ash/child_accounts/time_limits/web_time_limit_enforcer_browsertest.cc b/chrome/browser/ash/child_accounts/time_limits/web_time_limit_enforcer_browsertest.cc index 3465ecb..05ccf30 100644 --- a/chrome/browser/ash/child_accounts/time_limits/web_time_limit_enforcer_browsertest.cc +++ b/chrome/browser/ash/child_accounts/time_limits/web_time_limit_enforcer_browsertest.cc
@@ -42,6 +42,7 @@ #include "ui/base/window_open_disposition.h" #include "url/gurl.h" +namespace ash { namespace { constexpr char kExampleHost[] = "www.example.com"; @@ -84,6 +85,7 @@ run_loop_.Quit(); } } + } // namespace class WebTimeLimitEnforcerThrottleTest : public MixinBasedInProcessBrowserTest { @@ -93,9 +95,9 @@ void SetUpOnMainThread() override; bool IsErrorPageBeingShownInWebContents(content::WebContents* tab); void AllowlistUrlRegx(const std::string& host); - void AllowlistApp(const ash::app_time::AppId& app_id); + void AllowlistApp(const app_time::AppId& app_id); void BlockWeb(); - ash::app_time::WebTimeLimitEnforcer* GetWebTimeLimitEnforcer(); + app_time::WebTimeLimitEnforcer* GetWebTimeLimitEnforcer(); content::WebContents* InstallAndLaunchWebApp(const GURL& url, bool allowlisted_app); @@ -104,7 +106,7 @@ base::test::ScopedFeatureList scoped_feature_list_; - ash::app_time::AppTimeLimitsAllowlistPolicyBuilder builder_; + app_time::AppTimeLimitsAllowlistPolicyBuilder builder_; chromeos::LoggedInUserMixin logged_in_user_mixin_{ &mixin_host_, chromeos::LoggedInUserMixin::LogInType::kChild, @@ -154,7 +156,7 @@ } void WebTimeLimitEnforcerThrottleTest::AllowlistApp( - const ash::app_time::AppId& app_id) { + const app_time::AppId& app_id) { builder_.AppendToAllowlistAppList(app_id); UpdatePolicy(); } @@ -164,14 +166,13 @@ base::TimeDelta::FromHours(1)); } -ash::app_time::WebTimeLimitEnforcer* +app_time::WebTimeLimitEnforcer* WebTimeLimitEnforcerThrottleTest::GetWebTimeLimitEnforcer() { content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); content::BrowserContext* browser_context = web_contents->GetBrowserContext(); - ash::ChildUserService::TestApi child_user_service = - ash::ChildUserService::TestApi( - ash::ChildUserServiceFactory::GetForBrowserContext(browser_context)); + ChildUserService::TestApi child_user_service = ChildUserService::TestApi( + ChildUserServiceFactory::GetForBrowserContext(browser_context)); return child_user_service.web_time_enforcer(); } @@ -188,7 +189,7 @@ std::move(web_app_info)); if (allowlisted_app) - AllowlistApp(ash::app_time::AppId(apps::mojom::AppType::kWeb, app_id)); + AllowlistApp(app_time::AppId(apps::mojom::AppType::kWeb, app_id)); base::RunLoop().RunUntilIdle(); // Add a tab to |browser()| and return the newly added WebContents. @@ -211,8 +212,8 @@ const user_manager::UserManager* const user_manager = user_manager::UserManager::Get(); - Profile* profile = ash::ProfileHelper::Get()->GetProfileByUser( - user_manager->GetActiveUser()); + auto* profile = + ProfileHelper::Get()->GetProfileByUser(user_manager->GetActiveUser()); logged_in_user_mixin_.GetUserPolicyTestHelper()->RefreshPolicyAndWait( profile); @@ -417,7 +418,7 @@ ui_test_utils::NavigateToURL(¶ms); auto* web_contents = params.navigated_or_inserted_contents; auto* navigation_observer = - ash::app_time::WebTimeNavigationObserver::FromWebContents(web_contents); + app_time::WebTimeNavigationObserver::FromWebContents(web_contents); std::u16string title = web_contents->GetTitle(); EXPECT_EQ(title, navigation_observer->previous_title()); @@ -456,3 +457,5 @@ // TODO(yilkal): Add AllowlistedSchemeNotBlocked test for chrome://settings // TODO(yilkal): Add test for blocked web contents without browser window. + +} // namespace ash
diff --git a/chrome/browser/ash/child_accounts/time_limits/web_time_limit_error_page/web_time_limit_error_page.cc b/chrome/browser/ash/child_accounts/time_limits/web_time_limit_error_page/web_time_limit_error_page.cc index 70902df..84be70c 100644 --- a/chrome/browser/ash/child_accounts/time_limits/web_time_limit_error_page/web_time_limit_error_page.cc +++ b/chrome/browser/ash/child_accounts/time_limits/web_time_limit_error_page/web_time_limit_error_page.cc
@@ -20,6 +20,7 @@ #include "ui/base/webui/jstemplate_builder.h" #include "ui/base/webui/web_ui_util.h" +namespace ash { namespace { std::u16string GetTimeLimitMessage(base::TimeDelta time_limit) { @@ -94,3 +95,5 @@ return GetWebTimeLimitErrorPage(block_header, block_message, time_limit, app_locale, base::UTF8ToUTF16(app_name)); } + +} // namespace ash
diff --git a/chrome/browser/ash/child_accounts/time_limits/web_time_limit_error_page/web_time_limit_error_page.h b/chrome/browser/ash/child_accounts/time_limits/web_time_limit_error_page/web_time_limit_error_page.h index 7ef990aa..9f77a92e 100644 --- a/chrome/browser/ash/child_accounts/time_limits/web_time_limit_error_page/web_time_limit_error_page.h +++ b/chrome/browser/ash/child_accounts/time_limits/web_time_limit_error_page/web_time_limit_error_page.h
@@ -6,13 +6,14 @@ #define CHROME_BROWSER_ASH_CHILD_ACCOUNTS_TIME_LIMITS_WEB_TIME_LIMIT_ERROR_PAGE_WEB_TIME_LIMIT_ERROR_PAGE_H_ #include <string> + #include "third_party/abseil-cpp/absl/types/optional.h" namespace base { - class TimeDelta; +} -} // namespace base +namespace ash { // Generates the appropriate time limit error page for Chrome. // |domain| is the domain of the website that is being paused. @@ -32,4 +33,6 @@ const std::string& app_locale, const std::string& app_name); +} // namespace ash + #endif // CHROME_BROWSER_ASH_CHILD_ACCOUNTS_TIME_LIMITS_WEB_TIME_LIMIT_ERROR_PAGE_WEB_TIME_LIMIT_ERROR_PAGE_H_
diff --git a/chrome/browser/ash/crosapi/keystore_service_ash.cc b/chrome/browser/ash/crosapi/keystore_service_ash.cc index 549cdb7..539fe2c 100644 --- a/chrome/browser/ash/crosapi/keystore_service_ash.cc +++ b/chrome/browser/ash/crosapi/keystore_service_ash.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/platform_keys/platform_keys.h" #include "chrome/browser/profiles/profile_manager.h" #include "chromeos/crosapi/cpp/keystore_service_util.h" +#include "chromeos/crosapi/mojom/keystore_error.mojom.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "net/cert/x509_certificate.h" @@ -466,6 +467,49 @@ //------------------------------------------------------------------------------ +void KeystoreServiceAsh::GetPublicKey( + const std::vector<uint8_t>& certificate, + mojom::KeystoreSigningAlgorithmName algorithm_name, + GetPublicKeyCallback callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + absl::optional<std::string> name = + StringFromSigningAlgorithmName(algorithm_name); + if (!name) { + std::move(callback).Run(mojom::GetPublicKeyResult::NewError( + mojom::KeystoreError::kAlgorithmNotPermittedByCertificate)); + return; + } + + chromeos::platform_keys::GetPublicKeyAndAlgorithmOutput output = + chromeos::platform_keys::GetPublicKeyAndAlgorithm(certificate, + name.value()); + + mojom::GetPublicKeyResultPtr result_ptr = mojom::GetPublicKeyResult::New(); + if (output.status == chromeos::platform_keys::Status::kSuccess) { + absl::optional<crosapi::mojom::KeystoreSigningAlgorithmPtr> + signing_algorithm = + crosapi::keystore_service_util::SigningAlgorithmFromDictionary( + output.algorithm); + if (signing_algorithm) { + mojom::GetPublicKeySuccessResultPtr success_result_ptr = + mojom::GetPublicKeySuccessResult::New(); + success_result_ptr->public_key = std::move(output.public_key); + success_result_ptr->algorithm_properties = + std::move(signing_algorithm.value()); + result_ptr->set_success_result(std::move(success_result_ptr)); + } else { + result_ptr->set_error( + crosapi::mojom::KeystoreError::kUnsupportedAlgorithmType); + } + } else { + result_ptr->set_error( + chromeos::platform_keys::StatusToKeystoreError(output.status)); + } + std::move(callback).Run(std::move(result_ptr)); +} + +//------------------------------------------------------------------------------ + void KeystoreServiceAsh::DEPRECATED_GetPublicKey( const std::vector<uint8_t>& certificate, mojom::KeystoreSigningAlgorithmName algorithm_name,
diff --git a/chrome/browser/ash/crosapi/keystore_service_ash.h b/chrome/browser/ash/crosapi/keystore_service_ash.h index 7aad390..20916c8 100644 --- a/chrome/browser/ash/crosapi/keystore_service_ash.h +++ b/chrome/browser/ash/crosapi/keystore_service_ash.h
@@ -75,10 +75,9 @@ void RemoveCertificate(mojom::KeystoreType keystore, const std::vector<uint8_t>& certificate, RemoveCertificateCallback callback) override; - void DEPRECATED_GetPublicKey( - const std::vector<uint8_t>& certificate, - mojom::KeystoreSigningAlgorithmName algorithm_name, - DEPRECATED_GetPublicKeyCallback callback) override; + void GetPublicKey(const std::vector<uint8_t>& certificate, + mojom::KeystoreSigningAlgorithmName algorithm_name, + GetPublicKeyCallback callback) override; void GenerateKey(mojom::KeystoreType keystore, mojom::KeystoreSigningAlgorithmPtr algorithm, GenerateKeyCallback callback) override; @@ -114,6 +113,11 @@ const std::vector<uint8_t>& data, const std::string& extension_id, DEPRECATED_ExtensionSignCallback callback) override; + // DEPRECATED, use `GetPublicKey` instead. + void DEPRECATED_GetPublicKey( + const std::vector<uint8_t>& certificate, + mojom::KeystoreSigningAlgorithmName algorithm_name, + DEPRECATED_GetPublicKeyCallback callback) override; private: // Returns a correct instance of PlatformKeysService to use. If a specific
diff --git a/chrome/browser/ash/crosapi/keystore_service_ash_unittest.cc b/chrome/browser/ash/crosapi/keystore_service_ash_unittest.cc index 719df09..ec6f6623 100644 --- a/chrome/browser/ash/crosapi/keystore_service_ash_unittest.cc +++ b/chrome/browser/ash/crosapi/keystore_service_ash_unittest.cc
@@ -100,6 +100,14 @@ return *result; } +std::vector<uint8_t> CertToBlob( + const scoped_refptr<net::X509Certificate>& cert) { + const uint8_t* cert_buffer = + reinterpret_cast<const uint8_t*>(CRYPTO_BUFFER_data(cert->cert_buffer())); + return std::vector<uint8_t>( + cert_buffer, cert_buffer + CRYPTO_BUFFER_len(cert->cert_buffer())); +} + void AssertBlobEq(const mojom::KeystoreBinaryResultPtr& result, const std::vector<uint8_t>& expected_blob) { ASSERT_TRUE(result); @@ -392,5 +400,78 @@ EXPECT_EQ(observer.result, false); } +TEST_F(KeystoreServiceAshTest, GetPublicKeySuccess) { + const std::vector<uint8_t> cert_bin = + CertToBlob(GetCertificateList()->front()); + + CallbackObserver<mojom::GetPublicKeyResultPtr> observer; + keystore_service_.GetPublicKey( + cert_bin, mojom::KeystoreSigningAlgorithmName::kRsassaPkcs115, + observer.GetCallback()); + + ASSERT_TRUE(observer.result->is_success_result()); + ASSERT_EQ(observer.result->get_success_result()->public_key, + GetPublicKeyBin()); + ASSERT_TRUE(observer.result->get_success_result() + ->algorithm_properties->is_pkcs115()); + const mojom::KeystorePKCS115ParamsPtr& params = + observer.result->get_success_result() + ->algorithm_properties->get_pkcs115(); + EXPECT_EQ(params->modulus_length, 2048); + EXPECT_EQ(params->public_exponent, (std::vector<uint8_t>{1, 0, 1})); +} + +TEST_F(KeystoreServiceAshTest, GetPublicKeyFail) { + const std::vector<uint8_t> cert_bin = + CertToBlob(GetCertificateList()->front()); + + CallbackObserver<mojom::GetPublicKeyResultPtr> observer; + keystore_service_.GetPublicKey(cert_bin, + mojom::KeystoreSigningAlgorithmName::kUnknown, + observer.GetCallback()); + + ASSERT_TRUE(observer.result->is_error()); + EXPECT_EQ(observer.result->get_error(), + mojom::KeystoreError::kAlgorithmNotPermittedByCertificate); +} + +// Tests for deprecated methods. + +TEST_F(KeystoreServiceAshTest, DeprecatedGetPublicKeySuccess) { + const std::vector<uint8_t> cert_bin = + CertToBlob(GetCertificateList()->front()); + + CallbackObserver<mojom::DEPRECATED_GetPublicKeyResultPtr> observer; + keystore_service_.DEPRECATED_GetPublicKey( + cert_bin, mojom::KeystoreSigningAlgorithmName::kRsassaPkcs115, + observer.GetCallback()); + + ASSERT_TRUE(observer.result->is_success_result()); + ASSERT_EQ(observer.result->get_success_result()->public_key, + GetPublicKeyBin()); + ASSERT_TRUE(observer.result->get_success_result() + ->algorithm_properties->is_pkcs115()); + const mojom::KeystorePKCS115ParamsPtr& params = + observer.result->get_success_result() + ->algorithm_properties->get_pkcs115(); + EXPECT_EQ(params->modulus_length, 2048); + EXPECT_EQ(params->public_exponent, (std::vector<uint8_t>{1, 0, 1})); +} + +TEST_F(KeystoreServiceAshTest, DeprecatedGetPublicKeyFail) { + const std::vector<uint8_t> cert_bin = + CertToBlob(GetCertificateList()->front()); + + CallbackObserver<mojom::DEPRECATED_GetPublicKeyResultPtr> observer; + keystore_service_.DEPRECATED_GetPublicKey( + cert_bin, mojom::KeystoreSigningAlgorithmName::kUnknown, + observer.GetCallback()); + + ASSERT_TRUE(observer.result->is_error_message()); + EXPECT_EQ(observer.result->get_error_message(), + chromeos::platform_keys::KeystoreErrorToString( + mojom::KeystoreError::kAlgorithmNotPermittedByCertificate)); +} + } // namespace } // namespace crosapi
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen.cc b/chrome/browser/ash/login/enrollment/enrollment_screen.cc index 663db2a..c04d3ff8 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_screen.cc +++ b/chrome/browser/ash/login/enrollment/enrollment_screen.cc
@@ -315,6 +315,14 @@ Show(context()); } +bool EnrollmentScreen::HandleAccelerator(LoginAcceleratorAction action) { + if (action == LoginAcceleratorAction::kCancelScreenAction) { + OnCancel(); + return true; + } + return false; +} + void EnrollmentScreen::OnCancel() { if (enrollment_succeeded_) { // Cancellation is the same to confirmation after the successful enrollment. @@ -557,7 +565,6 @@ void EnrollmentScreen::ShowSigninScreen() { view_->Show(); - view_->ShowSigninScreen(); } void EnrollmentScreen::RecordEnrollmentErrorMetrics() {
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen.h b/chrome/browser/ash/login/enrollment/enrollment_screen.h index 90c2d92..aa9cc5e 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_screen.h +++ b/chrome/browser/ash/login/enrollment/enrollment_screen.h
@@ -105,6 +105,7 @@ bool MaybeSkip(WizardContext* context) override; void ShowImpl() override; void HideImpl() override; + bool HandleAccelerator(LoginAcceleratorAction action) override; // Expose the exit_callback to test screen overrides. ScreenExitCallback* exit_callback() { return &exit_callback_; }
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen_unittest.cc b/chrome/browser/ash/login/enrollment/enrollment_screen_unittest.cc index d683df91..89c249b86 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_screen_unittest.cc +++ b/chrome/browser/ash/login/enrollment/enrollment_screen_unittest.cc
@@ -221,7 +221,7 @@ SetUpEnrollmentScreenForFallback(); // Once we fallback we show a sign in screen for manual enrollment. - EXPECT_CALL(*GetMockScreenView(), ShowSigninScreen()).Times(1); + EXPECT_CALL(*GetMockScreenView(), Show()).Times(2); // Start enrollment. enrollment_screen_->Show(wizard_context_.get());
diff --git a/chrome/browser/ash/login/enterprise_enrollment_browsertest.cc b/chrome/browser/ash/login/enterprise_enrollment_browsertest.cc index f33acfe..9aa8081 100644 --- a/chrome/browser/ash/login/enterprise_enrollment_browsertest.cc +++ b/chrome/browser/ash/login/enterprise_enrollment_browsertest.cc
@@ -92,8 +92,6 @@ constexpr char kEnrollmentUI[] = "enterprise-enrollment"; constexpr char kAdDialog[] = "step-ad-join"; -const test::UIPath kBackButton = {kEnrollmentUI, "step-signin", - "signin-back-button"}; const test::UIPath kAdRetryButton = {kEnrollmentUI, "adRetryButton"}; const test::UIPath kWebview = {kEnrollmentUI, "step-signin", "signin-frame"}; @@ -180,9 +178,7 @@ // Setup the enrollment screen. void ShowEnrollmentScreen() { - LoginDisplayHost* host = LoginDisplayHost::default_host(); - ASSERT_TRUE(host != nullptr); - host->StartWizard(EnrollmentScreenView::kScreenId); + host()->StartWizard(EnrollmentScreenView::kScreenId); OobeScreenWaiter(EnrollmentScreenView::kScreenId).Wait(); ASSERT_TRUE(enrollment_screen() != nullptr); ASSERT_TRUE(WizardController::default_controller() != nullptr); @@ -198,6 +194,12 @@ test::EnrollmentUIMixin enrollment_ui_{&mixin_host_}; test::EnrollmentHelperMixin enrollment_helper_{&mixin_host_}; + LoginDisplayHost* host() { + LoginDisplayHost* host = LoginDisplayHost::default_host(); + EXPECT_NE(host, nullptr); + return host; + } + private: DISALLOW_COPY_AND_ASSIGN(EnterpriseEnrollmentTestBase); }; @@ -497,7 +499,7 @@ // Cancel button is enabled when the authenticator is ready. Do it manually // instead of waiting for it. test::ExecuteOobeJS("$('enterprise-enrollment').isCancelDisabled = false"); - test::OobeJS().ClickOnPath(kBackButton); + host()->HandleAccelerator(ash::LoginAcceleratorAction::kCancelScreenAction); // Simulate navigating over the enrollment screen a second time. ShowEnrollmentScreen();
diff --git a/chrome/browser/ash/login/screens/os_install_screen.cc b/chrome/browser/ash/login/screens/os_install_screen.cc index 391a029..10c4a9458 100644 --- a/chrome/browser/ash/login/screens/os_install_screen.cc +++ b/chrome/browser/ash/login/screens/os_install_screen.cc
@@ -9,8 +9,7 @@ #include "chrome/browser/ui/webui/chromeos/login/os_install_screen_handler.h" #include "chromeos/dbus/power/power_manager_client.h" -namespace chromeos { - +namespace ash { namespace { constexpr const char kUserActionIntroNextClicked[] = "os-install-intro-next"; @@ -58,7 +57,7 @@ view_->StartInstall(); } else if (action_id == kUserActionErrorSendFeedbackClicked) { LoginDisplayHost::default_host()->HandleAccelerator( - ash::LoginAcceleratorAction::kShowFeedback); + LoginAcceleratorAction::kShowFeedback); } else if (action_id == kUserActionErrorShutdownClicked || action_id == kUserActionSuccessShutdownClicked) { Shutdown(); @@ -72,4 +71,4 @@ power_manager::REQUEST_SHUTDOWN_FOR_USER, "OS install shut down"); } -} // namespace chromeos +} // namespace ash
diff --git a/chrome/browser/ash/login/screens/os_install_screen.h b/chrome/browser/ash/login/screens/os_install_screen.h index e303ed0..f726d75 100644 --- a/chrome/browser/ash/login/screens/os_install_screen.h +++ b/chrome/browser/ash/login/screens/os_install_screen.h
@@ -8,10 +8,10 @@ #include <string> #include "chrome/browser/ash/login/screens/base_screen.h" +// TODO(https://crbug.com/1164001): move to forward declaration. +#include "chrome/browser/ui/webui/chromeos/login/os_install_screen_handler.h" -namespace chromeos { - -class OsInstallScreenView; +namespace ash { class OsInstallScreen : public BaseScreen { public: @@ -33,12 +33,6 @@ OsInstallScreenView* view_ = nullptr; }; -} // namespace chromeos - -// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos -// source migration is finished. -namespace ash { -using ::chromeos::OsInstallScreen; -} +} // namespace ash #endif // CHROME_BROWSER_ASH_LOGIN_SCREENS_OS_INSTALL_SCREEN_H_
diff --git a/chrome/browser/ash/login/screens/os_install_screen_browsertest.cc b/chrome/browser/ash/login/screens/os_install_screen_browsertest.cc index dc81b3a..066dd5e 100644 --- a/chrome/browser/ash/login/screens/os_install_screen_browsertest.cc +++ b/chrome/browser/ash/login/screens/os_install_screen_browsertest.cc
@@ -12,8 +12,7 @@ #include "chromeos/dbus/power/fake_power_manager_client.h" #include "content/public/test/browser_test.h" -namespace chromeos { - +namespace ash { namespace { const test::UIPath kWelcomeScreen = {"connect", "welcomeScreen"}; @@ -172,4 +171,4 @@ EXPECT_EQ(power_manager_client->num_request_shutdown_calls(), 1); } -} // namespace chromeos +} // namespace ash
diff --git a/chrome/browser/ash/policy/enrollment/OWNERS b/chrome/browser/ash/policy/enrollment/OWNERS new file mode 100644 index 0000000..b5f321a --- /dev/null +++ b/chrome/browser/ash/policy/enrollment/OWNERS
@@ -0,0 +1 @@ +per-file *auto_enrollment*=amraboelkher@chromium.org
diff --git a/chrome/browser/ash/web_applications/chrome_camera_app_ui_delegate.cc b/chrome/browser/ash/web_applications/chrome_camera_app_ui_delegate.cc index 81b08545..205ad5e 100644 --- a/chrome/browser/ash/web_applications/chrome_camera_app_ui_delegate.cc +++ b/chrome/browser/ash/web_applications/chrome_camera_app_ui_delegate.cc
@@ -8,9 +8,14 @@ #include "ash/constants/devicetype.h" #include "ash/public/cpp/tablet_mode.h" +#include "base/bind_post_task.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/logging.h" +#include "base/sequenced_task_runner.h" #include "base/system/sys_info.h" +#include "base/task/task_traits.h" +#include "base/task/thread_pool.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/apps/app_service/launch_utils.h" @@ -101,10 +106,65 @@ ->CheckMediaAccessPermission(render_frame_host, security_origin, type); } -ChromeCameraAppUIDelegate::ChromeCameraAppUIDelegate(content::WebUI* web_ui) - : web_ui_(web_ui) {} +ChromeCameraAppUIDelegate::FileMonitor::FileMonitor() {} -ChromeCameraAppUIDelegate::~ChromeCameraAppUIDelegate() = default; +ChromeCameraAppUIDelegate::FileMonitor::~FileMonitor() = default; + +void ChromeCameraAppUIDelegate::FileMonitor::Monitor( + const base::FilePath& file_path, + base::OnceCallback<void(FileMonitorResult)> callback) { + // Cancel the previous monitor callback if it hasn't been notified. + if (!callback_.is_null()) { + std::move(callback_).Run(FileMonitorResult::CANCELED); + } + + // There is chance that the file is deleted during the task is scheduled and + // executed. Therefore, check here before watching it. + if (!base::PathExists(file_path)) { + std::move(callback).Run(FileMonitorResult::DELETED); + return; + } + + callback_ = std::move(callback); + file_watcher_ = std::make_unique<base::FilePathWatcher>(); + if (!file_watcher_->Watch( + file_path, base::FilePathWatcher::Type::kNonRecursive, + base::BindRepeating( + &ChromeCameraAppUIDelegate::FileMonitor::OnFileDeletion, + base::Unretained(this)))) { + std::move(callback_).Run(FileMonitorResult::ERROR); + } +} + +void ChromeCameraAppUIDelegate::FileMonitor::OnFileDeletion( + const base::FilePath& path, + bool error) { + if (callback_.is_null()) { + return; + } + + if (error) { + std::move(callback_).Run(FileMonitorResult::ERROR); + return; + } + std::move(callback_).Run(FileMonitorResult::DELETED); +} + +ChromeCameraAppUIDelegate::ChromeCameraAppUIDelegate(content::WebUI* web_ui) + : web_ui_(web_ui), + file_task_runner_(base::ThreadPool::CreateSequencedTaskRunner( + {base::MayBlock(), base::TaskPriority::USER_VISIBLE})) { + file_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&ChromeCameraAppUIDelegate::InitFileMonitorOnFileThread, + base::Unretained(this))); +} + +ChromeCameraAppUIDelegate::~ChromeCameraAppUIDelegate() { + // Destroy |file_monitor_| on |file_task_runner_|. + // TODO(wtlee): Ensure there is no lifetime issue before actually deleting it. + file_task_runner_->DeleteSoon(FROM_HERE, std::move(file_monitor_)); +} void ChromeCameraAppUIDelegate::SetLaunchDirectory() { Profile* profile = Profile::FromWebUI(web_ui_); @@ -204,19 +264,15 @@ return; } - // Cancel the previous monitor callback if it hasn't been notified. - if (!cur_file_monitor_callback_.is_null()) { - std::move(cur_file_monitor_callback_).Run(FileMonitorResult::CANCELED); - } - - cur_file_monitor_callback_ = std::move(callback); - file_watcher_.reset(new base::FilePathWatcher); - if (!file_watcher_->Watch( - file_path, base::FilePathWatcher::Type::kNonRecursive, - base::BindRepeating(&ChromeCameraAppUIDelegate::OnFileDeletion, - base::Unretained(this)))) { - std::move(cur_file_monitor_callback_).Run(FileMonitorResult::ERROR); - } + // We should return the response on current thread (mojo thread). + auto callback_on_current_thread = base::BindPostTask( + base::SequencedTaskRunnerHandle::Get(), std::move(callback), FROM_HERE); + file_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &ChromeCameraAppUIDelegate::MonitorFileDeletionOnFileThread, + base::Unretained(this), file_monitor_.get(), std::move(file_path), + std::move(callback_on_current_thread))); } base::FilePath ChromeCameraAppUIDelegate::GetFilePathByName( @@ -233,15 +289,17 @@ .Append(name_component); } -void ChromeCameraAppUIDelegate::OnFileDeletion(const base::FilePath& path, - bool error) { - if (cur_file_monitor_callback_.is_null()) { - return; - } +void ChromeCameraAppUIDelegate::InitFileMonitorOnFileThread() { + DCHECK(file_task_runner_->RunsTasksInCurrentSequence()); - if (error) { - std::move(cur_file_monitor_callback_).Run(FileMonitorResult::ERROR); - return; - } - std::move(cur_file_monitor_callback_).Run(FileMonitorResult::DELETED); + file_monitor_ = std::make_unique<FileMonitor>(); +} + +void ChromeCameraAppUIDelegate::MonitorFileDeletionOnFileThread( + FileMonitor* file_monitor, + const base::FilePath& file_path, + base::OnceCallback<void(FileMonitorResult)> callback) { + DCHECK(file_task_runner_->RunsTasksInCurrentSequence()); + + file_monitor->Monitor(file_path, std::move(callback)); }
diff --git a/chrome/browser/ash/web_applications/chrome_camera_app_ui_delegate.h b/chrome/browser/ash/web_applications/chrome_camera_app_ui_delegate.h index 0f77b1d..b13603e 100644 --- a/chrome/browser/ash/web_applications/chrome_camera_app_ui_delegate.h +++ b/chrome/browser/ash/web_applications/chrome_camera_app_ui_delegate.h
@@ -65,6 +65,25 @@ DISALLOW_COPY_AND_ASSIGN(CameraAppDialog); }; + class FileMonitor { + public: + FileMonitor(); + FileMonitor(const FileMonitor&) = delete; + FileMonitor& operator=(const FileMonitor&) = delete; + ~FileMonitor(); + + void Monitor(const base::FilePath& file_path, + base::OnceCallback<void(FileMonitorResult)> callback); + + private: + void OnFileDeletion(const base::FilePath& path, bool error); + + // Things which might be touched by the callback of |file_watcher_| should + // be destroyed later than the destruction of |file_watcher_|. + base::OnceCallback<void(FileMonitorResult)> callback_; + std::unique_ptr<base::FilePathWatcher> file_watcher_; + }; + explicit ChromeCameraAppUIDelegate(content::WebUI* web_ui); ChromeCameraAppUIDelegate(const ChromeCameraAppUIDelegate&) = delete; @@ -86,12 +105,17 @@ private: base::FilePath GetFilePathByName(const std::string& name); - void OnFileDeletion(const base::FilePath& path, bool error); + void InitFileMonitorOnFileThread(); + void MonitorFileDeletionOnFileThread( + FileMonitor* file_monitor, + const base::FilePath& file_path, + base::OnceCallback<void(FileMonitorResult)> callback); content::WebUI* web_ui_; // Owns |this|. - std::unique_ptr<base::FilePathWatcher> file_watcher_; - base::OnceCallback<void(FileMonitorResult)> cur_file_monitor_callback_; + scoped_refptr<base::SequencedTaskRunner> file_task_runner_; + // It should only be created, used and destroyed on |file_task_runner_|. + std::unique_ptr<FileMonitor> file_monitor_; }; #endif // CHROME_BROWSER_ASH_WEB_APPLICATIONS_CHROME_CAMERA_APP_UI_DELEGATE_H_
diff --git a/chrome/browser/background/background_contents.cc b/chrome/browser/background/background_contents.cc index 9f8e035..fc899aac 100644 --- a/chrome/browser/background/background_contents.cc +++ b/chrome/browser/background/background_contents.cc
@@ -98,7 +98,8 @@ return true; } -void BackgroundContents::DidNavigateMainFramePostCommit(WebContents* tab) { +void BackgroundContents::DidNavigatePrimaryMainFramePostCommit( + WebContents* tab) { // Note: because BackgroundContents are only available to extension apps, // navigation is limited to urls within the app's extent. This is enforced in // RenderView::decidePolicyForNavigation. If BackgroundContents become
diff --git a/chrome/browser/background/background_contents.h b/chrome/browser/background/background_contents.h index f9d6306..9474877 100644 --- a/chrome/browser/background/background_contents.h +++ b/chrome/browser/background/background_contents.h
@@ -78,7 +78,8 @@ // content::WebContentsDelegate implementation: void CloseContents(content::WebContents* source) override; bool ShouldSuppressDialogs(content::WebContents* source) override; - void DidNavigateMainFramePostCommit(content::WebContents* tab) override; + void DidNavigatePrimaryMainFramePostCommit( + content::WebContents* tab) override; void AddNewContents(content::WebContents* source, std::unique_ptr<content::WebContents> new_contents, const GURL& target_url,
diff --git a/chrome/browser/browser_switcher/browser_switcher_browsertest.cc b/chrome/browser/browser_switcher/browser_switcher_browsertest.cc index 978368d..4ac7e60c 100644 --- a/chrome/browser/browser_switcher/browser_switcher_browsertest.cc +++ b/chrome/browser/browser_switcher/browser_switcher_browsertest.cc
@@ -137,10 +137,9 @@ } void SetUpInProcessBrowserTestFixture() override { - ON_CALL(provider_, IsInitializationComplete(testing::_)) - .WillByDefault(testing::Return(true)); - ON_CALL(provider_, IsFirstPolicyLoadComplete(testing::_)) - .WillByDefault(testing::Return(true)); + provider_.SetDefaultReturns( + /*is_initialization_complete_return=*/true, + /*is_first_policy_load_complete_return=*/true); policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_); }
diff --git a/chrome/browser/browser_switcher/browser_switcher_prefs_unittest.cc b/chrome/browser/browser_switcher/browser_switcher_prefs_unittest.cc index b74b2ef8..235583a 100644 --- a/chrome/browser/browser_switcher/browser_switcher_prefs_unittest.cc +++ b/chrome/browser/browser_switcher/browser_switcher_prefs_unittest.cc
@@ -57,10 +57,9 @@ BrowserSwitcherPrefs::RegisterProfilePrefs(prefs_backend_.registry()); policy_provider_ = std::make_unique< testing::NiceMock<policy::MockConfigurationPolicyProvider>>(); - ON_CALL(*policy_provider_, IsInitializationComplete(_)) - .WillByDefault(Return(true)); - ON_CALL(*policy_provider_, IsFirstPolicyLoadComplete(_)) - .WillByDefault(Return(true)); + policy_provider_->SetDefaultReturns( + /*is_initialization_complete_return=*/true, + /*is_first_policy_load_complete_return=*/true); std::vector<policy::ConfigurationPolicyProvider*> providers = { policy_provider_.get()}; policy_service_ = std::make_unique<policy::PolicyServiceImpl>(providers);
diff --git a/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc b/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc index bedd7ce3..f14f949 100644 --- a/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc +++ b/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc
@@ -99,10 +99,9 @@ ~BrowserSwitcherServiceTest() override = default; void SetUpInProcessBrowserTestFixture() override { - ON_CALL(provider_, IsInitializationComplete(testing::_)) - .WillByDefault(testing::Return(true)); - ON_CALL(provider_, IsFirstPolicyLoadComplete(testing::_)) - .WillByDefault(testing::Return(true)); + provider_.SetDefaultReturns( + /*is_initialization_complete_return=*/true, + /*is_first_policy_load_complete_return=*/true); policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_); BrowserSwitcherService::SetRefreshDelayForTesting(base::TimeDelta()); }
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc index f6ec0b17..cad5ebc 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -99,6 +99,7 @@ #include "components/os_crypt/os_crypt_mocker.h" #include "components/password_manager/core/browser/mock_password_store.h" #include "components/password_manager/core/browser/mock_password_sync_metadata_store.h" +#include "components/password_manager/core/browser/mock_smart_bubble_stats_store.h" #include "components/password_manager/core/browser/password_manager_test_utils.h" #include "components/password_manager/core/browser/password_store_consumer.h" #include "components/password_manager/core/common/password_manager_features.h" @@ -579,10 +580,16 @@ return &account_metadata_store_; } + password_manager::MockSmartBubbleStatsStore* mock_smart_bubble_stats_store() { + return &mock_smart_bubble_stats_store_; + } + private: password_manager::MockPasswordStore* profile_store_; password_manager::MockPasswordStore* account_store_; password_manager::MockPasswordSyncMetadataStore account_metadata_store_; + testing::NiceMock<password_manager::MockSmartBubbleStatsStore> + mock_smart_bubble_stats_store_; }; class RemovePermissionPromptCountsTest { @@ -1985,9 +1992,16 @@ RemovePasswordsTester tester(GetProfile()); base::RepeatingCallback<bool(const GURL&)> empty_filter; - EXPECT_CALL(*tester.profile_store(), RemoveStatisticsByOriginAndTimeImpl( - ProbablySameFilter(empty_filter), - base::Time(), base::Time::Max())); + ON_CALL(*tester.profile_store(), GetSmartBubbleStatsStore) + .WillByDefault(Return(tester.mock_smart_bubble_stats_store())); + EXPECT_CALL( + *tester.mock_smart_bubble_stats_store(), + RemoveStatisticsByOriginAndTime(ProbablySameFilter(empty_filter), + base::Time(), base::Time::Max(), _)) + .WillOnce(testing::WithArg<3>([](base::OnceClosure completion) { + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + std::move(completion)); + })); BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), constants::DATA_TYPE_HISTORY, false); } @@ -2004,9 +2018,17 @@ builder->AddRegisterableDomain(kTestRegisterableDomain1); base::RepeatingCallback<bool(const GURL&)> filter = builder->BuildUrlFilter(); - EXPECT_CALL(*tester.profile_store(), - RemoveStatisticsByOriginAndTimeImpl( - ProbablySameFilter(filter), base::Time(), base::Time::Max())); + ON_CALL(*tester.profile_store(), GetSmartBubbleStatsStore) + .WillByDefault(Return(tester.mock_smart_bubble_stats_store())); + EXPECT_CALL( + *tester.mock_smart_bubble_stats_store(), + RemoveStatisticsByOriginAndTime(ProbablySameFilter(filter), base::Time(), + base::Time::Max(), _)) + .WillOnce(testing::WithArg<3>([](base::OnceClosure completion) { + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + std::move(completion)); + })); + BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), constants::DATA_TYPE_HISTORY, std::move(builder)); }
diff --git a/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler.cc b/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler.cc index 37e1dd8..424c466d 100644 --- a/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler.cc +++ b/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler.cc
@@ -144,6 +144,8 @@ void FullRestoreAppLaunchHandler::MaybeRestore() { restore_start_time_ = base::TimeTicks::Now(); + ::full_restore::FullRestoreReadHandler::GetInstance()->SetCheckRestoreData( + profile_->GetPath()); if (should_launch_browser_) { LaunchBrowser();
diff --git a/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler_browsertest.cc b/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler_browsertest.cc index 4fc63e51..d3e95d3e 100644 --- a/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler_browsertest.cc +++ b/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler_browsertest.cc
@@ -2330,6 +2330,11 @@ false /* should_notify_initialized */); } + bool HasWindowInfo(int32_t restore_window_id) { + return ::full_restore::FullRestoreReadHandler::GetInstance()->HasWindowInfo( + restore_window_id); + } + private: base::test::ScopedFeatureList scoped_feature_list_; }; @@ -2353,11 +2358,14 @@ // Close app_browser so that the SWA can be relaunched. web_app::CloseAndWait(app_browser); + ASSERT_FALSE(HasWindowInfo(window_id)); + // Set should restore. app_launch_handler->SetShouldRestore(); // Wait for the restoration. content::RunAllTasksUntilIdle(); + ASSERT_TRUE(HasWindowInfo(window_id)); // Get the restored browser for the system web app. Browser* restore_app_browser = GetBrowserForWindowId(window_id); @@ -2372,6 +2380,42 @@ EXPECT_EQ(window_id, restore_window_id); } +// Verify that when the full restore doesn't start, the browser window of the +// SWA doesn't have the restore info. +IN_PROC_BROWSER_TEST_P(FullRestoreAppLaunchHandlerSystemWebAppsBrowserTest, + LaunchSWAWithoutRestore) { + Browser* app_browser = LaunchSystemWebApp(); + ASSERT_TRUE(app_browser); + ASSERT_NE(browser(), app_browser); + + // Get the window id. + aura::Window* window = app_browser->window()->GetNativeWindow(); + int32_t window_id = window->GetProperty(::full_restore::kWindowIdKey); + + SaveWindowInfo(window); + WaitForAppLaunchInfoSaved(); + + // Create FullRestoreAppLaunchHandler. + auto app_launch_handler = + std::make_unique<FullRestoreAppLaunchHandler>(profile()); + + // Close app_browser so that the SWA can be relaunched. + web_app::CloseAndWait(app_browser); + + content::RunAllTasksUntilIdle(); + + ASSERT_FALSE(HasWindowInfo(window_id)); + + Browser* new_app_browser = LaunchSystemWebApp(); + + ASSERT_TRUE(new_app_browser); + ASSERT_NE(browser(), new_app_browser); + + window = new_app_browser->window()->GetNativeWindow(); + auto* window_state = ash::WindowState::Get(window); + EXPECT_FALSE(window_state->HasRestoreBounds()); +} + // Verify the restoration if the SWA is not available when set // restore, and the restoration can work if the SWA is added later. IN_PROC_BROWSER_TEST_P(FullRestoreAppLaunchHandlerSystemWebAppsBrowserTest,
diff --git a/chrome/browser/component_updater/cros_component_installer_chromeos.cc b/chrome/browser/component_updater/cros_component_installer_chromeos.cc index 4c64d0fb..00ead41 100644 --- a/chrome/browser/component_updater/cros_component_installer_chromeos.cc +++ b/chrome/browser/component_updater/cros_component_installer_chromeos.cc
@@ -39,9 +39,9 @@ "5.0", "1913a5e0a6cad30b6f03e176177e0d7ed62c5d6700a9c66da556d7c3f5d6a47e"}, {"cros-termina", ComponentConfig::PolicyType::kEnvVersion, "940.1", "e9d960f84f628e1f42d05de4046bb5b3154b6f1f65c08412c6af57a29aecaffb"}, - {"rtanalytics-light", ComponentConfig::PolicyType::kEnvVersion, "92.0", + {"rtanalytics-light", ComponentConfig::PolicyType::kEnvVersion, "94.0", "69f09d33c439c2ab55bbbe24b47ab55cb3f6c0bd1f1ef46eefea3216ec925038"}, - {"rtanalytics-full", ComponentConfig::PolicyType::kEnvVersion, "92.0", + {"rtanalytics-full", ComponentConfig::PolicyType::kEnvVersion, "94.0", "c93c3e1013c52100a20038b405ac854d69fa889f6dc4fa6f188267051e05e444"}, {"star-cups-driver", ComponentConfig::PolicyType::kEnvVersion, "1.1", "6d24de30f671da5aee6d463d9e446cafe9ddac672800a9defe86877dcde6c466"},
diff --git a/chrome/browser/devtools/devtools_browsertest.cc b/chrome/browser/devtools/devtools_browsertest.cc index 16d686f..bf738bb 100644 --- a/chrome/browser/devtools/devtools_browsertest.cc +++ b/chrome/browser/devtools/devtools_browsertest.cc
@@ -2560,10 +2560,9 @@ class DevToolsPolicyTest : public InProcessBrowserTest { protected: DevToolsPolicyTest() { - ON_CALL(provider_, IsInitializationComplete(testing::_)) - .WillByDefault(testing::Return(true)); - ON_CALL(provider_, IsFirstPolicyLoadComplete(testing::_)) - .WillByDefault(testing::Return(true)); + provider_.SetDefaultReturns( + /*is_initialization_complete_return=*/true, + /*is_first_policy_load_complete_return=*/true); } void SetUpInProcessBrowserTestFixture() override {
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index 9caae9a..d6b21ea 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -943,7 +943,6 @@ "//ui/base/clipboard", "//ui/base/dragdrop/mojom:mojom_shared", "//ui/base/ime", - "//ui/display/manager", "//ui/gfx", "//ui/gfx/geometry", "//ui/message_center", @@ -962,7 +961,10 @@ "api/printing/printer_capabilities_provider.cc", "api/printing/printer_capabilities_provider.h", ] - deps += [ "//chromeos/resources:media_app_bundle_resources_grit" ] + deps += [ + "//chromeos/resources:media_app_bundle_resources_grit", + "//ui/display/manager", + ] if (use_cups) { sources += [ "api/printing/print_job_submitter.cc",
diff --git a/chrome/browser/extensions/api/automation/automation_apitest.cc b/chrome/browser/extensions/api/automation/automation_apitest.cc index 178eac5..8daa09d 100644 --- a/chrome/browser/extensions/api/automation/automation_apitest.cc +++ b/chrome/browser/extensions/api/automation/automation_apitest.cc
@@ -49,7 +49,7 @@ #include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h" #include "ui/display/manager/display_manager.h" #include "ui/display/screen.h" -#include "ui/display/test/display_manager_test_api.h" +#include "ui/display/test/display_manager_test_api.h" // nogncheck #endif namespace extensions {
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_browsertest.cc b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_browsertest.cc index 82699bbf..8a0ccbc 100644 --- a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_browsertest.cc +++ b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_browsertest.cc
@@ -245,8 +245,14 @@ EXPECT_EQ(site_isolation_enabled(), info.site_isolation_enabled); } +// crbug.com/1230268 not working on Lacros. +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#define MAYBE_AffiliationIDs DISABLED_AffiliationIDs +#else +#define MAYBE_AffiliationIDs AffiliationIDs +#endif IN_PROC_BROWSER_TEST_P(EnterpriseReportingPrivateGetContextInfoBrowserTest, - AffiliationIDs) { + MAYBE_AffiliationIDs) { auto function = base::MakeRefCounted<EnterpriseReportingPrivateGetContextInfoFunction>(); auto context_info_value = std::unique_ptr<base::Value>(
diff --git a/chrome/browser/extensions/api/system_display/system_display_extension_apitest.cc b/chrome/browser/extensions/api/system_display/system_display_extension_apitest.cc new file mode 100644 index 0000000..7a4de4c --- /dev/null +++ b/chrome/browser/extensions/api/system_display/system_display_extension_apitest.cc
@@ -0,0 +1,83 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> +#include <string> + +#include "base/bind.h" +#include "base/debug/leak_annotations.h" +#include "base/macros.h" +#include "build/build_config.h" +#include "build/chromeos_buildflags.h" +#include "chrome/browser/extensions/extension_apitest.h" +#include "content/public/test/browser_test.h" +#include "extensions/browser/api/system_display/display_info_provider.h" +#include "extensions/browser/api/system_display/system_display_api.h" +#include "extensions/browser/api_test_utils.h" +#include "extensions/browser/mock_display_info_provider.h" +#include "extensions/browser/mock_screen.h" +#include "extensions/common/api/system_display.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" +#include "ui/display/test/scoped_screen_override.h" + +namespace extensions { + +using display::Screen; +using display::test::ScopedScreenOverride; + +class SystemDisplayExtensionApiTest : public ExtensionApiTest { + public: + SystemDisplayExtensionApiTest() = default; + ~SystemDisplayExtensionApiTest() override = default; + SystemDisplayExtensionApiTest(const SystemDisplayExtensionApiTest&) = delete; + SystemDisplayExtensionApiTest& operator=( + const SystemDisplayExtensionApiTest&) = delete; + + void SetUpOnMainThread() override { + ExtensionApiTest::SetUpOnMainThread(); + ANNOTATE_LEAKING_OBJECT_PTR(Screen::GetScreen()); + scoped_screen_override_ = + std::make_unique<ScopedScreenOverride>(screen_.get()); + DisplayInfoProvider::InitializeForTesting(provider_.get()); + } + + void TearDownOnMainThread() override { + ExtensionApiTest::TearDownOnMainThread(); + scoped_screen_override_.reset(); + } + + protected: + std::unique_ptr<MockDisplayInfoProvider> provider_ = + std::make_unique<MockDisplayInfoProvider>(); + + private: + std::unique_ptr<Screen> screen_ = std::make_unique<MockScreen>(); + std::unique_ptr<ScopedScreenOverride> scoped_screen_override_; +}; + +IN_PROC_BROWSER_TEST_F(SystemDisplayExtensionApiTest, GetDisplayInfo) { + ASSERT_TRUE(RunExtensionTest("system_display/info")) << message_; +} + +#if !BUILDFLAG(IS_CHROMEOS_ASH) + +IN_PROC_BROWSER_TEST_F(SystemDisplayExtensionApiTest, SetDisplay) { + scoped_refptr<SystemDisplaySetDisplayPropertiesFunction> set_info_function( + new SystemDisplaySetDisplayPropertiesFunction()); + + set_info_function->set_has_callback(true); + + EXPECT_EQ(SystemDisplayCrOSRestrictedFunction::kCrosOnlyError, + api_test_utils::RunFunctionAndReturnError( + set_info_function.get(), "[\"display_id\", {}]", profile())); + + std::unique_ptr<base::DictionaryValue> set_info = + provider_->GetSetInfoValue(); + EXPECT_FALSE(set_info); +} + +#endif // !BUILDFLAG(IS_CHROMEOS_ASH) + +} // namespace extensions
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc b/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc index 0f4edbc..ce543f1 100644 --- a/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc +++ b/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc
@@ -436,9 +436,7 @@ ExtensionPrefs::Get(profile())->AddDisableReason( kExtensionId1, disable_reason::DisableReason::DISABLE_NOT_VERIFIED); scoped_refptr<const Extension> ext2 = CreateNewExtension( - kExtensionName2, kExtensionId2, ExtensionStatus::kPending); - registry()->AddEnabled(ext2.get()); - force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); + kExtensionName2, kExtensionId2, ExtensionStatus::kLoaded); // ForceInstalledMetrics should still keep running as kExtensionId1 is // installed but not loaded. EXPECT_TRUE(fake_timer_->IsRunning()); @@ -460,9 +458,7 @@ disable_reason::DisableReason::DISABLE_NOT_VERIFIED | disable_reason::DisableReason::DISABLE_UNSUPPORTED_REQUIREMENT); scoped_refptr<const Extension> ext2 = CreateNewExtension( - kExtensionName2, kExtensionId2, ExtensionStatus::kPending); - registry()->AddEnabled(ext2.get()); - force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); + kExtensionName2, kExtensionId2, ExtensionStatus::kLoaded); // ForceInstalledMetrics should still keep running as kExtensionId1 is // installed but not loaded. EXPECT_TRUE(fake_timer_->IsRunning()); @@ -482,9 +478,7 @@ kExtensionName1, kExtensionId1, ExtensionStatus::kPending); registry()->AddEnabled(ext1.get()); scoped_refptr<const Extension> ext2 = CreateNewExtension( - kExtensionName2, kExtensionId2, ExtensionStatus::kPending); - registry()->AddEnabled(ext2.get()); - force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); + kExtensionName2, kExtensionId2, ExtensionStatus::kLoaded); // ForceInstalledMetrics should still keep running as kExtensionId1 is // installed but not loaded. EXPECT_TRUE(fake_timer_->IsRunning()); @@ -503,8 +497,6 @@ scoped_refptr<const Extension> ext1 = CreateNewExtension( kExtensionName1, kExtensionId1, ExtensionStatus::kLoaded); - registry()->AddEnabled(ext1.get()); - force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); install_stage_tracker()->ReportInstallationStage( kExtensionId2, InstallStageTracker::Stage::CREATED); install_stage_tracker()->ReportInstallCreationStage( @@ -532,9 +524,7 @@ kExtensionName1, kExtensionId1, ExtensionStatus::kPending); registry()->AddBlocklisted(ext1.get()); scoped_refptr<const Extension> ext2 = CreateNewExtension( - kExtensionName2, kExtensionId2, ExtensionStatus::kPending); - registry()->AddEnabled(ext2.get()); - force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); + kExtensionName2, kExtensionId2, ExtensionStatus::kLoaded); // ForceInstalledMetrics should still keep running as kExtensionId1 is // installed but not loaded. EXPECT_TRUE(fake_timer_->IsRunning()); @@ -642,9 +632,7 @@ CrxInstallError(SandboxedUnpackerFailureReason::CRX_HEADER_INVALID, std::u16string())); scoped_refptr<const Extension> ext2 = CreateNewExtension( - kExtensionName2, kExtensionId2, ExtensionStatus::kPending); - registry()->AddEnabled(ext2.get()); - force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); + kExtensionName2, kExtensionId2, ExtensionStatus::kLoaded); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. EXPECT_FALSE(fake_timer_->IsRunning()); @@ -668,9 +656,7 @@ CrxInstallError(SandboxedUnpackerFailureReason::CRX_HEADER_INVALID, std::u16string())); scoped_refptr<const Extension> ext2 = CreateNewExtension( - kExtensionName2, kExtensionId2, ExtensionStatus::kPending); - registry()->AddEnabled(ext2.get()); - force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); + kExtensionName2, kExtensionId2, ExtensionStatus::kLoaded); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. EXPECT_FALSE(fake_timer_->IsRunning()); @@ -695,9 +681,7 @@ CrxInstallError(SandboxedUnpackerFailureReason::CRX_HEADER_INVALID, std::u16string())); scoped_refptr<const Extension> ext2 = CreateNewExtension( - kExtensionName2, kExtensionId2, ExtensionStatus::kPending); - registry()->AddEnabled(ext2.get()); - force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); + kExtensionName2, kExtensionId2, ExtensionStatus::kLoaded); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. EXPECT_FALSE(fake_timer_->IsRunning()); @@ -721,9 +705,7 @@ kExtensionId1, InstallStageTracker::FailureReason::REPLACED_BY_SYSTEM_APP); scoped_refptr<const Extension> ext2 = CreateNewExtension( - kExtensionName2, kExtensionId2, ExtensionStatus::kPending); - registry()->AddEnabled(ext2.get()); - force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); + kExtensionName2, kExtensionId2, ExtensionStatus::kLoaded); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. EXPECT_FALSE(fake_timer_->IsRunning()); @@ -983,8 +965,6 @@ scoped_refptr<const Extension> ext1 = CreateNewExtension( kExtensionName1, kExtensionId1, ExtensionStatus::kLoaded); - registry()->AddEnabled(ext1.get()); - force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); install_stage_tracker()->ReportInstallationStage( kExtensionId2, InstallStageTracker::Stage::CREATED); install_stage_tracker()->ReportInstallCreationStage(
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_test_base.cc b/chrome/browser/extensions/forced_extensions/force_installed_test_base.cc index 851eca9..e9053ef 100644 --- a/chrome/browser/extensions/forced_extensions/force_installed_test_base.cc +++ b/chrome/browser/extensions/forced_extensions/force_installed_test_base.cc
@@ -114,9 +114,11 @@ case ForceInstalledTracker::ExtensionStatus::kFailed: break; case ForceInstalledTracker::ExtensionStatus::kLoaded: + registry()->AddEnabled(ext.get()); force_installed_tracker()->OnExtensionLoaded(profile(), ext.get()); break; case ForceInstalledTracker::ExtensionStatus::kReady: + registry()->AddEnabled(ext.get()); force_installed_tracker()->OnExtensionLoaded(profile(), ext.get()); force_installed_tracker()->OnExtensionReady(profile(), ext.get()); }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index e40b6a3..33640e4b 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -4031,6 +4031,11 @@ "expiry_milestone": 96 }, { + "name": "ntp-photos-module", + "owners": [ "jerem", "tiborg" ], + "expiry_milestone": 96 + }, + { "name": "ntp-realbox-suggestion-answers", "owners": [ "mahmadi", "mfacey" ], "expiry_milestone": 96
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 94f1e4f..a109842 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3752,6 +3752,10 @@ const char kNtpDriveModuleDescription[] = "Shows the Google Drive module on the New Tab Page"; +const char kNtpPhotosModuleName[] = "NTP Photos Module"; +const char kNtpPhotosModuleDescription[] = + "Shows the Google Photos module on the New Tab Page"; + const char kNtpRecipeTasksModuleName[] = "NTP Recipe Tasks Module"; const char kNtpRecipeTasksModuleDescription[] = "Shows the recipe tasks module on the New Tab Page.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 19b1c3d..5ebe37a 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2139,6 +2139,9 @@ extern const char kNtpDriveModuleName[]; extern const char kNtpDriveModuleDescription[]; +extern const char kNtpPhotosModuleName[]; +extern const char kNtpPhotosModuleDescription[]; + extern const char kNtpRecipeTasksModuleName[]; extern const char kNtpRecipeTasksModuleDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 366b9b8..00fd89f0 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -114,6 +114,7 @@ &shared_highlighting::kPreemptiveLinkToTextGeneration, &shared_highlighting::kSharedHighlightingV2, &shared_highlighting::kSharedHighlightingAmp, + &features::kElasticOverscroll, &features::kPrivacySandboxSettings, &features::kPrivacySandboxSettings2, &features::kPrioritizeBootstrapTasks,
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java index 6d650110..1a8ab4a 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
@@ -55,6 +55,7 @@ put(ChromeFeatureList.COMMAND_LINE_ON_NON_ROOTED, false); put(ChromeFeatureList.DOWNLOADS_AUTO_RESUMPTION_NATIVE, true); put(ChromeFeatureList.EARLY_LIBRARY_LOAD, false); + put(ChromeFeatureList.ELASTIC_OVERSCROLL, false); put(ChromeFeatureList.PRIORITIZE_BOOTSTRAP_TASKS, true); put(ChromeFeatureList.IMMERSIVE_UI_MODE, false); put(ChromeFeatureList.SWAP_PIXEL_FORMAT_TO_FIX_CONVERT_FROM_TRANSLUCENT, true);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index b6d0475..d354493 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -347,6 +347,7 @@ public static final String EDIT_PASSWORDS_IN_SETTINGS = "EditPasswordsInSettings"; public static final String EARLY_LIBRARY_LOAD = "EarlyLibraryLoad"; public static final String ENHANCED_PROTECTION_PROMO_CARD = "EnhancedProtectionPromoCard"; + public static final String ELASTIC_OVERSCROLL = "ElasticOverscroll"; public static final String EXPERIMENTS_FOR_AGSA = "ExperimentsForAgsa"; public static final String EXPLICIT_LANGUAGE_ASK = "ExplicitLanguageAsk"; public static final String EXPLORE_SITES = "ExploreSites";
diff --git a/chrome/browser/loader/signed_exchange_policy_browsertest.cc b/chrome/browser/loader/signed_exchange_policy_browsertest.cc index cd01b7ed..dc84daf1 100644 --- a/chrome/browser/loader/signed_exchange_policy_browsertest.cc +++ b/chrome/browser/loader/signed_exchange_policy_browsertest.cc
@@ -29,10 +29,9 @@ void SetUpInProcessBrowserTestFixture() override { CertVerifierBrowserTest::SetUpInProcessBrowserTestFixture(); - ON_CALL(policy_provider_, IsInitializationComplete(testing::_)) - .WillByDefault(testing::Return(true)); - ON_CALL(policy_provider_, IsFirstPolicyLoadComplete(testing::_)) - .WillByDefault(testing::Return(true)); + policy_provider_.SetDefaultReturns( + /*is_initialization_complete_return=*/true, + /*is_first_policy_load_complete_return=*/true); policy::BrowserPolicyConnector::SetPolicyProviderForTesting( &policy_provider_); }
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc index c54fe93..a261bebf 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.cc +++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -1058,17 +1058,21 @@ ukm_service_->Purge(); } -void ChromeMetricsServiceClient::OnUkmAllowedStateChanged(bool must_purge) { +void ChromeMetricsServiceClient::OnUkmAllowedStateChanged(bool total_purge) { if (!ukm_service_) return; - if (must_purge) { + + if (total_purge) { ukm_service_->Purge(); ukm_service_->ResetClientState(ukm::ResetReason::kOnUkmAllowedStateChanged); - } else if (!IsUkmAllowedWithExtensionsForAllProfiles()) { - ukm_service_->PurgeExtensions(); + } else { + if (!IsUkmAllowedWithExtensionsForAllProfiles()) + ukm_service_->PurgeExtensionsData(); + if (!IsUkmAllowedWithAppsForAllProfiles()) + ukm_service_->PurgeAppsData(); } - // Signal service manager to enable/disable UKM based on new state. + // Signal service manager to enable/disable UKM based on new states. UpdateRunningServices(); } @@ -1130,6 +1134,10 @@ return UkmConsentStateObserver::IsUkmAllowedForAllProfiles(); } +bool ChromeMetricsServiceClient::IsUkmAllowedWithAppsForAllProfiles() { + return UkmConsentStateObserver::IsUkmAllowedWithAppsForAllProfiles(); +} + bool ChromeMetricsServiceClient::IsUkmAllowedWithExtensionsForAllProfiles() { return UkmConsentStateObserver::IsUkmAllowedWithExtensionsForAllProfiles(); }
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.h b/chrome/browser/metrics/chrome_metrics_service_client.h index 4052e71..1e5a8ab 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.h +++ b/chrome/browser/metrics/chrome_metrics_service_client.h
@@ -83,6 +83,7 @@ metrics::EnableMetricsDefault GetMetricsReportingDefaultState() override; bool IsUMACellularUploadLogicEnabled() override; bool IsUkmAllowedForAllProfiles() override; + bool IsUkmAllowedWithAppsForAllProfiles() override; bool IsUkmAllowedWithExtensionsForAllProfiles() override; bool AreNotificationListenersEnabledOnAllProfiles() override; std::string GetAppPackageNameIfLoggable() override;
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc index 0347683d..c851880 100644 --- a/chrome/browser/net/profile_network_context_service.cc +++ b/chrome/browser/net/profile_network_context_service.cc
@@ -139,7 +139,10 @@ // Tests allowing ambient authentication with default credentials based on the // profile type. bool IsAmbientAuthAllowedForProfile(Profile* profile) { - if (profile->IsRegularProfile()) + // Ambient authentication is always enabled for regular and system profiles. + // System profiles (used in profile picker) may require authentication to let + // user login. + if (profile->IsRegularProfile() || profile->IsSystemProfile()) return true; // Non-primary OTR profiles are not used to create browser windows and are @@ -165,10 +168,6 @@ type == net::AmbientAuthAllowedProfileTypes::ALL; } - // System profile does not need ambient authentication. - if (profile->IsSystemProfile()) - return false; - // Profile type not yet supported. NOTREACHED();
diff --git a/chrome/browser/password_manager/android/password_store_android_backend.cc b/chrome/browser/password_manager/android/password_store_android_backend.cc index 3877898c..67d7f62 100644 --- a/chrome/browser/password_manager/android/password_store_android_backend.cc +++ b/chrome/browser/password_manager/android/password_store_android_backend.cc
@@ -85,4 +85,8 @@ // TODO(https://crbug.com/1229654): Implement. } +SmartBubbleStatsStore* PasswordStoreAndroidBackend::GetSmartBubbleStatsStore() { + return nullptr; +} + } // namespace password_manager
diff --git a/chrome/browser/password_manager/android/password_store_android_backend.h b/chrome/browser/password_manager/android/password_store_android_backend.h index 441062b..b5aebce 100644 --- a/chrome/browser/password_manager/android/password_store_android_backend.h +++ b/chrome/browser/password_manager/android/password_store_android_backend.h
@@ -58,6 +58,8 @@ void OnCompleteWithLogins(PasswordStoreAndroidBackendBridge::TaskId task_id, std::vector<PasswordForm> passwords) override; + SmartBubbleStatsStore* GetSmartBubbleStatsStore() override; + // Observer to propagate remote form changes to. RemoteChangesReceived remote_form_changes_received_;
diff --git a/chrome/browser/pdf/pdf_extension_interactive_uitest.cc b/chrome/browser/pdf/pdf_extension_interactive_uitest.cc new file mode 100644 index 0000000..3450f0a --- /dev/null +++ b/chrome/browser/pdf/pdf_extension_interactive_uitest.cc
@@ -0,0 +1,126 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/app/chrome_command_ids.h" +#include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/browser/pdf/pdf_extension_test_util.h" +#include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/browser/browser_plugin_guest_manager.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/hit_test_region_observer.h" +#include "content/public/test/test_utils.h" +#include "extensions/browser/api/extensions_api_client.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "testing/gmock/include/gmock/gmock.h" + +#if defined(TOOLKIT_VIEWS) && defined(USE_AURA) +#include "ui/events/base_event_utils.h" +#include "ui/events/event.h" +#include "ui/events/gesture_event_details.h" +#include "ui/events/types/event_type.h" +#include "ui/views/touchui/touch_selection_menu_views.h" +#include "ui/views/widget/any_widget_observer.h" +#endif // defined(TOOLKIT_VIEWS) && defined(USE_AURA) + +namespace { +using ::pdf_extension_test_util::ConvertPageCoordToScreenCoord; +using ::pdf_extension_test_util::EnsurePDFHasLoaded; +} // namespace + +class PDFExtensionInteractiveUITest : public extensions::ExtensionApiTest { + public: + ~PDFExtensionInteractiveUITest() override = default; + + void SetUpCommandLine(base::CommandLine* command_line) override { + content::IsolateAllSitesForTesting(command_line); + } + + void SetUpOnMainThread() override { + extensions::ExtensionApiTest::SetUpOnMainThread(); + host_resolver()->AddRule("*", "127.0.0.1"); + ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); + content::SetupCrossSiteRedirector(embedded_test_server()); + embedded_test_server()->StartAcceptingConnections(); + } + + void TearDownOnMainThread() override { + ASSERT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete()); + extensions::ExtensionApiTest::TearDownOnMainThread(); + } + + content::WebContents* LoadPdfGetGuestContents(const GURL& url) { + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + if (!EnsurePDFHasLoaded(GetActiveWebContents())) + return nullptr; + + content::WebContents* contents = GetActiveWebContents(); + content::BrowserPluginGuestManager* guest_manager = + contents->GetBrowserContext()->GetGuestManager(); + return guest_manager->GetFullPageGuest(contents); + } + + content::WebContents* GetActiveWebContents() { + return browser()->tab_strip_model()->GetActiveWebContents(); + } +}; + +#if defined(TOOLKIT_VIEWS) && defined(USE_AURA) +// On text selection, a touch selection menu should pop up. On clicking ellipsis +// icon on the menu, the context menu should open up. +IN_PROC_BROWSER_TEST_F(PDFExtensionInteractiveUITest, + ContextMenuOpensFromTouchSelectionMenu) { + const GURL url = embedded_test_server()->GetURL("/pdf/text_large.pdf"); + content::WebContents* const guest_contents = LoadPdfGetGuestContents(url); + ASSERT_TRUE(guest_contents); + content::WaitForHitTestData(guest_contents); + + views::NamedWidgetShownWaiter waiter(views::test::AnyWidgetTestPasskey{}, + "TouchSelectionMenuViews"); + gfx::Point screen_pos = + ConvertPageCoordToScreenCoord(guest_contents, {12, 12}); + content::SimulateTouchEventAt(GetActiveWebContents(), ui::ET_TOUCH_PRESSED, + screen_pos); + bool success = false; + ASSERT_TRUE(content::ExecuteScriptAndExtractBool( + GetActiveWebContents(), + "window.addEventListener('message', function(event) {" + " if (event.data.type == 'touchSelectionOccurred')" + " window.domAutomationController.send(true);" + "});", + &success)); + ASSERT_TRUE(success); + content::SimulateTouchEventAt(GetActiveWebContents(), ui::ET_TOUCH_RELEASED, + screen_pos); + views::Widget* widget = waiter.WaitIfNeededAndGet(); + ASSERT_TRUE(widget); + views::View* menu = widget->GetContentsView(); + ASSERT_TRUE(menu); + views::View* ellipsis_button = menu->GetViewByID( + views::TouchSelectionMenuViews::ButtonViewId::kEllipsisButton); + ASSERT_TRUE(ellipsis_button); + ContextMenuWaiter context_menu_observer; + ui::GestureEvent tap(0, 0, 0, ui::EventTimeForNow(), + ui::GestureEventDetails(ui::ET_GESTURE_TAP)); + ellipsis_button->OnGestureEvent(&tap); + context_menu_observer.WaitForMenuOpenAndClose(); + + // Verify that the expected context menu items are present. + // + // Note that the assertion below doesn't use exact matching via + // testing::ElementsAre, because some platforms may include unexpected extra + // elements (e.g. an extra separator and IDC=100 has been observed on some Mac + // bots). + EXPECT_THAT( + context_menu_observer.GetCapturedCommandIds(), + testing::IsSupersetOf( + {IDC_CONTENT_CONTEXT_COPY, IDC_CONTENT_CONTEXT_SEARCHWEBFOR, + IDC_PRINT, IDC_CONTENT_CONTEXT_ROTATECW, + IDC_CONTENT_CONTEXT_ROTATECCW, IDC_CONTENT_CONTEXT_INSPECTELEMENT})); +} +#endif // defined(TOOLKIT_VIEWS) && defined(USE_AURA)
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index c627bef..15617d0 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -126,15 +126,6 @@ #include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h" #endif -#if defined(TOOLKIT_VIEWS) && defined(USE_AURA) -#include "ui/events/base_event_utils.h" -#include "ui/events/event.h" -#include "ui/events/gesture_event_details.h" -#include "ui/events/types/event_type.h" -#include "ui/views/touchui/touch_selection_menu_views.h" -#include "ui/views/widget/any_widget_observer.h" -#endif // defined(TOOLKIT_VIEWS) && defined(USE_AURA) - using content::AXInspectFactory; using content::WebContents; using extensions::ExtensionsAPIClient; @@ -144,6 +135,9 @@ using ui::AXTreeFormatter; namespace { + +using ::pdf_extension_test_util::ConvertPageCoordToScreenCoord; + const int kNumberLoadTestParts = 10; // `base::test::WithFeatureOverride` for `chrome_pdf::features::kPdfUnseasoned`. @@ -204,9 +198,10 @@ return false; } -class PDFExtensionTest : public extensions::ExtensionApiTest { +class PDFExtensionTestWithoutUnseasonedOverride + : public extensions::ExtensionApiTest { public: - ~PDFExtensionTest() override {} + ~PDFExtensionTestWithoutUnseasonedOverride() override = default; void SetUpCommandLine(base::CommandLine* command_line) override { content::IsolateAllSitesForTesting(command_line); @@ -314,47 +309,6 @@ ASSERT_EQ(expect_success, success); } - void ConvertPageCoordToScreenCoord(WebContents* contents, gfx::Point* point) { - ASSERT_TRUE(contents); - ASSERT_TRUE(content::ExecuteScript( - contents, - "var visiblePage = viewer.viewport.getMostVisiblePage();" - "var visiblePageDimensions =" - " viewer.viewport.getPageScreenRect(visiblePage);" - "var viewportPosition = viewer.viewport.position;" - "var offsetParent = viewer.shadowRoot.querySelector('#container');" - "var scrollParent = viewer.shadowRoot.querySelector('#main');" - "var screenOffsetX = visiblePageDimensions.x - viewportPosition.x +" - " scrollParent.offsetLeft + offsetParent.offsetLeft;" - "var screenOffsetY = visiblePageDimensions.y - viewportPosition.y +" - " scrollParent.offsetTop + offsetParent.offsetTop;" - "var linkScreenPositionX =" - " Math.floor(" + - base::NumberToString(point->x()) + - " * viewer.viewport.internalZoom_" + - " + screenOffsetX);" - "var linkScreenPositionY =" - " Math.floor(" + - base::NumberToString(point->y()) + - " * viewer.viewport.internalZoom_" + - " +" - " screenOffsetY);")); - - int x; - ASSERT_TRUE(content::ExecuteScriptAndExtractInt( - contents, - "window.domAutomationController.send(linkScreenPositionX);", - &x)); - - int y; - ASSERT_TRUE(content::ExecuteScriptAndExtractInt( - contents, - "window.domAutomationController.send(linkScreenPositionY);", - &y)); - - point->SetPoint(x, y); - } - WebContents* GetActiveWebContents() { return browser()->tab_strip_model()->GetActiveWebContents(); } @@ -367,7 +321,8 @@ : content::GetIOThreadTaskRunner({}); task_runner->PostTaskAndReply( FROM_HERE, - base::BindOnce(&PDFExtensionTest::CountPDFProcessesOnProcessThread, + base::BindOnce(&PDFExtensionTestWithoutUnseasonedOverride:: + CountPDFProcessesOnProcessThread, base::Unretained(this), base::Unretained(&result)), run_loop.QuitClosure()); run_loop.Run(); @@ -406,11 +361,10 @@ base::test::ScopedFeatureList feature_list_; }; -class PDFExtensionTestWithUnseasonedOverride : public WithUnseasonedOverride, - public PDFExtensionTest {}; +class PDFExtensionTest : public WithUnseasonedOverride, + public PDFExtensionTestWithoutUnseasonedOverride {}; -class PDFExtensionTestWithTestGuestViewManager - : public PDFExtensionTestWithUnseasonedOverride { +class PDFExtensionTestWithTestGuestViewManager : public PDFExtensionTest { public: PDFExtensionTestWithTestGuestViewManager() { GuestViewManager::set_factory_for_testing(&factory_); @@ -610,14 +564,15 @@ } class PDFExtensionLoadTest - : public PDFExtensionTest, + : public PDFExtensionTestWithoutUnseasonedOverride, public testing::WithParamInterface<std::tuple<int, bool>> { protected: int part() const { return std::get<0>(GetParam()); } bool is_unseasoned() const { return std::get<1>(GetParam()); } std::vector<base::Feature> GetEnabledFeatures() const override { - std::vector<base::Feature> enabled = PDFExtensionTest::GetEnabledFeatures(); + std::vector<base::Feature> enabled = + PDFExtensionTestWithoutUnseasonedOverride::GetEnabledFeatures(); if (is_unseasoned()) enabled.push_back(chrome_pdf::features::kPdfUnseasoned); return enabled; @@ -625,7 +580,7 @@ std::vector<base::Feature> GetDisabledFeatures() const override { std::vector<base::Feature> disabled = - PDFExtensionTest::GetDisabledFeatures(); + PDFExtensionTestWithoutUnseasonedOverride::GetDisabledFeatures(); if (!is_unseasoned()) disabled.push_back(chrome_pdf::features::kPdfUnseasoned); return disabled; @@ -705,7 +660,7 @@ }; // Tests behavior when the PDF plugin is disabled in preferences. -class PDFPluginDisabledTest : public PDFExtensionTestWithUnseasonedOverride { +class PDFPluginDisabledTest : public PDFExtensionTest { protected: void SetUpCommandLine(base::CommandLine* command_line) override { PDFExtensionTest::SetUpCommandLine(command_line); @@ -851,7 +806,8 @@ ValidateSingleSuccessfulDownloadAndNoPDFPluginLaunch(); } -class PDFExtensionJSTestBase : public PDFExtensionTest { +class PDFExtensionJSTestBase + : public PDFExtensionTestWithoutUnseasonedOverride { public: ~PDFExtensionJSTestBase() override = default; @@ -1209,8 +1165,7 @@ // Ensure that the internal PDF plugin application/x-google-chrome-pdf won't be // loaded if it's not loaded in the chrome extension page. -IN_PROC_BROWSER_TEST_P(PDFExtensionTestWithUnseasonedOverride, - EnsureInternalPluginDisabled) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, EnsureInternalPluginDisabled) { std::string url = embedded_test_server()->GetURL("/pdf/test.pdf").spec(); std::string data_url = "data:text/html," @@ -1232,7 +1187,7 @@ } // Ensure cross-origin replies won't work for getSelectedText. -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, EnsureCrossOriginRepliesBlocked) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, EnsureCrossOriginRepliesBlocked) { std::string url = embedded_test_server()->GetURL("/pdf/test.pdf").spec(); std::string data_url = "data:text/html," @@ -1245,19 +1200,20 @@ } // Ensure same-origin replies do work for getSelectedText. -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, EnsureSameOriginRepliesAllowed) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, EnsureSameOriginRepliesAllowed) { TestGetSelectedTextReply(embedded_test_server()->GetURL("/pdf/test.pdf"), true); } // TODO(crbug.com/1004425): Should be allowed? -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, EnsureOpaqueOriginRepliesBlocked) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTestWithoutUnseasonedOverride, + EnsureOpaqueOriginRepliesBlocked) { TestGetSelectedTextReply( embedded_test_server()->GetURL("/pdf/data_url_rectangles.html"), false); } // Ensure that the PDF component extension cannot be loaded directly. -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, BlockDirectAccess) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, BlockDirectAccess) { WebContents* web_contents = GetActiveWebContents(); content::WebContentsConsoleObserver console_observer(web_contents); @@ -1275,7 +1231,8 @@ } // This test ensures that PDF can be loaded from local file -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, EnsurePDFFromLocalFileLoads) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTestWithoutUnseasonedOverride, + EnsurePDFFromLocalFileLoads) { GURL test_pdf_url; { base::ScopedAllowBlockingForTesting allow_blocking; @@ -1294,7 +1251,8 @@ } // Tests that PDF with no filename extension can be loaded from local file. -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, ExtensionlessPDFLocalFileLoads) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTestWithoutUnseasonedOverride, + ExtensionlessPDFLocalFileLoads) { GURL test_pdf_url; { base::ScopedAllowBlockingForTesting allow_blocking; @@ -1313,7 +1271,7 @@ } // This test ensures that link permissions are enforced properly in PDFs. -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, LinkPermissions) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, LinkPermissions) { GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test.pdf")); WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url); ASSERT_TRUE(guest_contents); @@ -1336,7 +1294,7 @@ } // This test ensures that titles are set properly for PDFs without /Title. -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, TabTitleWithNoTitle) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, TabTitleWithNoTitle) { GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test.pdf")); WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url); ASSERT_TRUE(guest_contents); @@ -1345,7 +1303,7 @@ } // This test ensures that titles are set properly for PDFs with /Title. -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, TabTitleWithTitle) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, TabTitleWithTitle) { GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-title.pdf")); WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url); ASSERT_TRUE(guest_contents); @@ -1354,7 +1312,7 @@ } // This test ensures that titles are set properly for embedded PDFs with /Title. -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, TabTitleWithEmbeddedPdf) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, TabTitleWithEmbeddedPdf) { std::string url = embedded_test_server()->GetURL("/pdf/test-title.pdf").spec(); std::string data_url = @@ -1373,7 +1331,7 @@ #else #define MAYBE_PdfZoomWithoutBubble PdfZoomWithoutBubble #endif -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, MAYBE_PdfZoomWithoutBubble) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, MAYBE_PdfZoomWithoutBubble) { GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test.pdf")); WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url); ASSERT_TRUE(guest_contents); @@ -1494,7 +1452,8 @@ " staticText '3'\n" " inlineTextBox '3'\n"; -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibility) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTestWithoutUnseasonedOverride, + PdfAccessibility) { content::BrowserAccessibilityState::GetInstance()->EnableAccessibility(); GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf")); @@ -1509,7 +1468,8 @@ ASSERT_MULTILINE_STR_MATCHES(kExpectedPDFAXTreePattern, ax_tree_dump); } -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityEnableLater) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTestWithoutUnseasonedOverride, + PdfAccessibilityEnableLater) { // In this test, load the PDF file first, with accessibility off. GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf")); WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url); @@ -1538,7 +1498,8 @@ #define MAYBE_PdfAccessibilityInIframe PdfAccessibilityInIframe #endif -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, MAYBE_PdfAccessibilityInIframe) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTestWithoutUnseasonedOverride, + MAYBE_PdfAccessibilityInIframe) { content::BrowserAccessibilityState::GetInstance()->EnableAccessibility(); GURL test_iframe_url(embedded_test_server()->GetURL("/pdf/test-iframe.html")); ui_test_utils::NavigateToURL(browser(), test_iframe_url); @@ -1558,7 +1519,8 @@ ASSERT_MULTILINE_STR_MATCHES(kExpectedPDFAXTreePattern, ax_tree_dump); } -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityInOOPIF) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTestWithoutUnseasonedOverride, + PdfAccessibilityInOOPIF) { content::BrowserAccessibilityState::GetInstance()->EnableAccessibility(); GURL test_iframe_url(embedded_test_server()->GetURL( "/pdf/test-cross-site-iframe.html")); @@ -1579,7 +1541,8 @@ ASSERT_MULTILINE_STR_MATCHES(kExpectedPDFAXTreePattern, ax_tree_dump); } -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityWordBoundaries) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTestWithoutUnseasonedOverride, + PdfAccessibilityWordBoundaries) { content::BrowserAccessibilityState::GetInstance()->EnableAccessibility(); GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf")); @@ -1612,7 +1575,8 @@ ASSERT_TRUE(found); } -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilitySelection) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTestWithoutUnseasonedOverride, + PdfAccessibilitySelection) { GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf")); WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url); ASSERT_TRUE(guest_contents); @@ -1659,7 +1623,8 @@ EXPECT_EQ(ax::mojom::Role::kRegion, region->data().role); } -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityContextMenuAction) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTestWithoutUnseasonedOverride, + PdfAccessibilityContextMenuAction) { // Validate the context menu arguments for PDF selection when context menu is // invoked via accessibility tree. const char kExepectedPDFSelection[] = @@ -1722,7 +1687,7 @@ #if BUILDFLAG(GOOGLE_CHROME_BRANDING) // Test a particular PDF encountered in the wild that triggered a crash // when accessibility is enabled. (http://crbug.com/668724) -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityTextRunCrash) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, PdfAccessibilityTextRunCrash) { content::BrowserAccessibilityState::GetInstance()->EnableAccessibility(); GURL test_pdf_url(embedded_test_server()->GetURL( "/pdf_private/accessibility_crash_2.pdf")); @@ -1736,7 +1701,7 @@ // Test that even if a different tab is selected when a navigation occurs, // the correct tab still gets navigated (see crbug.com/672563). -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, NavigationOnCorrectTab) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, NavigationOnCorrectTab) { GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test.pdf")); WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url); ASSERT_TRUE(guest_contents); @@ -1764,7 +1729,8 @@ EXPECT_FALSE(active_web_contents->GetController().GetPendingEntry()); } -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, MultipleDomains) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTestWithoutUnseasonedOverride, + MultipleDomains) { for (const std::string& domain : {"a.com", "b.com"}) { const GURL url = embedded_test_server()->GetURL(domain, "/pdf/test.pdf"); ASSERT_TRUE(LoadPdfInNewTab(url)); @@ -1772,7 +1738,8 @@ EXPECT_EQ(2, CountPDFProcesses()); } -class PDFExtensionLinkClickTest : public PDFExtensionTest { +class PDFExtensionLinkClickTest + : public PDFExtensionTestWithoutUnseasonedOverride { public: PDFExtensionLinkClickTest() : guest_contents_(nullptr) {} ~PDFExtensionLinkClickTest() override {} @@ -1795,9 +1762,7 @@ // This performs the [a] to [b] transformation, since that is the coordinate // space content::SimulateMouseClickAt() needs. gfx::Point GetLinkPosition() { - gfx::Point link_position(110, 110); - ConvertPageCoordToScreenCoord(guest_contents_, &link_position); - return link_position; + return ConvertPageCoordToScreenCoord(guest_contents_, {110, 110}); } void SetGuestContents(WebContents* guest_contents) { @@ -2020,7 +1985,8 @@ run_loop.Run(); } -class PDFExtensionInternalLinkClickTest : public PDFExtensionTest { +class PDFExtensionInternalLinkClickTest + : public PDFExtensionTestWithoutUnseasonedOverride { public: PDFExtensionInternalLinkClickTest() : guest_contents_(nullptr) {} ~PDFExtensionInternalLinkClickTest() override {} @@ -2035,9 +2001,7 @@ gfx::Point GetLinkPosition() { // The whole first page is a link. - gfx::Point link_position(100, 100); - ConvertPageCoordToScreenCoord(guest_contents_, &link_position); - return link_position; + return ConvertPageCoordToScreenCoord(guest_contents_, {100, 100}); } content::WebContents* GetWebContentsForInputRouting() { @@ -2123,20 +2087,21 @@ EXPECT_EQ("page=2&zoom=100,0,200", url.ref()); } -class PDFExtensionClipboardTest : public PDFExtensionTest, - public ui::ClipboardObserver { +class PDFExtensionClipboardTest + : public PDFExtensionTestWithoutUnseasonedOverride, + public ui::ClipboardObserver { public: PDFExtensionClipboardTest() : guest_contents_(nullptr) {} ~PDFExtensionClipboardTest() override {} // PDFExtensionTest: void SetUpOnMainThread() override { - PDFExtensionTest::SetUpOnMainThread(); + PDFExtensionTestWithoutUnseasonedOverride::SetUpOnMainThread(); ui::TestClipboard::CreateForCurrentThread(); } void TearDownOnMainThread() override { ui::Clipboard::DestroyClipboardForCurrentThread(); - PDFExtensionTest::TearDownOnMainThread(); + PDFExtensionTestWithoutUnseasonedOverride::TearDownOnMainThread(); } // ui::ClipboardObserver: @@ -2161,9 +2126,7 @@ // space coordinates. See PDFExtensionLinkClickTest::GetLinkPosition() for // more information on all the coordinate systems involved. gfx::Point GetEditableComboBoxLeftPosition() { - gfx::Point position(136, 318); - ConvertPageCoordToScreenCoord(guest_contents_, &position); - return position; + return ConvertPageCoordToScreenCoord(guest_contents_, {136, 318}); } void ClickLeftSideOfEditableComboBox() { @@ -2407,7 +2370,7 @@ // message to the <embed> is correctly forwarded to the extension. This is for // catching future regression in docs/ and slides/ pages (see // https://crbug.com/763812). -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PostMessageForZeroSizedEmbed) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, PostMessageForZeroSizedEmbed) { content::DOMMessageQueue queue; GURL url(embedded_test_server()->GetURL( "/pdf/post_message_zero_sized_embed.html")); @@ -2462,7 +2425,7 @@ } // Ensure that touchpad pinch events are handled by the PDF viewer. -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, TouchpadPinchInvokesCustomZoom) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, TouchpadPinchInvokesCustomZoom) { GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test.pdf")); WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url); ASSERT_TRUE(guest_contents); @@ -2484,7 +2447,7 @@ #if !defined(OS_MAC) // Ensure that ctrl-wheel events are handled by the PDF viewer. -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, CtrlWheelInvokesCustomZoom) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, CtrlWheelInvokesCustomZoom) { GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test.pdf")); WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url); ASSERT_TRUE(guest_contents); @@ -2512,7 +2475,7 @@ #define MAYBE_TouchscreenPinchInvokesCustomZoom \ TouchscreenPinchInvokesCustomZoom #endif -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, +IN_PROC_BROWSER_TEST_F(PDFExtensionTestWithoutUnseasonedOverride, MAYBE_TouchscreenPinchInvokesCustomZoom) { GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test.pdf")); WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url); @@ -2536,7 +2499,7 @@ #endif // !defined(OS_MAC) -using PDFExtensionHitTestTest = PDFExtensionTest; +using PDFExtensionHitTestTest = PDFExtensionTestWithoutUnseasonedOverride; // Flaky in nearly all configurations; see https://crbug.com/856169. IN_PROC_BROWSER_TEST_F(PDFExtensionHitTestTest, DISABLED_MouseLeave) { @@ -2644,64 +2607,9 @@ // UntrustworthyContextMenuParams. } -#if defined(TOOLKIT_VIEWS) && defined(USE_AURA) -// On text selection, a touch selection menu should pop up. On clicking ellipsis -// icon on the menu, the context menu should open up. -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, - ContextMenuOpensFromTouchSelectionMenu) { - const GURL url = embedded_test_server()->GetURL("/pdf/text_large.pdf"); - WebContents* const guest_contents = LoadPdfGetGuestContents(url); - ASSERT_TRUE(guest_contents); - content::WaitForHitTestData(guest_contents); - - views::NamedWidgetShownWaiter waiter(views::test::AnyWidgetTestPasskey{}, - "TouchSelectionMenuViews"); - gfx::Point text_selection_position(12, 12); - ConvertPageCoordToScreenCoord(guest_contents, &text_selection_position); - content::SimulateTouchEventAt(GetActiveWebContents(), ui::ET_TOUCH_PRESSED, - text_selection_position); - bool success = false; - ASSERT_TRUE(content::ExecuteScriptAndExtractBool( - GetActiveWebContents(), - "window.addEventListener('message', function(event) {" - " if (event.data.type == 'touchSelectionOccurred')" - " window.domAutomationController.send(true);" - "});", - &success)); - ASSERT_TRUE(success); - content::SimulateTouchEventAt(GetActiveWebContents(), ui::ET_TOUCH_RELEASED, - text_selection_position); - views::Widget* widget = waiter.WaitIfNeededAndGet(); - ASSERT_TRUE(widget); - views::View* menu = widget->GetContentsView(); - ASSERT_TRUE(menu); - views::View* ellipsis_button = menu->GetViewByID( - views::TouchSelectionMenuViews::ButtonViewId::kEllipsisButton); - ASSERT_TRUE(ellipsis_button); - ContextMenuWaiter context_menu_observer; - ui::GestureEvent tap(0, 0, 0, ui::EventTimeForNow(), - ui::GestureEventDetails(ui::ET_GESTURE_TAP)); - ellipsis_button->OnGestureEvent(&tap); - context_menu_observer.WaitForMenuOpenAndClose(); - - // Verify that the expected context menu items are present. - // - // Note that the assertion below doesn't use exact matching via - // testing::ElementsAre, because some platforms may include unexpected extra - // elements (e.g. an extra separator and IDC=100 has been observed on some Mac - // bots). - EXPECT_THAT( - context_menu_observer.GetCapturedCommandIds(), - testing::IsSupersetOf( - {IDC_CONTENT_CONTEXT_COPY, IDC_CONTENT_CONTEXT_SEARCHWEBFOR, - IDC_PRINT, IDC_CONTENT_CONTEXT_ROTATECW, - IDC_CONTENT_CONTEXT_ROTATECCW, IDC_CONTENT_CONTEXT_INSPECTELEMENT})); -} -#endif // defined(TOOLKIT_VIEWS) && defined(USE_AURA) - // The plugin document and the mime handler should both use the same background // color. -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, BackgroundColor) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, BackgroundColor) { // The background color for plugins is injected when the first response // is intercepted, at which point not all the plugins have loaded. This line // ensures that the PDF plugin has loaded and the right background color is @@ -2723,7 +2631,7 @@ EXPECT_EQ(inner, outer); } -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, DefaultFocusForEmbeddedPDF) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, DefaultFocusForEmbeddedPDF) { GURL url = embedded_test_server()->GetURL("/pdf/pdf_embed.html"); // Load page with embedded PDF and make sure it succeeds. @@ -2749,7 +2657,7 @@ ASSERT_TRUE(result); } -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, DefaultFocusForNonEmbeddedPDF) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, DefaultFocusForNonEmbeddedPDF) { GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test.pdf")); WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url); ASSERT_TRUE(guest_contents); @@ -2818,7 +2726,7 @@ // This is a regression test for a problem where DidStopLoading didn't get // propagated from a remote frame into the main frame. See also // https://crbug.com/964364. -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, DidStopLoading) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, DidStopLoading) { // Prepare to wait for requests for the main page of the MimeHandlerView for // PDFs. RequestWaiter interceptor( @@ -2858,7 +2766,7 @@ // This test verifies that it is possible to add an <embed src=pdf> element into // a new popup window when using document.write. See also // https://crbug.com/1041880. -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, DocumentWriteIntoNewPopup) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, DocumentWriteIntoNewPopup) { // Navigate to an empty/boring test page. GURL main_url(embedded_test_server()->GetURL("/title1.html")); ui_test_utils::NavigateToURL(browser(), main_url); @@ -2889,7 +2797,7 @@ // Tests that the PDF extension loads in the presence of an extension that, on // the completion of document loading, adds an <iframe> to the body element. // https://bugs.chromium.org/p/chromium/issues/detail?id=1046795 -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, PdfLoadsWithExtensionThatInjectsFrame) { // Load the test extension. const extensions::Extension* test_extension = LoadExtension( @@ -2902,7 +2810,7 @@ ASSERT_TRUE(LoadPdf(test_pdf_url)); } -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, Metrics) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTestWithoutUnseasonedOverride, Metrics) { base::HistogramTester histograms; base::UserActionTester actions; @@ -2929,7 +2837,7 @@ } // Flaky. See https://crbug.com/1101514. -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, DISABLED_TabInAndOutOfPDFPlugin) { +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, DISABLED_TabInAndOutOfPDFPlugin) { GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test.pdf")); content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url); ASSERT_TRUE(guest_contents); @@ -2979,7 +2887,8 @@ // internals, breaking lines & paragraphs where appropriate. Unlike // TreeDumpTests, this allows us to verify the kNextOnLine and kPreviousOnLine // relationships. -class PDFExtensionAccessibilityTextExtractionTest : public PDFExtensionTest { +class PDFExtensionAccessibilityTextExtractionTest + : public PDFExtensionTestWithoutUnseasonedOverride { public: PDFExtensionAccessibilityTextExtractionTest() = default; ~PDFExtensionAccessibilityTextExtractionTest() override = default; @@ -2999,7 +2908,8 @@ protected: std::vector<base::Feature> GetEnabledFeatures() const override { - std::vector<base::Feature> enabled = PDFExtensionTest::GetEnabledFeatures(); + std::vector<base::Feature> enabled = + PDFExtensionTestWithoutUnseasonedOverride::GetEnabledFeatures(); enabled.push_back(chrome_pdf::features::kAccessiblePDFForm); return enabled; } @@ -3191,14 +3101,14 @@ using AXInspectType = AXInspectFactory::Type; class PDFExtensionAccessibilityTreeDumpTest - : public PDFExtensionTest, + : public PDFExtensionTestWithoutUnseasonedOverride, public ::testing::WithParamInterface<AXInspectType> { public: PDFExtensionAccessibilityTreeDumpTest() : test_helper_(GetParam()) {} ~PDFExtensionAccessibilityTreeDumpTest() override = default; void SetUpCommandLine(base::CommandLine* command_line) override { - PDFExtensionTest::SetUpCommandLine(command_line); + PDFExtensionTestWithoutUnseasonedOverride::SetUpCommandLine(command_line); // Each test pass might require custom command-line setup test_helper_.SetUpCommandLine(command_line); @@ -3423,7 +3333,8 @@ } // This test suite validates the navigation done using the accessibility client. -using PDFExtensionAccessibilityNavigationTest = PDFExtensionTest; +using PDFExtensionAccessibilityNavigationTest = + PDFExtensionTestWithoutUnseasonedOverride; IN_PROC_BROWSER_TEST_F(PDFExtensionAccessibilityNavigationTest, LinkNavigation) { @@ -3457,8 +3368,7 @@ EXPECT_EQ("https://bing.com/", expected_url.spec()); } -class PDFExtensionPrerenderTest - : public PDFExtensionTestWithUnseasonedOverride { +class PDFExtensionPrerenderTest : public PDFExtensionTest { public: void SetUpCommandLine(base::CommandLine* command_line) override { PDFExtensionTest::SetUpCommandLine(command_line); @@ -3508,7 +3418,7 @@ } // TODO(crbug.com/702993): Stop testing both modes after unseasoned launches. -INSTANTIATE_FEATURE_OVERRIDE_TEST_SUITE(PDFExtensionTestWithUnseasonedOverride); +INSTANTIATE_FEATURE_OVERRIDE_TEST_SUITE(PDFExtensionTest); INSTANTIATE_FEATURE_OVERRIDE_TEST_SUITE( PDFExtensionTestWithTestGuestViewManager); INSTANTIATE_FEATURE_OVERRIDE_TEST_SUITE(PDFPluginDisabledTest);
diff --git a/chrome/browser/pdf/pdf_extension_test_util.cc b/chrome/browser/pdf/pdf_extension_test_util.cc index af966a9..435cebd 100644 --- a/chrome/browser/pdf/pdf_extension_test_util.cc +++ b/chrome/browser/pdf/pdf_extension_test_util.cc
@@ -14,20 +14,20 @@ bool load_success = false; if (!content::ExecuteScriptAndExtractBool( frame, - "window.addEventListener('message', event => {" - " if (event.origin !==" - " 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai') {" - " return;" - " }" - " if (event.data.type === 'documentLoaded') {" - " window.domAutomationController.send(" - " event.data.load_state === 'success');" - " } else if (event.data.type === 'passwordPrompted') {" - " window.domAutomationController.send(true);" - " }" - "});" - "document.getElementsByTagName('embed')[0].postMessage(" - " {type: 'initialize'});", + R"(window.addEventListener('message', event => { + if (event.origin !== + 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai') { + return; + } + if (event.data.type === 'documentLoaded') { + window.domAutomationController.send( + event.data.load_state === 'success'); + } else if (event.data.type === 'passwordPrompted') { + window.domAutomationController.send(true); + } + }); + document.getElementsByTagName('embed')[0].postMessage( + {type: 'initialize'});)", &load_success)) { return testing::AssertionFailure() << "Cannot communicate with PDF extension."; @@ -36,4 +36,56 @@ : (testing::AssertionFailure() << "Load failed."); } +gfx::Point ConvertPageCoordToScreenCoord(content::WebContents* contents, + const gfx::Point& point) { + if (!contents) { + ADD_FAILURE() << "contents needs to be non-null"; + return point; + } + if (!content::ExecuteScript( + contents, + "var visiblePage = viewer.viewport.getMostVisiblePage();" + "var visiblePageDimensions =" + " viewer.viewport.getPageScreenRect(visiblePage);" + "var viewportPosition = viewer.viewport.position;" + "var offsetParent = viewer.shadowRoot.querySelector('#container');" + "var scrollParent = viewer.shadowRoot.querySelector('#main');" + "var screenOffsetX = visiblePageDimensions.x - viewportPosition.x +" + " scrollParent.offsetLeft + offsetParent.offsetLeft;" + "var screenOffsetY = visiblePageDimensions.y - viewportPosition.y +" + " scrollParent.offsetTop + offsetParent.offsetTop;" + "var linkScreenPositionX =" + " Math.floor(" + + base::NumberToString(point.x()) + + " * viewer.viewport.internalZoom_" + + " + screenOffsetX);" + "var linkScreenPositionY =" + " Math.floor(" + + base::NumberToString(point.y()) + + " * viewer.viewport.internalZoom_" + + " +" + " screenOffsetY);")) { + ADD_FAILURE() << "Error executing script"; + return point; + } + + int x; + if (!content::ExecuteScriptAndExtractInt( + contents, "window.domAutomationController.send(linkScreenPositionX);", + &x)) { + ADD_FAILURE() << "error getting linkScreenPositionX"; + return point; + } + + int y; + if (!content::ExecuteScriptAndExtractInt( + contents, "window.domAutomationController.send(linkScreenPositionY);", + &y)) { + ADD_FAILURE() << "error getting linkScreenPositionY"; + return point; + } + + return {x, y}; +} + } // namespace pdf_extension_test_util
diff --git a/chrome/browser/pdf/pdf_extension_test_util.h b/chrome/browser/pdf/pdf_extension_test_util.h index a397deb..b53171d 100644 --- a/chrome/browser/pdf/pdf_extension_test_util.h +++ b/chrome/browser/pdf/pdf_extension_test_util.h
@@ -10,8 +10,13 @@ namespace content { class ToRenderFrameHost; +class WebContents; } // namespace content +namespace gfx { +class Point; +} // namespace gfx + namespace pdf_extension_test_util { // Ensures, inside the given `frame`, that a PDF has either finished @@ -21,6 +26,9 @@ testing::AssertionResult EnsurePDFHasLoaded( const content::ToRenderFrameHost& frame) WARN_UNUSED_RESULT; +gfx::Point ConvertPageCoordToScreenCoord(content::WebContents* contents, + const gfx::Point& point); + } // namespace pdf_extension_test_util #endif // CHROME_BROWSER_PDF_PDF_EXTENSION_TEST_UTIL_H_
diff --git a/chrome/browser/policy/chrome_browser_policy_connector.cc b/chrome/browser/policy/chrome_browser_policy_connector.cc index ffb3c1b..42f884b 100644 --- a/chrome/browser/policy/chrome_browser_policy_connector.cc +++ b/chrome/browser/policy/chrome_browser_policy_connector.cc
@@ -31,6 +31,7 @@ #include "components/policy/core/common/configuration_policy_provider.h" #include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_namespace.h" +#include "components/policy/core/common/policy_proto_decoders.h" #include "components/policy/core/common/policy_types.h" #include "components/policy/policy_constants.h" #include "content/public/common/content_switches.h" @@ -258,7 +259,8 @@ #elif BUILDFLAG(IS_CHROMEOS_LACROS) auto loader = std::make_unique<PolicyLoaderLacros>( base::ThreadPool::CreateSequencedTaskRunner( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT})); + {base::MayBlock(), base::TaskPriority::BEST_EFFORT}), + PolicyPerProfileFilter::kFalse); return std::make_unique<AsyncPolicyProvider>(GetSchemaRegistry(), std::move(loader)); #elif defined(OS_POSIX) && !defined(OS_ANDROID)
diff --git a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc index 4e7e1d39..df5fa95 100644 --- a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc +++ b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
@@ -25,6 +25,7 @@ #include "chrome/browser/policy/cloud/cloud_policy_test_utils.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" @@ -221,16 +222,26 @@ browser()->profile()->GetUserCloudPolicyManagerChromeOS(); ASSERT_TRUE(policy_manager); #else +#if BUILDFLAG(IS_CHROMEOS_LACROS) + base::FilePath dest_path = + g_browser_process->profile_manager()->user_data_dir(); + profile_ = Profile::CreateProfile( + dest_path.Append(FILE_PATH_LITERAL("New Profile 1")), nullptr, + Profile::CreateMode::CREATE_MODE_SYNCHRONOUS); + Profile* profile = profile_.get(); +#else + Profile* profile = browser()->profile(); +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + // Mock a signed-in user. This is used by the UserCloudPolicyStore to pass // the username to the UserCloudPolicyValidator. - auto* identity_manager = - IdentityManagerFactory::GetForProfile(browser()->profile()); + auto* identity_manager = IdentityManagerFactory::GetForProfile(profile); ASSERT_TRUE(identity_manager); signin::SetPrimaryAccount(identity_manager, GetTestUser(), signin::ConsentLevel::kSync); UserCloudPolicyManager* policy_manager = - browser()->profile()->GetUserCloudPolicyManager(); + profile->GetUserCloudPolicyManager(); ASSERT_TRUE(policy_manager); policy_manager->Connect( g_browser_process->local_state(), @@ -296,9 +307,23 @@ #endif } + void TearDownOnMainThread() override { +#if BUILDFLAG(IS_CHROMEOS_LACROS) + profile_.reset(); +#endif + } + + Profile* profile() { +#if BUILDFLAG(IS_CHROMEOS_LACROS) + return profile_.get(); +#else + return browser()->profile(); +#endif + } + PolicyService* GetPolicyService() { ProfilePolicyConnector* profile_connector = - browser()->profile()->GetProfilePolicyConnector(); + profile()->GetProfilePolicyConnector(); return profile_connector->policy_service(); } @@ -307,7 +332,7 @@ return static_cast<invalidation::FakeInvalidationService*>( static_cast<invalidation::ProfileInvalidationProvider*>( invalidation::ProfileInvalidationProviderFactory::GetInstance() - ->GetForProfile(browser()->profile())) + ->GetForProfile(profile())) ->GetInvalidationServiceForCustomSender(sender_id)); } @@ -334,6 +359,10 @@ std::unique_ptr<LocalPolicyTestServer> test_server_; base::FilePath user_policy_key_file_; base::OnceClosure on_policy_updated_; +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // For Lacros use non-main profile in these tests. + std::unique_ptr<Profile> profile_; +#endif }; // crbug.com/1224925 flaky on Win. @@ -393,7 +422,8 @@ #endif // crbug.com/1224925 flaky on Win. -#if defined(OS_WIN) +// crbug.com/1230268 not working on Lacros. +#if defined(OS_WIN) || BUILDFLAG(IS_CHROMEOS_LACROS) #define MAYBE_InvalidatePolicy DISABLED_InvalidatePolicy #else #define MAYBE_InvalidatePolicy InvalidatePolicy
diff --git a/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc b/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc index 575b882..675384c 100644 --- a/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc +++ b/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/policy/chrome_browser_policy_connector.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" #include "chrome/test/base/chrome_test_utils.h" #include "components/policy/core/browser/browser_policy_connector.h" #include "components/policy/core/common/cloud/cloud_policy_client.h" @@ -168,6 +169,14 @@ test_url_loader_factory_ = std::make_unique<network::TestURLLoaderFactory>(); +#if BUILDFLAG(IS_CHROMEOS_LACROS) + base::FilePath dest_path = + g_browser_process->profile_manager()->user_data_dir(); + profile_ = Profile::CreateProfile( + dest_path.Append(FILE_PATH_LITERAL("New Profile 1")), nullptr, + Profile::CreateMode::CREATE_MODE_SYNCHRONOUS); +#endif + BrowserPolicyConnector* connector = g_browser_process->browser_policy_connector(); connector->ScheduleServiceInitialization(0); @@ -195,6 +204,9 @@ // Verify that all the expected requests were handled. EXPECT_EQ(0, test_url_loader_factory_->NumPending()); identity_test_env_.reset(); +#if BUILDFLAG(IS_CHROMEOS_LACROS) + profile_.reset(); +#endif } #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -202,6 +214,10 @@ return chrome_test_utils::GetProfile(this) ->GetUserCloudPolicyManagerChromeOS(); } +#elif BUILDFLAG(IS_CHROMEOS_LACROS) + UserCloudPolicyManager* policy_manager() { + return profile_->GetUserCloudPolicyManager(); + } #else UserCloudPolicyManager* policy_manager() { return chrome_test_utils::GetProfile(this)->GetUserCloudPolicyManager(); @@ -243,6 +259,10 @@ std::unique_ptr<signin::IdentityTestEnvironment> identity_test_env_; std::unique_ptr<network::TestURLLoaderFactory> test_url_loader_factory_; +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // For Lacros use non-main profile in these tests. + std::unique_ptr<Profile> profile_; +#endif }; IN_PROC_BROWSER_TEST_F(CloudPolicyManagerTest, Register) {
diff --git a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc index 89c0608..1200e79 100644 --- a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc +++ b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
@@ -244,7 +244,8 @@ }; // crbug.com/1224925 flaky on Win. -#if defined(OS_WIN) +// crbug.com/1230268 not working on Lacros. +#if defined(OS_WIN) || BUILDFLAG(IS_CHROMEOS_LACROS) #define MAYBE_FetchExtensionPolicy DISABLED_FetchExtensionPolicy #else #define MAYBE_FetchExtensionPolicy FetchExtensionPolicy @@ -257,7 +258,8 @@ } // crbug.com/1224925 flaky on Win. -#if defined(OS_WIN) +// crbug.com/1230268 not working on Lacros. +#if defined(OS_WIN) || BUILDFLAG(IS_CHROMEOS_LACROS) #define MAYBE_UpdateExtensionPolicy DISABLED_UpdateExtensionPolicy #else #define MAYBE_UpdateExtensionPolicy UpdateExtensionPolicy @@ -291,7 +293,8 @@ } // crbug.com/1224925 flaky on Win. -#if defined(OS_WIN) +// crbug.com/1230268 not working on Lacros. +#if defined(OS_WIN) || BUILDFLAG(IS_CHROMEOS_LACROS) #define MAYBE_InstallNewExtension DISABLED_InstallNewExtension #else #define MAYBE_InstallNewExtension InstallNewExtension @@ -370,6 +373,7 @@ // Verify that the policy is fetched again if the user signs back in. ExtensionTestMessageListener event_listener2("event", true); + SignInAndRegister(); EXPECT_TRUE(event_listener2.WaitUntilSatisfied()); @@ -406,7 +410,8 @@ }; // crbug.com/1224925 flaky on Win. -#if defined(OS_WIN) +// crbug.com/1230268 not working on Lacros. +#if defined(OS_WIN) || BUILDFLAG(IS_CHROMEOS_LACROS) #define MAYBE_Basic DISABLED_Basic #else #define MAYBE_Basic Basic
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_browsertest.cc b/chrome/browser/policy/cloud/user_policy_signin_service_browsertest.cc index ae222fd8..baae0b3 100644 --- a/chrome/browser/policy/cloud/user_policy_signin_service_browsertest.cc +++ b/chrome/browser/policy/cloud/user_policy_signin_service_browsertest.cc
@@ -496,7 +496,8 @@ }; // TODO(https://crbug.com/1226762): flaky -#if defined(OS_WIN) +// crbug.com/1230268 not working on Lacros. +#if defined(OS_WIN) || BUILDFLAG(IS_CHROMEOS_LACROS) #define MAYBE_AcceptManagementDeclineSync DISABLED_AcceptManagementDeclineSync #else #define MAYBE_AcceptManagementDeclineSync AcceptManagementDeclineSync
diff --git a/chrome/browser/policy/profile_policy_connector_builder.cc b/chrome/browser/policy/profile_policy_connector_builder.cc index c05cec9..b7969531 100644 --- a/chrome/browser/policy/profile_policy_connector_builder.cc +++ b/chrome/browser/policy/profile_policy_connector_builder.cc
@@ -39,11 +39,11 @@ CreateProfilePolicyConnectorForBrowserContext( SchemaRegistry* schema_registry, UserCloudPolicyManager* user_cloud_policy_manager, + ConfigurationPolicyProvider* policy_provider, policy::ChromeBrowserPolicyConnector* browser_policy_connector, bool force_immediate_load, content::BrowserContext* context) { const user_manager::User* user = nullptr; - ConfigurationPolicyProvider* policy_provider = nullptr; const CloudPolicyStore* policy_store = nullptr; #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -62,15 +62,12 @@ ActiveDirectoryPolicyManager* active_directory_manager = profile->GetActiveDirectoryPolicyManager(); if (cloud_policy_manager) { - policy_provider = cloud_policy_manager; policy_store = cloud_policy_manager->core()->store(); } else if (active_directory_manager) { - policy_provider = active_directory_manager; policy_store = active_directory_manager->store(); } #else if (user_cloud_policy_manager) { - policy_provider = user_cloud_policy_manager; policy_store = user_cloud_policy_manager->core()->store(); } #endif // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/policy/profile_policy_connector_builder.h b/chrome/browser/policy/profile_policy_connector_builder.h index e8230e7..4891890 100644 --- a/chrome/browser/policy/profile_policy_connector_builder.h +++ b/chrome/browser/policy/profile_policy_connector_builder.h
@@ -29,6 +29,7 @@ CreateProfilePolicyConnectorForBrowserContext( SchemaRegistry* schema_registry, UserCloudPolicyManager* user_cloud_policy_manager, + ConfigurationPolicyProvider* user_policy_provider, policy::ChromeBrowserPolicyConnector* browser_policy_connector, bool force_immediate_load, content::BrowserContext* context);
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 0ea8b6ca..10bcdf6 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -1278,7 +1278,7 @@ ash::quick_unlock::RegisterProfilePrefs(registry); ash::RegisterSamlProfilePrefs(registry); ash::ScreenTimeController::RegisterProfilePrefs(registry); - SecondaryAccountConsentLogger::RegisterPrefs(registry); + ash::SecondaryAccountConsentLogger::RegisterPrefs(registry); ash::EduCoexistenceConsentInvalidationController::RegisterProfilePrefs( registry); ash::SigninErrorNotifier::RegisterPrefs(registry);
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 76c4187a..81724e8 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc
@@ -241,6 +241,9 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chromeos/crosapi/mojom/crosapi.mojom.h" #include "chromeos/lacros/lacros_service.h" +#include "components/policy/core/common/async_policy_provider.h" +#include "components/policy/core/common/policy_loader_lacros.h" +#include "components/policy/core/common/policy_proto_decoders.h" #include "components/signin/public/base/signin_switches.h" #endif @@ -586,6 +589,7 @@ bool force_immediate_policy_load = !async_prefs; policy::UserCloudPolicyManager* user_cloud_policy_manager; + policy::ConfigurationPolicyProvider* policy_provider; #if BUILDFLAG(IS_CHROMEOS_ASH) if (force_immediate_policy_load) ash::DeviceSettingsService::Get()->LoadImmediately(); @@ -595,16 +599,34 @@ &user_cloud_policy_manager_chromeos_, &active_directory_policy_manager_); user_cloud_policy_manager = nullptr; -#else - user_cloud_policy_manager_ = CreateUserCloudPolicyManager( - GetPath(), GetPolicySchemaRegistryService()->registry(), - force_immediate_policy_load, io_task_runner_); - user_cloud_policy_manager = user_cloud_policy_manager_.get(); + policy_provider = GetUserCloudPolicyManagerChromeOS(); + if (!policy_provider) { + policy_provider = GetActiveDirectoryPolicyManager(); + } +#else // !BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_LACROS) + if (IsMainProfile()) { + auto loader = std::make_unique<policy::PolicyLoaderLacros>( + io_task_runner_, policy::PolicyPerProfileFilter::kTrue); + user_policy_provider_ = std::make_unique<policy::AsyncPolicyProvider>( + schema_registry_service_->registry(), std::move(loader)); + user_policy_provider_->Init(schema_registry_service_->registry()); + policy_provider = user_policy_provider_.get(); + user_cloud_policy_manager = nullptr; + } else +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + { + user_cloud_policy_manager_ = CreateUserCloudPolicyManager( + GetPath(), GetPolicySchemaRegistryService()->registry(), + force_immediate_policy_load, io_task_runner_); + user_cloud_policy_manager = user_cloud_policy_manager_.get(); + policy_provider = user_cloud_policy_manager; + } #endif profile_policy_connector_ = policy::CreateProfilePolicyConnectorForBrowserContext( schema_registry_service_->registry(), user_cloud_policy_manager, - g_browser_process->browser_policy_connector(), + policy_provider, g_browser_process->browser_policy_connector(), force_immediate_policy_load, this); bool is_signin_profile = false; @@ -1198,7 +1220,11 @@ if (active_directory_policy_manager_) return active_directory_policy_manager_.get(); return nullptr; -#else +#else // !BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_LACROS) + if (user_policy_provider_) + return user_policy_provider_.get(); +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) return user_cloud_policy_manager_.get(); #endif }
diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h index d6971cd9..59ae8bb 100644 --- a/chrome/browser/profiles/profile_impl.h +++ b/chrome/browser/profiles/profile_impl.h
@@ -51,6 +51,7 @@ } namespace policy { +class AsyncPolicyProvider; class ConfigurationPolicyProvider; class ProfilePolicyConnector; } // namespace policy @@ -270,6 +271,9 @@ #else std::unique_ptr<policy::UserCloudPolicyManager> user_cloud_policy_manager_; #endif +#if BUILDFLAG(IS_CHROMEOS_LACROS) + std::unique_ptr<policy::AsyncPolicyProvider> user_policy_provider_; +#endif std::unique_ptr<policy::ProfilePolicyConnector> profile_policy_connector_;
diff --git a/chrome/browser/resources/chromeos/login/components/display_manager_types.js b/chrome/browser/resources/chromeos/login/components/display_manager_types.js index af000e9..b32e9c4d 100644 --- a/chrome/browser/resources/chromeos/login/components/display_manager_types.js +++ b/chrome/browser/resources/chromeos/login/components/display_manager_types.js
@@ -53,6 +53,7 @@ KIOSK: 11, MIGRATION: 12, USER_CREATION: 15, + ENROLLMENT_CANCEL_ENABLED: 16, }; /**
diff --git a/chrome/browser/resources/chromeos/login/enterprise_enrollment.html b/chrome/browser/resources/chromeos/login/enterprise_enrollment.html index c521226..56244bf 100644 --- a/chrome/browser/resources/chromeos/login/enterprise_enrollment.html +++ b/chrome/browser/resources/chromeos/login/enterprise_enrollment.html
@@ -59,6 +59,7 @@ on-backcancel="cancel" on-closesaml="cancel" on-identifierentered="onIdentifierEnteredMessage_" + hide-back-button-if-cant-go-back on-ready="onReady"> </gaia-dialog>
diff --git a/chrome/browser/resources/chromeos/login/enterprise_enrollment.js b/chrome/browser/resources/chromeos/login/enterprise_enrollment.js index a412ffb7..0fcfad2 100644 --- a/chrome/browser/resources/chromeos/login/enterprise_enrollment.js +++ b/chrome/browser/resources/chromeos/login/enterprise_enrollment.js
@@ -295,10 +295,8 @@ 'flow' in data ? (data.flow == 'enterpriseLicense') : false; cr.ui.login.invokePolymerMethod(this.$["step-ad-join"], 'onBeforeShow'); - if (!this.uiStep) { - this.showStep(this.isAutoEnroll_ ? - ENROLLMENT_STEP.WORKING : ENROLLMENT_STEP.SIGNIN); - } + this.showStep( + this.isAutoEnroll_ ? ENROLLMENT_STEP.WORKING : ENROLLMENT_STEP.SIGNIN); }, /** @@ -359,6 +357,7 @@ * Switches between the different steps in the enrollment flow. * @param {string} step the steps to show, one of "signin", "working", * "attribute-prompt", "error", "success". + * @suppress {missingProperties} setOobeUIState() exists */ showStep(step) { this.setUIStep(step); @@ -369,7 +368,14 @@ } this.isCancelDisabled = (step === ENROLLMENT_STEP.SIGNIN && !this.isManualEnrollment_) || - step === ENROLLMENT_STEP.AD_JOIN || step === ENROLLMENT_STEP.WORKING; + step === ENROLLMENT_STEP.AD_JOIN || step === ENROLLMENT_STEP.WORKING || + step === ENROLLMENT_STEP.CHECKING || step === ENROLLMENT_STEP.SUCCESS; + if (this.isCancelDisabled) { + Oobe.getInstance().setOobeUIState(OOBE_UI_STATE.ENROLLMENT); + } else { + Oobe.getInstance().setOobeUIState( + OOBE_UI_STATE.ENROLLMENT_CANCEL_ENABLED); + } }, doReload() {
diff --git a/chrome/browser/resources/chromeos/login/gaia_dialog.html b/chrome/browser/resources/chromeos/login/gaia_dialog.html index fd03ef0..10a0cd3a 100644 --- a/chrome/browser/resources/chromeos/login/gaia_dialog.html +++ b/chrome/browser/resources/chromeos/login/gaia_dialog.html
@@ -148,10 +148,11 @@ <webview id="signin-frame" class="flex" name="[[webviewName]]"> </webview> </div> - <div slot="back-navigation"> + <div slot="back-navigation" hidden$="[[navigationHidden]]"> <oobe-back-button id="signin-back-button" disabled="[[!navigationEnabled]]" - hidden$="[[navigationHidden]]" + hidden="[[isBackButtonHidden(hideBackButtonIfCantGoBack, + canGoBack)]]" on-click="onBackButtonClicked_"> </oobe-back-button> </div>
diff --git a/chrome/browser/resources/chromeos/login/gaia_dialog.js b/chrome/browser/resources/chromeos/login/gaia_dialog.js index d9085745..ce10eccf 100644 --- a/chrome/browser/resources/chromeos/login/gaia_dialog.js +++ b/chrome/browser/resources/chromeos/login/gaia_dialog.js
@@ -46,6 +46,14 @@ }, /** + * Whether to hide back button if form can't go back. + */ + hideBackButtonIfCantGoBack: { + type: Boolean, + value: false, + }, + + /** * Used to display SAML notice. * @private */ @@ -336,6 +344,16 @@ }, /** + * Whether the back button is hidden. + * @param {boolean} hideBackButtonIfCantGoBack - whether it should be hidden. + * @param {boolean} canGoBack - whether the form can go back. + * @private + */ + isBackButtonHidden(hideBackButtonIfCantGoBack, canGoBack) { + return hideBackButtonIfCantGoBack && !canGoBack; + }, + + /** * Whether popup overlay should be open. * @param {boolean} navigationEnabled * @param {boolean} isSamlSsoVisible
diff --git a/chrome/browser/resources/memories/app.html b/chrome/browser/resources/memories/app.html index cc6df4d..ccf33c3 100644 --- a/chrome/browser/resources/memories/app.html +++ b/chrome/browser/resources/memories/app.html
@@ -62,3 +62,10 @@ </cr-dialog> </template> </cr-lazy-render> +<cr-lazy-render id="confirmationToast"> + <template> + <cr-toast duration="5000"> + <div>[[toastMessage_]]</div> + </cr-toast> + </template> +</cr-lazy-render>
diff --git a/chrome/browser/resources/memories/app.ts b/chrome/browser/resources/memories/app.ts index dbf7356..554f386 100644 --- a/chrome/browser/resources/memories/app.ts +++ b/chrome/browser/resources/memories/app.ts
@@ -8,12 +8,14 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; import 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.m.js'; +import 'chrome://resources/cr_elements/cr_toast/cr_toast.m.js'; import 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar.js'; import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; import 'chrome://resources/polymer/v3_0/iron-scroll-threshold/iron-scroll-threshold.js'; import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; import {CrLazyRenderElement} from 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.m.js'; +import {CrToastElement} from 'chrome://resources/cr_elements/cr_toast/cr_toast.m.js'; import {CrToolbarElement} from 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar.js'; import {CrToolbarSearchFieldElement} from 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar_search_field.js'; import {assert} from 'chrome://resources/js/assert.m.js'; @@ -45,9 +47,10 @@ interface HistoryClustersAppElement { $: { confirmationDialog: CrLazyRenderElement<CrDialogElement>, + confirmationToast: CrLazyRenderElement<CrToastElement>, + container: Element, scrollThreshold: IronScrollThresholdElement, toolbar: CrToolbarElement, - container: Element, }; } @@ -88,6 +91,12 @@ }, /** + * The message to show in the toast when the request to browser to remove + * visits succeeds. + */ + toastMessage_: String, + + /** * The list of visits to be removed. A non-empty array indicates a pending * remove request to the browser. */ @@ -109,6 +118,7 @@ private query_: string = ''; private result_: QueryResult = new QueryResult(); private title_: string = ''; + private toastMessage_: string = ''; private visitsToBeRemoved_: Array<URLVisit> = []; //============================================================================ @@ -193,7 +203,12 @@ } this.visitsToBeRemoved_ = event.detail; - this.$.confirmationDialog.get().showModal(); + if (assert(this.visitsToBeRemoved_.length) > 1) { + this.$.confirmationDialog.get().showModal(); + } else { + // Bypass the confirmation dialog if removing one visit only. + this.onRemoveButtonClick_(); + } } /** @@ -280,6 +295,11 @@ * Called when the last accepted request to browser to remove visits succeeds. */ private onVisitsRemoved_() { + this.toastMessage_ = loadTimeData.getString( + assert(this.visitsToBeRemoved_.length) > 1 ? + 'removeAllFromHistoryToast' : + 'removeFromHistoryToast'); + this.$.confirmationToast.get().show(); this.visitsToBeRemoved_ = []; }
diff --git a/chrome/browser/resources/pdf/elements/viewer-bookmark.html b/chrome/browser/resources/pdf/elements/viewer-bookmark.html index df9c4573..d4639c3 100644 --- a/chrome/browser/resources/pdf/elements/viewer-bookmark.html +++ b/chrome/browser/resources/pdf/elements/viewer-bookmark.html
@@ -1,4 +1,4 @@ - <style> + <style include="pdf-shared"> #item { align-items: flex-start; cursor: pointer;
diff --git a/chrome/browser/resources/pdf/elements/viewer-bookmark.js b/chrome/browser/resources/pdf/elements/viewer-bookmark.js index 9b0d8d28..f4447145 100644 --- a/chrome/browser/resources/pdf/elements/viewer-bookmark.js +++ b/chrome/browser/resources/pdf/elements/viewer-bookmark.js
@@ -6,6 +6,7 @@ import 'chrome://resources/cr_elements/icons.m.js'; import 'chrome://resources/cr_elements/shared_vars_css.m.js'; import 'chrome://resources/polymer/v3_0/paper-styles/color.js'; +import './shared-css.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html index 0768f0e..85333f4 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html +++ b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html
@@ -265,14 +265,15 @@ aria-labelledby="deviceAccountFullName" aria-describedby="deviceAccountEmail"> <div class="profile-icon device-account-icon" + aria-hidden="true" style="background-image: [[getIconImageSet_(deviceAccount_.pic)]]"> - <template is="dom-if" - if="[[shouldShowManagedBadge_(isDeviceAccountManaged_, - isChildUser_)]]"> - <div class="managed-badge"> - <iron-icon icon="cr:work"></iron-icon> - </div> - </template> + <template is="dom-if" + if="[[shouldShowManagedBadge_(isDeviceAccountManaged_, + isChildUser_)]]"> + <div class="managed-badge"> + <iron-icon icon="cr:work"></iron-icon> + </div> + </template> </div> <span id="deviceAccountFullName" class="primary" aria-hidden="true"> [[deviceAccount_.fullName]]
diff --git a/chrome/browser/safe_browsing/BUILD.gn b/chrome/browser/safe_browsing/BUILD.gn index 322f6fd..68fe7675 100644 --- a/chrome/browser/safe_browsing/BUILD.gn +++ b/chrome/browser/safe_browsing/BUILD.gn
@@ -104,6 +104,8 @@ "chrome_password_protection_service_factory.h", "chrome_safe_browsing_blocking_page_factory.cc", "chrome_safe_browsing_blocking_page_factory.h", + "chrome_ui_manager_delegate.cc", + "chrome_ui_manager_delegate.h", "client_side_detection_host_delegate.cc", "client_side_detection_host_delegate.h", "client_side_detection_service_delegate.cc",
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc index 308b2a8..45786b6 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/password_manager/account_password_store_factory.h" #include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h" +#include "chrome/browser/safe_browsing/chrome_ui_manager_delegate.h" #include "chrome/browser/safe_browsing/ui_manager.h" #include "chrome/browser/signin/chrome_signin_client_factory.h" #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" @@ -315,6 +316,7 @@ new SafeBrowsingUIManager( static_cast<safe_browsing::SafeBrowsingService*>( SafeBrowsingService::CreateSafeBrowsingService()), + std::make_unique<ChromeSafeBrowsingUIManagerDelegate>(), std::make_unique<ChromeSafeBrowsingBlockingPageFactory>(), GURL(chrome::kChromeUINewTabURL)), sync_password_hash_provider, cache_manager_.get());
diff --git a/chrome/browser/safe_browsing/chrome_ui_manager_delegate.cc b/chrome/browser/safe_browsing/chrome_ui_manager_delegate.cc new file mode 100644 index 0000000..d0bf5fd --- /dev/null +++ b/chrome/browser/safe_browsing/chrome_ui_manager_delegate.cc
@@ -0,0 +1,41 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/safe_browsing/chrome_ui_manager_delegate.h" + +#include "chrome/browser/browser_process.h" +#include "chrome/browser/interstitials/enterprise_util.h" + +namespace safe_browsing { + +ChromeSafeBrowsingUIManagerDelegate::ChromeSafeBrowsingUIManagerDelegate() = + default; +ChromeSafeBrowsingUIManagerDelegate::~ChromeSafeBrowsingUIManagerDelegate() = + default; + +const std::string& ChromeSafeBrowsingUIManagerDelegate::GetApplicationLocale() { + return g_browser_process->GetApplicationLocale(); +} + +void ChromeSafeBrowsingUIManagerDelegate:: + TriggerSecurityInterstitialShownExtensionEventIfDesired( + content::WebContents* web_contents, + const GURL& page_url, + const std::string& reason, + int net_error_code) { + MaybeTriggerSecurityInterstitialShownEvent(web_contents, page_url, reason, + net_error_code); +} + +void ChromeSafeBrowsingUIManagerDelegate:: + TriggerSecurityInterstitialProceededExtensionEventIfDesired( + content::WebContents* web_contents, + const GURL& page_url, + const std::string& reason, + int net_error_code) { + MaybeTriggerSecurityInterstitialProceededEvent(web_contents, page_url, reason, + net_error_code); +} + +} // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/chrome_ui_manager_delegate.h b/chrome/browser/safe_browsing/chrome_ui_manager_delegate.h new file mode 100644 index 0000000..234f9dc --- /dev/null +++ b/chrome/browser/safe_browsing/chrome_ui_manager_delegate.h
@@ -0,0 +1,40 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SAFE_BROWSING_CHROME_UI_MANAGER_DELEGATE_H_ +#define CHROME_BROWSER_SAFE_BROWSING_CHROME_UI_MANAGER_DELEGATE_H_ + +#include "chrome/browser/safe_browsing/ui_manager.h" + +namespace safe_browsing { + +// Provides embedder-specific logic for SafeBrowsingUIManager. +class ChromeSafeBrowsingUIManagerDelegate + : public SafeBrowsingUIManager::Delegate { + public: + ChromeSafeBrowsingUIManagerDelegate(); + ~ChromeSafeBrowsingUIManagerDelegate() override; + + ChromeSafeBrowsingUIManagerDelegate( + const ChromeSafeBrowsingUIManagerDelegate&) = delete; + ChromeSafeBrowsingUIManagerDelegate& operator=( + const ChromeSafeBrowsingUIManagerDelegate&) = delete; + + // SafeBrowsingUIManager::Delegate: + const std::string& GetApplicationLocale() override; + void TriggerSecurityInterstitialShownExtensionEventIfDesired( + content::WebContents* web_contents, + const GURL& page_url, + const std::string& reason, + int net_error_code) override; + void TriggerSecurityInterstitialProceededExtensionEventIfDesired( + content::WebContents* web_contents, + const GURL& page_url, + const std::string& reason, + int net_error_code) override; +}; + +} // namespace safe_browsing + +#endif // CHROME_BROWSER_SAFE_BROWSING_CHROME_UI_MANAGER_DELEGATE_H_
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_browsertest.cc b/chrome/browser/safe_browsing/client_side_detection_host_browsertest.cc index d052ff9..533d6b3 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host_browsertest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_host_browsertest.cc
@@ -7,6 +7,7 @@ #include "base/run_loop.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h" +#include "chrome/browser/safe_browsing/chrome_ui_manager_delegate.h" #include "chrome/browser/safe_browsing/ui_manager.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -79,6 +80,7 @@ MockSafeBrowsingUIManager() : SafeBrowsingUIManager( nullptr, + std::make_unique<ChromeSafeBrowsingUIManagerDelegate>(), std::make_unique<ChromeSafeBrowsingBlockingPageFactory>(), GURL(chrome::kChromeUINewTabURL)) {}
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc index 0d22710..2fe3db7 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
@@ -21,6 +21,7 @@ #include "base/test/scoped_command_line.h" #include "base/test/simple_test_tick_clock.h" #include "chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h" +#include "chrome/browser/safe_browsing/chrome_ui_manager_delegate.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/safe_browsing/ui_manager.h" #include "chrome/common/chrome_switches.h" @@ -152,6 +153,7 @@ explicit MockSafeBrowsingUIManager(SafeBrowsingService* service) : SafeBrowsingUIManager( service, + std::make_unique<ChromeSafeBrowsingUIManagerDelegate>(), std::make_unique<ChromeSafeBrowsingBlockingPageFactory>(), GURL(chrome::kChromeUINewTabURL)) {}
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc index f7ce5700..9590ca49 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc
@@ -461,8 +461,14 @@ void SetProfileDMToken(Profile* profile, const std::string& dm_token) { auto client = std::make_unique<policy::MockCloudPolicyClient>(); client->SetDMToken(dm_token); + +// crbug.com/1230268 The main profile in Lacros doesn't have a +// CloudPolicyManager, but we might want to apply the code if it's a secondary +// profile. +#if !BUILDFLAG(IS_CHROMEOS_LACROS) profile->GetUserCloudPolicyManager()->Connect( g_browser_process->local_state(), std::move(client)); +#endif } #endif
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc index db81df2..ef2b8b7 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -30,6 +30,7 @@ #include "chrome/browser/safe_browsing/chrome_password_protection_service.h" #include "chrome/browser/safe_browsing/chrome_password_protection_service_factory.h" #include "chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h" +#include "chrome/browser/safe_browsing/chrome_ui_manager_delegate.h" #include "chrome/browser/safe_browsing/network_context_service.h" #include "chrome/browser/safe_browsing/network_context_service_factory.h" #include "chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h" @@ -277,7 +278,8 @@ SafeBrowsingUIManager* SafeBrowsingService::CreateUIManager() { return new SafeBrowsingUIManager( - this, std::make_unique<ChromeSafeBrowsingBlockingPageFactory>(), + this, std::make_unique<ChromeSafeBrowsingUIManagerDelegate>(), + std::make_unique<ChromeSafeBrowsingBlockingPageFactory>(), GURL(chrome::kChromeUINewTabURL)); }
diff --git a/chrome/browser/safe_browsing/test_safe_browsing_service.cc b/chrome/browser/safe_browsing/test_safe_browsing_service.cc index 405459c6..51a51d29 100644 --- a/chrome/browser/safe_browsing/test_safe_browsing_service.cc +++ b/chrome/browser/safe_browsing/test_safe_browsing_service.cc
@@ -6,6 +6,7 @@ #include "base/strings/string_util.h" #include "chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h" +#include "chrome/browser/safe_browsing/chrome_ui_manager_delegate.h" #include "chrome/browser/safe_browsing/download_protection/download_protection_service.h" #include "chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h" #include "chrome/browser/safe_browsing/services_delegate.h" @@ -201,6 +202,7 @@ TestSafeBrowsingUIManager::TestSafeBrowsingUIManager() : SafeBrowsingUIManager( nullptr, + std::make_unique<ChromeSafeBrowsingUIManagerDelegate>(), std::make_unique<ChromeSafeBrowsingBlockingPageFactory>(), GURL(chrome::kChromeUINewTabURL)) {} @@ -208,14 +210,17 @@ const scoped_refptr<SafeBrowsingService>& service) : SafeBrowsingUIManager( service, + std::make_unique<ChromeSafeBrowsingUIManagerDelegate>(), std::make_unique<ChromeSafeBrowsingBlockingPageFactory>(), GURL(chrome::kChromeUINewTabURL)) {} TestSafeBrowsingUIManager::TestSafeBrowsingUIManager( std::unique_ptr<SafeBrowsingBlockingPageFactory> blocking_page_factory) - : SafeBrowsingUIManager(nullptr, - std::move(blocking_page_factory), - GURL(chrome::kChromeUINewTabURL)) {} + : SafeBrowsingUIManager( + nullptr, + std::make_unique<ChromeSafeBrowsingUIManagerDelegate>(), + std::move(blocking_page_factory), + GURL(chrome::kChromeUINewTabURL)) {} void TestSafeBrowsingUIManager::SetSafeBrowsingService( SafeBrowsingService* sb_service) {
diff --git a/chrome/browser/safe_browsing/threat_details_unittest.cc b/chrome/browser/safe_browsing/threat_details_unittest.cc index 61288d0..f063226 100644 --- a/chrome/browser/safe_browsing/threat_details_unittest.cc +++ b/chrome/browser/safe_browsing/threat_details_unittest.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h" +#include "chrome/browser/safe_browsing/chrome_ui_manager_delegate.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/safe_browsing/ui_manager.h" #include "chrome/common/url_constants.h" @@ -165,6 +166,7 @@ MockSafeBrowsingUIManager() : SafeBrowsingUIManager( nullptr, + std::make_unique<ChromeSafeBrowsingUIManagerDelegate>(), std::make_unique<ChromeSafeBrowsingBlockingPageFactory>(), GURL(chrome::kChromeUINewTabURL)), report_sent_(false) {}
diff --git a/chrome/browser/safe_browsing/ui_manager.cc b/chrome/browser/safe_browsing/ui_manager.cc index 06ca1c78..2548b1e 100644 --- a/chrome/browser/safe_browsing/ui_manager.cc +++ b/chrome/browser/safe_browsing/ui_manager.cc
@@ -12,7 +12,6 @@ #include "base/threading/thread_restrictions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/history/history_service_factory.h" -#include "chrome/browser/interstitials/enterprise_util.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" #include "chrome/browser/prefetch/no_state_prefetch/chrome_no_state_prefetch_contents_delegate.h" #include "chrome/browser/profiles/profile.h" @@ -50,9 +49,11 @@ SafeBrowsingUIManager::SafeBrowsingUIManager( const scoped_refptr<SafeBrowsingService>& service, + std::unique_ptr<Delegate> delegate, std::unique_ptr<SafeBrowsingBlockingPageFactory> blocking_page_factory, const GURL& default_safe_page) : sb_service_(service), + delegate_(std::move(delegate)), blocking_page_factory_(std::move(blocking_page_factory)), default_safe_page_(default_safe_page) {} @@ -263,7 +264,7 @@ const std::string SafeBrowsingUIManager::app_locale() const { DCHECK_CURRENTLY_ON(BrowserThread::UI); - return g_browser_process->GetApplicationLocale(); + return delegate_->GetApplicationLocale(); } history::HistoryService* SafeBrowsingUIManager::history_service( @@ -309,7 +310,7 @@ BaseUIManager::OnBlockingPageDone(resources, proceed, web_contents, main_frame_url, showed_interstitial); if (proceed && !resources.empty()) { - MaybeTriggerSecurityInterstitialProceededEvent( + delegate_->TriggerSecurityInterstitialProceededExtensionEventIfDesired( web_contents, main_frame_url, GetThreatTypeStringForInterstitial(resources[0].threat_type), /*net_error_code=*/0); @@ -336,7 +337,7 @@ /*should_trigger_reporting=*/false); // Report that we showed an interstitial. - MaybeTriggerSecurityInterstitialShownEvent( + delegate_->TriggerSecurityInterstitialShownExtensionEventIfDesired( contents, blocked_url, GetThreatTypeStringForInterstitial(unsafe_resource.threat_type), /*net_error_code=*/0);
diff --git a/chrome/browser/safe_browsing/ui_manager.h b/chrome/browser/safe_browsing/ui_manager.h index 2baaf8b8..c5eae1c2 100644 --- a/chrome/browser/safe_browsing/ui_manager.h +++ b/chrome/browser/safe_browsing/ui_manager.h
@@ -56,8 +56,41 @@ DISALLOW_COPY_AND_ASSIGN(Observer); }; + // Interface via which the embedder supplies contextual information to + // SafeBrowsingUIManager. + class Delegate { + public: + Delegate() = default; + virtual ~Delegate() = default; + + Delegate(const Delegate&) = delete; + Delegate& operator=(const Delegate&) = delete; + + // Returns the locale used by the application. It is the IETF language tag, + // defined in BCP 47. The region subtag is not included when it adds no + // distinguishing information to the language tag (e.g. both "en-US" and + // "fr" are correct here). + virtual const std::string& GetApplicationLocale() = 0; + + // Notifies the embedder that given events occurred so that the embedder can + // trigger corresponding extension events if desired. This triggering is + // optional (e.g., not all embedders support extensions, even those who do + // might not wish to trigger extension events in incognito mode, etc). + virtual void TriggerSecurityInterstitialShownExtensionEventIfDesired( + content::WebContents* web_contents, + const GURL& page_url, + const std::string& reason, + int net_error_code) = 0; + virtual void TriggerSecurityInterstitialProceededExtensionEventIfDesired( + content::WebContents* web_contents, + const GURL& page_url, + const std::string& reason, + int net_error_code) = 0; + }; + SafeBrowsingUIManager( const scoped_refptr<SafeBrowsingService>& service, + std::unique_ptr<Delegate> delegate, std::unique_ptr<SafeBrowsingBlockingPageFactory> blocking_page_factory, const GURL& default_safe_page); @@ -144,6 +177,8 @@ // Safebrowsing service. scoped_refptr<SafeBrowsingService> sb_service_; + std::unique_ptr<Delegate> delegate_; + std::unique_ptr<SafeBrowsingBlockingPageFactory> blocking_page_factory_; GURL default_safe_page_;
diff --git a/chrome/browser/safe_browsing/ui_manager_unittest.cc b/chrome/browser/safe_browsing/ui_manager_unittest.cc index d775f40..f9fa4e0 100644 --- a/chrome/browser/safe_browsing/ui_manager_unittest.cc +++ b/chrome/browser/safe_browsing/ui_manager_unittest.cc
@@ -159,12 +159,36 @@ } }; +class TestSafeBrowsingUIManagerDelegate + : public SafeBrowsingUIManager::Delegate { + public: + TestSafeBrowsingUIManagerDelegate() = default; + ~TestSafeBrowsingUIManagerDelegate() override = default; + + // SafeBrowsingUIManager::Delegate: + const std::string& GetApplicationLocale() override { return app_locale_; } + void TriggerSecurityInterstitialShownExtensionEventIfDesired( + content::WebContents* web_contents, + const GURL& page_url, + const std::string& reason, + int net_error_code) override {} + void TriggerSecurityInterstitialProceededExtensionEventIfDesired( + content::WebContents* web_contents, + const GURL& page_url, + const std::string& reason, + int net_error_code) override {} + + private: + std::string app_locale_ = "en-us"; +}; + class SafeBrowsingUIManagerTest : public ChromeRenderViewHostTestHarness { public: SafeBrowsingUIManagerTest() : scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()) { ui_manager_ = new SafeBrowsingUIManager( - nullptr, std::make_unique<TestSafeBrowsingBlockingPageFactory>(), + nullptr, std::make_unique<TestSafeBrowsingUIManagerDelegate>(), + std::make_unique<TestSafeBrowsingBlockingPageFactory>(), GURL("chrome://new-tab-page/")); }
diff --git a/chrome/browser/search/ntp_custom_background_enabled_policy_handler_browsertest.cc b/chrome/browser/search/ntp_custom_background_enabled_policy_handler_browsertest.cc index 22bc546..b439a627 100644 --- a/chrome/browser/search/ntp_custom_background_enabled_policy_handler_browsertest.cc +++ b/chrome/browser/search/ntp_custom_background_enabled_policy_handler_browsertest.cc
@@ -26,10 +26,9 @@ : public InProcessBrowserTest { public: void SetUp() override { - ON_CALL(policy_provider_, IsInitializationComplete(testing::_)) - .WillByDefault(testing::Return(true)); - ON_CALL(policy_provider_, IsFirstPolicyLoadComplete(testing::_)) - .WillByDefault(testing::Return(true)); + policy_provider_.SetDefaultReturns( + /*is_initialization_complete_return=*/true, + /*is_first_policy_load_complete_return=*/true); policy::BrowserPolicyConnector::SetPolicyProviderForTesting( &policy_provider_); InProcessBrowserTest::SetUp();
diff --git a/chrome/browser/secure_origin_allowlist_browsertest.cc b/chrome/browser/secure_origin_allowlist_browsertest.cc index e5072f3..3dcd3d6c0 100644 --- a/chrome/browser/secure_origin_allowlist_browsertest.cc +++ b/chrome/browser/secure_origin_allowlist_browsertest.cc
@@ -74,8 +74,9 @@ // to the renderer via a command-line. Setting the policy in the test // itself or in SetUpOnMainThread works for update-able policies, but // is too late for this one. - EXPECT_CALL(provider_, IsInitializationComplete(testing::_)) - .WillRepeatedly(testing::Return(true)); + provider_.SetDefaultReturns( + /*is_initialization_complete_return=*/true, + /*is_first_policy_load_complete_return=*/true); policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_); base::Value urls(base::Value::Type::LIST); @@ -119,7 +120,7 @@ } private: - policy::MockConfigurationPolicyProvider provider_; + testing::NiceMock<policy::MockConfigurationPolicyProvider> provider_; }; INSTANTIATE_TEST_SUITE_P(SecureOriginAllowlistBrowsertest,
diff --git a/chrome/browser/signin/dice_intercepted_session_startup_helper.cc b/chrome/browser/signin/dice_intercepted_session_startup_helper.cc index da9e757..b06c9a0 100644 --- a/chrome/browser/signin/dice_intercepted_session_startup_helper.cc +++ b/chrome/browser/signin/dice_intercepted_session_startup_helper.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/callback_helpers.h" -#include "base/metrics/histogram_functions.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "chrome/browser/signin/account_reconcilor_factory.h" @@ -40,13 +39,6 @@ }) != accounts.end(); } -void RecordSessionStartupDuration(const std::string& histogram_name, - base::TimeDelta duration) { - base::UmaHistogramCustomTimes(histogram_name, duration, - /*min=*/base::TimeDelta::FromMilliseconds(1), - /*max=*/base::TimeDelta::FromSeconds(30), 50); -} - } // namespace DiceInterceptedSessionStartupHelper::DiceInterceptedSessionStartupHelper( @@ -65,7 +57,6 @@ void DiceInterceptedSessionStartupHelper::Startup(base::OnceClosure callback) { callback_ = std::move(callback); - session_startup_time_ = base::TimeTicks::Now(); // Wait until the account is set in cookies of the newly created profile // before opening the URL, so that the user is signed-in in content area. If @@ -77,14 +68,11 @@ identity_manager->GetAccountsInCookieJar(); if (cookie_info.accounts_are_fresh && CookieInfoContains(cookie_info, account_id_)) { - MoveTab(use_multilogin_ ? Result::kMultiloginNothingToDo - : Result::kReconcilorNothingToDo); + MoveTab(); } else { // Set the timeout. on_cookie_update_timeout_.Reset(base::BindOnce( - &DiceInterceptedSessionStartupHelper::MoveTab, base::Unretained(this), - use_multilogin_ ? Result::kMultiloginTimeout - : Result::kReconcilorTimeout)); + &DiceInterceptedSessionStartupHelper::MoveTab, base::Unretained(this))); // Adding accounts to the cookies can be an expensive operation. In // particular the ExternalCCResult fetch may time out after multiple seconds // (see kExternalCCResultTimeoutSeconds and https://crbug.com/750316#c37). @@ -110,8 +98,7 @@ if (!CookieInfoContains(accounts_in_cookie_jar_info, account_id_)) return; - MoveTab(use_multilogin_ ? Result::kMultiloginOtherSuccess - : Result::kReconcilorSuccess); + MoveTab(); } void DiceInterceptedSessionStartupHelper::OnStateChanged( @@ -166,23 +153,10 @@ void DiceInterceptedSessionStartupHelper::OnSetAccountInCookieCompleted( signin::SetAccountsInCookieResult result) { DCHECK(use_multilogin_); - Result session_startup_result = Result::kMultiloginOtherSuccess; - switch (result) { - case signin::SetAccountsInCookieResult::kSuccess: - session_startup_result = Result::kMultiloginSuccess; - break; - case signin::SetAccountsInCookieResult::kTransientError: - session_startup_result = Result::kMultiloginTransientError; - break; - case signin::SetAccountsInCookieResult::kPersistentError: - session_startup_result = Result::kMultiloginPersistentError; - break; - } - - MoveTab(session_startup_result); + MoveTab(); } -void DiceInterceptedSessionStartupHelper::MoveTab(Result result) { +void DiceInterceptedSessionStartupHelper::MoveTab() { accounts_in_cookie_observer_.Reset(); reconcilor_observer_.Reset(); on_cookie_update_timeout_.Cancel(); @@ -200,21 +174,6 @@ ui::PAGE_TRANSITION_AUTO_BOOKMARK); Navigate(¶ms); - base::UmaHistogramEnumeration("Signin.Intercept.SessionStartupResult", - result); - base::TimeDelta duration = base::TimeTicks::Now() - session_startup_time_; - if (use_multilogin_) { - RecordSessionStartupDuration( - "Signin.Intercept.SessionStartupDuration.Multilogin", duration); - } else { - RecordSessionStartupDuration( - "Signin.Intercept.SessionStartupDuration.Reconcilor", duration); - // TODO(https://crbug.com/1151313): Remove this histogram when the cause - // for the timeouts is understood. - base::UmaHistogramBoolean("Signin.Intercept.SessionStartupReconcileError", - reconcile_error_encountered_); - } - if (callback_) std::move(callback_).Run(); }
diff --git a/chrome/browser/signin/dice_intercepted_session_startup_helper.h b/chrome/browser/signin/dice_intercepted_session_startup_helper.h index d3c99e17..cd4b4f2 100644 --- a/chrome/browser/signin/dice_intercepted_session_startup_helper.h +++ b/chrome/browser/signin/dice_intercepted_session_startup_helper.h
@@ -9,7 +9,6 @@ #include "base/cancelable_callback.h" #include "base/memory/weak_ptr.h" #include "base/scoped_observation.h" -#include "base/time/time.h" #include "components/signin/core/browser/account_reconcilor.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "content/public/browser/web_contents_observer.h" @@ -38,21 +37,6 @@ public signin::IdentityManager::Observer, public AccountReconcilor::Observer { public: - // Used in UMA histograms, do not reorder or remove values. - enum class Result { - kReconcilorNothingToDo = 0, - kMultiloginNothingToDo = 1, - kReconcilorSuccess = 2, // The account was added by the reconcilor. - kMultiloginSuccess = 3, // The account was added by this object. - kMultiloginOtherSuccess = 4, // The account was added by something else. - kMultiloginTimeout = 5, - kReconcilorTimeout = 6, - kMultiloginTransientError = 7, - kMultiloginPersistentError = 8, - - kMaxValue = kMultiloginPersistentError - }; - // |profile| is the new profile that was created after signin interception. // |account_id| is the main account for the profile, it's already in the // profile. @@ -94,7 +78,7 @@ // Creates a browser with a new tab, and closes the intercepted tab if it's // still open. - void MoveTab(Result result); + void MoveTab(); Profile* const profile_; bool use_multilogin_; @@ -107,7 +91,6 @@ base::ScopedObservation<AccountReconcilor, AccountReconcilor::Observer> reconcilor_observer_{this}; std::unique_ptr<AccountReconcilor::Lock> reconcilor_lock_; - base::TimeTicks session_startup_time_; // Timeout while waiting for the account to be added to the cookies in the new // profile. base::CancelableOnceCallback<void()> on_cookie_update_timeout_;
diff --git a/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc b/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc index 6a594f89..7e5a7404 100644 --- a/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc +++ b/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc
@@ -170,8 +170,7 @@ // Checks that the interception histograms were correctly recorded. void CheckHistograms(const base::HistogramTester& histogram_tester, - SigninInterceptionHeuristicOutcome outcome, - bool intercept_to_guest = false) { + SigninInterceptionHeuristicOutcome outcome) { int profile_switch_count = outcome == SigninInterceptionHeuristicOutcome::kInterceptProfileSwitch || outcome == SigninInterceptionHeuristicOutcome:: @@ -193,18 +192,6 @@ profile_creation_count); histogram_tester.ExpectTotalCount("Signin.Intercept.ProfileSwitchDuration", profile_switch_count); - histogram_tester.ExpectTotalCount( - "Signin.Intercept.SessionStartupDuration.Multilogin", - profile_creation_count); - histogram_tester.ExpectTotalCount( - "Signin.Intercept.SessionStartupDuration.Reconcilor", - profile_switch_count); - histogram_tester.ExpectUniqueSample( - "Signin.Intercept.SessionStartupResult", - profile_switch_count - ? DiceInterceptedSessionStartupHelper::Result::kReconcilorSuccess - : DiceInterceptedSessionStartupHelper::Result::kMultiloginSuccess, - 1); } } // namespace
diff --git a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCacheRenderTest.java b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCacheRenderTest.java index 6bf73a1a..4bf6f3e7 100644 --- a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCacheRenderTest.java +++ b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCacheRenderTest.java
@@ -125,12 +125,12 @@ @Before public void setUp() { mocker.mock(IdentityManagerJni.TEST_HOOKS, mIdentityManagerNativeMock); - AccountInfoServiceProvider.init(mIdentityManager, mAccountTrackerServiceMock); doAnswer(AdditionalAnswers.answerVoid(Runnable::run)) .when(mAccountTrackerServiceMock) .seedAccountsIfNeeded(any(Runnable.class)); TestThreadUtils.runOnUiThreadBlocking(() -> { + AccountInfoServiceProvider.init(mIdentityManager, mAccountTrackerServiceMock); Activity activity = getActivity(); mContentView = new FrameLayout(activity); mImageView = new ChromeImageView(activity);
diff --git a/chrome/browser/signin/ui/android/junit/src/org/chromium/chrome/browser/signin/ui/account_picker/AccountPickerMediatorTest.java b/chrome/browser/signin/ui/android/junit/src/org/chromium/chrome/browser/signin/ui/account_picker/AccountPickerMediatorTest.java index acd5a81..46cd467 100644 --- a/chrome/browser/signin/ui/android/junit/src/org/chromium/chrome/browser/signin/ui/account_picker/AccountPickerMediatorTest.java +++ b/chrome/browser/signin/ui/android/junit/src/org/chromium/chrome/browser/signin/ui/account_picker/AccountPickerMediatorTest.java
@@ -4,12 +4,10 @@ package org.chromium.chrome.browser.signin.ui.account_picker; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import org.junit.After; import org.junit.Assert; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -26,9 +24,6 @@ import org.chromium.chrome.browser.signin.ui.account_picker.AccountPickerProperties.ExistingAccountRowProperties; import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule; -import org.chromium.components.signin.identitymanager.AccountInfoServiceProvider; -import org.chromium.components.signin.identitymanager.AccountTrackerService; -import org.chromium.components.signin.identitymanager.IdentityManager; import org.chromium.components.signin.test.util.FakeAccountInfoService; import org.chromium.ui.modelutil.MVCListAdapter; import org.chromium.ui.modelutil.PropertyModel; @@ -61,18 +56,11 @@ private AccountPickerMediator mMediator; - @Before - public void setUp() { - AccountInfoServiceProvider.init( - mock(IdentityManager.class), mock(AccountTrackerService.class)); - } - @After public void tearDown() { if (mMediator != null) { mMediator.destroy(); } - AccountInfoServiceProvider.resetForTests(); } @Test
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 33541e1..ec60a931 100644 --- a/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc +++ b/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
@@ -67,7 +67,7 @@ #include "ash/public/cpp/test/shell_test_api.h" #include "ui/display/manager/display_manager.h" #include "ui/display/screen.h" -#include "ui/display/test/display_manager_test_api.h" +#include "ui/display/test/display_manager_test_api.h" // nogncheck #endif namespace {
diff --git a/chrome/browser/ssl/ocsp_browsertest.cc b/chrome/browser/ssl/ocsp_browsertest.cc index f19063a..5e837414 100644 --- a/chrome/browser/ssl/ocsp_browsertest.cc +++ b/chrome/browser/ssl/ocsp_browsertest.cc
@@ -57,10 +57,9 @@ SystemNetworkContextManager::SetEnableCertificateTransparencyForTesting( false); - ON_CALL(policy_provider_, IsInitializationComplete(testing::_)) - .WillByDefault(testing::Return(true)); - ON_CALL(policy_provider_, IsFirstPolicyLoadComplete(testing::_)) - .WillByDefault(testing::Return(true)); + policy_provider_.SetDefaultReturns( + /*is_initialization_complete_return=*/true, + /*is_first_policy_load_complete_return=*/true); policy::BrowserPolicyConnector::SetPolicyProviderForTesting( &policy_provider_);
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc index 729e233..fbd708f0 100644 --- a/chrome/browser/ssl/ssl_browsertest.cc +++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -453,10 +453,9 @@ } void SetUp() override { - ON_CALL(policy_provider_, IsInitializationComplete(testing::_)) - .WillByDefault(testing::Return(true)); - ON_CALL(policy_provider_, IsFirstPolicyLoadComplete(testing::_)) - .WillByDefault(testing::Return(true)); + policy_provider_.SetDefaultReturns( + /*is_initialization_complete_return=*/true, + /*is_first_policy_load_complete_return=*/true); policy::BrowserPolicyConnector::SetPolicyProviderForTesting( &policy_provider_); @@ -1706,10 +1705,9 @@ } void SetUp() override { - ON_CALL(policy_provider_, IsInitializationComplete(testing::_)) - .WillByDefault(testing::Return(true)); - ON_CALL(policy_provider_, IsFirstPolicyLoadComplete(testing::_)) - .WillByDefault(testing::Return(true)); + policy_provider_.SetDefaultReturns( + /*is_initialization_complete_return=*/true, + /*is_first_policy_load_complete_return=*/true); policy::BrowserPolicyConnector::SetPolicyProviderForTesting( &policy_provider_);
diff --git a/chrome/browser/subresource_filter/subresource_filter_settings_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_settings_browsertest.cc index dde338f..d8f6ad8 100644 --- a/chrome/browser/subresource_filter/subresource_filter_settings_browsertest.cc +++ b/chrome/browser/subresource_filter/subresource_filter_settings_browsertest.cc
@@ -42,8 +42,9 @@ : public SubresourceFilterBrowserTest { public: void SetUp() override { - EXPECT_CALL(provider_, IsInitializationComplete(::testing::_)) - .WillRepeatedly(::testing::Return(true)); + provider_.SetDefaultReturns( + /*is_initialization_complete_return=*/true, + /*is_first_policy_load_complete_return=*/true); policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_); SubresourceFilterBrowserTest::SetUp(); } @@ -54,7 +55,7 @@ } private: - policy::MockConfigurationPolicyProvider provider_; + ::testing::NiceMock<policy::MockConfigurationPolicyProvider> provider_; }; IN_PROC_BROWSER_TEST_F(SubresourceFilterSettingsBrowserTest,
diff --git a/chrome/browser/sync/test/integration/enable_disable_test.cc b/chrome/browser/sync/test/integration/enable_disable_test.cc index bff8b66..a07c35a 100644 --- a/chrome/browser/sync/test/integration/enable_disable_test.cc +++ b/chrome/browser/sync/test/integration/enable_disable_test.cc
@@ -434,6 +434,7 @@ ASSERT_NE("", first_cache_guid); GetClient(0)->StopSyncServiceAndClearData(); + base::RunLoop().RunUntilIdle(); // Sync should have restarted in transport mode, creating a new cache GUID. EXPECT_NE("", prefs.GetCacheGuid()); EXPECT_NE(first_cache_guid, prefs.GetCacheGuid());
diff --git a/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc b/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc index 12b650e..0a254eae 100644 --- a/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc
@@ -82,8 +82,6 @@ // transport mode. secondary_account_helper::SignInSecondaryAccount( profile(), &test_url_loader_factory_, "user@email.com"); - EXPECT_EQ(syncer::SyncService::TransportState::INITIALIZING, - GetSyncService(0)->GetTransportState()); EXPECT_TRUE(GetClient(0)->AwaitSyncTransportActive());
diff --git a/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc index a97c78c..bad875f 100644 --- a/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc
@@ -105,7 +105,7 @@ protected: // Needs to be deleted after all Profiles are deleted. - policy::MockConfigurationPolicyProvider policy_provider_; + testing::NiceMock<policy::MockConfigurationPolicyProvider> policy_provider_; }; IN_PROC_BROWSER_TEST_F(TwoClientBookmarksSyncTest, Sanity) { @@ -2567,10 +2567,9 @@ // Verifies that managed bookmarks (installed by policy) don't get synced. IN_PROC_BROWSER_TEST_F(TwoClientBookmarksSyncTest, ManagedBookmarks) { // Make sure the first Profile has an overridden policy provider. - EXPECT_CALL(policy_provider_, IsInitializationComplete(testing::_)) - .WillRepeatedly(testing::Return(true)); - EXPECT_CALL(policy_provider_, IsFirstPolicyLoadComplete(testing::_)) - .WillRepeatedly(testing::Return(true)); + policy_provider_.SetDefaultReturns( + /*is_initialization_complete_return=*/true, + /*is_first_policy_load_complete_return=*/true); policy::PushProfilePolicyConnectorProviderForTesting(&policy_provider_); // Set up sync.
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc index e8d761e..7d61f9b 100644 --- a/chrome/browser/themes/browser_theme_pack.cc +++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -1244,7 +1244,7 @@ DCHECK(colors_value); DCHECK(colors_value->is_dict()); // Parse the incoming data from |colors_value| into an intermediary structure. - for (const auto& iter : colors_value->DictItems()) { + for (const auto iter : colors_value->DictItems()) { if (!iter.second.is_list()) continue; base::Value::ConstListView color_list = iter.second.GetList();
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 91f6c0ec..acd5472 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -603,7 +603,6 @@ "//ui/compositor", "//ui/content_accelerators", "//ui/display", - "//ui/display/manager", "//ui/events:gesture_detection", "//ui/gfx", "//ui/gfx/geometry", @@ -2873,6 +2872,7 @@ "//ui/chromeos/events", "//ui/chromeos/strings:strings_provider", "//ui/compositor_extra", + "//ui/display/manager", "//ui/events/ozone/layout:layout", "//ui/file_manager:file_manager", "//ui/ozone",
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 8fdddba..a001610 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -1858,7 +1858,7 @@ render_widget_host); } -void Browser::DidNavigateMainFramePostCommit(WebContents* web_contents) { +void Browser::DidNavigatePrimaryMainFramePostCommit(WebContents* web_contents) { if (web_contents == tab_strip_model_->GetActiveWebContents()) UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE); }
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index c2a3ab7..83c1677 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -822,7 +822,7 @@ void RendererResponsive( content::WebContents* source, content::RenderWidgetHost* render_widget_host) override; - void DidNavigateMainFramePostCommit( + void DidNavigatePrimaryMainFramePostCommit( content::WebContents* web_contents) override; content::JavaScriptDialogManager* GetJavaScriptDialogManager( content::WebContents* source) override;
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc index 83897b6..bfbda614 100644 --- a/chrome/browser/ui/browser_browsertest.cc +++ b/chrome/browser/ui/browser_browsertest.cc
@@ -295,7 +295,7 @@ // Cache the sizes of RenderWidgetHostView and WebContentsView when the // navigation entry is committed, which is before - // WebContentsDelegate::DidNavigateMainFramePostCommit is called. + // WebContentsDelegate::DidNavigatePrimaryMainFramePostCommit is called. void NavigationEntryCommitted( const content::LoadCommittedDetails& details) override { content::RenderViewHost* rvh = @@ -2448,7 +2448,8 @@ // should be the same as when it was first created. EXPECT_EQ(rwhv_create_size0, rwhv_commit_size0); // Sizes of the current RenderWidgetHostView and WebContentsView should not - // change before and after WebContentsDelegate::DidNavigateMainFramePostCommit + // change before and after + // WebContentsDelegate::DidNavigatePrimaryMainFramePostCommit // (implemented by Browser); we obtain the sizes before PostCommit via // WebContentsObserver::NavigationEntryCommitted (implemented by // RenderViewSizeObserver).
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc index d98a42b..e30e9af 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
@@ -35,7 +35,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "ash/shell.h" -#include "ui/display/test/display_manager_test_api.h" +#include "ui/display/test/display_manager_test_api.h" // nogncheck #endif // BUILDFLAG(IS_CHROMEOS_ASH) #if defined(OS_LINUX) && defined(USE_OZONE) @@ -294,8 +294,16 @@ ASSERT_FALSE(IsWindowFullscreenForTabOrPending()); } +// TODO(crbug.com/1230771) Flaky on Linux-ozone +#if defined(OS_LINUX) && defined(USE_OZONE) +#define MAYBE_TabEntersPresentationModeFromWindowed \ + DISABLED_TabEntersPresentationModeFromWindowed +#else +#define MAYBE_TabEntersPresentationModeFromWindowed \ + TabEntersPresentationModeFromWindowed +#endif IN_PROC_BROWSER_TEST_F(FullscreenControllerInteractiveTest, - TabEntersPresentationModeFromWindowed) { + MAYBE_TabEntersPresentationModeFromWindowed) { ASSERT_TRUE(embedded_test_server()->Start()); AddTabAtIndex(0, GURL(url::kAboutBlankURL), PAGE_TRANSITION_TYPED);
diff --git a/chrome/browser/ui/hats/trust_safety_sentiment_service.cc b/chrome/browser/ui/hats/trust_safety_sentiment_service.cc index 20c386a..8c98fec 100644 --- a/chrome/browser/ui/hats/trust_safety_sentiment_service.cc +++ b/chrome/browser/ui/hats/trust_safety_sentiment_service.cc
@@ -80,22 +80,34 @@ bool HasNonDefaultPrivacySetting(Profile* profile) { auto* prefs = profile->GetPrefs(); - // Check for the most relevant set of privacy preferences. - const bool has_non_default_pref = - !prefs->FindPreference(prefs::kSafeBrowsingEnabled)->IsDefaultValue() || - !prefs->FindPreference(prefs::kSafeBrowsingEnhanced)->IsDefaultValue() || - !prefs->FindPreference(prefs::kSafeBrowsingScoutReportingEnabled) - ->IsDefaultValue() || - !prefs->FindPreference(prefs::kEnableDoNotTrack)->IsDefaultValue() || - !prefs - ->FindPreference( - password_manager::prefs::kPasswordLeakDetectionEnabled) - ->IsDefaultValue() || - !prefs->FindPreference(prefs::kCookieControlsMode)->IsDefaultValue() || - // Users consenting to sync automatically enable UKM collection - (prefs->GetBoolean( - unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled) != - prefs->GetBoolean(prefs::kGoogleServicesConsentedToSync)); + std::vector<std::string> prefs_to_check = { + prefs::kSafeBrowsingEnabled, + prefs::kSafeBrowsingEnhanced, + prefs::kSafeBrowsingScoutReportingEnabled, + prefs::kEnableDoNotTrack, + password_manager::prefs::kPasswordLeakDetectionEnabled, + prefs::kCookieControlsMode, + }; + + bool has_non_default_pref = false; + for (const auto& pref_name : prefs_to_check) { + auto* pref = prefs->FindPreference(pref_name); + if (!pref->IsDefaultValue() && pref->IsUserControlled()) { + has_non_default_pref = true; + break; + } + } + + // Users consenting to sync automatically enable UKM collection + auto* ukm_pref = prefs->FindPreference( + unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled); + auto* sync_consent_pref = + prefs->FindPreference(prefs::kGoogleServicesConsentedToSync); + + bool has_non_default_ukm = + ukm_pref->GetValue()->GetBool() != + sync_consent_pref->GetValue()->GetBool() && + (ukm_pref->IsUserControlled() || sync_consent_pref->IsUserControlled()); // Check the default value for each user facing content setting. Note that // this will not include content setting exceptions set via permission @@ -105,21 +117,33 @@ for (auto content_setting_type : site_settings::GetVisiblePermissionCategories()) { - auto current_value = map->GetDefaultContentSetting(content_setting_type, - /*provider_id=*/nullptr); + std::string content_setting_provider; + auto current_value = map->GetDefaultContentSetting( + content_setting_type, &content_setting_provider); + auto content_setting_source = + HostContentSettingsMap::GetSettingSourceFromProviderName( + content_setting_provider); + + const bool user_controlled = + content_setting_source == + content_settings::SettingSource::SETTING_SOURCE_NONE || + content_setting_source == + content_settings::SettingSource::SETTING_SOURCE_USER; + auto default_value = static_cast<ContentSetting>( content_settings::WebsiteSettingsRegistry::GetInstance() ->Get(content_setting_type) ->initial_default_value() ->GetInt()); - if (current_value != default_value) { + if (current_value != default_value && user_controlled) { has_non_default_content_setting = true; break; } } - return has_non_default_pref || has_non_default_content_setting; + return has_non_default_pref || has_non_default_ukm || + has_non_default_content_setting; } // Generates the Product Specific Data which accompanies survey results for the
diff --git a/chrome/browser/ui/hats/trust_safety_sentiment_service_unittest.cc b/chrome/browser/ui/hats/trust_safety_sentiment_service_unittest.cc index c0d521a..1b4c66a 100644 --- a/chrome/browser/ui/hats/trust_safety_sentiment_service_unittest.cc +++ b/chrome/browser/ui/hats/trust_safety_sentiment_service_unittest.cc
@@ -14,6 +14,8 @@ #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/testing_profile.h" #include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/content_settings/core/test/content_settings_mock_provider.h" +#include "components/content_settings/core/test/content_settings_test_utils.h" #include "components/signin/public/base/signin_pref_names.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "components/unified_consent/pref_names.h" @@ -507,6 +509,25 @@ service()->InteractedWithPrivacySettings(web_contents.get()); task_environment()->RunUntilIdle(); service()->OpenedNewTabPage(); + + // A preference or content setting changed via policy should not be considered + // as non-default. + profile()->GetTestingPrefService()->SetManagedPref( + prefs::kEnableDoNotTrack, std::make_unique<base::Value>(true)); + auto managed_provider = std::make_unique<content_settings::MockProvider>(); + managed_provider->SetWebsiteSetting( + ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(), + ContentSettingsType::COOKIES, + std::make_unique<base::Value>(ContentSetting::CONTENT_SETTING_BLOCK)); + content_settings::TestUtils::OverrideProvider( + content_settings, std::move(managed_provider), + HostContentSettingsMap::POLICY_PROVIDER); + EXPECT_CALL(*mock_hats_service(), + LaunchSurvey(kHatsSurveyTriggerTrustSafetyPrivacySettings, + testing::_, testing::_, expected_psd)); + service()->InteractedWithPrivacySettings(web_contents.get()); + task_environment()->RunUntilIdle(); + service()->OpenedNewTabPage(); } TEST_F(TrustSafetySentimentServiceTest, ActiveIncognitoPreventsSurvey) {
diff --git a/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller_unittest.cc b/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller_unittest.cc index 3d09d6a..23ac96a9 100644 --- a/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller_unittest.cc +++ b/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller_unittest.cc
@@ -24,6 +24,7 @@ #include "chrome/test/base/testing_profile.h" #include "components/password_manager/core/browser/mock_password_feature_manager.h" #include "components/password_manager/core/browser/mock_password_store.h" +#include "components/password_manager/core/browser/mock_smart_bubble_stats_store.h" #include "components/password_manager/core/browser/password_form_metrics_recorder.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h" #include "components/password_manager/core/browser/password_manager_test_utils.h" @@ -106,6 +107,8 @@ &password_manager::BuildPasswordStore< content::BrowserContext, testing::StrictMock<password_manager::MockPasswordStore>>)); + EXPECT_CALL(*GetStore(), GetSmartBubbleStatsStore) + .WillRepeatedly(Return(&mock_smart_bubble_stats_store_)); pending_password_.url = GURL(kSiteOrigin); pending_password_.signon_realm = kSiteOrigin; pending_password_.username_value = kUsername; @@ -129,6 +132,10 @@ .get()); } + password_manager::MockSmartBubbleStatsStore* mock_smart_bubble_stats_store() { + return &mock_smart_bubble_stats_store_; + } + PasswordsModelDelegateMock* delegate() { return mock_delegate_.get(); } password_manager::MockPasswordFeatureManager* password_feature_manager() { @@ -171,6 +178,8 @@ testing::NiceMock<password_manager::MockPasswordFeatureManager> password_feature_manager_; std::unique_ptr<PasswordsModelDelegateMock> mock_delegate_; + testing::NiceMock<password_manager::MockSmartBubbleStatsStore> + mock_smart_bubble_stats_store_; password_manager::PasswordForm pending_password_; }; @@ -292,7 +301,7 @@ password_manager::InteractionsStats stats = GetTestStats(); stats.dismissal_count++; stats.update_time = now; - EXPECT_CALL(*GetStore(), AddSiteStatsImpl(stats)); + EXPECT_CALL(*mock_smart_bubble_stats_store(), AddSiteStats(stats)); EXPECT_CALL(*delegate(), OnNoInteraction()); EXPECT_CALL(*delegate(), SavePassword(_, _)).Times(0); EXPECT_CALL(*delegate(), NeverSavePassword()).Times(0); @@ -309,7 +318,8 @@ EXPECT_TRUE(controller()->enable_editing()); EXPECT_FALSE(controller()->IsCurrentStateUpdate()); - EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin())); + EXPECT_CALL(*mock_smart_bubble_stats_store(), + RemoveSiteStats(GURL(kSiteOrigin).GetOrigin())); EXPECT_CALL(*delegate(), OnPasswordsRevealed()).Times(0); EXPECT_CALL(*delegate(), SavePassword(pending_password().username_value, pending_password().password_value)); @@ -334,7 +344,8 @@ EXPECT_FALSE(controller()->IsCurrentStateUpdate()); EXPECT_FALSE(controller()->IsAccountStorageOptInRequired()); - EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin())); + EXPECT_CALL(*mock_smart_bubble_stats_store(), + RemoveSiteStats(GURL(kSiteOrigin).GetOrigin())); EXPECT_CALL(*delegate(), OnPasswordsRevealed()).Times(0); EXPECT_CALL(*delegate(), SavePassword(pending_password().username_value, pending_password().password_value)); @@ -359,7 +370,8 @@ EXPECT_FALSE(controller()->IsCurrentStateUpdate()); EXPECT_TRUE(controller()->IsAccountStorageOptInRequired()); - EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin())); + EXPECT_CALL(*mock_smart_bubble_stats_store(), + RemoveSiteStats(GURL(kSiteOrigin).GetOrigin())); EXPECT_CALL(*delegate(), SavePassword).Times(0); EXPECT_CALL(*delegate(), NeverSavePassword()).Times(0); EXPECT_CALL(*delegate(), OnNopeUpdateClicked()).Times(0); @@ -385,7 +397,8 @@ EXPECT_TRUE(controller()->IsCurrentStateUpdate()); EXPECT_FALSE(controller()->IsAccountStorageOptInRequired()); - EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin())); + EXPECT_CALL(*mock_smart_bubble_stats_store(), + RemoveSiteStats(GURL(kSiteOrigin).GetOrigin())); EXPECT_CALL(*delegate(), SavePassword(pending_password().username_value, pending_password().password_value)); EXPECT_CALL(*delegate(), NeverSavePassword()).Times(0); @@ -403,7 +416,8 @@ controller()->OnCredentialEdited(kUsernameNew, kPasswordEdited); EXPECT_FALSE(controller()->IsCurrentStateUpdate()); - EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin())); + EXPECT_CALL(*mock_smart_bubble_stats_store(), + RemoveSiteStats(GURL(kSiteOrigin).GetOrigin())); EXPECT_CALL(*delegate(), SavePassword(Eq(kUsernameNew), Eq(kPasswordEdited))); EXPECT_CALL(*delegate(), NeverSavePassword()).Times(0); EXPECT_CALL(*delegate(), OnNopeUpdateClicked()).Times(0); @@ -414,7 +428,8 @@ TEST_F(SaveUpdateWithAccountStoreBubbleControllerTest, ClickNever) { PretendPasswordWaiting(); - EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin())); + EXPECT_CALL(*mock_smart_bubble_stats_store(), + RemoveSiteStats(GURL(kSiteOrigin).GetOrigin())); EXPECT_CALL(*delegate(), SavePassword(_, _)).Times(0); EXPECT_CALL(*delegate(), NeverSavePassword()); controller()->OnNeverForThisSiteClicked(); @@ -429,7 +444,8 @@ EXPECT_TRUE(controller()->enable_editing()); EXPECT_TRUE(controller()->IsCurrentStateUpdate()); - EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin())); + EXPECT_CALL(*mock_smart_bubble_stats_store(), + RemoveSiteStats(GURL(kSiteOrigin).GetOrigin())); EXPECT_CALL(*delegate(), OnPasswordsRevealed()).Times(0); EXPECT_CALL(*delegate(), SavePassword(pending_password().username_value, pending_password().password_value)); @@ -446,7 +462,8 @@ controller()->OnCredentialEdited(kUsernameExisting, kPasswordEdited); EXPECT_TRUE(controller()->IsCurrentStateUpdate()); - EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin())); + EXPECT_CALL(*mock_smart_bubble_stats_store(), + RemoveSiteStats(GURL(kSiteOrigin).GetOrigin())); EXPECT_CALL(*delegate(), SavePassword(Eq(kUsernameExisting), Eq(kPasswordEdited))); EXPECT_CALL(*delegate(), NeverSavePassword()).Times(0); @@ -463,7 +480,8 @@ TEST_F(SaveUpdateWithAccountStoreBubbleControllerTest, EditCredential) { PretendPasswordWaiting(); - EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin())); + EXPECT_CALL(*mock_smart_bubble_stats_store(), + RemoveSiteStats(GURL(kSiteOrigin).GetOrigin())); const std::u16string kExpectedUsername = u"new_username"; const std::u16string kExpectedPassword = u"new_password"; @@ -477,8 +495,16 @@ DestroyModelAndVerifyControllerExpectations(); } +class SaveUpdateWithAccountStoreBubbleControllerUKMTest + : public SaveUpdateWithAccountStoreBubbleControllerTest, + public testing::WithParamInterface< + std::tuple<bool /* whether from the credential management API*/, + bool /* is update bubble */, + password_manager::PasswordFormMetricsRecorder:: + BubbleDismissalReason>> {}; + // Verify that URL keyed metrics are properly recorded. -TEST_F(SaveUpdateWithAccountStoreBubbleControllerTest, RecordUKMs) { +TEST_P(SaveUpdateWithAccountStoreBubbleControllerUKMTest, RecordUKMs) { using BubbleDismissalReason = password_manager::PasswordFormMetricsRecorder::BubbleDismissalReason; using BubbleTrigger = @@ -486,109 +512,108 @@ using password_manager::metrics_util::CredentialSourceType; using UkmEntry = ukm::builders::PasswordForm; - // |credential_management_api| defines whether credentials originate from the - // credential management API. - for (const bool credential_management_api : {false, true}) { - // |update| defines whether this is an update or a save bubble. - for (const bool update : {false, true}) { - for (const auto interaction : - {BubbleDismissalReason::kAccepted, BubbleDismissalReason::kDeclined, - BubbleDismissalReason::kIgnored}) { - SCOPED_TRACE(testing::Message() - << "update = " << update - << ", interaction = " << static_cast<int64_t>(interaction) - << ", credential management api =" - << credential_management_api); - ukm::TestAutoSetUkmRecorder test_ukm_recorder; - { - // Setup metrics recorder - auto recorder = base::MakeRefCounted< - password_manager::PasswordFormMetricsRecorder>( - true /*is_main_frame_secure*/, kTestSourceId, - /*pref_service=*/nullptr); + bool credential_management_api = std::get<0>(GetParam()); + bool update = std::get<1>(GetParam()); + BubbleDismissalReason interaction = std::get<2>(GetParam()); - // Exercise bubble. - ON_CALL(*delegate(), GetPasswordFormMetricsRecorder()) - .WillByDefault(Return(recorder.get())); - ON_CALL(*delegate(), GetCredentialSource()) - .WillByDefault( - Return(credential_management_api - ? CredentialSourceType::kCredentialManagementAPI - : CredentialSourceType::kPasswordManager)); + SCOPED_TRACE(testing::Message() + << "update = " << update + << ", interaction = " << static_cast<int64_t>(interaction) + << ", credential management api =" << credential_management_api); + ukm::TestAutoSetUkmRecorder test_ukm_recorder; + { + // Setup metrics recorder + auto recorder = + base::MakeRefCounted<password_manager::PasswordFormMetricsRecorder>( + true /*is_main_frame_secure*/, kTestSourceId, + /*pref_service=*/nullptr); - if (update) - PretendUpdatePasswordWaiting(); - else - PretendPasswordWaiting(); + // Exercise bubble. + ON_CALL(*delegate(), GetPasswordFormMetricsRecorder()) + .WillByDefault(Return(recorder.get())); + ON_CALL(*delegate(), GetCredentialSource()) + .WillByDefault( + Return(credential_management_api + ? CredentialSourceType::kCredentialManagementAPI + : CredentialSourceType::kPasswordManager)); - if (interaction == BubbleDismissalReason::kAccepted) { - EXPECT_CALL(*GetStore(), - RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin())); - EXPECT_CALL(*delegate(), - SavePassword(pending_password().username_value, - pending_password().password_value)); - controller()->OnSaveClicked(); - } else if (interaction == BubbleDismissalReason::kDeclined && - update) { - EXPECT_CALL(*delegate(), SavePassword(_, _)).Times(0); - controller()->OnNopeUpdateClicked(); - } else if (interaction == BubbleDismissalReason::kDeclined && - !update) { - EXPECT_CALL(*GetStore(), - RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin())); - EXPECT_CALL(*delegate(), SavePassword(_, _)).Times(0); - EXPECT_CALL(*delegate(), NeverSavePassword()); - controller()->OnNeverForThisSiteClicked(); - } else if (interaction == BubbleDismissalReason::kIgnored && update) { - EXPECT_CALL(*delegate(), SavePassword(_, _)).Times(0); - EXPECT_CALL(*delegate(), NeverSavePassword()).Times(0); - } else if (interaction == BubbleDismissalReason::kIgnored && - !update) { - EXPECT_CALL(*GetStore(), AddSiteStatsImpl(testing::_)); - EXPECT_CALL(*delegate(), OnNoInteraction()); - EXPECT_CALL(*delegate(), SavePassword(_, _)).Times(0); - EXPECT_CALL(*delegate(), NeverSavePassword()).Times(0); - } else { - NOTREACHED(); - } - DestroyModelAndVerifyControllerExpectations(); - } + if (update) + PretendUpdatePasswordWaiting(); + else + PretendPasswordWaiting(); - ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(delegate())); - // Flush async calls on password store. - base::RunLoop().RunUntilIdle(); - ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(GetStore())); - - // Verify metrics. - const auto& entries = - test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName); - EXPECT_EQ(1u, entries.size()); - for (const auto* entry : entries) { - EXPECT_EQ(kTestSourceId, entry->source_id); - test_ukm_recorder.ExpectEntryMetric( - entry, - update ? UkmEntry::kUpdating_Prompt_ShownName - : UkmEntry::kSaving_Prompt_ShownName, - 1); - test_ukm_recorder.ExpectEntryMetric( - entry, - update ? UkmEntry::kUpdating_Prompt_TriggerName - : UkmEntry::kSaving_Prompt_TriggerName, - static_cast<int64_t>( - credential_management_api - ? BubbleTrigger::kCredentialManagementAPIAutomatic - : BubbleTrigger::kPasswordManagerSuggestionAutomatic)); - test_ukm_recorder.ExpectEntryMetric( - entry, - update ? UkmEntry::kUpdating_Prompt_InteractionName - : UkmEntry::kSaving_Prompt_InteractionName, - static_cast<int64_t>(interaction)); - } - } + if (interaction == BubbleDismissalReason::kAccepted) { + EXPECT_CALL(*mock_smart_bubble_stats_store(), + RemoveSiteStats(GURL(kSiteOrigin).GetOrigin())); + EXPECT_CALL(*delegate(), SavePassword(pending_password().username_value, + pending_password().password_value)); + controller()->OnSaveClicked(); + } else if (interaction == BubbleDismissalReason::kDeclined && update) { + EXPECT_CALL(*delegate(), SavePassword(_, _)).Times(0); + controller()->OnNopeUpdateClicked(); + } else if (interaction == BubbleDismissalReason::kDeclined && !update) { + EXPECT_CALL(*mock_smart_bubble_stats_store(), + RemoveSiteStats(GURL(kSiteOrigin).GetOrigin())); + EXPECT_CALL(*delegate(), SavePassword(_, _)).Times(0); + EXPECT_CALL(*delegate(), NeverSavePassword()); + controller()->OnNeverForThisSiteClicked(); + } else if (interaction == BubbleDismissalReason::kIgnored && update) { + EXPECT_CALL(*delegate(), SavePassword(_, _)).Times(0); + EXPECT_CALL(*delegate(), NeverSavePassword()).Times(0); + } else if (interaction == BubbleDismissalReason::kIgnored && !update) { + EXPECT_CALL(*mock_smart_bubble_stats_store(), AddSiteStats); + EXPECT_CALL(*delegate(), OnNoInteraction()); + EXPECT_CALL(*delegate(), SavePassword(_, _)).Times(0); + EXPECT_CALL(*delegate(), NeverSavePassword()).Times(0); + } else { + NOTREACHED(); } + DestroyModelAndVerifyControllerExpectations(); + } + + // Flush async calls on password store. + base::RunLoop().RunUntilIdle(); + + // Verify metrics. + const auto& entries = + test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName); + EXPECT_EQ(1u, entries.size()); + for (const auto* entry : entries) { + EXPECT_EQ(kTestSourceId, entry->source_id); + test_ukm_recorder.ExpectEntryMetric( + entry, + update ? UkmEntry::kUpdating_Prompt_ShownName + : UkmEntry::kSaving_Prompt_ShownName, + 1); + test_ukm_recorder.ExpectEntryMetric( + entry, + update ? UkmEntry::kUpdating_Prompt_TriggerName + : UkmEntry::kSaving_Prompt_TriggerName, + static_cast<int64_t>( + credential_management_api + ? BubbleTrigger::kCredentialManagementAPIAutomatic + : BubbleTrigger::kPasswordManagerSuggestionAutomatic)); + test_ukm_recorder.ExpectEntryMetric( + entry, + update ? UkmEntry::kUpdating_Prompt_InteractionName + : UkmEntry::kSaving_Prompt_InteractionName, + static_cast<int64_t>(interaction)); } } +INSTANTIATE_TEST_SUITE_P( + SaveUpdateWithAccountStoreBubbleController, + SaveUpdateWithAccountStoreBubbleControllerUKMTest, + testing::Combine( + testing::Bool(), + testing::Bool(), + testing::Values(password_manager::PasswordFormMetricsRecorder:: + BubbleDismissalReason::kAccepted, + password_manager::PasswordFormMetricsRecorder:: + BubbleDismissalReason::kDeclined, + password_manager::PasswordFormMetricsRecorder:: + BubbleDismissalReason::kIgnored))); + class SaveUpdateWithAccountStoreBubbleControllerPasswordRevealingTest : public SaveUpdateWithAccountStoreBubbleControllerTest, public testing::WithParamInterface<
diff --git a/chrome/browser/ui/popup_browsertest.cc b/chrome/browser/ui/popup_browsertest.cc index 3c27e2f..cfbbc192b 100644 --- a/chrome/browser/ui/popup_browsertest.cc +++ b/chrome/browser/ui/popup_browsertest.cc
@@ -26,7 +26,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "ash/shell.h" -#include "ui/display/test/display_manager_test_api.h" +#include "ui/display/test/display_manager_test_api.h" // nogncheck #endif // BUILDFLAG(IS_CHROMEOS_ASH) namespace {
diff --git a/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.cc b/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.cc index 86bc7d3..19fe7f8 100644 --- a/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.cc +++ b/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.cc
@@ -119,22 +119,22 @@ const std::u16string& shared_tab_name, const std::u16string& app_name, bool shared_tab, - bool can_share, + bool can_share_instead, absl::optional<FocusTarget> focus_target, TabSharingUI* ui, bool favicons_used_for_switch_to_tab_button) { DCHECK(infobar_manager); return infobar_manager->AddInfoBar( CreateConfirmInfoBar(base::WrapUnique(new TabSharingInfoBarDelegate( - shared_tab_name, app_name, shared_tab, can_share, focus_target, ui, - favicons_used_for_switch_to_tab_button)))); + shared_tab_name, app_name, shared_tab, can_share_instead, + focus_target, ui, favicons_used_for_switch_to_tab_button)))); } TabSharingInfoBarDelegate::TabSharingInfoBarDelegate( std::u16string shared_tab_name, std::u16string app_name, bool shared_tab, - bool can_share, + bool can_share_instead, absl::optional<FocusTarget> focus_target, TabSharingUI* ui, bool favicons_used_for_switch_to_tab_button) @@ -147,7 +147,7 @@ if (focus_target.has_value()) { secondary_button_ = std::make_unique<SwitchToTabButton>(*focus_target, shared_tab); - } else if (can_share) { + } else if (can_share_instead) { secondary_button_ = std::make_unique<ShareTabInsteadButton>(ui_); } }
diff --git a/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.h b/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.h index 557014d..7c8f4522 100644 --- a/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.h +++ b/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.h
@@ -46,15 +46,15 @@ // // If |focus_target| has a value, the secondary button switches focus. // The image on the secondary button is derived from |focus_target|. - // Else, if |can_share|, the secondary button changes the capture target - // to be the tab associated with |this| object. + // Else, if |can_share_instead|, the secondary button changes the + // capture target to be the tab associated with |this| object. // Otherwise, there is no secondary button. static infobars::InfoBar* Create( infobars::ContentInfoBarManager* infobar_manager, const std::u16string& shared_tab_name, const std::u16string& app_name, bool shared_tab, - bool can_share, + bool can_share_instead, absl::optional<FocusTarget> focus_target, TabSharingUI* ui, bool favicons_used_for_switch_to_tab_button = false); @@ -65,7 +65,7 @@ TabSharingInfoBarDelegate(std::u16string shared_tab_name, std::u16string app_name, bool shared_tab, - bool can_share, + bool can_share_instead, absl::optional<FocusTarget> focus_target, TabSharingUI* ui, bool favicons_used_for_switch_to_tab_button);
diff --git a/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate_unittest.cc b/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate_unittest.cc index ace19e72..5058b4ba 100644 --- a/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate_unittest.cc +++ b/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate_unittest.cc
@@ -53,13 +53,13 @@ std::u16string shared_tab_name, std::u16string app_name, bool shared_tab, - bool can_share, + bool can_share_instead, int tab_index = 0, absl::optional<FocusTarget> focus_target = absl::nullopt) { return TabSharingInfoBarDelegate::Create( infobars::ContentInfoBarManager::FromWebContents( browser()->tab_strip_model()->GetWebContentsAt(tab_index)), - shared_tab_name, app_name, shared_tab, can_share, focus_target, + shared_tab_name, app_name, shared_tab, can_share_instead, focus_target, tab_sharing_mock_ui(), favicons_used_for_switch_to_tab_button_); } @@ -67,11 +67,11 @@ std::u16string shared_tab_name, std::u16string app_name, bool shared_tab, - bool can_share, + bool can_share_instead, int tab_index = 0, absl::optional<FocusTarget> focus_target = absl::nullopt) { infobars::InfoBar* infobar = - CreateInfobar(shared_tab_name, app_name, shared_tab, can_share, + CreateInfobar(shared_tab_name, app_name, shared_tab, can_share_instead, tab_index, focus_target); return static_cast<ConfirmInfoBarDelegate*>(infobar->delegate()); } @@ -222,14 +222,14 @@ // Create infobar for shared tab. AddTab(browser(), GURL("about:blank")); ConfirmInfoBarDelegate* delegate_shared_tab = CreateDelegate( - std::u16string(), kAppName, true, false /* can_share */, 0); + std::u16string(), kAppName, true, false /* can_share_instead */, 0); EXPECT_EQ(delegate_shared_tab->GetButtons(), ConfirmInfoBarDelegate::BUTTON_OK); // Create infobar for another not shared tab. AddTab(browser(), GURL("about:blank")); - ConfirmInfoBarDelegate* delegate = - CreateDelegate(kSharedTabName, kAppName, false, false /* can_share */, 1); + ConfirmInfoBarDelegate* delegate = CreateDelegate( + kSharedTabName, kAppName, false, false /* can_share_instead */, 1); EXPECT_EQ(delegate->GetButtons(), ConfirmInfoBarDelegate::BUTTON_OK); }
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc index 18897624..bbe72d2c 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc
@@ -1223,6 +1223,14 @@ EXPECT_TRUE(web_app_menu_button_->HasFocus()); } +// Tests the app icon and title are not shown. +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, IconAndTitleNotShown) { + SetUpWebApp(); + auto* browser_view = BrowserView::GetBrowserViewForBrowser(app_browser_); + EXPECT_FALSE(browser_view->ShouldShowWindowIcon()); + EXPECT_FALSE(browser_view->ShouldShowWindowTitle()); +} + // Tests that the custom tab bar is focusable from the keyboard. IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, CustomTabBarIsFocusable) {
diff --git a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc index 265ca29..cfb7363 100644 --- a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc +++ b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc
@@ -27,6 +27,7 @@ #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" +#include "extensions/common/constants.h" #include "net/base/url_util.h" #include "services/network/public/cpp/is_potentially_trustworthy.h" #include "ui/gfx/color_palette.h" @@ -130,6 +131,18 @@ static_cast<uint8_t*>(bitmap->getPixels()), bitmap->computeByteSize())); } +bool CanFocusCapturer(GlobalRenderFrameHostId capturer_id) { + // Note that both FromID() and FromRenderFrameHost() are robust to null input. + WebContents* const capturer = + WebContents::FromRenderFrameHost(RenderFrameHost::FromID(capturer_id)); + if (!capturer) { + return false; + } + + return !capturer->GetLastCommittedURL().SchemeIs( + extensions::kExtensionScheme); +} + } // namespace // static @@ -148,6 +161,7 @@ std::u16string app_name, bool favicons_used_for_switch_to_tab_button) : capturer_(capturer), + can_focus_capturer_(CanFocusCapturer(capturer)), shared_tab_media_id_(media_id), app_name_(std::move(app_name)), favicons_used_for_switch_to_tab_button_( @@ -329,24 +343,30 @@ const bool is_capturing_tab = (GetGlobalId(contents) == capturer_); const bool is_captured_tab = (contents == shared_tab_); - // Self-capture -> no switch-to button. - // Capturer -> switch-to-captured. - // Captured -> switch-to-capturer. - // Otherwise -> no switch-to button. + // Never show the [share this tab instead] button on either the capturing + // tab or the captured tab. + const bool can_share_instead = + !source_callback_.is_null() && !is_capturing_tab && !is_captured_tab; + absl::optional<TabSharingInfoBarDelegate::FocusTarget> focus_target; - if (is_capturing_tab && !is_captured_tab) { - focus_target = {GetGlobalId(shared_tab_), TabFavicon(shared_tab_)}; - captured_favicon_hash_ = GetHash(focus_target->icon); - } else if (!is_capturing_tab && is_captured_tab) { - focus_target = {capturer_, TabFavicon(capturer_)}; - capturer_favicon_hash_ = GetHash(focus_target->icon); + if (can_focus_capturer_) { + // Self-capture -> no switch-to button. + // Capturer -> switch-to-captured. + // Captured -> switch-to-capturer. + // Otherwise -> no switch-to button. + if (is_capturing_tab && !is_captured_tab) { + focus_target = {GetGlobalId(shared_tab_), TabFavicon(shared_tab_)}; + captured_favicon_hash_ = GetHash(focus_target->icon); + } else if (!is_capturing_tab && is_captured_tab) { + focus_target = {capturer_, TabFavicon(capturer_)}; + capturer_favicon_hash_ = GetHash(focus_target->icon); + } } infobars_[contents] = TabSharingInfoBarDelegate::Create( infobar_manager, shared_tab_name_, app_name_, - shared_tab_ == contents /*shared_tab*/, - !source_callback_.is_null() /*can_share*/, focus_target, this, - favicons_used_for_switch_to_tab_button_); + shared_tab_ == contents /*shared_tab*/, can_share_instead, focus_target, + this, favicons_used_for_switch_to_tab_button_); } void TabSharingUIViews::RemoveInfobarsForAllTabs() {
diff --git a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.h b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.h index d22c1c1..22462c1 100644 --- a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.h +++ b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.h
@@ -112,6 +112,7 @@ std::map<content::WebContents*, infobars::InfoBar*> infobars_; const content::GlobalRenderFrameHostId capturer_; + const bool can_focus_capturer_; content::DesktopMediaID shared_tab_media_id_; const std::u16string app_name_; content::WebContents* shared_tab_;
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc index 8e856b9f..17f1827 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -101,7 +101,7 @@ #include "ui/aura/client/screen_position_client.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/display/manager/display_manager.h" -#include "ui/display/test/display_manager_test_api.h" +#include "ui/display/test/display_manager_test_api.h" // nogncheck #include "ui/events/base_event_utils.h" #include "ui/events/gesture_detection/gesture_configuration.h" #endif
diff --git a/chrome/browser/ui/webui/chromeos/login/os_install_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/os_install_screen_handler.cc index 2e39545..ba0862a 100644 --- a/chrome/browser/ui/webui/chromeos/login/os_install_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/os_install_screen_handler.cc
@@ -87,7 +87,7 @@ ShowScreen(kScreenId); } -void OsInstallScreenHandler::Bind(OsInstallScreen* screen) { +void OsInstallScreenHandler::Bind(ash::OsInstallScreen* screen) { screen_ = screen; BaseScreenHandler::SetBaseScreen(screen_); }
diff --git a/chrome/browser/ui/webui/chromeos/login/os_install_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/os_install_screen_handler.h index 6f8dab8..8f29b24 100644 --- a/chrome/browser/ui/webui/chromeos/login/os_install_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/os_install_screen_handler.h
@@ -9,13 +9,15 @@ #include "chromeos/dbus/os_install/os_install_client.h" #include "third_party/abseil-cpp/absl/types/optional.h" +namespace ash { +class OsInstallScreen; +} + namespace login { class LocalizedValuesBuilder; } // namespace login namespace chromeos { - -class OsInstallScreen; class JSCallsContainer; // Interface for dependency injection between OsInstallScreen and its @@ -30,7 +32,7 @@ virtual void Show() = 0; // Binds |screen| to the view. - virtual void Bind(OsInstallScreen* screen) = 0; + virtual void Bind(ash::OsInstallScreen* screen) = 0; // Unbinds the screen from the view. virtual void Unbind() = 0; @@ -59,7 +61,7 @@ // OsInstallScreenView: void Show() override; - void Bind(OsInstallScreen* screen) override; + void Bind(ash::OsInstallScreen* screen) override; void Unbind() override; void ShowStep(const char* step) override; void ShowConfirmStep() override; @@ -71,7 +73,7 @@ void OsInstallStarted(absl::optional<OsInstallClient::Status> status); - OsInstallScreen* screen_ = nullptr; + ash::OsInstallScreen* screen_ = nullptr; base::WeakPtrFactory<OsInstallScreenHandler> weak_factory_{this}; };
diff --git a/chrome/browser/ui/webui/history/foreign_session_handler.cc b/chrome/browser/ui/webui/history/foreign_session_handler.cc index 30ff0a7..44e4b70 100644 --- a/chrome/browser/ui/webui/history/foreign_session_handler.cc +++ b/chrome/browser/ui/webui/history/foreign_session_handler.cc
@@ -261,6 +261,13 @@ } } +void ForeignSessionHandler::OnJavascriptDisallowed() { + // Avoid notifying Javascript listeners due to foreign session changes, which + // is now disallowed and would otherwise run into CHECK failures in + // OnForeignSessionUpdated(). + foreign_session_updated_subscription_ = base::CallbackListSubscription(); +} + void ForeignSessionHandler::OnForeignSessionUpdated() { FireWebUIListener("foreign-sessions-changed", std::move(GetForeignSessions()));
diff --git a/chrome/browser/ui/webui/history/foreign_session_handler.h b/chrome/browser/ui/webui/history/foreign_session_handler.h index cb5ba68..65b1305 100644 --- a/chrome/browser/ui/webui/history/foreign_session_handler.h +++ b/chrome/browser/ui/webui/history/foreign_session_handler.h
@@ -51,6 +51,7 @@ // WebUIMessageHandler implementation. void RegisterMessages() override; void OnJavascriptAllowed() override; + void OnJavascriptDisallowed() override; ForeignSessionHandler(); ~ForeignSessionHandler() override; @@ -73,6 +74,8 @@ static sync_sessions::OpenTabsUIDelegate* GetOpenTabsUIDelegate( content::WebUI* web_ui); + void SetWebUIForTesting(content::WebUI* web_ui) { set_web_ui(web_ui); } + private: void OnForeignSessionUpdated();
diff --git a/chrome/browser/ui/webui/history/foreign_session_handler_unittest.cc b/chrome/browser/ui/webui/history/foreign_session_handler_unittest.cc new file mode 100644 index 0000000..50d489b8 --- /dev/null +++ b/chrome/browser/ui/webui/history/foreign_session_handler_unittest.cc
@@ -0,0 +1,134 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/history/foreign_session_handler.h" + +#include "base/callback_list.h" +#include "chrome/browser/sync/session_sync_service_factory.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "components/sync_sessions/session_sync_service.h" +#include "content/public/test/test_web_ui.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace browser_sync { + +namespace { + +// Partial SessionSyncService that can fake behavior for +// SubscribeToForeignSessionsChanged() including the notification to +// subscribers. +class FakeSessionSyncService : public sync_sessions::SessionSyncService { + public: + FakeSessionSyncService() = default; + ~FakeSessionSyncService() override = default; + + void NotifyForeignSessionsChanged() { subscriber_list_.Notify(); } + + // SessionSyncService overrides. + syncer::GlobalIdMapper* GetGlobalIdMapper() const override { return nullptr; } + + sync_sessions::OpenTabsUIDelegate* GetOpenTabsUIDelegate() override { + return nullptr; + } + + base::CallbackListSubscription SubscribeToForeignSessionsChanged( + const base::RepeatingClosure& cb) override { + return subscriber_list_.Add(cb); + } + + base::WeakPtr<syncer::ModelTypeControllerDelegate> GetControllerDelegate() + override { + return nullptr; + } + + void ProxyTabsStateChanged(syncer::DataTypeController::State state) override { + } + + private: + base::RepeatingClosureList subscriber_list_; +}; + +class ForeignSessionHandlerTest : public ChromeRenderViewHostTestHarness { + public: + void SetUp() override { + ChromeRenderViewHostTestHarness::SetUp(); + + web_ui_ = std::make_unique<content::TestWebUI>(); + web_ui_->set_web_contents(web_contents()); + + handler_ = std::make_unique<ForeignSessionHandler>(); + handler_->SetWebUIForTesting(web_ui_.get()); + } + + void TearDown() override { + handler_.reset(); + web_ui_.reset(); + ChromeRenderViewHostTestHarness::TearDown(); + } + + TestingProfile::TestingFactories GetTestingFactories() const override { + return { + {SessionSyncServiceFactory::GetInstance(), + base::BindRepeating([](content::BrowserContext* context) + -> std::unique_ptr<KeyedService> { + return std::make_unique<FakeSessionSyncService>(); + })}, + }; + } + + FakeSessionSyncService* session_sync_service() { + return static_cast<FakeSessionSyncService*>( + SessionSyncServiceFactory::GetForProfile(profile())); + } + + content::TestWebUI* web_ui() { return web_ui_.get(); } + + ForeignSessionHandler* handler() { return handler_.get(); } + + private: + std::unique_ptr<content::TestWebUI> web_ui_; + std::unique_ptr<ForeignSessionHandler> handler_; +}; + +TEST_F(ForeignSessionHandlerTest, + ShouldFireForeignSessionsChangedWhileJavascriptAllowed) { + handler()->AllowJavascriptForTesting(); + ASSERT_TRUE(handler()->IsJavascriptAllowed()); + + web_ui()->ClearTrackedCalls(); + session_sync_service()->NotifyForeignSessionsChanged(); + + ASSERT_EQ(1U, web_ui()->call_data().size()); + + const content::TestWebUI::CallData& call_data = *web_ui()->call_data()[0]; + EXPECT_EQ("cr.webUIListenerCallback", call_data.function_name()); + EXPECT_EQ("foreign-sessions-changed", call_data.arg1()->GetString()); +} + +TEST_F(ForeignSessionHandlerTest, + ShouldNotFireForeignSessionsChangedBeforeJavascriptAllowed) { + ASSERT_FALSE(handler()->IsJavascriptAllowed()); + + web_ui()->ClearTrackedCalls(); + session_sync_service()->NotifyForeignSessionsChanged(); + + EXPECT_EQ(0U, web_ui()->call_data().size()); +} + +TEST_F(ForeignSessionHandlerTest, + ShouldNotFireForeignSessionsChangedAfterJavascriptDisallowed) { + handler()->AllowJavascriptForTesting(); + ASSERT_TRUE(handler()->IsJavascriptAllowed()); + handler()->DisallowJavascript(); + ASSERT_FALSE(handler()->IsJavascriptAllowed()); + + web_ui()->ClearTrackedCalls(); + session_sync_service()->NotifyForeignSessionsChanged(); + + EXPECT_EQ(0U, web_ui()->call_data().size()); +} + +} // namespace + +} // namespace browser_sync
diff --git a/chrome/browser/ui/webui/history_clusters/memories_ui.cc b/chrome/browser/ui/webui/history_clusters/memories_ui.cc index cd5f9ec..162689c 100644 --- a/chrome/browser/ui/webui/history_clusters/memories_ui.cc +++ b/chrome/browser/ui/webui/history_clusters/memories_ui.cc
@@ -42,6 +42,8 @@ source->AddString("headerTitle", u"Based on web activity related to \"$1\""); source->AddString("relatedSearchesLabel", u"Related:"); source->AddString("removeAllFromHistory", u"Remove all from history"); + source->AddString("removeAllFromHistoryToast", u"Pages removed"); + source->AddString("removeFromHistoryToast", u"Page removed"); source->AddString("savedInTabGroup", u"Saved in tab group"); source->AddString("searchPrompt", u"Search clusters"); source->AddString("toggleButtonLabelLess", u"Show less");
diff --git a/chrome/browser/upgrade_detector/get_installed_version_linux_unittest.cc b/chrome/browser/upgrade_detector/get_installed_version_linux_unittest.cc index 7e2269a..f5a3b6f1 100644 --- a/chrome/browser/upgrade_detector/get_installed_version_linux_unittest.cc +++ b/chrome/browser/upgrade_detector/get_installed_version_linux_unittest.cc
@@ -119,8 +119,7 @@ // Tests that the expected instance is returned when the child process reports a // valid version. -// TODO(crbug.com/1230474): Reenable. Failed consistently on Linux Tests (dbg). -TEST_F(GetInstalledVersionLinuxTest, DISABLED_WithVersion) { +TEST_F(GetInstalledVersionLinuxTest, WithVersion) { AddChildCommandLineSwitches(ChildMode::kWithVersion); InstalledAndCriticalVersion versions = GetInstalledVersion(); ASSERT_TRUE(versions.installed_version.IsValid());
diff --git a/chrome/browser/window_placement/window_placement_browsertest.cc b/chrome/browser/window_placement/window_placement_browsertest.cc index 3a1f3af..15efcf9 100644 --- a/chrome/browser/window_placement/window_placement_browsertest.cc +++ b/chrome/browser/window_placement/window_placement_browsertest.cc
@@ -21,7 +21,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "ash/shell.h" -#include "ui/display/test/display_manager_test_api.h" +#include "ui/display/test/display_manager_test_api.h" // nogncheck #endif // BUILDFLAG(IS_CHROMEOS_ASH) class WindowPlacementTest : public InProcessBrowserTest {
diff --git a/chrome/browser/window_placement/window_placement_permission_context_browsertest.cc b/chrome/browser/window_placement/window_placement_permission_context_browsertest.cc index 35cce720..5a74751 100644 --- a/chrome/browser/window_placement/window_placement_permission_context_browsertest.cc +++ b/chrome/browser/window_placement/window_placement_permission_context_browsertest.cc
@@ -22,7 +22,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "ash/shell.h" -#include "ui/display/test/display_manager_test_api.h" +#include "ui/display/test/display_manager_test_api.h" // nogncheck #endif // BUILDFLAG(IS_CHROMEOS_ASH) namespace {
diff --git a/chrome/common/extensions/manifest_handlers/theme_handler.cc b/chrome/common/extensions/manifest_handlers/theme_handler.cc index a41367e..85125318 100644 --- a/chrome/common/extensions/manifest_handlers/theme_handler.cc +++ b/chrome/common/extensions/manifest_handlers/theme_handler.cc
@@ -65,7 +65,7 @@ theme_value->FindDictPath(keys::kThemeColors); if (colors_value) { // Validate that the colors are RGB or RGBA lists. - for (const auto& it : colors_value->DictItems()) { + for (const auto it : colors_value->DictItems()) { if (!it.second.is_list()) { *error = base::ASCIIToUTF16(errors::kInvalidThemeColors); return false;
diff --git a/chrome/installer/setup/google_chrome_behaviors.cc b/chrome/installer/setup/google_chrome_behaviors.cc index 4da165f..37531b4 100644 --- a/chrome/installer/setup/google_chrome_behaviors.cc +++ b/chrome/installer/setup/google_chrome_behaviors.cc
@@ -104,8 +104,7 @@ installer::InstallStatus install_status) { GoogleUpdateSettings::UpdateInstallStatus( install_static::IsSystemInstall(), archive_type, - InstallUtil::GetInstallReturnCode(install_status), - install_static::GetAppGuid()); + InstallUtil::GetInstallReturnCode(install_status)); } // Returns a string holding the following URL query parameters:
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc index 9d37e5f..b5c6a23 100644 --- a/chrome/installer/setup/uninstall.cc +++ b/chrome/installer/setup/uninstall.cc
@@ -46,7 +46,6 @@ #include "chrome/installer/setup/setup_util.h" #include "chrome/installer/setup/user_hive_visitor.h" #include "chrome/installer/util/auto_launch_util.h" -#include "chrome/installer/util/channel_info.h" #include "chrome/installer/util/delete_after_reboot_helper.h" #include "chrome/installer/util/firewall_manager_win.h" #include "chrome/installer/util/google_update_constants.h"
diff --git a/chrome/installer/util/BUILD.gn b/chrome/installer/util/BUILD.gn index 2ea95551d..7e36bd5 100644 --- a/chrome/installer/util/BUILD.gn +++ b/chrome/installer/util/BUILD.gn
@@ -123,6 +123,8 @@ ] sources += [ + "additional_parameters.cc", + "additional_parameters.h", "advanced_firewall_manager_win.cc", "advanced_firewall_manager_win.h", "app_command.cc", @@ -135,8 +137,6 @@ "beacons.h", "callback_work_item.cc", "callback_work_item.h", - "channel_info.cc", - "channel_info.h", "conditional_work_item_list.cc", "conditional_work_item_list.h", "copy_tree_work_item.cc", @@ -295,10 +295,10 @@ test("installer_util_unittests") { sources = [ + "additional_parameters_unittest.cc", "advanced_firewall_manager_win_unittest.cc", "beacons_unittest.cc", "callback_work_item_unittest.cc", - "channel_info_unittest.cc", "conditional_work_item_list_unittest.cc", "copy_tree_work_item_unittest.cc", "create_dir_work_item_unittest.cc",
diff --git a/chrome/installer/util/additional_parameters.cc b/chrome/installer/util/additional_parameters.cc new file mode 100644 index 0000000..a051dc2 --- /dev/null +++ b/chrome/installer/util/additional_parameters.cc
@@ -0,0 +1,129 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/installer/util/additional_parameters.h" + +#include <windows.h> + +#include "base/check.h" +#include "base/strings/string_piece.h" +#include "base/strings/string_util.h" +#include "base/win/registry.h" +#include "chrome/install_static/install_details.h" + +namespace installer { + +namespace { + +constexpr wchar_t kRegValueAp[] = L"ap"; +constexpr base::WStringPiece kFullSuffix = L"-full"; + +// Returns null if the value was not found or otherwise could not be read. +absl::optional<std::wstring> ReadAdditionalParameters() { + absl::optional<std::wstring> result; + base::win::RegKey key; + + if (key.Open(install_static::IsSystemInstall() ? HKEY_LOCAL_MACHINE + : HKEY_CURRENT_USER, + install_static::GetClientStateKeyPath().c_str(), + KEY_WOW64_32KEY | KEY_QUERY_VALUE) == ERROR_SUCCESS) { + result.emplace(); + if (key.ReadValue(kRegValueAp, &result.value()) != ERROR_SUCCESS) + result.reset(); + } + return result; +} + +// Writes `value` to the "ap" value in the registry, or deletes the "ap" value +// if `value` is null. Returns false and sets the Windows last-error code on +// failure; otherwise, returns true. +bool WriteAdditionalParameters(const absl::optional<std::wstring>& value) { + base::win::RegKey key; + LONG result = ERROR_SUCCESS; + + if (!value) { + // Delete the value if it exists. + result = key.Open(install_static::IsSystemInstall() ? HKEY_LOCAL_MACHINE + : HKEY_CURRENT_USER, + install_static::GetClientStateKeyPath().c_str(), + KEY_WOW64_32KEY | KEY_SET_VALUE); + if (result == ERROR_SUCCESS) + result = key.DeleteValue(kRegValueAp); + // Report success if the value was deleted or if either it or the key didn't + // exist to start with. + if (result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND || + result == ERROR_PATH_NOT_FOUND) { + return true; + } + ::SetLastError(result); + return false; + } + + // Write the value to the key. + result = key.Create(install_static::IsSystemInstall() ? HKEY_LOCAL_MACHINE + : HKEY_CURRENT_USER, + install_static::GetClientStateKeyPath().c_str(), + KEY_WOW64_32KEY | KEY_SET_VALUE); + if (result == ERROR_SUCCESS) + result = key.WriteValue(kRegValueAp, value->c_str()); + if (result == ERROR_SUCCESS) + return true; + ::SetLastError(result); + return false; +} + +bool HasFullSuffix(const absl::optional<std::wstring>& value) { + return value ? base::EndsWith(*value, kFullSuffix) : false; +} + +} // namespace + +AdditionalParameters::AdditionalParameters() + : value_(ReadAdditionalParameters()) {} + +AdditionalParameters::~AdditionalParameters() = default; + +const wchar_t* AdditionalParameters::value() const { + return value_ ? value_->c_str() : L""; +} + +wchar_t AdditionalParameters::GetStatsDefault() const { + if (!value_) + return 0; + + static constexpr base::WStringPiece kStatsdef = L"-statsdef_"; + base::WStringPiece value(*value_); + auto pos = value.find(kStatsdef); + if (pos == base::WStringPiece::npos) + return 0; + pos += kStatsdef.size(); + return pos < value.size() ? value[pos] : 0; +} + +bool AdditionalParameters::SetFullSuffix(bool set_full_suffix) { + if (HasFullSuffix(value_) == set_full_suffix) + return false; // Nothing to do. + if (set_full_suffix) { + if (!value_) { + value_ = std::wstring(kFullSuffix); + } else { + value_->append(kFullSuffix.data(), kFullSuffix.size()); + } + } else { + DCHECK(value_); + const auto value_size = value_->size(); + if (value_size == kFullSuffix.size()) { + value_.reset(); + } else { + value_->resize(value_size - kFullSuffix.size()); + } + } + return true; +} + +bool AdditionalParameters::Commit() { + return WriteAdditionalParameters(value_); +} + +} // namespace installer
diff --git a/chrome/installer/util/additional_parameters.h b/chrome/installer/util/additional_parameters.h new file mode 100644 index 0000000..52e741a --- /dev/null +++ b/chrome/installer/util/additional_parameters.h
@@ -0,0 +1,52 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_INSTALLER_UTIL_ADDITIONAL_PARAMETERS_H_ +#define CHROME_INSTALLER_UTIL_ADDITIONAL_PARAMETERS_H_ + +#include <string> + +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace installer { + +// Provides utility functions for accessing and modifying the "additional +// parameters" value stored in the Client State key in the Windows registry. +// This value is included in update checks made by Omaha and is used by the +// update server when selecting a release build. +class AdditionalParameters { + public: + // Loads the value from the registry. + AdditionalParameters(); + AdditionalParameters(const AdditionalParameters&) = delete; + AdditionalParameters& operator=(const AdditionalParameters&) = delete; + ~AdditionalParameters(); + + // Returns the "ap" value. + const wchar_t* value() const; + + // Returns the character identifying the stats default state (i.e., the + // starting value of the "send usage stats" checkbox during install), or zero + // if the -statsdef_ modifier is not present in the value. + wchar_t GetStatsDefault() const; + + // Adds or removes the -full suffix, returning true if the value is + // modified. Commit() must be used to write modified values back to the + // registry. When such a modification results in an empty value, the "ap" + // value will be removed from the Windows registry upon Commit(). + bool SetFullSuffix(bool value); + + // Commits any changes to the Windows registry. Returns true on success. + // The Windows last-error code is set on failure. + bool Commit(); + + private: + // null if no value is present in the registry, or if any value in the + // registry should be removed on commit. + absl::optional<std::wstring> value_; +}; + +} // namespace installer + +#endif // CHROME_INSTALLER_UTIL_ADDITIONAL_PARAMETERS_H_
diff --git a/chrome/installer/util/additional_parameters_unittest.cc b/chrome/installer/util/additional_parameters_unittest.cc new file mode 100644 index 0000000..919b2121 --- /dev/null +++ b/chrome/installer/util/additional_parameters_unittest.cc
@@ -0,0 +1,156 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/installer/util/additional_parameters.h" + +#include "base/strings/string_piece.h" +#include "base/test/test_reg_util_win.h" +#include "base/win/registry.h" +#include "chrome/install_static/install_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace installer { + +class AdditionalParametersTest : public ::testing::Test { + protected: + AdditionalParametersTest() = default; + + static void CreateKey() { + ASSERT_TRUE( + base::win::RegKey(HKEY_CURRENT_USER, + install_static::GetClientStateKeyPath().c_str(), + KEY_SET_VALUE) + .Valid()); + } + + static void SetAp(const wchar_t* value) { + ASSERT_EQ(base::win::RegKey(HKEY_CURRENT_USER, + install_static::GetClientStateKeyPath().c_str(), + KEY_WOW64_32KEY | KEY_SET_VALUE) + .WriteValue(L"ap", value), + ERROR_SUCCESS); + } + + static absl::optional<std::wstring> GetAp() { + std::wstring value; + if (base::win::RegKey(HKEY_CURRENT_USER, + install_static::GetClientStateKeyPath().c_str(), + KEY_WOW64_32KEY | KEY_QUERY_VALUE) + .ReadValue(L"ap", &value) == ERROR_SUCCESS) { + return std::move(value); + } + return absl::nullopt; + } + + // ::testing::Test: + void SetUp() override { + ASSERT_FALSE(install_static::IsSystemInstall()) + << "system-level not supported"; + ASSERT_NO_FATAL_FAILURE( + registry_override_.OverrideRegistry(HKEY_CURRENT_USER)); + } + + private: + registry_util::RegistryOverrideManager registry_override_; +}; + +TEST_F(AdditionalParametersTest, GetStatsDefaultNoKey) { + AdditionalParameters ap; + EXPECT_EQ(ap.GetStatsDefault(), 0); +} + +TEST_F(AdditionalParametersTest, GetStatsDefaultNoValue) { + ASSERT_NO_FATAL_FAILURE(CreateKey()); + AdditionalParameters ap; + EXPECT_EQ(ap.GetStatsDefault(), 0); +} + +TEST_F(AdditionalParametersTest, GetStatsDefault) { + static constexpr struct { + const wchar_t* ap_value; + wchar_t expected; + } kExpectations[] = { + {L"", 0}, + {L"somevaluebutnothing", 0}, + {L"-statsdef", 0}, + {L"-statsdef_", 0}, + {L"statsdef_0", 0}, + {L"-statsdef_0", L'0'}, + {L"-statsdef_1", L'1'}, + {L"-statsdef_1000", L'1'}, + {L"blahblah-statsdef_1-blah", L'1'}, + }; + for (const auto& expectation : kExpectations) { + ASSERT_NO_FATAL_FAILURE(SetAp(expectation.ap_value)); + AdditionalParameters ap; + EXPECT_EQ(ap.GetStatsDefault(), expectation.expected); + } +} + +TEST_F(AdditionalParametersTest, SetFullSuffixNoKey) { + { + AdditionalParameters ap; + EXPECT_FALSE(ap.SetFullSuffix(false)); + EXPECT_EQ(GetAp(), absl::nullopt); + } + + { + AdditionalParameters ap; + EXPECT_TRUE(ap.SetFullSuffix(true)); + ASSERT_TRUE(ap.Commit()); + EXPECT_EQ(GetAp(), absl::optional<std::wstring>(L"-full")); + } +} + +TEST_F(AdditionalParametersTest, SetFullSuffixNoValue) { + ASSERT_NO_FATAL_FAILURE(CreateKey()); + { + AdditionalParameters ap; + EXPECT_FALSE(ap.SetFullSuffix(false)); + EXPECT_EQ(GetAp(), absl::nullopt); + } + + { + AdditionalParameters ap; + EXPECT_TRUE(ap.SetFullSuffix(true)); + ASSERT_TRUE(ap.Commit()); + EXPECT_EQ(GetAp(), absl::optional<std::wstring>(L"-full")); + } +} + +TEST_F(AdditionalParametersTest, SetFullSuffix) { + static constexpr struct { + const wchar_t* without; + const wchar_t* with; + } kExpectations[] = { + {L"", L"-full"}, + {L"somevaluebutnothing", L"somevaluebutnothing-full"}, + {L"full", L"full-full"}, + {L"-fullspam", L"-fullspam-full"}, + }; + for (const auto& expectation : kExpectations) { + SCOPED_TRACE(::testing::Message() + << "without=\"" << expectation.without << "\" with=\"" + << expectation.with << "\""); + ASSERT_NO_FATAL_FAILURE(SetAp(expectation.without)); + AdditionalParameters ap; + + // Add -full. + EXPECT_TRUE(ap.SetFullSuffix(true)); + ASSERT_TRUE(ap.Commit()); + EXPECT_EQ(GetAp(), absl::optional<std::wstring>(expectation.with)); + + // Remove -full. + EXPECT_TRUE(ap.SetFullSuffix(false)); + ASSERT_TRUE(ap.Commit()); + if (!*expectation.without) { + EXPECT_EQ(GetAp(), absl::nullopt); + } else { + EXPECT_EQ(GetAp(), absl::optional<std::wstring>(expectation.without)); + } + } +} + +} // namespace installer
diff --git a/chrome/installer/util/channel_info.cc b/chrome/installer/util/channel_info.cc deleted file mode 100644 index 7943662..0000000 --- a/chrome/installer/util/channel_info.cc +++ /dev/null
@@ -1,175 +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. - -#include "chrome/installer/util/channel_info.h" - -#include <stddef.h> - -#include "base/cxx17_backports.h" -#include "base/logging.h" -#include "base/win/registry.h" -#include "chrome/installer/util/google_update_constants.h" -#include "chrome/installer/util/util_constants.h" - -using base::win::RegKey; - -namespace { - -const wchar_t kModStage[] = L"-stage:"; -const wchar_t kModStatsDefault[] = L"-statsdef_"; -const wchar_t kSfxFull[] = L"-full"; - -const wchar_t* const kModifiers[] = { - kModStatsDefault, - kModStage, - kSfxFull, -}; - -enum ModifierIndex { MOD_STATS_DEFAULT, MOD_STAGE, SFX_FULL, NUM_MODIFIERS }; - -static_assert(NUM_MODIFIERS == base::size(kModifiers), - "kModifiers disagrees with ModifierIndex; they must match!"); - -// Returns true if the modifier is found, in which case |position| holds the -// location at which the modifier was found. The number of characters in the -// modifier is returned in |length|, if non-nullptr. -bool FindModifier(ModifierIndex index, - const std::wstring& ap_value, - std::wstring::size_type* position, - std::wstring::size_type* length) { - DCHECK_NE(position, nullptr); - std::wstring::size_type mod_position = std::wstring::npos; - std::wstring::size_type mod_length = - std::wstring::traits_type::length(kModifiers[index]); - char last_char = kModifiers[index][mod_length - 1]; - const bool mod_takes_arg = (last_char == L':' || last_char == L'_'); - std::wstring::size_type pos = 0; - do { - mod_position = ap_value.find(kModifiers[index], pos, mod_length); - if (mod_position == std::wstring::npos) - return false; // Modifier not found. - pos = mod_position + mod_length; - // Modifiers that take an argument gobble up to the next separator or to the - // end. - if (mod_takes_arg) { - pos = ap_value.find(L'-', pos); - if (pos == std::wstring::npos) - pos = ap_value.size(); - break; - } - // Regular modifiers must be followed by '-' or the end of the string. - } while (pos != ap_value.size() && ap_value[pos] != L'-'); - DCHECK_NE(mod_position, std::wstring::npos); - *position = mod_position; - if (length != nullptr) - *length = pos - mod_position; - return true; -} - -bool HasModifier(ModifierIndex index, const std::wstring& ap_value) { - DCHECK(index >= 0 && index < NUM_MODIFIERS); - std::wstring::size_type position; - return FindModifier(index, ap_value, &position, nullptr); -} - -std::wstring::size_type FindInsertionPoint(ModifierIndex index, - const std::wstring& ap_value) { - // Return the location of the next modifier. - std::wstring::size_type result; - - for (int scan = index + 1; scan < NUM_MODIFIERS; ++scan) { - if (FindModifier(static_cast<ModifierIndex>(scan), ap_value, &result, - nullptr)) { - return result; - } - } - - return ap_value.size(); -} - -// Returns true if |ap_value| is modified. -bool SetModifier(ModifierIndex index, bool set, std::wstring* ap_value) { - DCHECK(index >= 0 && index < NUM_MODIFIERS); - DCHECK(ap_value); - std::wstring::size_type position; - std::wstring::size_type length; - bool have_modifier = FindModifier(index, *ap_value, &position, &length); - if (set) { - if (!have_modifier) { - ap_value->insert(FindInsertionPoint(index, *ap_value), kModifiers[index]); - return true; - } - } else { - if (have_modifier) { - ap_value->erase(position, length); - return true; - } - } - return false; -} - -// Returns the value of a modifier - that is for a modifier of the form -// "-foo:bar", returns "bar". Returns an empty string if the modifier -// is not present or does not have a value. -std::wstring GetModifierValue(ModifierIndex modifier_index, - const std::wstring& value) { - std::wstring::size_type position; - std::wstring::size_type length; - - if (FindModifier(modifier_index, value, &position, &length)) { - // Return the portion after the prefix. - std::wstring::size_type pfx_length = - std::wstring::traits_type::length(kModifiers[modifier_index]); - DCHECK_LE(pfx_length, length); - return value.substr(position + pfx_length, length - pfx_length); - } - return std::wstring(); -} - -} // namespace - -namespace installer { - -bool ChannelInfo::Initialize(const RegKey& key) { - LONG result = key.ReadValue(google_update::kRegApField, &value_); - return result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND || - result == ERROR_INVALID_HANDLE; -} - -bool ChannelInfo::Write(RegKey* key) const { - DCHECK(key); - // Google Update deletes the value when it is empty, so we may as well, too. - LONG result = value_.empty() ? key->DeleteValue(google_update::kRegApField) - : key->WriteValue(google_update::kRegApField, - value_.c_str()); - if (result != ERROR_SUCCESS) { - LOG(ERROR) << "Failed writing channel info; result: " << result; - return false; - } - return true; -} - -bool ChannelInfo::ClearStage() { - std::wstring::size_type position; - std::wstring::size_type length; - if (FindModifier(MOD_STAGE, value_, &position, &length)) { - value_.erase(position, length); - return true; - } - return false; -} - -std::wstring ChannelInfo::GetStatsDefault() const { - return GetModifierValue(MOD_STATS_DEFAULT, value_); -} - -bool ChannelInfo::HasFullSuffix() const { - return HasModifier(SFX_FULL, value_); -} - -bool ChannelInfo::SetFullSuffix(bool value) { - return SetModifier(SFX_FULL, value, &value_); -} - -} // namespace installer
diff --git a/chrome/installer/util/channel_info.h b/chrome/installer/util/channel_info.h deleted file mode 100644 index 981a820..0000000 --- a/chrome/installer/util/channel_info.h +++ /dev/null
@@ -1,58 +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. - -#ifndef CHROME_INSTALLER_UTIL_CHANNEL_INFO_H_ -#define CHROME_INSTALLER_UTIL_CHANNEL_INFO_H_ - -#include <string> - -namespace base { -namespace win { -class RegKey; -} -} // namespace base - -namespace installer { - -// A helper class for parsing and modifying the Google Update additional -// parameter ("ap") client state value for a product. -class ChannelInfo { - public: - // Initialize an instance from the "ap" value in a given registry key. - // Returns false if the value is present but could not be read from the - // registry. Returns true if the value was not present or could be read. - // Also returns true if the key is not valid. - // An absent "ap" value is treated identically to an empty "ap" value. - bool Initialize(const base::win::RegKey& key); - - // Writes the info to the "ap" value in a given registry key. - // Returns false if the value could not be written to the registry. - bool Write(base::win::RegKey* key) const; - - const std::wstring& value() const { return value_; } - void set_value(const std::wstring& value) { value_ = value; } - bool Equals(const ChannelInfo& other) const { return value_ == other.value_; } - - // Removes the -stage: modifier, returning true if the value is modified. - bool ClearStage(); - - // Returns the string identifying the stats default state (i.e., the starting - // value of the "send usage stats" checkbox during install), or an empty - // string if the -statsdef_ modifier is not present in the value. - std::wstring GetStatsDefault() const; - - // Returns true if the -full suffix is present in the value. - bool HasFullSuffix() const; - - // Adds or removes the -full suffix, returning true if the value is - // modified. - bool SetFullSuffix(bool value); - - private: - std::wstring value_; -}; // class ChannelInfo - -} // namespace installer - -#endif // CHROME_INSTALLER_UTIL_CHANNEL_INFO_H_
diff --git a/chrome/installer/util/channel_info_unittest.cc b/chrome/installer/util/channel_info_unittest.cc deleted file mode 100644 index 75c2b523..0000000 --- a/chrome/installer/util/channel_info_unittest.cc +++ /dev/null
@@ -1,98 +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. - -#include "chrome/installer/util/channel_info.h" - -#include <utility> - -#include "chrome/installer/util/util_constants.h" -#include "testing/gtest/include/gtest/gtest.h" - -using installer::ChannelInfo; - -TEST(ChannelInfoTest, FullInstall) { - ChannelInfo ci; - - ci.set_value(L""); - EXPECT_TRUE(ci.SetFullSuffix(true)); - EXPECT_TRUE(ci.HasFullSuffix()); - EXPECT_EQ(L"-full", ci.value()); - EXPECT_FALSE(ci.SetFullSuffix(true)); - EXPECT_TRUE(ci.HasFullSuffix()); - EXPECT_EQ(L"-full", ci.value()); - EXPECT_TRUE(ci.SetFullSuffix(false)); - EXPECT_FALSE(ci.HasFullSuffix()); - EXPECT_EQ(L"", ci.value()); - EXPECT_FALSE(ci.SetFullSuffix(false)); - EXPECT_FALSE(ci.HasFullSuffix()); - EXPECT_EQ(L"", ci.value()); - - ci.set_value(L"2.0-beta"); - EXPECT_TRUE(ci.SetFullSuffix(true)); - EXPECT_TRUE(ci.HasFullSuffix()); - EXPECT_EQ(L"2.0-beta-full", ci.value()); - EXPECT_FALSE(ci.SetFullSuffix(true)); - EXPECT_TRUE(ci.HasFullSuffix()); - EXPECT_EQ(L"2.0-beta-full", ci.value()); - EXPECT_TRUE(ci.SetFullSuffix(false)); - EXPECT_FALSE(ci.HasFullSuffix()); - EXPECT_EQ(L"2.0-beta", ci.value()); - EXPECT_FALSE(ci.SetFullSuffix(false)); - EXPECT_FALSE(ci.HasFullSuffix()); - EXPECT_EQ(L"2.0-beta", ci.value()); -} - -TEST(ChannelInfoTest, ClearStage) { - ChannelInfo ci; - - ci.set_value(L""); - EXPECT_FALSE(ci.ClearStage()); - EXPECT_EQ(L"", ci.value()); - ci.set_value(L"-stage:spammy"); - EXPECT_TRUE(ci.ClearStage()); - EXPECT_EQ(L"", ci.value()); - - ci.set_value(L"-multi"); - EXPECT_FALSE(ci.ClearStage()); - EXPECT_EQ(L"-multi", ci.value()); - ci.set_value(L"-stage:spammy-multi"); - EXPECT_TRUE(ci.ClearStage()); - EXPECT_EQ(L"-multi", ci.value()); - - ci.set_value(L"2.0-beta-multi"); - EXPECT_FALSE(ci.ClearStage()); - EXPECT_EQ(L"2.0-beta-multi", ci.value()); - ci.set_value(L"2.0-beta-stage:spammy-multi"); - EXPECT_TRUE(ci.ClearStage()); - EXPECT_EQ(L"2.0-beta-multi", ci.value()); - - ci.set_value(L"2.0-beta-stage:-multi"); - EXPECT_TRUE(ci.ClearStage()); - EXPECT_EQ(L"2.0-beta-multi", ci.value()); -} - -TEST(ChannelInfoTest, GetStatsDefault) { - const std::wstring base_values[] = { - L"", L"x64-stable", L"1.1-beta", L"x64-beta", L"2.0-dev", L"x64-dev", - }; - const std::wstring suffixes[] = {L"", L"-multi", L"-multi-chrome"}; - - for (const auto& base_value : base_values) { - for (const auto& suffix : suffixes) { - ChannelInfo ci; - std::wstring channel; - - ci.set_value(base_value + suffix); - EXPECT_EQ(L"", ci.GetStatsDefault()); - ci.set_value(base_value + L"-statsdef" + suffix); - EXPECT_EQ(L"", ci.GetStatsDefault()); - ci.set_value(base_value + L"-statsdef_" + suffix); - EXPECT_EQ(L"", ci.GetStatsDefault()); - ci.set_value(base_value + L"-statsdef_0" + suffix); - EXPECT_EQ(L"0", ci.GetStatsDefault()); - ci.set_value(base_value + L"-statsdef_1" + suffix); - EXPECT_EQ(L"1", ci.GetStatsDefault()); - } - } -}
diff --git a/chrome/installer/util/google_update_settings.cc b/chrome/installer/util/google_update_settings.cc index 5b17407..2c6660b 100644 --- a/chrome/installer/util/google_update_settings.cc +++ b/chrome/installer/util/google_update_settings.cc
@@ -22,7 +22,7 @@ #include "base/win/registry.h" #include "build/branding_buildflags.h" #include "chrome/install_static/install_util.h" -#include "chrome/installer/util/channel_info.h" +#include "chrome/installer/util/additional_parameters.h" #include "chrome/installer/util/install_util.h" #include "chrome/installer/util/installation_state.h" @@ -139,16 +139,6 @@ key.DeleteValue(name) == ERROR_SUCCESS; } -// Initializes |channel_info| based on |system_install|. Returns false on -// failure. -bool InitChannelInfo(bool system_install, - installer::ChannelInfo* channel_info) { - HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; - RegKey key(root_key, install_static::GetClientStateKeyPath().c_str(), - KEY_QUERY_VALUE | KEY_WOW64_32KEY); - return channel_info->Initialize(key); -} - #if BUILDFLAG(GOOGLE_CHROME_BRANDING) // Populates |update_policy| with the UpdatePolicy enum value corresponding to a // DWORD read from the registry and returns true if |value| is within range. @@ -262,13 +252,14 @@ // static bool GoogleUpdateSettings::GetCollectStatsConsentDefault( bool* stats_consent_default) { - installer::ChannelInfo channel_info; - if (InitChannelInfo(IsSystemInstall(), &channel_info)) { - std::wstring stats_default = channel_info.GetStatsDefault(); - if (stats_default == L"0" || stats_default == L"1") { - *stats_consent_default = (stats_default == L"1"); - return true; - } + wchar_t stats_default = installer::AdditionalParameters().GetStatsDefault(); + if (stats_default == L'0') { + *stats_consent_default = false; + return true; + } + if (stats_default == L'1') { + *stats_consent_default = true; + return true; } return false; } @@ -389,44 +380,17 @@ void GoogleUpdateSettings::UpdateInstallStatus( bool system_install, installer::ArchiveType archive_type, - int install_return_code, - const std::wstring& product_guid) { + int install_return_code) { DCHECK(archive_type != installer::UNKNOWN_ARCHIVE_TYPE || install_return_code != 0); - HKEY reg_root = (system_install) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; - RegKey key; - installer::ChannelInfo channel_info; - std::wstring reg_key(google_update::kRegPathClientState); - reg_key.append(L"\\"); - reg_key.append(product_guid); - LONG result = key.Open(reg_root, reg_key.c_str(), - KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_WOW64_32KEY); - if (result == ERROR_SUCCESS) - channel_info.Initialize(key); - else if (result != ERROR_FILE_NOT_FOUND) - LOG(ERROR) << "Failed to open " << reg_key << "; Error: " << result; - + installer::AdditionalParameters additional_parameters; if (UpdateGoogleUpdateApKey(archive_type, install_return_code, - &channel_info)) { - // We have a modified channel_info value to write. - // Create the app's ClientState key if it doesn't already exist. - if (!key.Valid()) { - result = key.Open(reg_root, google_update::kRegPathClientState, - KEY_CREATE_SUB_KEY | KEY_WOW64_32KEY); - if (result == ERROR_SUCCESS) - result = key.CreateKey(product_guid.c_str(), - KEY_SET_VALUE | KEY_WOW64_32KEY); - - if (result != ERROR_SUCCESS) { - LOG(ERROR) << "Failed to create " << reg_key << "; Error: " << result; - return; - } - } - if (!channel_info.Write(&key)) { - LOG(ERROR) << "Failed to write to application's ClientState key " - << google_update::kRegApField << " = " << channel_info.value(); - } + &additional_parameters) && + !additional_parameters.Commit()) { + PLOG(ERROR) << "Failed to write to application's ClientState key " + << google_update::kRegApField << " = " + << additional_parameters.value(); } } @@ -446,26 +410,26 @@ bool GoogleUpdateSettings::UpdateGoogleUpdateApKey( installer::ArchiveType archive_type, int install_return_code, - installer::ChannelInfo* value) { + installer::AdditionalParameters* additional_parameters) { DCHECK(archive_type != installer::UNKNOWN_ARCHIVE_TYPE || install_return_code != 0); bool modified = false; if (archive_type == installer::FULL_ARCHIVE_TYPE || !install_return_code) { - if (value->SetFullSuffix(false)) { + if (additional_parameters->SetFullSuffix(false)) { VLOG(1) << "Removed incremental installer failure key; " "switching to channel: " - << value->value(); + << additional_parameters->value(); modified = true; } } else if (archive_type == installer::INCREMENTAL_ARCHIVE_TYPE) { - if (value->SetFullSuffix(true)) { + if (additional_parameters->SetFullSuffix(true)) { VLOG(1) << "Incremental installer failed; switching to channel: " - << value->value(); + << additional_parameters->value(); modified = true; } else { VLOG(1) << "Incremental installer failure; already on channel: " - << value->value(); + << additional_parameters->value(); } } else { // It's okay if we don't know the archive type. In this case, leave the @@ -473,12 +437,6 @@ DCHECK_EQ(installer::UNKNOWN_ARCHIVE_TYPE, archive_type); } - if (value->ClearStage()) { - VLOG(1) << "Removed (legacy) stage information; switching to channel: " - << value->value(); - modified = true; - } - return modified; }
diff --git a/chrome/installer/util/google_update_settings.h b/chrome/installer/util/google_update_settings.h index a67fc64b..057151bb 100644 --- a/chrome/installer/util/google_update_settings.h +++ b/chrome/installer/util/google_update_settings.h
@@ -23,7 +23,7 @@ #include "components/metrics/client_info.h" namespace installer { -class ChannelInfo; +class AdditionalParameters; class InstallationState; } // namespace installer @@ -176,8 +176,7 @@ // - Unconditionally clear a legacy "-stage:" modifier. static void UpdateInstallStatus(bool system_install, installer::ArchiveType archive_type, - int install_return_code, - const std::wstring& product_guid); + int install_return_code); // Sets the InstallerProgress value in the registry so that Google Update can // provide informative user feedback. |path| is the full path to the app's @@ -204,7 +203,7 @@ // Returns true if |value| is modified. static bool UpdateGoogleUpdateApKey(installer::ArchiveType archive_type, int install_return_code, - installer::ChannelInfo* value); + installer::AdditionalParameters* value); // Returns the effective update policy for |app_guid| as dictated by // Group Policy settings. |is_overridden|, if non-nullptr, is populated with
diff --git a/chrome/installer/util/google_update_settings_unittest.cc b/chrome/installer/util/google_update_settings_unittest.cc index 706a8d19..94a953d 100644 --- a/chrome/installer/util/google_update_settings_unittest.cc +++ b/chrome/installer/util/google_update_settings_unittest.cc
@@ -21,7 +21,7 @@ #include "chrome/common/chrome_constants.h" #include "chrome/install_static/install_util.h" #include "chrome/install_static/test/scoped_install_details.h" -#include "chrome/installer/util/channel_info.h" +#include "chrome/installer/util/additional_parameters.h" #include "chrome/installer/util/fake_installation_state.h" #include "chrome/installer/util/google_update_constants.h" #include "chrome/installer/util/helper.h" @@ -30,12 +30,9 @@ #include "testing/gtest/include/gtest/gtest.h" using base::win::RegKey; -using installer::ChannelInfo; namespace { -const wchar_t kTestProductGuid[] = L"{89F1B351-B15D-48D4-8F10-1298721CF13D}"; - const wchar_t kTestExperimentLabel[] = L"test_label_value"; // This test fixture redirects the HKLM and HKCU registry hives for @@ -108,11 +105,10 @@ bool CreateApKey(WorkItemList* work_item_list, const std::wstring& value) { HKEY reg_root = HKEY_CURRENT_USER; std::wstring reg_key = GetApKeyPath(); - work_item_list->AddCreateRegKeyWorkItem(reg_root, reg_key, - WorkItem::kWow64Default); - work_item_list->AddSetRegValueWorkItem( - reg_root, reg_key, WorkItem::kWow64Default, google_update::kRegApField, - value.c_str(), true); + work_item_list->AddCreateRegKeyWorkItem(reg_root, reg_key, KEY_WOW64_32KEY); + work_item_list->AddSetRegValueWorkItem(reg_root, reg_key, KEY_WOW64_32KEY, + google_update::kRegApField, + value.c_str(), true); if (!work_item_list->Do()) { work_item_list->Rollback(); return false; @@ -120,13 +116,12 @@ return true; } + static std::wstring GetProductGuid() { return install_static::GetAppGuid(); } + // Returns the key path of "ap" key, e.g.: // Google\Update\ClientState\<kTestProductGuid> std::wstring GetApKeyPath() { - std::wstring reg_key(google_update::kRegPathClientState); - reg_key.append(L"\\"); - reg_key.append(kTestProductGuid); - return reg_key; + return install_static::GetClientStateKeyPath(); } // Utility method to read "ap" key value @@ -134,8 +129,8 @@ RegKey key; std::wstring ap_key_value; std::wstring reg_key = GetApKeyPath(); - if (key.Open(HKEY_CURRENT_USER, reg_key.c_str(), KEY_ALL_ACCESS) == - ERROR_SUCCESS) { + if (key.Open(HKEY_CURRENT_USER, reg_key.c_str(), + KEY_WOW64_32KEY | KEY_QUERY_VALUE) == ERROR_SUCCESS) { key.ReadValue(google_update::kRegApField, &ap_key_value); } @@ -230,9 +225,19 @@ const wchar_t* const full[] = {L"-full", L"1.1-full", L"1.1-dev-full"}; static_assert(base::size(full) == base::size(plain), "bad full array size"); const wchar_t* const* input_arrays[] = {plain, full}; - ChannelInfo v; for (const installer::ArchiveType archive_type : archive_types) { + SCOPED_TRACE(::testing::Message() + << "archive_type=" + << (archive_type == installer::UNKNOWN_ARCHIVE_TYPE + ? "UNKNOWN" + : (archive_type == installer::FULL_ARCHIVE_TYPE + ? "FULL" + : "INCREMENTAL"))); for (const int result : results) { + SCOPED_TRACE(::testing::Message() + << "result=" + << (result == installer::FIRST_INSTALL_SUCCESS ? "SUCCESS" + : "FAILED")); // The archive type will/must always be known on install success. if (archive_type == installer::UNKNOWN_ARCHIVE_TYPE && result == installer::FIRST_INSTALL_SUCCESS) { @@ -257,22 +262,22 @@ for (size_t input_idx = 0; input_idx < base::size(plain); ++input_idx) { const wchar_t* input = inputs[input_idx]; const wchar_t* output = outputs[input_idx]; + SCOPED_TRACE(::testing::Message() << "input=\"" << input << "\""); + SCOPED_TRACE(::testing::Message() << "output=\"" << output << "\""); - v.set_value(input); - if (output == v.value()) { + std::unique_ptr<WorkItemList> work_item_list( + WorkItem::CreateWorkItemList()); + + ASSERT_TRUE(CreateApKey(work_item_list.get(), input)); + installer::AdditionalParameters ap; + if (base::WStringPiece(output) == ap.value()) { EXPECT_FALSE(GoogleUpdateSettings::UpdateGoogleUpdateApKey( - archive_type, result, &v)) - << "archive_type: " << archive_type << ", result: " << result - << ", input ap value: " << input; + archive_type, result, &ap)); } else { EXPECT_TRUE(GoogleUpdateSettings::UpdateGoogleUpdateApKey( - archive_type, result, &v)) - << "archive_type: " << archive_type << ", result: " << result - << ", input ap value: " << input; + archive_type, result, &ap)); } - EXPECT_EQ(output, v.value()) - << "archive_type: " << archive_type << ", result: " << result - << ", input ap value: " << input; + EXPECT_STREQ(output, ap.value()); } } } @@ -285,8 +290,7 @@ ASSERT_TRUE(CreateApKey(work_item_list.get(), L"")) << "Failed to create ap key."; GoogleUpdateSettings::UpdateInstallStatus( - false, installer::INCREMENTAL_ARCHIVE_TYPE, installer::INSTALL_FAILED, - kTestProductGuid); + false, installer::INCREMENTAL_ARCHIVE_TYPE, installer::INSTALL_FAILED); EXPECT_STREQ(ReadApKeyValue().c_str(), L"-full"); work_item_list->Rollback(); @@ -294,9 +298,9 @@ // Test incremental install success ASSERT_TRUE(CreateApKey(work_item_list.get(), L"")) << "Failed to create ap key."; - GoogleUpdateSettings::UpdateInstallStatus( - false, installer::INCREMENTAL_ARCHIVE_TYPE, - installer::FIRST_INSTALL_SUCCESS, kTestProductGuid); + GoogleUpdateSettings::UpdateInstallStatus(false, + installer::INCREMENTAL_ARCHIVE_TYPE, + installer::FIRST_INSTALL_SUCCESS); EXPECT_STREQ(ReadApKeyValue().c_str(), L""); work_item_list->Rollback(); @@ -305,8 +309,7 @@ ASSERT_TRUE(CreateApKey(work_item_list.get(), L"-full")) << "Failed to create ap key."; GoogleUpdateSettings::UpdateInstallStatus(false, installer::FULL_ARCHIVE_TYPE, - installer::INSTALL_FAILED, - kTestProductGuid); + installer::INSTALL_FAILED); EXPECT_STREQ(ReadApKeyValue().c_str(), L""); work_item_list->Rollback(); @@ -315,8 +318,7 @@ ASSERT_TRUE(CreateApKey(work_item_list.get(), L"-full")) << "Failed to create ap key."; GoogleUpdateSettings::UpdateInstallStatus(false, installer::FULL_ARCHIVE_TYPE, - installer::FIRST_INSTALL_SUCCESS, - kTestProductGuid); + installer::FIRST_INSTALL_SUCCESS); EXPECT_STREQ(ReadApKeyValue().c_str(), L""); work_item_list->Rollback(); @@ -327,30 +329,27 @@ HKEY reg_root = HKEY_CURRENT_USER; bool ap_key_deleted = false; RegKey key; - if (key.Open(HKEY_CURRENT_USER, reg_key.c_str(), KEY_ALL_ACCESS) != - ERROR_SUCCESS) { - work_item_list->AddCreateRegKeyWorkItem(reg_root, reg_key, - WorkItem::kWow64Default); + if (key.Open(HKEY_CURRENT_USER, reg_key.c_str(), + KEY_WOW64_32KEY | KEY_SET_VALUE) != ERROR_SUCCESS) { + work_item_list->AddCreateRegKeyWorkItem(reg_root, reg_key, KEY_WOW64_32KEY); ASSERT_TRUE(work_item_list->Do()) << "Failed to create ClientState key."; } else if (key.DeleteValue(google_update::kRegApField) == ERROR_SUCCESS) { ap_key_deleted = true; } // try differential installer GoogleUpdateSettings::UpdateInstallStatus( - false, installer::INCREMENTAL_ARCHIVE_TYPE, installer::INSTALL_FAILED, - kTestProductGuid); + false, installer::INCREMENTAL_ARCHIVE_TYPE, installer::INSTALL_FAILED); EXPECT_STREQ(ReadApKeyValue().c_str(), L"-full"); // try full installer now GoogleUpdateSettings::UpdateInstallStatus(false, installer::FULL_ARCHIVE_TYPE, - installer::INSTALL_FAILED, - kTestProductGuid); + installer::INSTALL_FAILED); EXPECT_STREQ(ReadApKeyValue().c_str(), L""); // Now cleanup to leave the system in unchanged state. // - Diff installer creates an ap key if it didn't exist, so delete this ap // key // - If we created any reg key path for ap, roll it back // - Finally restore the original value of ap key. - key.Open(HKEY_CURRENT_USER, reg_key.c_str(), KEY_ALL_ACCESS); + key.Open(HKEY_CURRENT_USER, reg_key.c_str(), KEY_WOW64_32KEY | KEY_SET_VALUE); key.DeleteValue(google_update::kRegApField); work_item_list->Rollback(); if (ap_key_deleted) { @@ -393,7 +392,7 @@ GoogleUpdateSettings::kPoliciesKey, KEY_QUERY_VALUE)); bool is_overridden = true; EXPECT_EQ(GoogleUpdateSettings::kDefaultUpdatePolicy, - GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, + GoogleUpdateSettings::GetAppUpdatePolicy(GetProductGuid(), &is_overridden)); EXPECT_FALSE(is_overridden); @@ -406,7 +405,7 @@ GoogleUpdateSettings::kPoliciesKey, KEY_QUERY_VALUE)); is_overridden = true; EXPECT_EQ(GoogleUpdateSettings::kDefaultUpdatePolicy, - GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, + GoogleUpdateSettings::GetAppUpdatePolicy(GetProductGuid(), &is_overridden)); EXPECT_FALSE(is_overridden); } @@ -423,7 +422,7 @@ static_cast<DWORD>(0))); bool is_overridden = true; EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED, - GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, + GoogleUpdateSettings::GetAppUpdatePolicy(GetProductGuid(), &is_overridden)); EXPECT_FALSE(is_overridden); @@ -434,7 +433,7 @@ static_cast<DWORD>(1))); is_overridden = true; EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES, - GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, + GoogleUpdateSettings::GetAppUpdatePolicy(GetProductGuid(), &is_overridden)); EXPECT_FALSE(is_overridden); @@ -445,7 +444,7 @@ static_cast<DWORD>(2))); is_overridden = true; EXPECT_EQ(GoogleUpdateSettings::MANUAL_UPDATES_ONLY, - GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, + GoogleUpdateSettings::GetAppUpdatePolicy(GetProductGuid(), &is_overridden)); EXPECT_FALSE(is_overridden); @@ -456,7 +455,7 @@ static_cast<DWORD>(3))); is_overridden = true; EXPECT_EQ(GoogleUpdateSettings::AUTO_UPDATES_ONLY, - GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, + GoogleUpdateSettings::GetAppUpdatePolicy(GetProductGuid(), &is_overridden)); EXPECT_FALSE(is_overridden); @@ -468,7 +467,7 @@ static_cast<DWORD>(4))); is_overridden = true; EXPECT_EQ(GoogleUpdateSettings::kDefaultUpdatePolicy, - GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, + GoogleUpdateSettings::GetAppUpdatePolicy(GetProductGuid(), &is_overridden)); EXPECT_FALSE(is_overridden); } @@ -477,7 +476,7 @@ TEST_F(GoogleUpdateSettingsTest, GetAppUpdatePolicyAppOverride) { std::wstring app_policy_value( GoogleUpdateSettings::kUpdateOverrideValuePrefix); - app_policy_value.append(kTestProductGuid); + app_policy_value.append(GetProductGuid()); EXPECT_EQ(ERROR_SUCCESS, RegKey(HKEY_LOCAL_MACHINE, GoogleUpdateSettings::kPoliciesKey, @@ -490,7 +489,7 @@ .WriteValue(app_policy_value.c_str(), static_cast<DWORD>(0))); bool is_overridden = false; EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED, - GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, + GoogleUpdateSettings::GetAppUpdatePolicy(GetProductGuid(), &is_overridden)); EXPECT_TRUE(is_overridden); @@ -505,7 +504,7 @@ .WriteValue(app_policy_value.c_str(), static_cast<DWORD>(1))); is_overridden = false; EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES, - GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, + GoogleUpdateSettings::GetAppUpdatePolicy(GetProductGuid(), &is_overridden)); EXPECT_TRUE(is_overridden); @@ -515,7 +514,7 @@ .WriteValue(app_policy_value.c_str(), static_cast<DWORD>(2))); is_overridden = false; EXPECT_EQ(GoogleUpdateSettings::MANUAL_UPDATES_ONLY, - GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, + GoogleUpdateSettings::GetAppUpdatePolicy(GetProductGuid(), &is_overridden)); EXPECT_TRUE(is_overridden); @@ -525,7 +524,7 @@ .WriteValue(app_policy_value.c_str(), static_cast<DWORD>(3))); is_overridden = false; EXPECT_EQ(GoogleUpdateSettings::AUTO_UPDATES_ONLY, - GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, + GoogleUpdateSettings::GetAppUpdatePolicy(GetProductGuid(), &is_overridden)); EXPECT_TRUE(is_overridden); @@ -536,7 +535,7 @@ .WriteValue(app_policy_value.c_str(), static_cast<DWORD>(4))); is_overridden = true; EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED, - GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, + GoogleUpdateSettings::GetAppUpdatePolicy(GetProductGuid(), &is_overridden)); EXPECT_FALSE(is_overridden); } @@ -694,7 +693,7 @@ TEST_P(SetProgressTest, SetProgress) { std::wstring path(google_update::kRegPathClientState); path += L"\\"; - path += kTestProductGuid; + path += GetProductGuid(); constexpr int kValues[] = {0, 25, 50, 99, 100}; for (int value : kValues) {
diff --git a/chrome/installer/util/installation_state.cc b/chrome/installer/util/installation_state.cc index c95d276..c305dca 100644 --- a/chrome/installer/util/installation_state.cc +++ b/chrome/installer/util/installation_state.cc
@@ -89,8 +89,6 @@ if (key.Open(root_key, state_key.c_str(), kAccess) == ERROR_SUCCESS) { std::wstring setup_path; std::wstring uninstall_arguments; - // "ap" will be absent if not managed by Google Update. - channel_.Initialize(key); // Read in the brand code, it may be absent key.ReadValue(google_update::kRegBrandField, &brand_); @@ -151,7 +149,6 @@ } ProductState& ProductState::CopyFrom(const ProductState& other) { - channel_.set_value(other.channel_.value()); version_.reset(other.version_.get() ? new base::Version(*other.version_) : nullptr); old_version_.reset(other.old_version_.get() @@ -173,7 +170,6 @@ } void ProductState::Clear() { - channel_.set_value(std::wstring()); version_.reset(); old_version_.reset(); brand_.clear();
diff --git a/chrome/installer/util/installation_state.h b/chrome/installer/util/installation_state.h index 22f3434..b588871 100644 --- a/chrome/installer/util/installation_state.h +++ b/chrome/installer/util/installation_state.h
@@ -12,7 +12,6 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "chrome/installer/util/app_commands.h" -#include "chrome/installer/util/channel_info.h" namespace base { class Version; @@ -36,9 +35,6 @@ // exists and has a "pv" value); false otherwise. bool Initialize(bool system_install); - // Returns the product's channel info (i.e., the Google Update "ap" value). - const ChannelInfo& channel() const { return channel_; } - // Returns the path to the product's "setup.exe"; may be empty. base::FilePath GetSetupPath() const; @@ -93,7 +89,6 @@ void Clear(); protected: - ChannelInfo channel_; std::unique_ptr<base::Version> version_; std::unique_ptr<base::Version> old_version_; std::wstring brand_;
diff --git a/chrome/installer/util/product_state_unittest.cc b/chrome/installer/util/product_state_unittest.cc index b657f57..dfc8a814 100644 --- a/chrome/installer/util/product_state_unittest.cc +++ b/chrome/installer/util/product_state_unittest.cc
@@ -187,38 +187,6 @@ } } -// Test extraction of the "ap" value from the ClientState key. -TEST_P(ProductStateTest, InitializeChannelInfo) { - MinimallyInstallProduct(L"10.0.1.1"); - - // No "ap" value. - { - ProductState state; - LONG result = client_state_.DeleteValue(google_update::kRegApField); - EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND); - EXPECT_TRUE(state.Initialize(system_install_)); - EXPECT_TRUE(state.channel().value().empty()); - } - - // Empty "ap" value. - { - ProductState state; - LONG result = client_state_.WriteValue(google_update::kRegApField, L""); - EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND); - EXPECT_TRUE(state.Initialize(system_install_)); - EXPECT_TRUE(state.channel().value().empty()); - } - - // Valid "ap" value. - { - ProductState state; - LONG result = client_state_.WriteValue(google_update::kRegApField, L"spam"); - EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND); - EXPECT_TRUE(state.Initialize(system_install_)); - EXPECT_EQ(L"spam", state.channel().value()); - } -} - // Test extraction of the uninstall command and arguments from the ClientState // key. TEST_P(ProductStateTest, InitializeUninstallCommand) {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index b26cb9f..d4444e78f 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -943,6 +943,18 @@ } } +source_set("pdf_extension_test_utils") { + testonly = true + sources = [ + "../browser/pdf/pdf_extension_test_util.cc", + "../browser/pdf/pdf_extension_test_util.h", + ] + deps = [ + ":test_support", + "//base", + ] +} + static_library("browser_tests_runner") { testonly = true sources = [] @@ -977,6 +989,7 @@ deps = [ ":browser_tests_runner", + ":pdf_extension_test_utils", ":policy_testserver_pyproto", ":sync_integration_test_support", ":test_support", @@ -1261,9 +1274,7 @@ "//ui/base/clipboard:clipboard_test_support", "//ui/base/dragdrop/mojom", "//ui/compositor:test_support", - "//ui/display:display_manager_test_api", "//ui/display:test_support", - "//ui/display/manager", "//ui/native_theme:test_support", "//ui/resources", "//ui/shell_dialogs:test_support", @@ -1455,9 +1466,7 @@ "../browser/download/download_started_animation_browsertest.cc", "../browser/download/save_page_browsertest.cc", "../browser/engagement/site_engagement_helper_browsertest.cc", - "../browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc", "../browser/enterprise/connectors/analysis/content_analysis_dialog_browsertest.cc", - "../browser/enterprise/connectors/connectors_service_browsertest.cc", "../browser/enterprise/reporting/report_scheduler_browsertest.cc", "../browser/enterprise/util/managed_browser_utils_browsertest.cc", "../browser/extensions/protocol_handler_apitest.cc", @@ -1639,8 +1648,6 @@ "../browser/password_manager/credential_manager_browsertest.cc", "../browser/password_manager/password_manager_browsertest.cc", "../browser/pdf/pdf_extension_test.cc", - "../browser/pdf/pdf_extension_test_util.cc", - "../browser/pdf/pdf_extension_test_util.h", "../browser/performance_manager/background_tab_loading_policy_browsertest.cc", "../browser/performance_manager/frame_node_impl_browsertest.cc", "../browser/performance_manager/mechanisms/page_discarder_browsertest.cc", @@ -1751,7 +1758,6 @@ "../browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.h", "../browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc", "../browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.h", - "../browser/safe_browsing/download_protection/deep_scanning_browsertest.cc", "../browser/safe_browsing/download_protection/download_protection_service_browsertest.cc", "../browser/safe_browsing/test_safe_browsing_database_helper.cc", "../browser/safe_browsing/test_safe_browsing_database_helper.h", @@ -2050,6 +2056,15 @@ "v8/wasm_trap_handler_browsertest.cc", ] + # crbug.com/1230268 These tests need to be fixed for Lacros. + if (!is_chromeos_lacros) { + sources += [ + "../browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc", + "../browser/enterprise/connectors/connectors_service_browsertest.cc", + "../browser/safe_browsing/download_protection/deep_scanning_browsertest.cc", + ] + } + # If this target is used on Android in the future, these browser/speech/* # files will probably not be applicable. sources += [ @@ -2316,6 +2331,8 @@ "//ui/base/idle:test_support", "//ui/base/ime/chromeos", "//ui/chromeos", + "//ui/display:display_manager_test_api", + "//ui/display/manager", "//ui/events/devices:test_support", "//ui/wm/public", "//url", @@ -2607,6 +2624,7 @@ "../browser/extensions/api/settings_private/settings_private_apitest.cc", "../browser/extensions/api/socket/socket_apitest.cc", "../browser/extensions/api/storage/settings_apitest.cc", + "../browser/extensions/api/system_display/system_display_extension_apitest.cc", "../browser/extensions/api/system_indicator/system_indicator_apitest.cc", "../browser/extensions/api/system_private/system_private_apitest.cc", "../browser/extensions/api/tab_capture/tab_capture_apitest.cc", @@ -5738,6 +5756,7 @@ "../browser/ui/webui/downloads/mock_downloads_page.h", "../browser/ui/webui/flags/flags_ui_unittest.cc", "../browser/ui/webui/history/browsing_history_handler_unittest.cc", + "../browser/ui/webui/history/foreign_session_handler_unittest.cc", "../browser/ui/webui/managed_ui_handler_unittest.cc", "../browser/ui/webui/management/management_ui_handler_unittest.cc", "../browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc", @@ -7992,9 +8011,7 @@ "//ui/base:test_support", "//ui/base/clipboard:clipboard_test_support", "//ui/compositor:test_support", - "//ui/display:display_manager_test_api", "//ui/display:test_support", - "//ui/display/manager", "//ui/events:events_interactive_ui_tests", "//ui/events:gesture_detection", "//ui/events:test_support", @@ -8050,6 +8067,7 @@ if (toolkit_views) { sources += [ + "../browser/pdf/pdf_extension_interactive_uitest.cc", "../browser/ui/read_later/read_later_test_utils.cc", "../browser/ui/read_later/read_later_test_utils.h", "../browser/ui/views/autofill/payments/offer_notification_bubble_views_interactive_uitest.cc", @@ -8095,6 +8113,7 @@ "../browser/ui/views/user_education/feature_promo_snooze_interactive_uitest.cc", ] deps += [ + ":pdf_extension_test_utils", "//ui/base/dragdrop:types", "//ui/base/dragdrop/mojom", "//ui/views", @@ -8150,6 +8169,8 @@ "//chromeos/dbus", "//chromeos/login/auth", "//chromeos/ui/frame:test_support", + "//ui/display:display_manager_test_api", + "//ui/display/manager", ] sources += [ "../browser/ash/login/login_manager_test.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java index b60c787..eee2b221 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java
@@ -9,6 +9,7 @@ import android.graphics.Canvas; import android.graphics.drawable.Drawable; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.content.res.AppCompatResources; @@ -20,13 +21,11 @@ import org.chromium.chrome.browser.sync.SyncService; import org.chromium.components.signin.AccountManagerFacadeProvider; import org.chromium.components.signin.AccountUtils; -import org.chromium.components.signin.ProfileDataSource; import org.chromium.components.signin.base.AccountInfo; import org.chromium.components.signin.base.CoreAccountInfo; import org.chromium.components.signin.identitymanager.AccountInfoServiceProvider; import org.chromium.components.signin.test.util.FakeAccountInfoService; import org.chromium.components.signin.test.util.FakeAccountManagerFacade; -import org.chromium.components.signin.test.util.FakeProfileDataSource; import org.chromium.components.signin.test.util.R; import org.chromium.content_public.browser.test.util.TestThreadUtils; @@ -40,7 +39,7 @@ public class AccountManagerTestRule implements TestRule { public static final String TEST_ACCOUNT_EMAIL = "test@gmail.com"; - private final FakeAccountManagerFacade mFakeAccountManagerFacade; + private final @NonNull FakeAccountManagerFacade mFakeAccountManagerFacade; private final @Nullable FakeAccountInfoService mFakeAccountInfoService; private boolean mIsSignedIn; @@ -48,16 +47,12 @@ this(new FakeAccountManagerFacade(null)); } - public AccountManagerTestRule(FakeProfileDataSource fakeProfileDataSource) { - this(new FakeAccountManagerFacade(fakeProfileDataSource)); - } - - public AccountManagerTestRule(FakeAccountManagerFacade fakeAccountManagerFacade) { + public AccountManagerTestRule(@NonNull FakeAccountManagerFacade fakeAccountManagerFacade) { mFakeAccountManagerFacade = fakeAccountManagerFacade; mFakeAccountInfoService = null; } - public AccountManagerTestRule(FakeAccountInfoService fakeAccountInfoService) { + public AccountManagerTestRule(@NonNull FakeAccountInfoService fakeAccountInfoService) { mFakeAccountManagerFacade = new FakeAccountManagerFacade(null); mFakeAccountInfoService = fakeAccountInfoService; } @@ -106,14 +101,13 @@ } /** - * Add an account to the fake AccountManagerFacade, if the {@link FakeAccountInfoService} is + * Adds an account to the fake AccountManagerFacade, if the {@link FakeAccountInfoService} is * set up, add the corresponding {@link AccountInfo} to the {@link FakeAccountInfoService}. * @return The CoreAccountInfo for the account added. */ public CoreAccountInfo addAccount(Account account) { if (mFakeAccountInfoService != null) { - return addAccount( - account.name, /* fullName= */ "", /* givenName= */ "", /* avatar= */ null); + return addAccountWithNameAndAvatar(account.name); } else { mFakeAccountManagerFacade.addAccount(account); return toCoreAccountInfo(account.name); @@ -121,7 +115,7 @@ } /** - * Add an account of the given accountName to the fake AccountManagerFacade. + * Adds an account of the given accountName to the fake AccountManagerFacade. * @return The CoreAccountInfo for the account added. */ public CoreAccountInfo addAccount(String accountName) { @@ -129,23 +123,12 @@ } /** - * Add an account to the fake AccountManagerFacade and its profileData to the - * ProfileDataSource of the fake AccountManagerFacade. - * @return The account added. - */ - public CoreAccountInfo addAccount(ProfileDataSource.ProfileData profileData) { - CoreAccountInfo coreAccountInfo = addAccount(profileData.getAccountEmail()); - mFakeAccountManagerFacade.addProfileData(profileData); - return coreAccountInfo; - } - - /** - * Add an account to the fake AccountManagerFacade and {@link AccountInfo} to + * Adds an account to the fake AccountManagerFacade and {@link AccountInfo} to * {@link FakeAccountInfoService}. */ public CoreAccountInfo addAccount( String email, String fullName, String givenName, @Nullable Bitmap avatar) { - assert mFakeAccountManagerFacade != null; + assert mFakeAccountInfoService != null; mFakeAccountInfoService.addAccountInfo(email, fullName, givenName, avatar); final Account account = AccountUtils.createAccountFromName(email); mFakeAccountManagerFacade.addAccount(account); @@ -153,6 +136,16 @@ } /** + * Adds an account to the fake AccountManagerFacade and the corresponding {@link AccountInfo} + * with name and avatar to {@link FakeAccountInfoService}. + */ + public CoreAccountInfo addAccountWithNameAndAvatar(String email) { + assert mFakeAccountInfoService != null; + final String baseEmail = email.split("@", 2)[0]; + return addAccount(email, baseEmail + ".full", baseEmail + ".given", createAvatar()); + } + + /** * Removes an account with the given account email. */ public void removeAccount(String accountEmail) { @@ -167,15 +160,12 @@ } /** - * Adds an account and seed it in native code. Will create a ProfileData entry for the account - * if ProfileDataSource is not null. + * Adds an account and seed it in native code. * * This method invokes native code. It shouldn't be called in a Robolectric test. */ public CoreAccountInfo addAccountAndWaitForSeeding(String accountName) { - CoreAccountInfo coreAccountInfo = mFakeAccountManagerFacade.getProfileDataSource() == null - ? addAccount(accountName) - : addAccount(createProfileDataFromName(accountName)); + final CoreAccountInfo coreAccountInfo = addAccount(accountName); waitForSeeding(); return coreAccountInfo; } @@ -231,17 +221,6 @@ } /** - * Creates ProfileData object from accountName. - */ - public ProfileDataSource.ProfileData createProfileDataFromName(String accountName) { - String email = accountName.split("@", 2)[0]; - String givenName = email + ".given"; - String fullName = email + ".full"; - return new ProfileDataSource.ProfileData( - accountName, createProfileImage(), fullName, givenName); - } - - /** * Returns the currently signed in account. * * This method invokes native code. It shouldn't be called in a Robolectric test. @@ -269,9 +248,9 @@ } /** - * Returns a profile image created from test resource. + * Returns an avatar image created from test resource. */ - public Bitmap createProfileImage() { + private static Bitmap createAvatar() { Drawable drawable = AppCompatResources.getDrawable( ContextUtils.getApplicationContext(), R.drawable.test_profile_picture); Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
diff --git a/extensions/test/data/system/display/info/manifest.json b/chrome/test/data/extensions/api_test/system_display/info/manifest.json similarity index 100% rename from extensions/test/data/system/display/info/manifest.json rename to chrome/test/data/extensions/api_test/system_display/info/manifest.json
diff --git a/extensions/test/data/system/display/info/test_display_api.js b/chrome/test/data/extensions/api_test/system_display/info/test_display_api.js similarity index 100% rename from extensions/test/data/system/display/info/test_display_api.js rename to chrome/test/data/extensions/api_test/system_display/info/test_display_api.js
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 46e44c9e..2ad83c4a 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -2077,7 +2077,8 @@ }, "prefs": { "auth.server_allowlist": { - "location": "local_state" + "location": "local_state", + "value": "localhost" } } } @@ -2093,12 +2094,25 @@ ], "policy_pref_mapping_tests": [ { + "note": "Default value (no policies set).", + "policies": {}, + "prefs": { + "auth.server_allowlist": { + "location": "local_state", + "default_value": "" + } + } + }, + { + "note": "New policy override deprecated one.", "policies": { - "AuthServerAllowlist": "localhost" + "AuthServerAllowlist": "192.168.0.*,192.168.1.*", + "AuthServerWhitelist": "192.168.0.*,192.168.1.*,192.168.2.*" }, "prefs": { "auth.server_allowlist": { - "location": "local_state" + "location": "local_state", + "value": "192.168.0.*,192.168.1.*" } } } @@ -3594,10 +3608,30 @@ "policy_pref_mapping_tests": [ { "policies": { + "ScreenCaptureAllowed": true + }, + "prefs": { + "hardware.screen_capture_enabled": { + "value": true + } + } + }, + { + "policies": { "ScreenCaptureAllowed": false }, "prefs": { - "hardware.screen_capture_enabled": {} + "hardware.screen_capture_enabled": { + "value": false + } + } + }, + { + "policies": {}, + "prefs": { + "hardware.screen_capture_enabled": { + "default_value": true + } } } ] @@ -5191,12 +5225,23 @@ ], "policy_pref_mapping_tests": [ { + "note": "Default value (no policies set).", + "prefs": { + "ssl.version_min": { + "location": "local_state", + "default_value": "" + } + } + }, + { + "note": "Simple value", "policies": { "SSLVersionMin": "tls1.1" }, "prefs": { "ssl.version_min": { - "location": "local_state" + "location": "local_state", + "value": "tls1.1" } } } @@ -6351,21 +6396,6 @@ } ] }, - "ScreenLockDelayAC": { - "os": [ - "chromeos" - ], - "policy_pref_mapping_tests": [ - { - "policies": { - "ScreenLockDelayAC": 600000 - }, - "prefs": { - "power.ac_screen_lock_delay_ms": {} - } - } - ] - }, "IdleWarningDelayAC": { "os": [ "chromeos" @@ -6447,21 +6477,6 @@ } ] }, - "ScreenLockDelayBattery": { - "os": [ - "chromeos" - ], - "policy_pref_mapping_tests": [ - { - "policies": { - "ScreenLockDelayBattery": 600000 - }, - "prefs": { - "power.battery_screen_lock_delay_ms": {} - } - } - ] - }, "IdleWarningDelayBattery": { "os": [ "chromeos" @@ -6723,12 +6738,77 @@ } ] }, + "ScreenLockDelayAC": { + "os": [ + "chromeos" + ], + "policy_pref_mapping_tests": [ + { + "note": "Check default values (no policies set)", + "prefs": { + "power.ac_screen_lock_delay_ms": { + "default_value": 0 + } + } + }, + { + "note": "Simple value", + "policies": { + "ScreenLockDelayAC": 600000 + }, + "prefs": { + "power.ac_screen_lock_delay_ms": { + "location": "user_profile", + "value": 600000 + } + } + } + ] + }, + "ScreenLockDelayBattery": { + "os": [ + "chromeos" + ], + "policy_pref_mapping_tests": [ + { + "note": "Check default values (no policies set)", + "prefs": { + "power.battery_screen_lock_delay_ms": { + "default_value": 0 + } + } + }, + { + "note": "Simple value", + "policies": { + "ScreenLockDelayBattery": 600000 + }, + "prefs": { + "power.battery_screen_lock_delay_ms": { + "value": 600000 + } + } + } + ] + }, "ScreenLockDelays": { "os": [ "chromeos" ], "policy_pref_mapping_tests": [ { + "note": "Check default values (no policies set)", + "prefs": { + "power.ac_screen_lock_delay_ms": { + "default_value": 0 + }, + "power.battery_screen_lock_delay_ms": { + "default_value": 0 + } + } + }, + { + "note": "Simple value", "policies": { "ScreenLockDelays": { "AC": 6000, @@ -6743,6 +6823,25 @@ "value": 2000 } } + }, + { + "note": "Policy merging precedence (ScreenLockDelays wins)", + "policies": { + "ScreenLockDelays": { + "AC": 1, + "Battery": 2 + }, + "ScreenLockDelayBattery": 3, + "ScreenLockDelayAC": 4 + }, + "prefs": { + "power.ac_screen_lock_delay_ms": { + "value": 1 + }, + "power.battery_screen_lock_delay_ms": { + "value": 2 + } + } } ] }, @@ -7348,11 +7447,22 @@ ], "policy_pref_mapping_tests": [ { + "note":"Check default values (no policies set)", + "prefs": { + "ssl.error_override_allowed": { + "default_value": true + } + } + }, + { + "note": "Simple value", "policies": { - "SSLErrorOverrideAllowed": true + "SSLErrorOverrideAllowed": false }, "prefs": { - "ssl.error_override_allowed": {} + "ssl.error_override_allowed": { + "value": false + } } } ] @@ -7367,15 +7477,26 @@ ], "policy_pref_mapping_tests": [ { + "note": "Check default values (no policies set)", + "prefs": { + "ssl.error_override_allowed_for_origins": { + "default_value": [] + } + } + }, + { + "note": "Simple value", "policies": { "SSLErrorOverrideAllowedForOrigins": [ - "google.com" + "meow.com", + "woof.net" ] }, "prefs": { "ssl.error_override_allowed_for_origins": { "value": [ - "google.com" + "meow.com", + "woof.net" ] } } @@ -7657,11 +7778,31 @@ ], "policy_pref_mapping_tests": [ { + "policies": {}, + "prefs": { + "crostini.usage_reporting_enabled": { + "default_value": false + } + } + }, + { "policies": { "ReportCrostiniUsageEnabled": false }, "prefs": { - "crostini.usage_reporting_enabled": {} + "crostini.usage_reporting_enabled": { + "value": false + } + } + }, + { + "policies": { + "ReportCrostiniUsageEnabled": true + }, + "prefs": { + "crostini.usage_reporting_enabled": { + "value": true + } } } ] @@ -8705,7 +8846,7 @@ "os": [ "chromeos" ], - "reason_for_missing_test": "TODO(crbug.com/1213429) add test case" + "reason_for_missing_test": "Maps into CrosSettings" }, "AttestationEnabledForDevice": { "reason_for_missing_test": "Maps into CrosSettings" @@ -9093,13 +9234,34 @@ "chromeos", "android" ], + "can_be_recommended": true, "policy_pref_mapping_tests": [ { "policies": { "SafeBrowsingExtendedReportingEnabled": true }, "prefs": { - "safebrowsing.scout_reporting_enabled": {} + "safebrowsing.scout_reporting_enabled": { + "value": true + } + } + }, + { + "policies": { + "SafeBrowsingExtendedReportingEnabled": false + }, + "prefs": { + "safebrowsing.scout_reporting_enabled": { + "value": false + } + } + }, + { + "policies": {}, + "prefs": { + "safebrowsing.scout_reporting_enabled": { + "default_value": false + } } } ] @@ -9143,11 +9305,31 @@ ], "policy_pref_mapping_tests": [ { + "policies": {}, + "prefs": { + "crostini.user_allowed_by_policy": { + "default_value": true + } + } + }, + { "policies": { "CrostiniAllowed": false }, "prefs": { - "crostini.user_allowed_by_policy": {} + "crostini.user_allowed_by_policy": { + "value": false + } + } + }, + { + "policies": { + "CrostiniAllowed": true + }, + "prefs": { + "crostini.user_allowed_by_policy": { + "value": true + } } } ] @@ -9161,11 +9343,31 @@ ], "policy_pref_mapping_tests": [ { + "policies": {}, + "prefs": { + "crostini.user_export_import_ui_allowed_by_policy": { + "default_value": true + } + } + }, + { "policies": { "CrostiniExportImportUIAllowed": false }, "prefs": { - "crostini.user_export_import_ui_allowed_by_policy": {} + "crostini.user_export_import_ui_allowed_by_policy": { + "value": false + } + } + }, + { + "policies": { + "CrostiniExportImportUIAllowed": true + }, + "prefs": { + "crostini.user_export_import_ui_allowed_by_policy": { + "value": true + } } } ] @@ -9176,11 +9378,31 @@ ], "policy_pref_mapping_tests": [ { + "policies": {}, + "prefs": { + "crostini.user_root_access_allowed_by_policy": { + "default_value": true + } + } + }, + { "policies": { "CrostiniRootAccessAllowed": false }, "prefs": { - "crostini.user_root_access_allowed_by_policy": {} + "crostini.user_root_access_allowed_by_policy": { + "value": false + } + } + }, + { + "policies": { + "CrostiniRootAccessAllowed": true + }, + "prefs": { + "crostini.user_root_access_allowed_by_policy": { + "value": true + } } } ] @@ -9233,11 +9455,31 @@ ], "policy_pref_mapping_tests": [ { + "policies": {}, + "prefs": { + "crostini.port_forwarding_allowed_by_policy": { + "default_value": true + } + } + }, + { "policies": { "CrostiniPortForwardingAllowed": false }, "prefs": { - "crostini.port_forwarding_allowed_by_policy": {} + "crostini.port_forwarding_allowed_by_policy": { + "value": false + } + } + }, + { + "policies": { + "CrostiniPortForwardingAllowed": true + }, + "prefs": { + "crostini.port_forwarding_allowed_by_policy": { + "value": true + } } } ] @@ -9293,12 +9535,16 @@ "policy_pref_mapping_tests": [ { "policies": { - "SafeBrowsingAllowlistDomains": [ + "SafeBrowsingWhitelistDomains": [ "google.com" ] }, "prefs": { - "safebrowsing.safe_browsing_whitelist_domains": {} + "safebrowsing.safe_browsing_whitelist_domains": { + "value": [ + "google.com" + ] + } } } ] @@ -9318,7 +9564,38 @@ ] }, "prefs": { - "safebrowsing.safe_browsing_whitelist_domains": {} + "safebrowsing.safe_browsing_whitelist_domains": { + "value": [ + "google.com" + ] + } + } + }, + { + "policies": {}, + "prefs": { + "safebrowsing.safe_browsing_whitelist_domains": { + "default_value": [ + ] + } + } + }, + { + "note": "SafeBrowsingWhitelistDomains has been deprecated, and the new name should take precedence.", + "policies": { + "SafeBrowsingWhitelistDomains": [ + "old.name.com" + ], + "SafeBrowsingAllowlistDomains": [ + "new.name.com" + ] + }, + "prefs": { + "safebrowsing.safe_browsing_whitelist_domains": { + "value": [ + "new.name.com" + ] + } } } ] @@ -11194,7 +11471,7 @@ ] }, "TabFreezingEnabled": { - "reason_for_missing_test": "Polic was removed" + "reason_for_missing_test": "Policy was removed" }, "AccessibilityImageLabelsEnabled": { "os": [ @@ -11205,11 +11482,25 @@ ], "policy_pref_mapping_tests": [ { + "note": "Check default values (no policies set)", + "policies": {}, + "prefs": { + "settings.a11y.enable_accessibility_image_labels": { + "location": "user_profile", + "default_value": false + } + } + }, + { + "note": "Check policy value", "policies": { "AccessibilityImageLabelsEnabled": true }, "prefs": { - "settings.a11y.enable_accessibility_image_labels": {} + "settings.a11y.enable_accessibility_image_labels": { + "location": "user_profile", + "value": true + } } } ]
diff --git a/chrome/test/data/webui/chromeos/diagnostics/ip_config_info_drawer_test.js b/chrome/test/data/webui/chromeos/diagnostics/ip_config_info_drawer_test.js index 6e01155a..631f243 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/ip_config_info_drawer_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/ip_config_info_drawer_test.js
@@ -4,9 +4,11 @@ import 'chrome://diagnostics/ip_config_info_drawer.js'; -import {assertTrue} from '../../chai_assert.js'; +import {assertFalse, assertTrue} from '../../chai_assert.js'; import {flushTasks, isVisible} from '../../test_util.m.js'; +import * as dx_utils from './diagnostics_test_utils.js'; + export function ipConfigInfoDrawerTestSuite() { /** @type {?IpConfigInfoDrawerElement} */ let ipConfigInfoDrawerElement = null; @@ -28,9 +30,49 @@ return flushTasks(); } + /** + * Selects the drawer's hideable content area if the drawer is expanded. + * @return {HTMLElement} + */ + function getDrawerContentContainer() { + return /** @type {!HTMLElement} */ ( + ipConfigInfoDrawerElement.$$('#ipConfigInfoElement')); + } + + /** + * Selects the drawer's toggle button. + * @return {!HTMLElement} + */ + function getDrawerToggle() { + const toggleButton = ipConfigInfoDrawerElement.$$('cr-expand-button'); + assertTrue(!!toggleButton); + return /** @type {!HTMLElement} */ (toggleButton); + } + test('IpConfigInfoDrawerInitialized', () => { return initializeIpConfigInfoDrawerElement().then(() => { - assertTrue(!!ipConfigInfoDrawerElement.$$('#ipConfigInfoElement')); + const expectedDrawerHeader = + ipConfigInfoDrawerElement.i18n('ipConfigInfoDrawerTitle'); + const toggleButtonLabel = /** @type {HTMLElement} */ ( + ipConfigInfoDrawerElement.$$('cr-expand-button > span')); + + assertTrue(isVisible(getDrawerToggle())); + dx_utils.assertElementContainsText( + toggleButtonLabel, expectedDrawerHeader); }); }); + + test('IpConfigInfoDrawerContentVisibilityTogglesOnClick', () => { + return initializeIpConfigInfoDrawerElement() + .then(() => { + // Initial state is unexpanded causing element to be hidden. + assertFalse(!!getDrawerContentContainer()); + }) + // Click toggle button to expand drawer. + .then(() => getDrawerToggle().click()) + .then(() => { + // Confirm expanded state visibility is correctly updated. + assertTrue(!!(getDrawerContentContainer())); + }); + }); }
diff --git a/chromecast/browser/exo/cast_wm_helper.cc b/chromecast/browser/exo/cast_wm_helper.cc index de6b046..6852d46 100644 --- a/chromecast/browser/exo/cast_wm_helper.cc +++ b/chromecast/browser/exo/cast_wm_helper.cc
@@ -13,8 +13,7 @@ #include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h" #include "ui/compositor/layer.h" #include "ui/display/display.h" -#include "ui/display/manager/display_configurator.h" -#include "ui/display/manager/display_manager.h" +#include "ui/display/manager/managed_display_info.h" #include "ui/display/screen.h" #include "ui/display/types/display_snapshot.h" #include "ui/events/devices/device_data_manager.h"
diff --git a/chromecast/cast_core/BUILD.gn b/chromecast/cast_core/BUILD.gn index 55197ad..1bd5d71c 100644 --- a/chromecast/cast_core/BUILD.gn +++ b/chromecast/cast_core/BUILD.gn
@@ -55,6 +55,45 @@ deps = [ "//url" ] } +cast_source_set("message_port") { + sources = [ + "message_port_handler.cc", + "message_port_handler.h", + "message_port_service.cc", + "message_port_service.h", + ] + + public_deps = [ + ":grpc_support", + "//base", + "//components/cast/message_port", + "//third_party/openscreen/src/cast/cast_core/api:core_application_service_proto", + "//third_party/openscreen/src/cast/cast_core/api:message_channel_proto", + ] +} + +if (is_linux) { + cast_source_set("core_runtime_bindings") { + sources = [ + "bindings_manager_web_runtime.cc", + "bindings_manager_web_runtime.h", + ] + + public_deps = [ + ":message_port", + "//base", + "//chromecast/bindings/public/mojom", + "//components/cast/api_bindings:manager", + "//components/cast/message_port", + "//mojo/public/cpp/bindings", + "//third_party/openscreen/src/cast/cast_core/api:core_application_service_proto", + "//third_party/openscreen/src/cast/cast_core/api:message_channel_proto", + ] + + deps = [ "//chromecast/bindings:bindings_manager_cast" ] + } +} + cast_source_set("renderer") { sources = [ "cast_runtime_content_renderer_client.cc",
diff --git a/chromecast/cast_core/DEPS b/chromecast/cast_core/DEPS index 9d1879b..4e17817 100644 --- a/chromecast/cast_core/DEPS +++ b/chromecast/cast_core/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+chromecast/app", + "+chromecast/bindings", "+chromecast/browser", "+chromecast/chromecast_buildflags.h", "+chromecast/common",
diff --git a/chromecast/cast_core/bindings_manager_web_runtime.cc b/chromecast/cast_core/bindings_manager_web_runtime.cc new file mode 100644 index 0000000..239eeda5 --- /dev/null +++ b/chromecast/cast_core/bindings_manager_web_runtime.cc
@@ -0,0 +1,79 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromecast/cast_core/bindings_manager_web_runtime.h" + +#include "base/bind.h" +#include "base/notreached.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/stringprintf.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "chromecast/cast_core/message_port_handler.h" +#include "components/cast/message_port/cast/message_port_cast.h" +#include "components/cast/message_port/platform_message_port.h" +#include "mojo/public/cpp/bindings/pending_remote.h" + +namespace chromecast { + +BindingsManagerWebRuntime::BindingsManagerWebRuntime( + grpc::CompletionQueue* grpc_cq, + cast::v2::CoreApplicationService::Stub* core_app_stub) + : message_port_service_( + base::BindRepeating( + &cast_api_bindings::CreatePlatformMessagePortPair), + grpc_cq, + core_app_stub) {} + +BindingsManagerWebRuntime::~BindingsManagerWebRuntime() = default; + +void BindingsManagerWebRuntime::AddBinding(base::StringPiece binding_script) { + int id = next_script_id_++; + bindings_[base::NumberToString(id)] = std::string(binding_script); +} + +void BindingsManagerWebRuntime::HandleMessage( + const cast::web::Message& message, + cast::web::MessagePortStatus* response) { + message_port_service_.HandleMessage(message, response); +} + +mojo::PendingRemote<mojom::ApiBindings> +BindingsManagerWebRuntime::CreateRemote() { + DCHECK(!receiver_.is_bound()); + + mojo::PendingRemote<mojom::ApiBindings> pending_remote = + receiver_.BindNewPipeAndPassRemote(); + receiver_.set_disconnect_handler( + base::BindOnce(&BindingsManagerWebRuntime::OnMojoClientDisconnected, + base::Unretained(this))); + + return pending_remote; +} + +void BindingsManagerWebRuntime::OnMojoClientDisconnected() { + receiver_.reset(); +} + +void BindingsManagerWebRuntime::AddBinding(base::StringPiece binding_name, + base::StringPiece binding_script) { + bindings_[std::string(binding_name)] = std::string(binding_script); +} + +void BindingsManagerWebRuntime::GetAll(GetAllCallback callback) { + std::vector<chromecast::mojom::ApiBindingPtr> bindings_vector; + for (auto& bindings_name_and_script : bindings_) { + auto api_binding = + chromecast::mojom::ApiBinding::New(bindings_name_and_script.second); + bindings_vector.emplace_back(std::move(api_binding)); + } + std::move(callback).Run(std::move(bindings_vector)); +} + +void BindingsManagerWebRuntime::Connect(const std::string& port_name, + blink::MessagePortDescriptor port) { + message_port_service_.ConnectToPort( + port_name, cast_api_bindings::MessagePortCast::Create(std::move(port))); +} + +} // namespace chromecast
diff --git a/chromecast/cast_core/bindings_manager_web_runtime.h b/chromecast/cast_core/bindings_manager_web_runtime.h new file mode 100644 index 0000000..8aa20fc --- /dev/null +++ b/chromecast/cast_core/bindings_manager_web_runtime.h
@@ -0,0 +1,75 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMECAST_CAST_CORE_BINDINGS_MANAGER_WEB_RUNTIME_H_ +#define CHROMECAST_CAST_CORE_BINDINGS_MANAGER_WEB_RUNTIME_H_ + +#include <map> +#include <memory> + +#include "base/containers/flat_map.h" +#include "base/memory/weak_ptr.h" +#include "chromecast/bindings/public/mojom/api_bindings.mojom.h" +#include "chromecast/cast_core/message_port_service.h" +#include "components/cast/api_bindings/manager.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "third_party/openscreen/src/cast/cast_core/api/v2/core_application_service.grpc.pb.h" +#include "third_party/openscreen/src/cast/cast_core/api/web/message_channel.pb.h" + +namespace chromecast { + +// This class will be initialized with a set of bindings received over gRPC and +// will inject them into the app's CastWebContents when the page loads. It then +// handles connecting PortConnector requests from those bindings by making gRPC +// ApiBindings requests to Cast Core. There should be one instance of this +// class for a single CastWebContents. +class BindingsManagerWebRuntime final : public cast_api_bindings::Manager, + public chromecast::mojom::ApiBindings { + public: + // |cast_web_contents|, |grpc_cq|, and |core_app_stub| all need to outlive + // |this|. + BindingsManagerWebRuntime( + grpc::CompletionQueue* grpc_cq, + cast::v2::CoreApplicationService::Stub* core_app_stub); + ~BindingsManagerWebRuntime() override; + + BindingsManagerWebRuntime(const BindingsManagerWebRuntime&) = delete; + BindingsManagerWebRuntime(BindingsManagerWebRuntime&&) = delete; + BindingsManagerWebRuntime& operator=(const BindingsManagerWebRuntime&) = + delete; + BindingsManagerWebRuntime& operator=(BindingsManagerWebRuntime&&) = delete; + + void AddBinding(base::StringPiece binding_script); + void HandleMessage(const cast::web::Message& message, + cast::web::MessagePortStatus* response); + + // Returns a mojo::PendingRemote bound to |this|. + // At most one bound remote can exist at the same time. + mojo::PendingRemote<mojom::ApiBindings> CreateRemote(); + + private: + // Callback invoked when client of mojom::ApiBindings disconnects. + void OnMojoClientDisconnected(); + + // cast_api_bindings::Manager overrides. + void AddBinding(base::StringPiece binding_name, + base::StringPiece binding_script) override; + + // chromecast::mojom::ApiBindings implementation. + void GetAll(GetAllCallback callback) override; + void Connect(const std::string& port_name, + blink::MessagePortDescriptor port) override; + + int next_script_id_{0}; + // Stores all bindings, keyed on the string-based IDs provided by the + // ApiBindings interface. + std::map<std::string, std::string> bindings_; + mojo::Receiver<mojom::ApiBindings> receiver_{this}; + + MessagePortService message_port_service_; +}; + +} // namespace chromecast + +#endif // CHROMECAST_CAST_CORE_BINDINGS_MANAGER_WEB_RUNTIME_H_
diff --git a/chromecast/cast_core/cast_runtime_content_browser_client.h b/chromecast/cast_core/cast_runtime_content_browser_client.h index c2307ab..096127e 100644 --- a/chromecast/cast_core/cast_runtime_content_browser_client.h +++ b/chromecast/cast_core/cast_runtime_content_browser_client.h
@@ -11,8 +11,7 @@ class CastFeatureListCreator; -class CastRuntimeContentBrowserClient final - : public shell::CastContentBrowserClient { +class CastRuntimeContentBrowserClient : public shell::CastContentBrowserClient { public: static std::unique_ptr<CastRuntimeContentBrowserClient> Create( CastFeatureListCreator* feature_list_creator);
diff --git a/chromecast/cast_core/message_port_handler.cc b/chromecast/cast_core/message_port_handler.cc new file mode 100644 index 0000000..9b442f2 --- /dev/null +++ b/chromecast/cast_core/message_port_handler.cc
@@ -0,0 +1,279 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromecast/cast_core/message_port_handler.h" + +#include <utility> + +#include "base/logging.h" +#include "chromecast/cast_core/message_port_service.h" + +namespace chromecast { +namespace { + +// This is used as a timeout for both sending cast::web::Message requests and +// awaiting responses. Reaching this timeout without a response from the peer +// will close the connection and Blink message port. +constexpr base::TimeDelta kMessageTimeout = base::TimeDelta::FromSeconds(10); + +} // namespace + +#define DLOG_CHANNEL(level) DLOG(level) << "channel " << channel_id_ << ": " +#define DVLOG_CHANNEL(level) DVLOG(level) << "channel " << channel_id_ << ": " + +MessagePortHandler::MessagePortHandler( + std::unique_ptr<cast_api_bindings::MessagePort> message_port, + uint32_t channel_id, + MessagePortService* message_port_service, + grpc::CompletionQueue* cq, + cast::v2::CoreApplicationService::Stub* core_app_stub, + scoped_refptr<base::SequencedTaskRunner> task_runner) + : task_runner_(std::move(task_runner)), + message_port_service_(message_port_service), + grpc_cq_(cq), + core_app_stub_(core_app_stub), + message_port_(std::move(message_port)), + channel_id_(channel_id) { + DCHECK(message_port_service_); + DCHECK(grpc_cq_); + DCHECK(core_app_stub_); + message_port_->SetReceiver(this); +} + +MessagePortHandler::~MessagePortHandler() = default; + +bool MessagePortHandler::HandleMessage(const cast::web::Message& message) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!message_port_) { + return false; + } + + switch (message.message_type_case()) { + case cast::web::Message::kStatus: { + if (message.status().status() == + cast::web::MessagePortStatus_Status_ERROR) { + DLOG_CHANNEL(WARNING) << "Received error message"; + CloseAndRemove(); + } else if (message.status().status() == + cast::web::MessagePortStatus_Status_STARTED) { + bool was_started = started_; + started_ = true; + if (!was_started && !pending_messages_.empty()) { + ForwardNextMessage(); + } + } + return true; + } + case cast::web::Message::kRequest: { + DLOG_CHANNEL(INFO) << "Received request: " << message.request().data(); + std::vector<std::unique_ptr<cast_api_bindings::MessagePort>> ports; + ports.reserve(message.request().ports_size()); + for (const auto& port : message.request().ports()) { + std::unique_ptr<cast_api_bindings::MessagePort> client; + std::unique_ptr<cast_api_bindings::MessagePort> server; + message_port_service_->CreatePair(&client, &server); + message_port_service_->RegisterIncomingPort(port.channel().channel_id(), + std::move(client)); + ports.push_back(std::move(server)); + + cast::web::Message notification; + notification.mutable_channel()->set_channel_id( + port.channel().channel_id()); + notification.mutable_status()->set_status( + cast::web::MessagePortStatus_Status_STARTED); + ForwardMessage(std::move(notification)); + } + bool result = message_port_->PostMessageWithTransferables( + message.request().data(), std::move(ports)); + SendResponse(result); + return true; + } + case cast::web::Message::kResponse: { + if (!awaiting_response_) { + LOG(FATAL) << "Received response while not expecting one."; + return false; + } + message_timeout_callback_.Cancel(); + awaiting_response_ = false; + if (!pending_messages_.empty() && !pending_request_) { + ForwardNextMessage(); + } + return true; + } + default: + return false; + } +} + +void MessagePortHandler::Close() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DLOG_CHANNEL(INFO) << "Closing channel"; + message_timeout_callback_.Cancel(); + pending_messages_.clear(); + message_port_->Close(); + message_port_.reset(); +} + +void MessagePortHandler::CloseAndRemove() { + Close(); + message_port_service_->Remove(channel_id_); +} + +void MessagePortHandler::CloseWithError(CloseError error) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + switch (error) { + case CloseError::kPipeError: + DLOG_CHANNEL(INFO) << "Closing with pipe error"; + break; + case CloseError::kTimeout: + DLOG_CHANNEL(INFO) << "Closing from timeout"; + break; + } + Close(); + + cast::web::Message message; + message.mutable_status()->set_status( + cast::web::MessagePortStatus_Status_ERROR); + message.mutable_channel()->set_channel_id(channel_id_); + new AsyncMessage(message, core_app_stub_, grpc_cq_, nullptr); + message_port_service_->Remove(channel_id_); +} + +void MessagePortHandler::SendResponse(bool result) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + cast::web::Message message; + message.mutable_response()->set_result(result); + message.mutable_channel()->set_channel_id(channel_id_); + ForwardMessage(std::move(message)); +} + +void MessagePortHandler::ForwardNextMessage() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!awaiting_response_); + DCHECK(!pending_messages_.empty()); + DCHECK(!pending_request_); + cast::web::Message next = std::move(pending_messages_.front()); + pending_messages_.pop_front(); + ForwardMessageNow(std::move(next)); +} + +bool MessagePortHandler::ForwardMessage(cast::web::Message&& message) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (message.has_request() && + (!started_ || awaiting_response_ || !pending_messages_.empty() || + pending_request_)) { + pending_messages_.emplace_back(std::move(message)); + return true; + } + + ForwardMessageNow(message); + return true; +} + +void MessagePortHandler::ForwardMessageNow(const cast::web::Message& message) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!message.has_request() || !pending_request_); + auto* async_message = new AsyncMessage(message, core_app_stub_, grpc_cq_, + weak_factory_.GetWeakPtr()); + if (message.has_request()) { + DLOG_CHANNEL(INFO) << "Sending message: " << message.request().data(); + pending_request_ = async_message; + awaiting_response_ = true; + } + ResetTimeout(); +} + +void MessagePortHandler::ResetTimeout() { + message_timeout_callback_.Reset( + base::BindOnce(&MessagePortHandler::CloseWithError, + weak_factory_.GetWeakPtr(), CloseError::kTimeout)); + task_runner_->PostDelayedTask(FROM_HERE, message_timeout_callback_.callback(), + kMessageTimeout); +} + +void MessagePortHandler::OnMessageComplete( + bool ok, + bool was_request, + const cast::web::MessagePortStatus& response) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + pending_request_ = nullptr; + message_timeout_callback_.Cancel(); + if (!message_port_) { + return; + } + + if (!ok || response.status() != cast::web::MessagePortStatus_Status_OK) { + DLOG_CHANNEL(WARNING) << "Send failed (" << ok << ", " + << cast::web::MessagePortStatus_Status_Name( + response.status()) + << ")"; + CloseAndRemove(); + return; + } + + if (was_request && awaiting_response_) { + ResetTimeout(); + } else if (!awaiting_response_ && !pending_messages_.empty()) { + ForwardNextMessage(); + } +} + +bool MessagePortHandler::OnMessage( + base::StringPiece message, + std::vector<std::unique_ptr<cast_api_bindings::MessagePort>> ports) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + cast::web::Message request; + request.mutable_request()->set_data(std::string(message)); + request.mutable_channel()->set_channel_id(channel_id_); + std::vector<cast::web::Message> started_notifications; + started_notifications.reserve(ports.size()); + for (auto& port : ports) { + auto* descriptor = request.mutable_request()->mutable_ports()->Add(); + uint32_t channel_id = + message_port_service_->RegisterOutgoingPort(std::move(port)); + descriptor->mutable_channel()->set_channel_id(channel_id); + descriptor->set_sequence_number(0); + + cast::web::Message notification; + notification.mutable_channel()->set_channel_id(channel_id); + notification.mutable_status()->set_status( + cast::web::MessagePortStatus_Status_STARTED); + started_notifications.push_back(std::move(notification)); + } + ForwardMessage(std::move(request)); + for (auto& notification : started_notifications) { + ForwardMessage(std::move(notification)); + } + return true; +} + +void MessagePortHandler::OnPipeError() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CloseWithError(CloseError::kPipeError); +} + +MessagePortHandler::AsyncMessage::AsyncMessage( + const cast::web::Message& request, + cast::v2::CoreApplicationService::Stub* core_app_stub, + grpc::CompletionQueue* cq, + base::WeakPtr<MessagePortHandler> port) + : port_(port), was_request_(request.has_request()) { + response_reader_ = + core_app_stub->PrepareAsyncPostMessage(&context_, request, cq); + response_reader_->StartCall(); + response_reader_->Finish(&response_, &status_, static_cast<GRPC*>(this)); +} + +MessagePortHandler::AsyncMessage::~AsyncMessage() = default; + +void MessagePortHandler::AsyncMessage::StepGRPC(grpc::Status status) { + if (port_) { + port_->OnMessageComplete(status_.ok() && status.ok(), was_request_, + response_); + } + delete this; +} + +} // namespace chromecast
diff --git a/chromecast/cast_core/message_port_handler.h b/chromecast/cast_core/message_port_handler.h new file mode 100644 index 0000000..af52fa1 --- /dev/null +++ b/chromecast/cast_core/message_port_handler.h
@@ -0,0 +1,134 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMECAST_CAST_CORE_MESSAGE_PORT_HANDLER_H_ +#define CHROMECAST_CAST_CORE_MESSAGE_PORT_HANDLER_H_ + +#include <deque> +#include <memory> + +#include "base/cancelable_callback.h" +#include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" +#include "base/sequenced_task_runner.h" +#include "chromecast/cast_core/grpc_method.h" +#include "components/cast/message_port/message_port.h" +#include "third_party/openscreen/src/cast/cast_core/api/v2/core_application_service.grpc.pb.h" +#include "third_party/openscreen/src/cast/cast_core/api/web/message_channel.pb.h" + +namespace chromecast { + +class MessagePortService; + +class MessagePortHandler final + : public cast_api_bindings::MessagePort::Receiver { + public: + // |message_port_service|, |cq|, and |core_app_stub| should all outlive + // |this|. Furthermore, |message_port_service| should actually own |this|. + MessagePortHandler( + std::unique_ptr<cast_api_bindings::MessagePort> message_port, + uint32_t channel_id, + MessagePortService* message_port_service, + grpc::CompletionQueue* cq, + cast::v2::CoreApplicationService::Stub* core_app_stub, + scoped_refptr<base::SequencedTaskRunner> task_runner); + ~MessagePortHandler() override; + + MessagePortHandler(const MessagePortHandler&) = delete; + MessagePortHandler(MessagePortHandler&&) = delete; + MessagePortHandler& operator=(const MessagePortHandler&) = delete; + MessagePortHandler& operator=(MessagePortHandler&&) = delete; + + // Handles a message incoming from the gRPC API. Returns true if it was able + // to be handled successfully, false otherwise. + bool HandleMessage(const cast::web::Message& message); + + private: + class AsyncMessage final : public GrpcCall { + public: + AsyncMessage(const cast::web::Message& request, + cast::v2::CoreApplicationService::Stub* core_app_stub, + grpc::CompletionQueue* cq, + base::WeakPtr<MessagePortHandler> port); + ~AsyncMessage() override; + + // GrpcCall overrides. + void StepGRPC(grpc::Status status) override; + + private: + base::WeakPtr<MessagePortHandler> port_; + bool was_request_; + + cast::web::MessagePortStatus response_; + std::unique_ptr< + grpc::ClientAsyncResponseReader<cast::web::MessagePortStatus>> + response_reader_; + }; + + enum class CloseError { + kPipeError, + kTimeout, + }; + + // Closes the message port. + void Close(); + + // Closes the message port and removes this channel from + // |message_port_service_|. + void CloseAndRemove(); + + // Closes the message port, sends an error on the channel, and removes this + // channel from |message_port_service_|. + void CloseWithError(CloseError error); + + // Sends a MessageResponse with the value |result|. + void SendResponse(bool result); + + // Forwards the next message from |pending_messages_| over this channel. + void ForwardNextMessage(); + + // Forwards |message| over this channel if possible, but queues it if there's + // already a pending request. + bool ForwardMessage(cast::web::Message&& message); + + // Forwards |message| over this channel now. + void ForwardMessageNow(const cast::web::Message& message); + + // Resets the timeout on the port that indicates we should close due to + // inactivity. + void ResetTimeout(); + + // Callback invoked when an AsyncMessage gets a gRPC result. + void OnMessageComplete(bool ok, + bool was_request, + const cast::web::MessagePortStatus& response); + + // cast_api_bindings::MessagePort::Receiver overrides. + bool OnMessage(base::StringPiece message, + std::vector<std::unique_ptr<cast_api_bindings::MessagePort>> + ports) override; + void OnPipeError() override; + + scoped_refptr<base::SequencedTaskRunner> task_runner_; + MessagePortService* message_port_service_; + grpc::CompletionQueue* grpc_cq_; + cast::v2::CoreApplicationService::Stub* core_app_stub_; + std::unique_ptr<cast_api_bindings::MessagePort> message_port_; + uint32_t channel_id_; + + base::CancelableOnceClosure message_timeout_callback_; + std::deque<cast::web::Message> pending_messages_; + AsyncMessage* pending_request_{nullptr}; + bool awaiting_response_{false}; + bool started_{false}; + + SEQUENCE_CHECKER(sequence_checker_); + + base::WeakPtrFactory<MessagePortHandler> weak_factory_{this}; +}; + +} // namespace chromecast + +#endif // CHROMECAST_CAST_CORE_MESSAGE_PORT_HANDLER_H_
diff --git a/chromecast/cast_core/message_port_service.cc b/chromecast/cast_core/message_port_service.cc new file mode 100644 index 0000000..54261b5 --- /dev/null +++ b/chromecast/cast_core/message_port_service.cc
@@ -0,0 +1,135 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromecast/cast_core/message_port_service.h" + +#include "base/logging.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "chromecast/cast_core/message_port_handler.h" + +namespace chromecast { + +MessagePortService::MessagePortService( + CreatePairCallback create_pair, + grpc::CompletionQueue* grpc_cq, + cast::v2::CoreApplicationService::Stub* core_app_stub) + : create_pair_(std::move(create_pair)), + grpc_cq_(grpc_cq), + core_app_stub_(core_app_stub) { + DCHECK(create_pair_); + DCHECK(grpc_cq_); + DCHECK(core_app_stub_); +} + +MessagePortService::~MessagePortService() = default; + +void MessagePortService::HandleMessage(const cast::web::Message& message, + cast::web::MessagePortStatus* response) { + uint32_t channel_id = message.channel().channel_id(); + auto entry = ports_.find(channel_id); + if (entry == ports_.end()) { + DLOG(INFO) << "Got message for unknown channel: " << channel_id; + response->set_status(cast::web::MessagePortStatus_Status_ERROR); + return; + } + + if (entry->second->HandleMessage(message)) { + response->set_status(cast::web::MessagePortStatus_Status_OK); + } else { + response->set_status(cast::web::MessagePortStatus_Status_ERROR); + } +} + +void MessagePortService::CreatePair( + std::unique_ptr<cast_api_bindings::MessagePort>* client, + std::unique_ptr<cast_api_bindings::MessagePort>* server) { + create_pair_.Run(client, server); +} + +bool MessagePortService::ConnectToPort( + base::StringPiece port_name, + std::unique_ptr<cast_api_bindings::MessagePort> port) { + DLOG(INFO) << "MessagePortService connecting to port '" << port_name + << "' as channel " << next_outgoing_channel_id_; + cast::web::MessagePortDescriptor port_descriptor; + port_descriptor.mutable_channel()->set_channel_id( + next_outgoing_channel_id_++); + port_descriptor.mutable_peer_status()->set_status( + cast::web::MessagePortStatus_Status_STARTED); + port_descriptor.set_sequence_number(0); + + cast::bindings::ConnectRequest connect_request; + connect_request.set_port_name(std::string(port_name)); + *connect_request.mutable_port() = port_descriptor; + new AsyncConnect(connect_request, std::move(port), core_app_stub_, grpc_cq_, + weak_factory_.GetWeakPtr()); + return true; +} + +uint32_t MessagePortService::RegisterOutgoingPort( + std::unique_ptr<cast_api_bindings::MessagePort> port) { + uint32_t channel_id = next_outgoing_channel_id_++; + ports_.emplace(channel_id, + MakeMessagePortHandler(channel_id, std::move(port))); + return channel_id; +} + +void MessagePortService::RegisterIncomingPort( + uint32_t channel_id, + std::unique_ptr<cast_api_bindings::MessagePort> port) { + auto result = ports_.emplace( + channel_id, MakeMessagePortHandler(channel_id, std::move(port))); + DCHECK(result.second); +} + +void MessagePortService::Remove(uint32_t channel_id) { + ports_.erase(channel_id); +} + +std::unique_ptr<MessagePortHandler> MessagePortService::MakeMessagePortHandler( + uint32_t channel_id, + std::unique_ptr<cast_api_bindings::MessagePort> port) { + auto port_handler = std::make_unique<MessagePortHandler>( + std::move(port), channel_id, this, grpc_cq_, core_app_stub_, + base::SequencedTaskRunnerHandle::Get()); + return port_handler; +} + +void MessagePortService::OnConnectComplete( + bool ok, + uint32_t channel_id, + std::unique_ptr<cast_api_bindings::MessagePort> port) { + if (ok) { + DLOG(INFO) << "CoreApplicationService::Connect succeeded"; + auto result = ports_.emplace( + channel_id, MakeMessagePortHandler(channel_id, std::move(port))); + DCHECK(result.second); + } +} + +MessagePortService::AsyncConnect::AsyncConnect( + const cast::bindings::ConnectRequest& request, + std::unique_ptr<cast_api_bindings::MessagePort> port, + cast::v2::CoreApplicationService::Stub* core_app_stub, + grpc::CompletionQueue* cq, + base::WeakPtr<MessagePortService> service) + : service_(service), + port_(std::move(port)), + channel_id_(request.port().channel().channel_id()) { + response_reader_ = core_app_stub->PrepareAsyncConnect(&context_, request, cq); + response_reader_->StartCall(); + response_reader_->Finish(&response_, &status_, static_cast<GRPC*>(this)); +} + +MessagePortService::AsyncConnect::~AsyncConnect() = default; + +void MessagePortService::AsyncConnect::StepGRPC(grpc::Status status) { + if (service_) { + service_->OnConnectComplete(status_.ok() && status.ok(), channel_id_, + std::move(port_)); + } + delete this; +} + +} // namespace chromecast
diff --git a/chromecast/cast_core/message_port_service.h b/chromecast/cast_core/message_port_service.h new file mode 100644 index 0000000..60c0de5 --- /dev/null +++ b/chromecast/cast_core/message_port_service.h
@@ -0,0 +1,113 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMECAST_CAST_CORE_MESSAGE_PORT_SERVICE_H_ +#define CHROMECAST_CAST_CORE_MESSAGE_PORT_SERVICE_H_ + +#include <vector> + +#include "base/callback.h" +#include "base/containers/flat_map.h" +#include "base/memory/weak_ptr.h" +#include "chromecast/cast_core/grpc_method.h" +#include "components/cast/message_port/message_port.h" +#include "third_party/openscreen/src/cast/cast_core/api/v2/core_application_service.grpc.pb.h" +#include "third_party/openscreen/src/cast/cast_core/api/web/message_channel.pb.h" + +namespace chromecast { + +class MessagePortHandler; + +class MessagePortService { + public: + using CreatePairCallback = base::RepeatingCallback<void( + std::unique_ptr<cast_api_bindings::MessagePort>*, + std::unique_ptr<cast_api_bindings::MessagePort>*)>; + + // |create_pair| is used to create a connected pair of MessagePorts in place + // of calling MessagePort::CreatePair. This is to allow multiple MessagePort + // implementations to be used with this service in the same binary. |grpc_cq| + // and |core_app_stub| must outlive |this|. + MessagePortService(CreatePairCallback create_pair, + grpc::CompletionQueue* grpc_cq, + cast::v2::CoreApplicationService::Stub* core_app_stub); + ~MessagePortService(); + + // Handles a message incoming from the gRPC API. The message will be routed + // to the appropriate MessagePortHandler based on its channel ID. |response| + // is set to |OK| if MessagePortHandler reports success and |ERROR| otherwise, + // including the case that there's no MessagePortHandler for the incoming + // channel ID. + void HandleMessage(const cast::web::Message& message, + cast::web::MessagePortStatus* response); + + void CreatePair(std::unique_ptr<cast_api_bindings::MessagePort>* client, + std::unique_ptr<cast_api_bindings::MessagePort>* server); + + // Connects |port| to the remote port with name |port_name|. + bool ConnectToPort(base::StringPiece port_name, + std::unique_ptr<cast_api_bindings::MessagePort> port); + + // Registers a port opened locally via a port transfer. This allocates a + // |channel_id| for the port in order to send it over gRPC. + uint32_t RegisterOutgoingPort( + std::unique_ptr<cast_api_bindings::MessagePort> port); + + // Registers a port opened by the peer via a port transfer. |channel_id| is + // provided by the peer. + void RegisterIncomingPort( + uint32_t channel_id, + std::unique_ptr<cast_api_bindings::MessagePort> port); + + // Removes the MessagePortHandler for |channel_id|. Note that this will + // destroy it. + void Remove(uint32_t channel_id); + + private: + class AsyncConnect final : public GrpcCall { + public: + AsyncConnect(const cast::bindings::ConnectRequest& request, + std::unique_ptr<cast_api_bindings::MessagePort> port, + cast::v2::CoreApplicationService::Stub* core_app_stub, + grpc::CompletionQueue* cq, + base::WeakPtr<MessagePortService> service); + ~AsyncConnect() override; + + void StepGRPC(grpc::Status status) override; + + private: + base::WeakPtr<MessagePortService> service_; + cast::bindings::ConnectResponse response_; + std::unique_ptr< + grpc::ClientAsyncResponseReader<cast::bindings::ConnectResponse>> + response_reader_; + + std::unique_ptr<cast_api_bindings::MessagePort> port_; + uint32_t channel_id_; + }; + + std::unique_ptr<MessagePortHandler> MakeMessagePortHandler( + uint32_t channel_id, + std::unique_ptr<cast_api_bindings::MessagePort> port); + + // Callback invoked when AsyncConnect gets a gRPC result. + void OnConnectComplete(bool ok, + uint32_t channel_id, + std::unique_ptr<cast_api_bindings::MessagePort> port); + + CreatePairCallback create_pair_; + + grpc::CompletionQueue* grpc_cq_; + cast::v2::CoreApplicationService::Stub* core_app_stub_; + + int next_outgoing_channel_id_{0}; + // NOTE: Keyed by channel_id of cast::web::MessageChannelDescriptor. + base::flat_map<uint32_t, std::unique_ptr<MessagePortHandler>> ports_; + + base::WeakPtrFactory<MessagePortService> weak_factory_{this}; +}; + +} // namespace chromecast + +#endif // CHROMECAST_CAST_CORE_MESSAGE_PORT_SERVICE_H_
diff --git a/chromecast/cast_core/streaming_receiver_session_client.h b/chromecast/cast_core/streaming_receiver_session_client.h index 9d0addb6..18c5dcd9 100644 --- a/chromecast/cast_core/streaming_receiver_session_client.h +++ b/chromecast/cast_core/streaming_receiver_session_client.h
@@ -11,6 +11,10 @@ #include "components/cast/message_port/message_port.h" #include "components/cast_streaming/browser/public/receiver_session.h" +namespace content { +class NavigationHandle; +} // namespace content + namespace chromecast { // This class wraps all //components/cast_streaming functionality, only
diff --git a/chromecast/graphics/BUILD.gn b/chromecast/graphics/BUILD.gn index d7eaeb47..b670300 100644 --- a/chromecast/graphics/BUILD.gn +++ b/chromecast/graphics/BUILD.gn
@@ -168,7 +168,6 @@ "//ui/aura", "//ui/aura:test_support", "//ui/base:test_support", - "//ui/display/manager:manager", "//ui/events:test_support", "//ui/gfx", "//ui/gl:test_support",
diff --git a/chromecast/graphics/accessibility/partial_magnification_controller_unittest.cc b/chromecast/graphics/accessibility/partial_magnification_controller_unittest.cc index eff3426..c9c1b58 100644 --- a/chromecast/graphics/accessibility/partial_magnification_controller_unittest.cc +++ b/chromecast/graphics/accessibility/partial_magnification_controller_unittest.cc
@@ -5,7 +5,6 @@ #include "chromecast/graphics/accessibility/partial_magnification_controller.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/test/test_window_delegate.h" -#include "ui/display/manager/display_manager.h" #include "ui/events/test/event_generator.h" #include "ui/views/test/views_test_base.h" #include "ui/views/widget/widget.h"
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index e60e94b..1a60cb4 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -233,6 +233,9 @@ <message name="IDS_ASH_ENTERPRISE_ENROLLMENT_BUTTON" desc="Text shown on enterprise enrollment button on oobe screen."> Enterprise enrollment </message> + <message name="IDS_ASH_SHELF_SIGNIN_BUTTON" desc="Text shown on sign in button on enrollment screen."> + Use as personal device + </message> <message name="IDS_ASH_SHELF_OS_INSTALL_BUTTON" desc="Text shown on install cloudready button on login screen."> Install CloudReady </message> @@ -1523,6 +1526,9 @@ <message name="IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_MEDIA_FAILURE" desc="Error message shown when a connection cannot be established to the video conferencing media servers"> Unable to connect to media servers </message> + <message name="IDS_NETWORK_DIAGNOSTICS_IP_CONFIG_INFO_DRAWER_TITLE" desc="This element is the header for a collapsible content area responsible to showcasing IP related configuration data." > + IP Configuration + </message> <!-- Personalization App --> <message name="IDS_PERSONALIZATION_APP_TITLE" desc="Name of the system web app for personalizing ChromeOS.">
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_SHELF_SIGNIN_BUTTON.png.sha1 b/chromeos/chromeos_strings_grd/IDS_ASH_SHELF_SIGNIN_BUTTON.png.sha1 new file mode 100644 index 0000000..dbc2326 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_ASH_SHELF_SIGNIN_BUTTON.png.sha1
@@ -0,0 +1 @@ +7c044f041a3bdc058653ab28845d6e6e99a5af13 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_IP_CONFIG_INFO_DRAWER_TITLE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_IP_CONFIG_INFO_DRAWER_TITLE.png.sha1 new file mode 100644 index 0000000..ec055ad --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_IP_CONFIG_INFO_DRAWER_TITLE.png.sha1
@@ -0,0 +1 @@ +d3d50b0930f6be1ca01d61e50eaed67d19bec6ce \ No newline at end of file
diff --git a/chromeos/components/camera_app_ui/resources/images/camera_button_settings.svg b/chromeos/components/camera_app_ui/resources/images/camera_button_settings.svg index fa86ec8e..1957c1de 100644 --- a/chromeos/components/camera_app_ui/resources/images/camera_button_settings.svg +++ b/chromeos/components/camera_app_ui/resources/images/camera_button_settings.svg
@@ -12,15 +12,13 @@ <path d="M11.6628542,19 L8.33386438,19 C7.66806642,19 7.11023569,18.5256223 7.02926026,17.8843338 L6.78633397,16.2240117 C6.54340769,16.1010249 6.30947867,15.9692533 6.07554965,15.8199122 L4.45604108,16.4524158 C3.82623219,16.6808199 3.13344241,16.4260615 2.82753524,15.8814056 L1.18103486,13.0966325 C0.866130414,12.5168375 1.00108946,11.8316252 1.50493657,11.4450952 L2.88151886,10.3997072 C2.87252159,10.2679356 2.86352432,10.136164 2.86352432,9.99560761 C2.86352432,9.86383602 2.87252159,9.72327965 2.88151886,9.59150805 L1.51393384,8.54612006 C0.983094922,8.15080527 0.848135875,7.43923865 1.18103486,6.89458272 L2.84552978,4.09224012 C3.15143695,3.54758419 3.84422673,3.30161054 4.45604108,3.53879941 L6.08454692,4.18008785 C6.31847594,4.03074671 6.55240496,3.89897511 6.78633397,3.77598829 L7.02926026,2.09809663 C7.11023569,1.48316252 7.66806642,1 8.32486711,1 L11.653857,1 C12.3196549,1 12.8774857,1.47437775 12.9584611,2.11566618 L13.2013874,3.77598829 C13.4443137,3.89897511 13.6782427,4.03074671 13.9121717,4.18008785 L15.5316803,3.54758419 C16.1704864,3.31918009 16.8632762,3.57393851 17.1691834,4.11859444 L18.824681,6.91215227 C19.1485827,7.49194729 19.0046264,8.17715959 18.5007793,8.5636896 L17.1331943,9.6090776 C17.1421916,9.74084919 17.1511888,9.87262079 17.1511888,10.0131772 C17.1511888,10.1537335 17.1421916,10.2855051 17.1331943,10.4172767 L18.5007793,11.4626647 C19.0046264,11.8579795 19.1485827,12.5431918 18.8336783,13.0966325 L17.1601861,15.9253294 C16.8542789,16.4699854 16.1614891,16.715959 15.5406775,16.4787701 L13.921169,15.8462665 C13.6872399,15.9956076 13.4533109,16.1273792 13.2193819,16.250366 L12.9764556,17.9282577 C12.8864829,18.5256223 12.3286522,19 11.6628542,19 Z M11.1859989,17.6559297 L11.1859989,17.6734993 L11.1859989,17.6559297 Z M8.81071969,17.6383602 L8.81071969,17.6559297 C8.81971696,17.6559297 8.81971696,17.6471449 8.81071969,17.6383602 Z M8.75673607,17.2430454 L11.2399825,17.2430454 L11.5728815,15.0029283 L12.0497368,14.8096633 C12.4456167,14.6515373 12.8414966,14.4231332 13.255371,14.124451 L13.6602481,13.8257687 L15.8015984,14.6691069 L17.0432216,12.5607613 L15.2167758,11.1727672 L15.2797567,10.6808199 C15.3067485,10.4524158 15.3337403,10.2327965 15.3337403,9.99560761 C15.3337403,9.75841874 15.3067485,9.53001464 15.2797567,9.31039531 L15.2167758,8.81844802 L17.0432216,7.43045388 L15.7926011,5.32210835 L13.6422536,6.16544656 L13.2373764,5.8579795 C12.8594911,5.57686676 12.454614,5.34846266 12.0407396,5.18155198 L11.5728815,4.98828697 L11.2399825,2.74816984 L8.75673607,2.74816984 L8.42383708,4.98828697 L7.94698178,5.1727672 C7.55110191,5.33967789 7.15522203,5.55929722 6.74134762,5.86676428 L6.33647048,6.15666179 L4.19512026,5.32210835 L2.94449975,7.42166911 L4.77094553,8.80966325 L4.70796464,9.30161054 C4.68097283,9.53001464 4.65398102,9.76720351 4.65398102,9.99560761 C4.65398102,10.2240117 4.67197556,10.4612006 4.70796464,10.6808199 L4.77094553,11.1727672 L2.94449975,12.5607613 L4.18612299,14.6691069 L6.33647048,13.8257687 L6.74134762,14.1332357 C7.12823023,14.4231332 7.51511283,14.6427526 7.93798451,14.8096633 L8.41483981,15.0029283 L8.75673607,17.2430454 Z M15.5946611,15.0204978 C15.5946611,15.0292826 15.5856639,15.0380673 15.5856639,15.0468521 L15.5946611,15.0204978 Z M4.39306019,15.011713 L4.40205746,15.0292826 C4.40205746,15.0204978 4.39306019,15.011713 4.39306019,15.011713 Z M15.5946611,4.96193265 C15.5946611,4.97071742 15.6036584,4.9795022 15.6036584,4.9795022 L15.5946611,4.96193265 Z M4.41105473,4.9443631 L4.40205746,4.96193265 C4.40205746,4.96193265 4.41105473,4.95314788 4.41105473,4.9443631 Z M11.1770017,2.33528551 L11.1770017,2.35285505 L11.1770017,2.33528551 Z M9.99835931,6.92093704 C8.87331407,6.92093702 7.83372939,7.50696591 7.27120676,8.45827231 C6.70868414,9.4095787 6.70868414,10.5816365 7.27120676,11.5329429 C7.83372939,12.4842493 8.87331407,13.0702782 9.99835931,13.0702782 C11.7375285,13.0702782 13.1474038,11.6937013 13.1474038,9.99560761 C13.1474038,8.29751395 11.7375285,6.92093704 9.99835931,6.92093704 Z" id="path-2"></path> </defs> <g id="Mocks" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> - <g id="camera_grid_3:3-copy" transform="translate(-24.000000, -35.000000)"> - <g id="Left-bar" transform="translate(26.000000, 35.000000)"> - <g id="ic_settings" filter="url(#filter-1)"> - <polygon id="Shape" points="0 0 20 0 20 20 0 20"></polygon> - <mask id="mask-3" fill="white"> - <use xlink:href="#path-2"></use> - </mask> - <use id="ic_settings_24px" fill="#FFFFFF" fill-rule="nonzero" xlink:href="#path-2"></use> - </g> + <g id="camera_grid_3:3" transform="translate(2.000000, 2.000000)"> + <g id="ic_settings" filter="url(#filter-1)"> + <polygon id="Shape" points="0 0 20 0 20 20 0 20"></polygon> + <mask id="mask-3" fill="white"> + <use xlink:href="#path-2"></use> + </mask> + <use id="ic_settings_24px" fill="#FFFFFF" fill-rule="nonzero" xlink:href="#path-2"></use> </g> </g> </g>
diff --git a/chromeos/components/camera_app_ui/resources/views/main.html b/chromeos/components/camera_app_ui/resources/views/main.html index ce7cd927..bd15f50 100644 --- a/chromeos/components/camera_app_ui/resources/views/main.html +++ b/chromeos/components/camera_app_ui/resources/views/main.html
@@ -223,7 +223,7 @@ <span i18n-text="new_control_toast" aria-hidden="true"></span> </div> - <div id="options-group" class="left-stripe buttons"> + <div id="options-group" class="left-stripe buttons circle"> <button id="open-ptz-panel" tabindex="0" aria-haspopup="true" i18n-label="open_ptz_panel_button"> <div class="ripple"></div> @@ -242,7 +242,7 @@ i18n-tooltip-true="label_60fps" i18n-tooltip-false="label_30fps"> </div> - <div class="top-stripe left-stripe buttons"> + <div class="top-stripe left-stripe buttons circle"> <button id="open-settings" tabindex="0" i18n-label="settings_button" aria-haspopup="true"></button> </div>
diff --git a/chromeos/crosapi/mojom/keystore_service.mojom b/chromeos/crosapi/mojom/keystore_service.mojom index acf4be7..697562e7 100644 --- a/chromeos/crosapi/mojom/keystore_service.mojom +++ b/chromeos/crosapi/mojom/keystore_service.mojom
@@ -138,10 +138,10 @@ }; // Returned by GetPublicKey(). -[Stable, RenamedFrom="crosapi.mojom.GetPublicKeyResult"] -union DEPRECATED_GetPublicKeyResult { +[Stable] +union GetPublicKeyResult { // Implies failure. - string error_message; + KeystoreError error; // Implies success. GetPublicKeySuccessResult success_result; @@ -174,6 +174,17 @@ array<uint8> blob; }; +// DEPRECATED, use `GetPublicKeyResult` instead. +// Returned by DEPRECATED_GetPublicKey(). +[Stable] +union DEPRECATED_GetPublicKeyResult { + // Implies failure. + string error_message; + + // Implies success. + GetPublicKeySuccessResult success_result; +}; + // This interface is implemented by ash-chrome. It provides lacros-chrome a // mechanism to modify and query the attestation-only and generate purpose // keystores. @@ -228,10 +239,10 @@ // WebCrypto algorithm |algorithm_name|. If so, returns the key info and // details about the signing algorithm. |certificate| must be a DER encoded // X.509 certificate. - [MinVersion=3, RenamedFrom="crosapi.mojom.GetPublicKey"] - DEPRECATED_GetPublicKey@6(array<uint8> certificate, + [MinVersion=11] + GetPublicKey@15(array<uint8> certificate, KeystoreSigningAlgorithmName algorithm_name) => - (DEPRECATED_GetPublicKeyResult result); + (GetPublicKeyResult result); // Generates a private/public key-pair with |algorithm| and stores the results // in |keystore|. Returns the public key as a binary blob. @@ -298,4 +309,13 @@ KeystoreSigningScheme scheme, array<uint8> data, string extension_id) => (DEPRECATED_ExtensionKeystoreBinaryResult result); + + // DEPRECATED, use `GetPublicKey` instead. + // Checks whether |certificate| certifies a key that allows usage of the + // WebCrypto algorithm |algorithm_name|. If so, returns the key info and + // details about the signing algorithm. |certificate| must be a DER encoded + // X.509 certificate. + DEPRECATED_GetPublicKey@6(array<uint8> certificate, + KeystoreSigningAlgorithmName algorithm_name) => + (DEPRECATED_GetPublicKeyResult result); };
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt index 56faf535..cf41828 100644 --- a/chromeos/profiles/bigcore.afdo.newest.txt +++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-bigcore-93-4554.0-1626087514-benchmark-93.0.4577.5-r1-redacted.afdo.xz +chromeos-chrome-amd64-bigcore-93-4554.0-1626687898-benchmark-93.0.4577.6-r1-redacted.afdo.xz
diff --git a/components/arc/enterprise/arc_data_snapshotd_manager.cc b/components/arc/enterprise/arc_data_snapshotd_manager.cc index d5f1d68..b382b7c 100644 --- a/components/arc/enterprise/arc_data_snapshotd_manager.cc +++ b/components/arc/enterprise/arc_data_snapshotd_manager.cc
@@ -548,8 +548,6 @@ break; case State::kRunning: - state_ = State::kNone; - snapshot_.GetCurrentSnapshot()->set_verified(true); snapshot_.GetCurrentSnapshot()->set_updated(false); snapshot_.Sync();
diff --git a/components/arc/enterprise/arc_data_snapshotd_manager_unittest.cc b/components/arc/enterprise/arc_data_snapshotd_manager_unittest.cc index c366ad98..eabf1a7 100644 --- a/components/arc/enterprise/arc_data_snapshotd_manager_unittest.cc +++ b/components/arc/enterprise/arc_data_snapshotd_manager_unittest.cc
@@ -1070,11 +1070,12 @@ CheckVerifiedLastSnapshot(); CheckSnapshots(2 /* expected_snapshots_number */, false /* expected_blocked_ui_mode */); + EXPECT_EQ(manager->state(), ArcDataSnapshotdManager::State::kRunning); } else { CheckSnapshots(0 /* expected_snapshots_number */, false /* expected_blocked_ui_mode */); + EXPECT_EQ(manager->state(), ArcDataSnapshotdManager::State::kNone); } - EXPECT_EQ(manager->state(), ArcDataSnapshotdManager::State::kNone); // Exit MGS successfully. LogoutPublicSession();
diff --git a/components/arc/enterprise/snapshot_session_controller.cc b/components/arc/enterprise/snapshot_session_controller.cc index 76dce22..d095c0db 100644 --- a/components/arc/enterprise/snapshot_session_controller.cc +++ b/components/arc/enterprise/snapshot_session_controller.cc
@@ -17,7 +17,7 @@ namespace { // The maximum duration of all required apps being installed. -const base::TimeDelta kDuration = base::TimeDelta::FromMinutes(5); +const base::TimeDelta kDuration = base::TimeDelta::FromMinutes(40); // This class tracks a user session lifetime and notifies its observers about // the appropriate session state changes.
diff --git a/components/arc/enterprise/snapshot_session_controller_unittest.cc b/components/arc/enterprise/snapshot_session_controller_unittest.cc index 1d351b19..9460c7c 100644 --- a/components/arc/enterprise/snapshot_session_controller_unittest.cc +++ b/components/arc/enterprise/snapshot_session_controller_unittest.cc
@@ -201,7 +201,7 @@ EXPECT_TRUE(session_controller->get_timer_for_testing()->IsRunning()); EXPECT_EQ(1, apps_tracker()->start_tracking_num()); - task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(5)); + task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(40)); task_environment_.RunUntilIdle(); EXPECT_FALSE(session_controller->get_timer_for_testing()->IsRunning());
diff --git a/components/autofill/content/renderer/form_cache.h b/components/autofill/content/renderer/form_cache.h index b6d6e8315..22afde1 100644 --- a/components/autofill/content/renderer/form_cache.h +++ b/components/autofill/content/renderer/form_cache.h
@@ -67,10 +67,6 @@ const std::vector<FieldRendererId>& fields_eligible_for_manual_filling); private: - FRIEND_TEST_ALL_PREFIXES(FormCacheTest, - ShouldShowAutocompleteConsoleWarnings_Enabled); - FRIEND_TEST_ALL_PREFIXES(FormCacheTest, - ShouldShowAutocompleteConsoleWarnings_Disabled); FRIEND_TEST_ALL_PREFIXES(FormCacheBrowserTest, FreeDataOnElementRemoval); FRIEND_TEST_ALL_PREFIXES( FormCacheBrowserTest, @@ -90,14 +86,6 @@ void SaveInitialValues( const std::vector<blink::WebFormControlElement>& control_elements); - // Returns whether we should show a console warning related to a wrong - // autocomplete attribute. We will show a warning if (1) there is no - // autocomplete attribute and we have a guess for one or (2) we recognize the - // autocomplete attribute but it appears to be the wrong one. - bool ShouldShowAutocompleteConsoleWarnings( - const std::string& predicted_autocomplete, - const std::string& actual_autocomplete); - // Clears the value of the |control_element|. void ClearElement(blink::WebFormControlElement& control_element, const blink::WebFormControlElement& element);
diff --git a/components/browser_ui/site_settings/android/BUILD.gn b/components/browser_ui/site_settings/android/BUILD.gn index 26464cf..69571247 100644 --- a/components/browser_ui/site_settings/android/BUILD.gn +++ b/components/browser_ui/site_settings/android/BUILD.gn
@@ -79,6 +79,7 @@ deps = [ ":java_resources", "//base:base_java", + "//build/android:build_config_java", "//components/browser_ui/settings/android:java", "//components/browser_ui/widget/android:java", "//components/content_settings/android:content_settings_enums_java",
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ChosenObjectSettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ChosenObjectSettings.java index f4c6d5a..8e1aa82c2 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ChosenObjectSettings.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ChosenObjectSettings.java
@@ -20,7 +20,7 @@ import androidx.preference.PreferenceScreen; import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; -import org.chromium.base.annotations.RemovableInRelease; +import org.chromium.build.BuildConfig; import org.chromium.components.browser_ui.settings.ChromeImageViewPreference; import org.chromium.components.browser_ui.settings.ManagedPreferencesUtils; @@ -82,11 +82,12 @@ * returns the same value. This must be true because this activity is displaying permissions * for a single object. Each instance varies only in which site it represents. */ - @RemovableInRelease private void checkObjectConsistency() { - String exampleObject = mObjectInfos.get(0).getObject(); - for (ChosenObjectInfo info : mObjectInfos) { - assert info.getObject().equals(exampleObject); + if (BuildConfig.ENABLE_ASSERTS) { + String exampleObject = mObjectInfos.get(0).getObject(); + for (ChosenObjectInfo info : mObjectInfos) { + assert info.getObject().equals(exampleObject); + } } }
diff --git a/components/browser_ui/styles/android/BUILD.gn b/components/browser_ui/styles/android/BUILD.gn index 6d7cfc06..986c777 100644 --- a/components/browser_ui/styles/android/BUILD.gn +++ b/components/browser_ui/styles/android/BUILD.gn
@@ -176,7 +176,6 @@ "java/res/values-night/values.xml", "java/res/values-sw600dp-v27/styles.xml", "java/res/values-v27/styles.xml", - "java/res/values-v31/styles.xml", "java/res/values/colors.xml", "java/res/values/dimens.xml", "java/res/values/drawables.xml",
diff --git a/components/browser_ui/styles/android/java/res/values-v31/styles.xml b/components/browser_ui/styles/android/java/res/values-v31/styles.xml deleted file mode 100644 index ba8d47d..0000000 --- a/components/browser_ui/styles/android/java/res/values-v31/styles.xml +++ /dev/null
@@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2021 The Chromium Authors. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. --> - -<resources> - <style name="Theme.BrowserUI" parent="Base.Theme.BrowserUI" > - <!-- TODO(https://crbug.com/1201349): Disable overscroll on S due to - consistency issues between browser and web platform. --> - <item name="android:overScrollMode">never</item> - </style> -</resources>
diff --git a/components/browser_ui/styles/android/java/res/values/styles.xml b/components/browser_ui/styles/android/java/res/values/styles.xml index 58e8c53..7f2d4aa8 100644 --- a/components/browser_ui/styles/android/java/res/values/styles.xml +++ b/components/browser_ui/styles/android/java/res/values/styles.xml
@@ -5,7 +5,7 @@ <resources xmlns:tools="http://schemas.android.com/tools"> <!-- Theme shared between Chrome and embedders. --> - <style name="Base.Theme.BrowserUI" parent="Theme.MaterialComponents.DayNight.NoActionBar"> + <style name="Theme.BrowserUI" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <!-- Text colors --> <item name="android:textColorLink">@color/default_text_color_link</item> <item name="android:textColorHighlight">@color/text_highlight_color</item> @@ -55,7 +55,6 @@ <item name="radioButtonStyle">@style/Widget.AppCompat.CompoundButton.RadioButton</item> <item name="checkboxStyle">@style/Widget.AppCompat.CompoundButton.CheckBox</item> </style> - <style name="Theme.BrowserUI" parent="Base.Theme.BrowserUI" /> <style name="TextInputStyle" parent="Widget.Design.TextInputLayout"> <item name="errorTextAppearance">@style/TextAppearance.ErrorCaption</item>
diff --git a/components/dom_distiller/core/page_features.cc b/components/dom_distiller/core/page_features.cc index 52b027d..8728f41 100644 --- a/components/dom_distiller/core/page_features.cc +++ b/components/dom_distiller/core/page_features.cc
@@ -147,13 +147,12 @@ std::vector<double> CalculateDerivedFeaturesFromJSON( const base::Value* stringified_json) { - std::string stringified; - if (!stringified_json->GetAsString(&stringified)) { + if (!stringified_json->is_string()) { return std::vector<double>(); } std::unique_ptr<base::Value> json = - base::JSONReader::ReadDeprecated(stringified); + base::JSONReader::ReadDeprecated(stringified_json->GetString()); if (!json) { return std::vector<double>(); }
diff --git a/components/exo/BUILD.gn b/components/exo/BUILD.gn index b6e12528..20b2d3b7 100644 --- a/components/exo/BUILD.gn +++ b/components/exo/BUILD.gn
@@ -371,7 +371,6 @@ "//ui/aura:test_support", "//ui/base", "//ui/compositor:test_support", - "//ui/display:display_manager_test_api", "//ui/gl:test_support", ] @@ -391,6 +390,7 @@ "//ash:test_support", "//ash/public/cpp", "//components/exo/server:unit_tests", + "//ui/display:display_manager_test_api", ] data_deps += [
diff --git a/components/full_restore/full_restore_read_handler.cc b/components/full_restore/full_restore_read_handler.cc index 01705bc..b7cd2bb 100644 --- a/components/full_restore/full_restore_read_handler.cc +++ b/components/full_restore/full_restore_read_handler.cc
@@ -89,6 +89,11 @@ active_profile_path_ = profile_path; } +void FullRestoreReadHandler::SetCheckRestoreData( + const base::FilePath& profile_path) { + should_check_restore_data_.insert(profile_path); +} + void FullRestoreReadHandler::OnTaskCreated(const std::string& app_id, int32_t task_id, int32_t session_id) { @@ -178,8 +183,10 @@ } bool FullRestoreReadHandler::HasWindowInfo(int32_t restore_window_id) { - if (!SessionID::IsValidValue(restore_window_id)) + if (!SessionID::IsValidValue(restore_window_id) || + !base::Contains(should_check_restore_data_, active_profile_path_)) { return false; + } auto it = window_id_to_app_restore_info_.find(restore_window_id); if (it == window_id_to_app_restore_info_.end()) @@ -258,8 +265,10 @@ // TODO(sammiequon): Separate full restore and desk templates logic. window_info = DeskTemplateReadHandler::GetInstance()->GetWindowInfo( restore_window_id); - if (!window_info) + if (!window_info && + base::Contains(should_check_restore_data_, active_profile_path_)) { window_info = GetWindowInfo(restore_window_id); + } } if (!window_info) return;
diff --git a/components/full_restore/full_restore_read_handler.h b/components/full_restore/full_restore_read_handler.h index 7f98381..0111e3a5 100644 --- a/components/full_restore/full_restore_read_handler.h +++ b/components/full_restore/full_restore_read_handler.h
@@ -65,6 +65,11 @@ void SetActiveProfilePath(const base::FilePath& profile_path); + // Sets whether we should check the restore data for `profile_path`. If the + // user selects `Restore`, then we should check the restore data for restored + // windows. Otherwise, we don't need to to check the restore data. + void SetCheckRestoreData(const base::FilePath& profile_path); + // Invoked when the task is created for an ARC app. void OnTaskCreated(const std::string& app_id, int32_t task_id, @@ -200,6 +205,12 @@ std::unique_ptr<ArcReadHandler> arc_read_handler_; + // Records whether we need to check the restore data for the profile path. If + // the profile path is recorded, we should check the restore data. Otherwise, + // we don't need to check the restore data, because the restore process hasn't + // started yet. + std::set<base::FilePath> should_check_restore_data_; + base::ScopedObservation<aura::Env, aura::EnvObserver> env_observer_{this}; base::ScopedMultiSourceObservation<aura::Window, aura::WindowObserver>
diff --git a/components/history/core/browser/history_backend_unittest.cc b/components/history/core/browser/history_backend_unittest.cc index 442c811..780c2d4d 100644 --- a/components/history/core/browser/history_backend_unittest.cc +++ b/components/history/core/browser/history_backend_unittest.cc
@@ -1959,15 +1959,15 @@ int cur_version = HistoryDatabase::GetCurrentVersion(); sql::Database db; ASSERT_TRUE(db.Open(new_history_file)); - sql::Statement s(db.GetUniqueStatement( - "SELECT value FROM meta WHERE key = 'version'")); + sql::Statement s( + db.GetUniqueStatement("SELECT value FROM meta WHERE key='version'")); ASSERT_TRUE(s.Step()); int file_version = s.ColumnInt(0); EXPECT_EQ(cur_version, file_version); // Check visit_source table is created and empty. s.Assign(db.GetUniqueStatement( - "SELECT name FROM sqlite_master WHERE name=\"visit_source\"")); + "SELECT name FROM sqlite_master WHERE name='visit_source'")); ASSERT_TRUE(s.Step()); s.Assign(db.GetUniqueStatement("SELECT * FROM visit_source LIMIT 10")); EXPECT_FALSE(s.Step());
diff --git a/components/history/core/browser/url_database.cc b/components/history/core/browser/url_database.cc index 3809314..a966b62 100644 --- a/components/history/core/browser/url_database.cc +++ b/components/history/core/browser/url_database.cc
@@ -654,7 +654,7 @@ kv.keyword_id = ? AND u.last_visit_time > ? AND kv.normalized_term IS NOT NULL - AND kv.normalized_term != "" + AND kv.normalized_term != '' GROUP BY normalized_term, rnd_last_visit_time ) GROUP BY normalized_term
diff --git a/components/history/core/browser/visit_database.cc b/components/history/core/browser/visit_database.cc index 2c4aba0d..1689e77 100644 --- a/components/history/core/browser/visit_database.cc +++ b/components/history/core/browser/visit_database.cc
@@ -758,25 +758,27 @@ base::Time end_time) { sql::Statement statement(GetDB().GetCachedStatement( SQL_FROM_HERE, + // clang-format off "SELECT " - " visit_time, " - " u.url " - "FROM " - " urls u JOIN visits v ON u.id = v.url " - "WHERE " - // Pre-filtering to limit the number of entries to process in - // C++. The url column is indexed so this makes the query more - // efficient. We then confirm in C++ that the domain of an entry - // is a valid Google domain before counting the visit. - " (u.url LIKE \"https://www.google.__/search%\" OR " - " u.url LIKE \"https://www.google.___/search%\" OR " - " u.url LIKE \"https://www.google.__.__/search%\" OR " - " u.url LIKE \"https://www.google.___.__/search%\") AND " - // Restrict to visits that are more recent than the specified start - // time. - " visit_time >= ? AND " - // Restrict to visits that are older than the specified end time. - " visit_time < ? ")); + "visit_time," + "u.url " + "FROM " + "urls u JOIN visits v ON u.id=v.url " + "WHERE " + // Pre-filtering to limit the number of entries to process in + // C++. The url column is indexed so this makes the query more + // efficient. We then confirm in C++ that the domain of an entry + // is a valid Google domain before counting the visit. + "(u.url LIKE 'https://www.google.__/search%' OR " + "u.url LIKE 'https://www.google.___/search%' OR " + "u.url LIKE 'https://www.google.__.__/search%' OR " + "u.url LIKE 'https://www.google.___.__/search%') AND " + // Restrict to visits that are more recent than the specified + // start time. + "visit_time >= ? AND " + // Restrict to visits that are older than the specified end time. + "visit_time < ?")); + // clang-format on statement.BindTime(0, begin_time); statement.BindTime(1, end_time); std::vector<DomainVisit> domain_visits;
diff --git a/components/history_clusters/core/history_clusters_service.cc b/components/history_clusters/core/history_clusters_service.cc index cdba4d6..6cddd0e9 100644 --- a/components/history_clusters/core/history_clusters_service.cc +++ b/components/history_clusters/core/history_clusters_service.cc
@@ -5,6 +5,7 @@ #include "components/history_clusters/core/history_clusters_service.h" #include <algorithm> +#include <iterator> #include <numeric> #include <utility> @@ -12,7 +13,10 @@ #include "base/feature_list.h" #include "base/i18n/case_conversion.h" #include "base/ranges/algorithm.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/time/time.h" +#include "base/time/time_to_iso8601.h" #include "components/history/core/browser/history_types.h" #include "components/history_clusters/core/history_clusters_buildflags.h" #include "components/history_clusters/core/memories_features.h" @@ -104,14 +108,6 @@ return clusters; } -HistoryClustersService::QueryClustersResult MakeQueryClustersResult( - std::vector<history::Cluster> clusters) { - HistoryClustersService::QueryClustersResult result; - result.clusters = std::move(clusters); - // TODO(tommycli): Fill `continuation_end_time` once pagination done. - return result; -} - } // namespace HistoryClustersService::QueryClustersResult::QueryClustersResult() = default; @@ -217,6 +213,9 @@ QueryClustersCallback callback, base::CancelableTaskTracker* task_tracker) { NotifyDebugMessage("HistoryClustersService::QueryClusters()"); + NotifyDebugMessage(" end_time = " + (end_time.is_null() + ? "null" + : base::TimeToISO8601(end_time))); if (!backend_ || !backend_weak_factory_) { NotifyDebugMessage( @@ -226,58 +225,15 @@ return; } - // TODO(crbug.com/1220765): Fully support pagination using `end_time` and - // `max_count`. - auto on_visits_callback = base::BindOnce( - &ClusteringBackend::GetClusters, backend_weak_factory_->GetWeakPtr(), - base::BindOnce(&FilterClustersMatchingQuery, query) - .Then(base::BindOnce(&SortClusters)) - .Then(base::BindOnce(&MakeQueryClustersResult)) - .Then(std::move(callback))); + size_t max_visit_count = kMaxVisitsToCluster.Get(); + if (max_count > 0) { + // As a primitive heuristic, fetch 3x the amount of visits as requested + // clusters. We don't know in advance how big the clusters will be. + max_visit_count = max_count * 3; + } - // TODO(tommycli): Support pagination by setting `begin_time` on `options`. - history::QueryOptions options; - options.max_count = kMaxVisitsToCluster.Get(); - - history_service_->GetAnnotatedVisits( - options, - base::BindOnce( - [](const IncompleteVisitMap& incomplete_visits, - const history::QueryOptions& options, - std::vector<history::AnnotatedVisit> visits) { - // Append incomplete visits to `visits` too, as otherwise they will - // be mysteriously missing from the Clusters UI. They haven't - // recorded the page end metrics yet, but that's fine. - for (const auto& item : incomplete_visits) { - auto& incomplete_visit = item.second; - if (incomplete_visit.url_row.id() == 0 || - incomplete_visit.visit_row.visit_id == 0) { - // Discard incomplete visits that don't have visit_ids yet. - continue; - } - - const auto& visit_time = incomplete_visit.visit_row.visit_time; - if (visit_time < options.begin_time || - (!options.end_time.is_null() && - visit_time >= options.end_time)) { - // Discard incomplete visits outside the `options` time bounds. - // `begin_time` is inclusive, and `end_time` is exclusive. - continue; - } - - visits.push_back({incomplete_visit.url_row, - incomplete_visit.visit_row, - incomplete_visit.context_annotations, - // Content annotations not provided, but it's - // not provided for complete visits either. - {}}); - } - - return visits; - }, - incomplete_visit_context_annotations_, options) - .Then(std::move(on_visits_callback)), - task_tracker); + StartOnTheFlyClustering(query, end_time, max_visit_count, std::move(callback), + task_tracker); } void HistoryClustersService::RemoveVisits( @@ -337,4 +293,153 @@ all_keywords_cache_timestamp_ = base::Time::Now(); } +void HistoryClustersService::StartOnTheFlyClustering( + const std::string& query, + base::Time end_time, + size_t max_visit_count, + QueryClustersCallback callback, + base::CancelableTaskTracker* task_tracker) const { + DCHECK(history_service_); + + history::QueryOptions options; + options.end_time = end_time; + + // Super simple method of pagination: one day a time, broken up at 4AM. + { + // Get 4AM yesterday in the morning, and 4AM today in the afternoon. + base::Time begin = end_time.is_null() ? base::Time::Now() : end_time; + begin -= base::TimeDelta::FromHours(12); + + base::Time::Exploded exploded_begin; + begin.LocalExplode(&exploded_begin); + exploded_begin.hour = 4; + exploded_begin.minute = 0; + exploded_begin.second = 0; + exploded_begin.millisecond = 0; + + // If for some reason this fails, fallback to 24 hours ago. + if (!base::Time::FromLocalExploded(exploded_begin, &options.begin_time)) { + options.begin_time = end_time - base::TimeDelta::FromDays(1); + } + } + + NotifyDebugMessage("HistoryClustersService::StartOnTheFlyClustering()"); + NotifyDebugMessage(" begin_time = " + + (options.begin_time.is_null() + ? "null" + : base::TimeToISO8601(options.begin_time))); + NotifyDebugMessage(" end_time = " + + (options.end_time.is_null() + ? "null" + : base::TimeToISO8601(options.end_time))); + history_service_->GetAnnotatedVisits( + options, + base::BindOnce(&HistoryClustersService::OnGotHistoryVisits, + weak_ptr_factory_.GetWeakPtr(), query, + /*original_end_time=*/end_time, max_visit_count, + std::move(callback), options, task_tracker, + std::vector<history::AnnotatedVisit>()), + task_tracker); +} + +void HistoryClustersService::OnGotHistoryVisits( + const std::string& query, + base::Time original_end_time, + size_t max_visit_count, + QueryClustersCallback callback, + history::QueryOptions options, + base::CancelableTaskTracker* task_tracker, + std::vector<history::AnnotatedVisit> accumulated_visits, + std::vector<history::AnnotatedVisit> newly_fetched_visits) const { + NotifyDebugMessage("HistoryClustersService::OnGotHistoryVisits()"); + NotifyDebugMessage(base::StringPrintf(" newly_fetched_visits.size() = %zu", + newly_fetched_visits.size())); + + // Tack on all the newly fetched visits onto our accumulator vector. + base::ranges::move(newly_fetched_visits, + std::back_inserter(accumulated_visits)); + + // TODO(tommycli): Connect this to History's limit defined internally in + // components/history. + bool exhausted_history = + (base::Time::Now() - options.begin_time) >= base::TimeDelta::FromDays(90); + NotifyDebugMessage( + base::StringPrintf(" exhausted_history = %d", exhausted_history)); + + // If we didn't get enough visits, ask for another day's worth from + // History and call this method again when done. + if (!exhausted_history && accumulated_visits.size() < max_visit_count) { + options.end_time = options.begin_time; + options.begin_time = options.end_time - base::TimeDelta::FromDays(1); + + NotifyDebugMessage("Starting History Query:"); + NotifyDebugMessage(" begin_time = " + + (options.begin_time.is_null() + ? "null" + : base::TimeToISO8601(options.begin_time))); + NotifyDebugMessage(" end_time = " + + (options.end_time.is_null() + ? "null" + : base::TimeToISO8601(options.end_time))); + history_service_->GetAnnotatedVisits( + options, + base::BindOnce(&HistoryClustersService::OnGotHistoryVisits, + weak_ptr_factory_.GetWeakPtr(), query, original_end_time, + max_visit_count, std::move(callback), options, + task_tracker, std::move(accumulated_visits)), + task_tracker); + return; + } + + // Assuming we didn't completely exhaust history, the `continuation_end_time` + // is the `options.begin_time` of the latest History query we completed. + base::Time continuation_end_time; + if (!exhausted_history) + continuation_end_time = options.begin_time; + + // Now we have enough visits for clustering, add all incomplete visits between + // the current `options.begin_time` and `original_end_time`, as otherwise they + // will be mysteriously missing from the Clusters UI. They haven't recorded + // the page end metrics yet, but that's fine. + for (const auto& item : incomplete_visit_context_annotations_) { + auto& incomplete_visit = item.second; + if (incomplete_visit.url_row.id() == 0 || + incomplete_visit.visit_row.visit_id == 0) { + // Discard incomplete visits that don't have visit_ids yet. + continue; + } + + const auto& visit_time = incomplete_visit.visit_row.visit_time; + if (visit_time < options.begin_time || + (!original_end_time.is_null() && visit_time >= original_end_time)) { + // Discard incomplete visits outside the `options` time bounds. + // `begin_time` is inclusive, and `end_time` is exclusive. + continue; + } + + accumulated_visits.push_back({ + incomplete_visit.url_row, + incomplete_visit.visit_row, + incomplete_visit.context_annotations, + // TODO(tommycli): Add content annotations. + {}, + }); + } + + NotifyDebugMessage("Calling backend_->GetClusters()"); + backend_->GetClusters( + base::BindOnce( + [](const std::string& query, base::Time continuation_end_time, + QueryClustersCallback callback, + const std::vector<history::Cluster>& clusters) { + HistoryClustersService::QueryClustersResult result; + result.continuation_end_time = continuation_end_time; + result.clusters = FilterClustersMatchingQuery(query, clusters); + result.clusters = SortClusters(result.clusters); + std::move(callback).Run(std::move(result)); + }, + query, continuation_end_time, std::move(callback)), + accumulated_visits); +} + } // namespace history_clusters
diff --git a/components/history_clusters/core/history_clusters_service.h b/components/history_clusters/core/history_clusters_service.h index f5ab181..e3393c9 100644 --- a/components/history_clusters/core/history_clusters_service.h +++ b/components/history_clusters/core/history_clusters_service.h
@@ -119,6 +119,27 @@ // keywords in `clusters`. void PopulateClusterKeywordCache(QueryClustersResult result); + // Queries `HistoryService` for visits, one day at a time, until there's + // at least `max_visit_count`. This also appends eligible incomplete visits. + // Finally, this calls `callback` with the resulting vector, and the + // `continuation_end_time` needed for the next page of visits. + void StartOnTheFlyClustering(const std::string& query, + base::Time end_time, + size_t max_visit_count, + QueryClustersCallback callback, + base::CancelableTaskTracker* task_tracker) const; + + // Internally used callback for GetVisitsForOnTheFlyClustering. + void OnGotHistoryVisits( + const std::string& query, + base::Time original_end_time, + size_t max_visit_count, + QueryClustersCallback callback, + history::QueryOptions options, + base::CancelableTaskTracker* task_tracker, + std::vector<history::AnnotatedVisit> accumulated_visits, + std::vector<history::AnnotatedVisit> newly_fetched_visits) const; + // `VisitContextAnnotations`s are constructed stepwise; they're initially // placed in `incomplete_visit_context_annotations_` and saved to the history // database once completed (if persistence is enabled).
diff --git a/components/history_clusters/core/history_clusters_service_test_api.cc b/components/history_clusters/core/history_clusters_service_test_api.cc index ad1f79b..38d09e3 100644 --- a/components/history_clusters/core/history_clusters_service_test_api.cc +++ b/components/history_clusters/core/history_clusters_service_test_api.cc
@@ -11,37 +11,40 @@ // static std::vector<history::AnnotatedVisit> GetHardcodedTestVisits() { - std::vector<history::AnnotatedVisit> visits; + // For non-flakiness, return a static list of visits, as this relies on Now(). + static std::vector<history::AnnotatedVisit> visits; - { - history::AnnotatedVisit visit; - visit.url_row.set_id(1); - visit.url_row.set_url(GURL("https://google.com/")); - visit.url_row.set_title(u"Google title"); - visit.visit_row.visit_id = 1; - // Choose a recent time, as otherwise History will discard the visit. - visit.visit_row.visit_time = - base::Time::Now() - base::TimeDelta::FromDays(2); - visit.visit_row.visit_duration = base::TimeDelta::FromMilliseconds(5600); - visit.context_annotations.page_end_reason = 3; - visit.context_annotations.is_new_bookmark = true; - visits.push_back(visit); - } + if (visits.empty()) { + { + history::AnnotatedVisit visit; + visit.url_row.set_id(1); + visit.url_row.set_url(GURL("https://google.com/")); + visit.url_row.set_title(u"Google title"); + visit.visit_row.visit_id = 1; + // Choose a recent time, as otherwise History will discard the visit. + visit.visit_row.visit_time = + base::Time::Now() - base::TimeDelta::FromDays(2); + visit.visit_row.visit_duration = base::TimeDelta::FromMilliseconds(5600); + visit.context_annotations.page_end_reason = 3; + visit.context_annotations.is_new_bookmark = true; + visits.push_back(visit); + } - { - history::AnnotatedVisit visit; - visit.url_row.set_id(2); - visit.url_row.set_url(GURL("https://github.com/")); - visit.url_row.set_title(u"Github title"); - visit.visit_row.visit_id = 2; - // Choose a recent time, as otherwise History will discard the visit. - visit.visit_row.visit_time = - base::Time::Now() - base::TimeDelta::FromDays(1); - visit.visit_row.visit_duration = base::TimeDelta::FromSeconds(20); - visit.visit_row.referring_visit = 1; - visit.context_annotations.page_end_reason = 5; - visit.context_annotations.is_existing_part_of_tab_group = true; - visits.push_back(visit); + { + history::AnnotatedVisit visit; + visit.url_row.set_id(2); + visit.url_row.set_url(GURL("https://github.com/")); + visit.url_row.set_title(u"Github title"); + visit.visit_row.visit_id = 2; + // Choose a recent time, as otherwise History will discard the visit. + visit.visit_row.visit_time = + base::Time::Now() - base::TimeDelta::FromDays(1); + visit.visit_row.visit_duration = base::TimeDelta::FromSeconds(20); + visit.visit_row.referring_visit = 1; + visit.context_annotations.page_end_reason = 5; + visit.context_annotations.is_existing_part_of_tab_group = true; + visits.push_back(visit); + } } return visits;
diff --git a/components/history_clusters/core/history_clusters_service_unittest.cc b/components/history_clusters/core/history_clusters_service_unittest.cc index 783e782..e10e572 100644 --- a/components/history_clusters/core/history_clusters_service_unittest.cc +++ b/components/history_clusters/core/history_clusters_service_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include <string> +#include "base/callback_forward.h" #include "base/containers/contains.h" #include "base/files/scoped_temp_dir.h" #include "base/run_loop.h" @@ -41,6 +42,8 @@ const std::vector<history::AnnotatedVisit>& visits) override { callback_ = std::move(callback); last_clustered_visits_ = visits; + + std::move(wait_for_get_clusters_closure_).Run(); } void FulfillCallback(const std::vector<history::Cluster>& clusters) { @@ -64,7 +67,15 @@ return history::ScoredAnnotatedVisit(); } + void WaitForGetClustersCall() { + base::RunLoop loop; + wait_for_get_clusters_closure_ = loop.QuitClosure(); + loop.Run(); + } + private: + base::OnceClosure wait_for_get_clusters_closure_; + ClustersCallback callback_; std::vector<history::AnnotatedVisit> last_clustered_visits_; }; @@ -129,7 +140,9 @@ } // Verifies that the hardcoded visits were passed to the clustering backend. - void VerifyTestClusteringBackendRequest() { + void AwaitAndVerifyTestClusteringBackendRequest() { + test_clustering_backend_->WaitForGetClustersCall(); + std::vector<history::AnnotatedVisit> visits = test_clustering_backend_->last_clustered_visits(); ASSERT_EQ(visits.size(), 2u); @@ -184,7 +197,7 @@ AddHardcodedTestDataToHistoryService(); history_clusters_service_->QueryClusters( - /*query=*/"", /*max_time=*/base::Time::Now(), /* max_count=*/0, + /*query=*/"", /*end_time=*/base::Time(), /* max_count=*/0, // This "expect" block is not run until after the fake response is sent // further down in this method. base::BindLambdaForTesting( @@ -211,8 +224,7 @@ }), &task_tracker_); - history::BlockUntilHistoryProcessesPendingRequests(history_service_.get()); - VerifyTestClusteringBackendRequest(); + AwaitAndVerifyTestClusteringBackendRequest(); std::vector<history::Cluster> clusters; // This first cluster is meant to validate that the higher scoring "visit 1" @@ -269,7 +281,7 @@ auto run_loop_quit = run_loop.QuitClosure(); history_clusters_service_->QueryClusters( - test_data[i].query, /*max_time=*/base::Time::Now(), + test_data[i].query, /*end_time=*/base::Time(), /* max_count=*/0, // This "expect" block is not run until after the fake response is sent // further down in this method. @@ -333,8 +345,7 @@ }), &task_tracker_); - history::BlockUntilHistoryProcessesPendingRequests(history_service_.get()); - VerifyTestClusteringBackendRequest(); + AwaitAndVerifyTestClusteringBackendRequest(); std::vector<history::Cluster> clusters; clusters.push_back( @@ -499,8 +510,7 @@ EXPECT_FALSE(history_clusters_service_->DoesQueryMatchAnyCluster("appl")); // Providing the response and running the task loop should populate the cache. - history::BlockUntilHistoryProcessesPendingRequests(history_service_.get()); - VerifyTestClusteringBackendRequest(); + AwaitAndVerifyTestClusteringBackendRequest(); std::vector<history::Cluster> clusters; clusters.push_back(
diff --git a/components/metrics/demographics/demographic_metrics_provider.cc b/components/metrics/demographics/demographic_metrics_provider.cc index 7dd42b16..6ea6865 100644 --- a/components/metrics/demographics/demographic_metrics_provider.cc +++ b/components/metrics/demographics/demographic_metrics_provider.cc
@@ -18,12 +18,9 @@ bool CanUploadDemographicsToGoogle(syncer::SyncService* sync_service) { DCHECK(sync_service); - // Require that the user has opted into sync the feature, without just relying - // on PRIORITY_PREFERENCES start sync-ing. - if (!sync_service->IsSyncFeatureEnabled()) { - return false; - } - + // PRIORITY_PREFERENCES is the sync datatype used to propagate demographics + // information to the client. In its absence, demographics info is unavailable + // thus cannot be uploaded. switch (GetUploadToGoogleState(sync_service, syncer::PRIORITY_PREFERENCES)) { case syncer::UploadState::NOT_ACTIVE: return false; @@ -117,7 +114,7 @@ base::UmaHistogramEnumeration("UMA.UserDemographics.Status", status); // If the user demographics data was retrieved successfully, then the user // must be between the ages of |kUserDemographicsMinAgeInYears|+1=21 and - // |kUserDemographicsMaxAgeinYears|=85, so the user is not a minor. + // |kUserDemographicsMaxAgeInYears|=85, so the user is not a minor. base::UmaHistogramBoolean("UMA.UserDemographics.IsNoisedAgeOver21Under85", status == UserDemographicsStatus::kSuccess); return;
diff --git a/components/metrics/demographics/demographic_metrics_provider.h b/components/metrics/demographics/demographic_metrics_provider.h index fe4aa99..58b68d73 100644 --- a/components/metrics/demographics/demographic_metrics_provider.h +++ b/components/metrics/demographics/demographic_metrics_provider.h
@@ -12,7 +12,6 @@ #include "components/metrics/metrics_log_uploader.h" #include "components/metrics/metrics_provider.h" #include "components/metrics/ukm_demographic_metrics_provider.h" -#include "components/sync/driver/sync_service.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h" #include "third_party/metrics_proto/user_demographics.pb.h" @@ -23,6 +22,10 @@ struct Feature; } +namespace syncer { +class SyncService; +} + namespace metrics { // Provider of the synced user’s noised birth year and gender to the UMA metrics
diff --git a/components/metrics/demographics/demographic_metrics_provider_unittest.cc b/components/metrics/demographics/demographic_metrics_provider_unittest.cc index d02d523..758eb25a 100644 --- a/components/metrics/demographics/demographic_metrics_provider_unittest.cc +++ b/components/metrics/demographics/demographic_metrics_provider_unittest.cc
@@ -53,8 +53,10 @@ case SYNC_FEATURE_NOT_ENABLED: sync_service_ = std::make_unique<syncer::TestSyncService>(); - // Mimic sync-the-feature being disabled. - sync_service_->SetFirstSetupComplete(false); + // Set an arbitrary disable reason to mimic sync feature being unable to + // start. + sync_service_->SetDisableReasons( + syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR); break; case SYNC_FEATURE_ENABLED:
diff --git a/components/network_time/network_time_tracker.cc b/components/network_time/network_time_tracker.cc index e38ab86..e7394b5 100644 --- a/components/network_time/network_time_tracker.cc +++ b/components/network_time/network_time_tracker.cc
@@ -13,8 +13,7 @@ #include "base/i18n/time_formatting.h" #include "base/json/json_reader.h" #include "base/logging.h" -#include "base/metrics/histogram_functions.h" -#include "base/metrics/histogram_macros.h" +#include "base/metrics/histogram_macros_local.h" #include "base/rand_util.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" @@ -169,7 +168,7 @@ } void RecordFetchValidHistogram(bool valid) { - UMA_HISTOGRAM_BOOLEAN("NetworkTimeTracker.UpdateTimeFetchValid", valid); + LOCAL_HISTOGRAM_BOOLEAN("NetworkTimeTracker.UpdateTimeFetchValid", valid); } } // namespace @@ -359,7 +358,7 @@ base::TimeDelta time_delta = clock_->Now() - time_at_last_measurement_; if (time_delta.InMilliseconds() < 0) { // Has wall clock run backward? DVLOG(1) << "Discarding network time due to wall clock running backward"; - UMA_HISTOGRAM_CUSTOM_TIMES( + LOCAL_HISTOGRAM_CUSTOM_TIMES( "NetworkTimeTracker.WallClockRanBackwards", time_delta.magnitude(), base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(7), 50); network_time_at_last_measurement_ = base::Time(); @@ -378,11 +377,11 @@ // without causing the buckets to change and making data from // old/new clients incompatible. if (divergence.InMilliseconds() < 0) { - UMA_HISTOGRAM_CUSTOM_TIMES( + LOCAL_HISTOGRAM_CUSTOM_TIMES( "NetworkTimeTracker.ClockDivergence.Negative", divergence.magnitude(), base::TimeDelta::FromSeconds(60), base::TimeDelta::FromDays(7), 50); } else { - UMA_HISTOGRAM_CUSTOM_TIMES( + LOCAL_HISTOGRAM_CUSTOM_TIMES( "NetworkTimeTracker.ClockDivergence.Positive", divergence.magnitude(), base::TimeDelta::FromSeconds(60), base::TimeDelta::FromDays(7), 50); } @@ -501,8 +500,10 @@ DVLOG(1) << "fetch failed code=" << response_code; // The error code is negated because net errors are negative, but // the corresponding histogram enum is positive. - base::UmaHistogramSparse("NetworkTimeTracker.UpdateTimeFetchFailed", - -time_fetcher_->NetError()); + const int kPositiveError = -time_fetcher_->NetError(); + DCHECK_LE(kPositiveError, 10000); + LOCAL_HISTOGRAM_COUNTS_10000("NetworkTimeTracker.UpdateTimeFetchFailed", + kPositiveError); return false; } @@ -547,12 +548,12 @@ // Record histograms for the latency of the time query and the time delta // between time fetches. base::TimeDelta latency = tick_clock_->NowTicks() - fetch_started_; - UMA_HISTOGRAM_TIMES("NetworkTimeTracker.TimeQueryLatency", latency); + LOCAL_HISTOGRAM_TIMES("NetworkTimeTracker.TimeQueryLatency", latency); if (!last_fetched_time_.is_null()) { - UMA_HISTOGRAM_CUSTOM_TIMES("NetworkTimeTracker.TimeBetweenFetches", - current_time - last_fetched_time_, - base::TimeDelta::FromHours(1), - base::TimeDelta::FromDays(7), 50); + LOCAL_HISTOGRAM_CUSTOM_TIMES("NetworkTimeTracker.TimeBetweenFetches", + current_time - last_fetched_time_, + base::TimeDelta::FromHours(1), + base::TimeDelta::FromDays(7), 50); } last_fetched_time_ = current_time;
diff --git a/components/offline_pages/core/prefetch/tasks/page_bundle_update_task.cc b/components/offline_pages/core/prefetch/tasks/page_bundle_update_task.cc index 8284eaa7..1a9257c3 100644 --- a/components/offline_pages/core/prefetch/tasks/page_bundle_update_task.cc +++ b/components/offline_pages/core/prefetch/tasks/page_bundle_update_task.cc
@@ -35,14 +35,17 @@ // in the database. For GetOperation, the operation name is already set. // This statement ensures that the item's operation_name is assigned, and that // an item can't be reassigned an operation name. - static const char kSql[] = R"(UPDATE prefetch_items - SET state = ?, - final_archived_url = ?, - archive_body_name = ?, - archive_body_length = ?, - operation_name = ? - WHERE requested_url = ? AND state IN (?, ?) AND operation_name IN ("", ?) - )"; + static constexpr char kSql[] = + // clang-format off + "UPDATE prefetch_items " + "SET state=?," + "final_archived_url=?," + "archive_body_name=?," + "archive_body_length=?," + "operation_name=? " + "WHERE requested_url=? AND state IN (?,?) " + "AND operation_name IN ('',?)"; + // clang-format on sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); DCHECK(statement.is_valid()); @@ -78,12 +81,15 @@ PrefetchItemErrorCode final_status) { DCHECK_NE(page.status, RenderStatus::RENDERED); - static const char kSql[] = R"(UPDATE prefetch_items - SET state = ?, - error_code = ?, - operation_name = ? - WHERE requested_url = ? AND state IN (?, ?) AND operation_name IN ("", ?) - )"; + static constexpr char kSql[] = + // clang-format off + "UPDATE prefetch_items " + "SET state=?," + "error_code=?," + "operation_name=? " + "WHERE requested_url=? AND state IN (?,?) " + "AND operation_name IN ('',?)"; + // clang-format on sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); DCHECK(statement.is_valid()); @@ -111,11 +117,11 @@ void MarkAwaitingGCMSync(sql::Database* db, const RenderPageInfo& page, const std::string& operation_name) { - static const char kSql[] = R"(UPDATE prefetch_items - SET state = ?, - operation_name = ? - WHERE state = ? AND requested_url = ? - )"; + static constexpr char kSql[] = + // clang-format off + "UPDATE prefetch_items " + "SET state=?,operation_name=? " + "WHERE state=? AND requested_url=?"; sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); DCHECK(statement.is_valid());
diff --git a/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc b/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc index 3269739..4654d91e 100644 --- a/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc +++ b/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc
@@ -211,6 +211,7 @@ WebFeature::kHidDeviceOpen, WebFeature::kCrossOriginWasmModuleSharing, WebFeature::kControlledNonBlobURLWorkerWillBeUncontrolled, + WebFeature::kSameSiteCookieInclusionChangedByCrossSiteRedirect, })); return *opt_in_features; }
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index 75f15b8..08c9199 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn
@@ -515,6 +515,8 @@ "mock_password_store_interface.h", "mock_password_sync_metadata_store.cc", "mock_password_sync_metadata_store.h", + "mock_smart_bubble_stats_store.cc", + "mock_smart_bubble_stats_store.h", "password_manager_test_utils.cc", "password_manager_test_utils.h", "site_affiliation/mock_affiliation_fetcher_factory.cc",
diff --git a/components/password_manager/core/browser/form_fetcher_impl.cc b/components/password_manager/core/browser/form_fetcher_impl.cc index 84c41351..589b8a3 100644 --- a/components/password_manager/core/browser/form_fetcher_impl.cc +++ b/components/password_manager/core/browser/form_fetcher_impl.cc
@@ -123,7 +123,9 @@ // The statistics is needed for the "Save password?" bubble. password_manager::SmartBubbleStatsStore* stats_store = password_store->GetSmartBubbleStatsStore(); - stats_store->GetSiteStats(form_digest_.url.GetOrigin(), this); + // `stats_store` can be null in tests. + if (stats_store) + stats_store->GetSiteStats(form_digest_.url.GetOrigin(), this); // The desktop bubble needs this information. password_store->GetMatchingInsecureCredentials(form_digest_.signon_realm,
diff --git a/components/password_manager/core/browser/form_fetcher_impl_unittest.cc b/components/password_manager/core/browser/form_fetcher_impl_unittest.cc index e04d7ef..8a5a9b6 100644 --- a/components/password_manager/core/browser/form_fetcher_impl_unittest.cc +++ b/components/password_manager/core/browser/form_fetcher_impl_unittest.cc
@@ -19,6 +19,7 @@ #include "components/password_manager/core/browser/android_affiliation/affiliated_match_helper.h" #include "components/password_manager/core/browser/android_affiliation/mock_affiliated_match_helper.h" #include "components/password_manager/core/browser/mock_password_store.h" +#include "components/password_manager/core/browser/mock_smart_bubble_stats_store.h" #include "components/password_manager/core/browser/multi_store_form_fetcher.h" #include "components/password_manager/core/browser/password_form.h" #include "components/password_manager/core/browser/password_manager_test_utils.h" @@ -230,15 +231,16 @@ } } + void SetUp() override { + ON_CALL(*mock_store_, GetSmartBubbleStatsStore) + .WillByDefault(Return(&mock_smart_bubble_stats_store_)); + } + ~FormFetcherImplTest() override { mock_store_->ShutdownOnUIThread(); } protected: // A wrapper around form_fetcher_.Fetch(), adding the call expectations. void Fetch() { -#if !defined(OS_IOS) && !defined(OS_ANDROID) - EXPECT_CALL(*mock_store_, GetSiteStatsImpl(_)) - .WillOnce(Return(std::vector<InteractionsStats>())); -#endif EXPECT_CALL(*mock_store_, GetLogins(form_digest_, form_fetcher_.get())); form_fetcher_->Fetch(); task_environment_.RunUntilIdle(); @@ -253,6 +255,7 @@ std::unique_ptr<FormFetcherImpl> form_fetcher_; MockConsumer consumer_; scoped_refptr<MockPasswordStore> mock_store_; + testing::NiceMock<MockSmartBubbleStatsStore> mock_smart_bubble_stats_store_; FakePasswordManagerClient client_; private: @@ -504,8 +507,19 @@ stats.dismissal_count = 5; std::vector<InteractionsStats> db_stats = {stats}; EXPECT_CALL(*mock_store_, GetLogins(form_digest_, form_fetcher_.get())); - EXPECT_CALL(*mock_store_, GetSiteStatsImpl(stats.origin_domain)) - .WillOnce(Return(db_stats)); + EXPECT_CALL(mock_smart_bubble_stats_store_, + GetSiteStats(stats.origin_domain, _)) + .WillOnce( + testing::WithArg<1>([db_stats](PasswordStoreConsumer* consumer) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce( + [](PasswordStoreConsumer* con, + const std::vector<InteractionsStats>& stats) { + con->OnGetSiteStatistics( + std::vector<InteractionsStats>(stats)); + }, + consumer, db_stats)); + })); form_fetcher_->Fetch(); task_environment_.RunUntilIdle(); @@ -529,7 +543,7 @@ #else TEST_P(FormFetcherImplTest, DontFetchStatistics) { EXPECT_CALL(*mock_store_, GetLogins(form_digest_, form_fetcher_.get())); - EXPECT_CALL(*mock_store_, GetSiteStatsImpl(_)).Times(0); + EXPECT_CALL(mock_smart_bubble_stats_store_, GetSiteStats).Times(0); form_fetcher_->Fetch(); task_environment_.RunUntilIdle(); }
diff --git a/components/password_manager/core/browser/http_auth_manager_unittest.cc b/components/password_manager/core/browser/http_auth_manager_unittest.cc index 382be18..0fcc4e3c 100644 --- a/components/password_manager/core/browser/http_auth_manager_unittest.cc +++ b/components/password_manager/core/browser/http_auth_manager_unittest.cc
@@ -19,6 +19,7 @@ #include "components/password_manager/core/browser/form_fetcher_impl.h" #include "components/password_manager/core/browser/http_auth_manager_impl.h" #include "components/password_manager/core/browser/mock_password_store.h" +#include "components/password_manager/core/browser/mock_smart_bubble_stats_store.h" #include "components/password_manager/core/browser/password_form_manager.h" #include "components/password_manager/core/browser/password_form_manager_for_ui.h" #include "components/password_manager/core/browser/password_manager_driver.h" @@ -109,8 +110,8 @@ .WillByDefault(Return(store_.get())); ON_CALL(client_, GetAccountPasswordStore()) .WillByDefault(Return(account_store_.get())); - - EXPECT_CALL(*store_, GetSiteStatsImpl(_)).Times(AnyNumber()); + EXPECT_CALL(*store_, GetSmartBubbleStatsStore) + .WillRepeatedly(Return(&smart_bubble_stats_store_)); httpauth_manager_ = std::make_unique<HttpAuthManagerImpl>(&client_); @@ -136,6 +137,7 @@ scoped_refptr<MockPasswordStore> store_; scoped_refptr<MockPasswordStore> account_store_; testing::NiceMock<MockPasswordManagerClient> client_; + testing::NiceMock<MockSmartBubbleStatsStore> smart_bubble_stats_store_; std::unique_ptr<HttpAuthManagerImpl> httpauth_manager_; };
diff --git a/components/password_manager/core/browser/http_password_store_migrator_unittest.cc b/components/password_manager/core/browser/http_password_store_migrator_unittest.cc index f353c04..c976436 100644 --- a/components/password_manager/core/browser/http_password_store_migrator_unittest.cc +++ b/components/password_manager/core/browser/http_password_store_migrator_unittest.cc
@@ -9,6 +9,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/task_environment.h" #include "components/password_manager/core/browser/mock_password_store.h" +#include "components/password_manager/core/browser/mock_smart_bubble_stats_store.h" #include "services/network/test/test_network_context.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -20,6 +21,7 @@ using testing::ElementsAre; using testing::Invoke; using testing::Pointee; +using testing::Return; using testing::SaveArg; using testing::Unused; @@ -112,9 +114,11 @@ MockConsumer& consumer() { return consumer_; } MockPasswordStore& store() { return *mock_store_; } - MockNetworkContext& mock_network_context() { return mock_network_context_; } + password_manager::MockSmartBubbleStatsStore& smart_bubble_stats_store() { + return mock_smart_bubble_stats_store_; + } - void WaitForPasswordStore() { task_environment_.RunUntilIdle(); } + MockNetworkContext& mock_network_context() { return mock_network_context_; } protected: void TestEmptyStore(bool is_hsts); @@ -127,6 +131,7 @@ scoped_refptr<MockPasswordStore> mock_store_ = base::MakeRefCounted<testing::StrictMock<MockPasswordStore>>(); testing::NiceMock<MockNetworkContext> mock_network_context_; + testing::NiceMock<MockSmartBubbleStatsStore> mock_smart_bubble_stats_store_; DISALLOW_COPY_AND_ASSIGN(HttpPasswordStoreMigratorTest); }; @@ -140,15 +145,16 @@ .WillOnce(testing::WithArg<1>( [is_hsts](auto cb) { std::move(cb).Run(is_hsts); })); + EXPECT_CALL(store(), GetSmartBubbleStatsStore) + .WillRepeatedly(Return(&smart_bubble_stats_store())); + + EXPECT_CALL(smart_bubble_stats_store(), + RemoveSiteStats(GURL(kTestHttpURL).GetOrigin())) + .Times(is_hsts); + HttpPasswordStoreMigrator migrator(url::Origin::Create(GURL(kTestHttpsURL)), &store(), &mock_network_context(), &consumer()); - // We expect a potential call to |RemoveSiteStatsImpl| which is a async task - // posted from |PasswordStore::RemoveSiteStats|. Hence the following lines are - // necessary to ensure |RemoveSiteStatsImpl| gets called when expected. - EXPECT_CALL(store(), RemoveSiteStatsImpl(GURL(kTestHttpURL).GetOrigin())) - .Times(is_hsts); - WaitForPasswordStore(); EXPECT_CALL(consumer(), ProcessForms(std::vector<PasswordForm*>())); migrator.OnGetPasswordStoreResults( @@ -163,15 +169,14 @@ .Times(1) .WillOnce(testing::WithArg<1>( [is_hsts](auto cb) { std::move(cb).Run(is_hsts); })); + EXPECT_CALL(store(), GetSmartBubbleStatsStore) + .WillRepeatedly(Return(&smart_bubble_stats_store())); + EXPECT_CALL(smart_bubble_stats_store(), + RemoveSiteStats(GURL(kTestHttpURL).GetOrigin())) + .Times(is_hsts); HttpPasswordStoreMigrator migrator(url::Origin::Create(GURL(kTestHttpsURL)), &store(), &mock_network_context(), &consumer()); - // We expect a potential call to |RemoveSiteStatsImpl| which is a async task - // posted from |PasswordStore::RemoveSiteStats|. Hence the following lines are - // necessary to ensure |RemoveSiteStatsImpl| gets called when expected. - EXPECT_CALL(store(), RemoveSiteStatsImpl(GURL(kTestHttpURL).GetOrigin())) - .Times(is_hsts); - WaitForPasswordStore(); PasswordForm form = CreateTestForm(); PasswordForm psl_form = CreateTestPSLForm(); @@ -211,7 +216,12 @@ .Times(1) .WillOnce(testing::WithArg<1>( [is_hsts](auto cb) { std::move(cb).Run(is_hsts); })); + EXPECT_CALL(store(), GetSmartBubbleStatsStore) + .WillRepeatedly(Return(&smart_bubble_stats_store())); + EXPECT_CALL(smart_bubble_stats_store(), + RemoveSiteStats(GURL(kTestHttpURL).GetOrigin())) + .Times(is_hsts); // Construct the migrator, call |OnGetPasswordStoreResults| explicitly and // manually delete it. auto migrator = std::make_unique<HttpPasswordStoreMigrator>( @@ -224,13 +234,6 @@ migrator->OnGetPasswordStoreResults( std::vector<std::unique_ptr<PasswordForm>>()); - - // We expect a potential call to |RemoveSiteStatsImpl| which is a async task - // posted from |PasswordStore::RemoveSiteStats|. Hence the following lines are - // necessary to ensure |RemoveSiteStatsImpl| gets called when expected. - EXPECT_CALL(store(), RemoveSiteStatsImpl(GURL(kTestHttpURL).GetOrigin())) - .Times(is_hsts); - WaitForPasswordStore(); } TEST_F(HttpPasswordStoreMigratorTest, EmptyStoreWithHSTS) {
diff --git a/components/password_manager/core/browser/mock_password_store.h b/components/password_manager/core/browser/mock_password_store.h index 1b877175..80e285c 100644 --- a/components/password_manager/core/browser/mock_password_store.h +++ b/components/password_manager/core/browser/mock_password_store.h
@@ -13,7 +13,6 @@ #include "components/password_manager/core/browser/insecure_credentials_table.h" #include "components/password_manager/core/browser/password_form.h" #include "components/password_manager/core/browser/password_store.h" -#include "components/password_manager/core/browser/statistics_table.h" #include "testing/gmock/include/gmock/gmock.h" namespace password_manager { @@ -61,12 +60,6 @@ ReportMetricsImpl, (const std::string&, bool, BulkCheckDone), (override)); - MOCK_METHOD(bool, - RemoveStatisticsByOriginAndTimeImpl, - (const base::RepeatingCallback<bool(const GURL&)>&, - base::Time, - base::Time), - (override)); MOCK_METHOD(PasswordStoreChangeList, DisableAutoSignInForOriginsImpl, (const base::RepeatingCallback<bool(const GURL&)>&), @@ -75,12 +68,6 @@ FillMatchingLoginsByPassword, (const std::u16string&), (override)); - MOCK_METHOD(std::vector<InteractionsStats>, - GetSiteStatsImpl, - (const GURL& origin_domain), - (override)); - MOCK_METHOD(void, AddSiteStatsImpl, (const InteractionsStats&)); - MOCK_METHOD(void, RemoveSiteStatsImpl, (const GURL&), (override)); MOCK_METHOD(PasswordStoreChangeList, AddInsecureCredentialImpl, (const InsecureCredential&), @@ -121,6 +108,8 @@ MOCK_METHOD(bool, IsAbleToSavePasswords, (), (override, const)); + MOCK_METHOD(SmartBubbleStatsStore*, GetSmartBubbleStatsStore, (), (override)); + protected: ~MockPasswordStore() override;
diff --git a/components/password_manager/core/browser/mock_smart_bubble_stats_store.cc b/components/password_manager/core/browser/mock_smart_bubble_stats_store.cc new file mode 100644 index 0000000..a3ba454 --- /dev/null +++ b/components/password_manager/core/browser/mock_smart_bubble_stats_store.cc
@@ -0,0 +1,13 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/password_manager/core/browser/mock_smart_bubble_stats_store.h" + +namespace password_manager { + +MockSmartBubbleStatsStore::MockSmartBubbleStatsStore() = default; + +MockSmartBubbleStatsStore::~MockSmartBubbleStatsStore() = default; + +} // namespace password_manager
diff --git a/components/password_manager/core/browser/mock_smart_bubble_stats_store.h b/components/password_manager/core/browser/mock_smart_bubble_stats_store.h new file mode 100644 index 0000000..394e87b0 --- /dev/null +++ b/components/password_manager/core/browser/mock_smart_bubble_stats_store.h
@@ -0,0 +1,36 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_MOCK_SMART_BUBBLE_STATS_STORE_H_ +#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_MOCK_SMART_BUBBLE_STATS_STORE_H_ + +#include "base/callback.h" +#include "components/password_manager/core/browser/smart_bubble_stats_store.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace password_manager { + +class MockSmartBubbleStatsStore : public SmartBubbleStatsStore { + public: + MockSmartBubbleStatsStore(); + ~MockSmartBubbleStatsStore() override; + + MOCK_METHOD(void, AddSiteStats, (const InteractionsStats&), (override)); + MOCK_METHOD(void, RemoveSiteStats, (const GURL&), (override)); + MOCK_METHOD(void, + GetSiteStats, + (const GURL&, PasswordStoreConsumer*), + (override)); + MOCK_METHOD(void, + RemoveStatisticsByOriginAndTime, + (const base::RepeatingCallback<bool(const GURL&)>&, + base::Time, + base::Time, + base::OnceClosure), + (override)); +}; + +} // namespace password_manager + +#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_MOCK_SMART_BUBBLE_STATS_STORE_H_
diff --git a/components/password_manager/core/browser/multi_store_form_fetcher_unittest.cc b/components/password_manager/core/browser/multi_store_form_fetcher_unittest.cc index c8f756b..c2cc71d8 100644 --- a/components/password_manager/core/browser/multi_store_form_fetcher_unittest.cc +++ b/components/password_manager/core/browser/multi_store_form_fetcher_unittest.cc
@@ -12,7 +12,9 @@ #include "build/build_config.h" #include "components/autofill/core/common/gaia_id_hash.h" #include "components/password_manager/core/browser/mock_password_store.h" +#include "components/password_manager/core/browser/mock_smart_bubble_stats_store.h" #include "components/password_manager/core/browser/password_form.h" +#include "components/password_manager/core/browser/statistics_table.h" #include "components/password_manager/core/browser/stub_password_manager_client.h" #include "components/password_manager/core/common/password_manager_features.h" #include "url/gurl.h" @@ -147,15 +149,16 @@ account_mock_store_->ShutdownOnUIThread(); } + void SetUp() override { + ON_CALL(*profile_mock_store_, GetSmartBubbleStatsStore) + .WillByDefault(Return(&mock_smart_bubble_stats_store)); + } + FakePasswordManagerClient* client() { return &client_; } protected: // A wrapper around form_fetcher_.Fetch(), adding the call expectations. void Fetch() { -#if !defined(OS_IOS) && !defined(OS_ANDROID) - EXPECT_CALL(*profile_mock_store_, GetSiteStatsImpl(_)) - .WillOnce(Return(std::vector<InteractionsStats>())); -#endif EXPECT_CALL(*profile_mock_store_, GetLogins(form_digest_, form_fetcher_.get())); EXPECT_CALL(*account_mock_store_, @@ -173,6 +176,7 @@ MockConsumer consumer_; scoped_refptr<MockPasswordStore> profile_mock_store_; scoped_refptr<MockPasswordStore> account_mock_store_; + testing::NiceMock<MockSmartBubbleStatsStore> mock_smart_bubble_stats_store; FakePasswordManagerClient client_; private:
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc index a146c06..65dee04 100644 --- a/components/password_manager/core/browser/password_manager_unittest.cc +++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -34,6 +34,7 @@ #include "components/password_manager/core/browser/leak_detection/mock_leak_detection_check_factory.h" #include "components/password_manager/core/browser/mock_password_reuse_manager.h" #include "components/password_manager/core/browser/mock_password_store.h" +#include "components/password_manager/core/browser/mock_smart_bubble_stats_store.h" #include "components/password_manager/core/browser/password_autofill_manager.h" #include "components/password_manager/core/browser/password_bubble_experiment.h" #include "components/password_manager/core/browser/password_form_manager.h" @@ -373,7 +374,9 @@ ON_CALL(client_, GetProfilePasswordStore()) .WillByDefault(Return(store_.get())); - EXPECT_CALL(*store_, GetSiteStatsImpl(_)).Times(AnyNumber()); + + ON_CALL(*store_, GetSmartBubbleStatsStore) + .WillByDefault(Return(&smart_bubble_stats_store_)); if (base::FeatureList::IsEnabled( features::kEnablePasswordsAccountStorage)) { @@ -627,6 +630,7 @@ MockPasswordReuseManager reuse_manager_; testing::NiceMock<MockPasswordManagerClient> client_; MockPasswordManagerDriver driver_; + testing::NiceMock<MockSmartBubbleStatsStore> smart_bubble_stats_store_; std::unique_ptr<TestingPrefServiceSimple> prefs_; std::unique_ptr<PasswordAutofillManager> password_autofill_manager_; std::unique_ptr<PasswordManager> manager_;
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc index 5150171..e3d1632 100644 --- a/components/password_manager/core/browser/password_store.cc +++ b/components/password_manager/core/browser/password_store.cc
@@ -315,7 +315,7 @@ } SmartBubbleStatsStore* PasswordStore::GetSmartBubbleStatsStore() { - return this; + return backend_->GetSmartBubbleStatsStore(); } void PasswordStore::ReportMetrics(const std::string& sync_username, @@ -454,36 +454,6 @@ DCHECK(shutdown_called_); } -void PasswordStore::AddSiteStats(const InteractionsStats& stats) { - DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); - ScheduleTask(base::BindOnce(&PasswordStore::AddSiteStatsImpl, this, stats)); -} - -void PasswordStore::RemoveSiteStats(const GURL& origin_domain) { - DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); - ScheduleTask( - base::BindOnce(&PasswordStore::RemoveSiteStatsImpl, this, origin_domain)); -} - -void PasswordStore::GetSiteStats(const GURL& origin_domain, - PasswordStoreConsumer* consumer) { - DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); - PostStatsTaskAndReplyToConsumerWithResult( - consumer, - base::BindOnce(&PasswordStore::GetSiteStatsImpl, this, origin_domain)); -} - -void PasswordStore::RemoveStatisticsByOriginAndTime( - const base::RepeatingCallback<bool(const GURL&)>& origin_filter, - base::Time delete_begin, - base::Time delete_end, - base::OnceClosure completion) { - DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); - ScheduleTask(base::BindOnce( - &PasswordStore::RemoveStatisticsByOriginAndTimeInternal, this, - origin_filter, delete_begin, delete_end, std::move(completion))); -} - scoped_refptr<base::SequencedTaskRunner> PasswordStore::CreateBackgroundTaskRunner() const { return base::ThreadPool::CreateSequencedTaskRunner( @@ -497,15 +467,6 @@ LOG(ERROR) << "Called function without implementation: " << __func__; } -bool PasswordStore::RemoveStatisticsByOriginAndTimeImpl( - const base::RepeatingCallback<bool(const GURL&)>& origin_filter, - base::Time delete_begin, - base::Time delete_end) { - // TODO(crbug.com/1217070): Move as implementation detail into backend. - LOG(ERROR) << "Called function without implementation: " << __func__; - return false; -} - PasswordStoreChangeList PasswordStore::DisableAutoSignInForOriginsImpl( const base::RepeatingCallback<bool(const GURL&)>& origin_filter) { // TODO(crbug.com/1217070): Move as implementation detail into backend. @@ -523,23 +484,6 @@ return std::vector<std::unique_ptr<PasswordForm>>(); } -void PasswordStore::AddSiteStatsImpl(const InteractionsStats& stats) { - // TODO(crbug.com/1217070): Move as implementation detail into backend. - LOG(ERROR) << "Called function without implementation: " << __func__; -} - -void PasswordStore::RemoveSiteStatsImpl(const GURL& origin_domain) { - // TODO(crbug.com/1217070): Move as implementation detail into backend. - LOG(ERROR) << "Called function without implementation: " << __func__; -} - -std::vector<InteractionsStats> PasswordStore::GetSiteStatsImpl( - const GURL& origin_domain) { - // TODO(crbug.com/1217070): Move as implementation detail into backend. - LOG(ERROR) << "Called function without implementation: " << __func__; - return std::vector<InteractionsStats>(); -} - PasswordStoreChangeList PasswordStore::AddInsecureCredentialImpl( const InsecureCredential& insecure_credential) { // TODO(crbug.com/1217070): Move as implementation detail into backend. @@ -651,19 +595,6 @@ consumer->GetWeakPtr(), base::RetainedRef(this))); } -void PasswordStore::RemoveStatisticsByOriginAndTimeInternal( - const base::RepeatingCallback<bool(const GURL&)>& origin_filter, - base::Time delete_begin, - base::Time delete_end, - base::OnceClosure completion) { - DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); - TRACE_EVENT0("passwords", - "PasswordStore::RemoveStatisticsByOriginAndTimeInternal"); - RemoveStatisticsByOriginAndTimeImpl(origin_filter, delete_begin, delete_end); - if (completion) - main_task_runner_->PostTask(FROM_HERE, std::move(completion)); -} - void PasswordStore::DisableAutoSignInForOriginsInternal( const base::RepeatingCallback<bool(const GURL&)>& origin_filter, base::OnceClosure completion) {
diff --git a/components/password_manager/core/browser/password_store.h b/components/password_manager/core/browser/password_store.h index 10b6fc51b..c9e90e2 100644 --- a/components/password_manager/core/browser/password_store.h +++ b/components/password_manager/core/browser/password_store.h
@@ -57,8 +57,7 @@ // from the UI thread. // PasswordStoreSync is a hidden base class because only PasswordSyncBridge // needs to access these methods. -class PasswordStore : public PasswordStoreInterface, - protected SmartBubbleStatsStore { +class PasswordStore : public PasswordStoreInterface { public: // Used to notify that unsynced credentials are about to be deleted. class UnsyncedCredentialsDeletionNotifier { @@ -207,17 +206,6 @@ PasswordStore(); ~PasswordStore() override; - // SmartBubbleStatsStore: - void AddSiteStats(const InteractionsStats& stats) override; - void RemoveSiteStats(const GURL& origin_domain) override; - void GetSiteStats(const GURL& origin_domain, - PasswordStoreConsumer* consumer) override; - void RemoveStatisticsByOriginAndTime( - const base::RepeatingCallback<bool(const GURL&)>& origin_filter, - base::Time delete_begin, - base::Time delete_end, - base::OnceClosure completion) override; - // Create a TaskRunner to be saved in |background_task_runner_|. virtual scoped_refptr<base::SequencedTaskRunner> CreateBackgroundTaskRunner() const; @@ -228,12 +216,6 @@ bool custom_passphrase_sync_enabled, BulkCheckDone bulk_check_done); - // Synchronous implementation to remove the statistics. - virtual bool RemoveStatisticsByOriginAndTimeImpl( - const base::RepeatingCallback<bool(const GURL&)>& origin_filter, - base::Time delete_begin, - base::Time delete_end); - // Synchronous implementation to disable auto sign-in. virtual PasswordStoreChangeList DisableAutoSignInForOriginsImpl( const base::RepeatingCallback<bool(const GURL&)>& origin_filter); @@ -243,12 +225,6 @@ virtual std::vector<std::unique_ptr<PasswordForm>> FillMatchingLoginsByPassword(const std::u16string& plain_text_password); - // Synchronous implementation for manipulating with statistics. - virtual void AddSiteStatsImpl(const InteractionsStats& stats); - virtual void RemoveSiteStatsImpl(const GURL& origin_domain); - virtual std::vector<InteractionsStats> GetSiteStatsImpl( - const GURL& origin_domain); - // Synchronous implementation for manipulating with information about // insecure credentials. // Returns PasswordStoreChangeList for the updated password forms.
diff --git a/components/password_manager/core/browser/password_store_backend.h b/components/password_manager/core/browser/password_store_backend.h index f6e8c4e..dbdb7e33 100644 --- a/components/password_manager/core/browser/password_store_backend.h +++ b/components/password_manager/core/browser/password_store_backend.h
@@ -16,6 +16,8 @@ struct PasswordForm; +class SmartBubbleStatsStore; + using LoginsResult = std::vector<std::unique_ptr<PasswordForm>>; using LoginsReply = base::OnceCallback<void(LoginsResult)>; using PasswordStoreChangeListReply = @@ -94,6 +96,8 @@ const std::u16string& plain_text_password) {} virtual void FillAutofillableLoginsAsync(LoginsReply callback) {} virtual void FillBlocklistLoginsAsync(LoginsReply callback) {} + + virtual SmartBubbleStatsStore* GetSmartBubbleStatsStore() = 0; }; } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_impl.cc b/components/password_manager/core/browser/password_store_impl.cc index a10c6839..8335f6b 100644 --- a/components/password_manager/core/browser/password_store_impl.cc +++ b/components/password_manager/core/browser/password_store_impl.cc
@@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/logging.h" #include "components/password_manager/core/browser/password_store_change.h" +#include "components/password_manager/core/browser/password_store_consumer.h" #include "components/password_manager/core/browser/sync/password_sync_bridge.h" #include "components/prefs/pref_service.h" #include "components/sync/model/client_tag_based_model_type_processor.h" @@ -96,14 +97,6 @@ return changes; } -bool PasswordStoreImpl::RemoveStatisticsByOriginAndTimeImpl( - const base::RepeatingCallback<bool(const GURL&)>& origin_filter, - base::Time delete_begin, - base::Time delete_end) { - return login_db_ && login_db_->stats_table().RemoveStatsByOriginAndTime( - origin_filter, delete_begin, delete_end); -} - std::vector<std::unique_ptr<PasswordForm>> PasswordStoreImpl::FillMatchingLoginsByPassword( const std::u16string& plain_text_password) { @@ -121,25 +114,35 @@ return login_db_->DeleteUndecryptableLogins(); } -void PasswordStoreImpl::AddSiteStatsImpl(const InteractionsStats& stats) { +void PasswordStoreImpl::AddSiteStatsInternal(const InteractionsStats& stats) { DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); if (login_db_) login_db_->stats_table().AddRow(stats); } -void PasswordStoreImpl::RemoveSiteStatsImpl(const GURL& origin_domain) { +void PasswordStoreImpl::RemoveSiteStatsInternal(const GURL& origin_domain) { DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); if (login_db_) login_db_->stats_table().RemoveRow(origin_domain); } -std::vector<InteractionsStats> PasswordStoreImpl::GetSiteStatsImpl( +std::vector<InteractionsStats> PasswordStoreImpl::GetSiteStatsInternal( const GURL& origin_domain) { DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); return login_db_ ? login_db_->stats_table().GetRows(origin_domain) : std::vector<InteractionsStats>(); } +void PasswordStoreImpl::RemoveStatisticsByOriginAndTimeInternal( + const base::RepeatingCallback<bool(const GURL&)>& origin_filter, + base::Time delete_begin, + base::Time delete_end) { + if (login_db_) { + login_db_->stats_table().RemoveStatsByOriginAndTime( + origin_filter, delete_begin, delete_end); + } +} + PasswordStoreChangeList PasswordStoreImpl::AddInsecureCredentialImpl( const InsecureCredential& credential) { DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); @@ -471,6 +474,49 @@ std::move(callback)); } +SmartBubbleStatsStore* PasswordStoreImpl::GetSmartBubbleStatsStore() { + return this; +} + +void PasswordStoreImpl::AddSiteStats(const InteractionsStats& stats) { + DCHECK(main_task_runner()->RunsTasksInCurrentSequence()); + background_task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&PasswordStoreImpl::AddSiteStatsInternal, this, stats)); +} + +void PasswordStoreImpl::RemoveSiteStats(const GURL& origin_domain) { + DCHECK(main_task_runner()->RunsTasksInCurrentSequence()); + background_task_runner()->PostTask( + FROM_HERE, base::BindOnce(&PasswordStoreImpl::RemoveSiteStatsInternal, + this, origin_domain)); +} + +void PasswordStoreImpl::GetSiteStats(const GURL& origin_domain, + PasswordStoreConsumer* consumer) { + DCHECK(main_task_runner()->RunsTasksInCurrentSequence()); + consumer->cancelable_task_tracker()->PostTaskAndReplyWithResult( + background_task_runner().get(), FROM_HERE, + base::BindOnce(&PasswordStoreImpl::GetSiteStatsInternal, this, + origin_domain), + base::BindOnce(&PasswordStoreConsumer::OnGetSiteStatistics, + consumer->GetWeakPtr())); +} + +void PasswordStoreImpl::RemoveStatisticsByOriginAndTime( + const base::RepeatingCallback<bool(const GURL&)>& origin_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion) { + DCHECK(main_task_runner()->RunsTasksInCurrentSequence()); + background_task_runner()->PostTaskAndReply( + FROM_HERE, + base::BindOnce( + &PasswordStoreImpl::RemoveStatisticsByOriginAndTimeInternal, this, + origin_filter, delete_begin, delete_end), + std::move(completion)); +} + bool PasswordStoreImpl::InitOnBackgroundSequence( RemoteChangesReceived remote_form_changes_received, base::RepeatingClosure sync_enabled_or_disabled_cb) {
diff --git a/components/password_manager/core/browser/password_store_impl.h b/components/password_manager/core/browser/password_store_impl.h index fa8778b..60de28f 100644 --- a/components/password_manager/core/browser/password_store_impl.h +++ b/components/password_manager/core/browser/password_store_impl.h
@@ -22,7 +22,8 @@ // the LoginDatabase. class PasswordStoreImpl : protected PasswordStoreSync, public PasswordStore, - public PasswordStoreBackend { + public PasswordStoreBackend, + public SmartBubbleStatsStore { public: // The |login_db| must not have been Init()-ed yet. It will be initialized in // a deferred manner on the background sequence. @@ -45,17 +46,9 @@ BulkCheckDone bulk_check_done) override; PasswordStoreChangeList DisableAutoSignInForOriginsImpl( const base::RepeatingCallback<bool(const GURL&)>& origin_filter) override; - bool RemoveStatisticsByOriginAndTimeImpl( - const base::RepeatingCallback<bool(const GURL&)>& origin_filter, - base::Time delete_begin, - base::Time delete_end) override; std::vector<std::unique_ptr<PasswordForm>> FillMatchingLoginsByPassword( const std::u16string& plain_text_password) override; DatabaseCleanupResult DeleteUndecryptableLogins() override; - void AddSiteStatsImpl(const InteractionsStats& stats) override; - void RemoveSiteStatsImpl(const GURL& origin_domain) override; - std::vector<InteractionsStats> GetSiteStatsImpl( - const GURL& origin_domain) override; PasswordStoreChangeList AddInsecureCredentialImpl( const InsecureCredential& insecure_credential) override; PasswordStoreChangeList RemoveInsecureCredentialsImpl( @@ -131,6 +124,18 @@ base::Time delete_end, base::OnceCallback<void(bool)> sync_completion, PasswordStoreChangeListReply callback) override; + SmartBubbleStatsStore* GetSmartBubbleStatsStore() override; + + // SmartBubbleStatsStore: + void AddSiteStats(const InteractionsStats& stats) override; + void RemoveSiteStats(const GURL& origin_domain) override; + void GetSiteStats(const GURL& origin_domain, + PasswordStoreConsumer* consumer) override; + void RemoveStatisticsByOriginAndTime( + const base::RepeatingCallback<bool(const GURL&)>& origin_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion) override; // Opens |login_db_| and creates |sync_bridge_| on the background sequence. bool InitOnBackgroundSequence( @@ -162,6 +167,16 @@ base::Time delete_end, base::OnceCallback<void(bool)> sync_completion); + // Synchronous implementation for manipulating with statistics. + void AddSiteStatsInternal(const InteractionsStats& stats); + void RemoveSiteStatsInternal(const GURL& origin_domain); + std::vector<InteractionsStats> GetSiteStatsInternal( + const GURL& origin_domain); + void RemoveStatisticsByOriginAndTimeInternal( + const base::RepeatingCallback<bool(const GURL&)>& origin_filter, + base::Time delete_begin, + base::Time delete_end); + // The login SQL database. The LoginDatabase instance is received via the // in an uninitialized state, so as to allow injecting mocks, then Init() is // called on the background sequence in a deferred manner. If opening the DB
diff --git a/components/password_manager/core/browser/password_store_unittest.cc b/components/password_manager/core/browser/password_store_unittest.cc index 5494237..8c5514e 100644 --- a/components/password_manager/core/browser/password_store_unittest.cc +++ b/components/password_manager/core/browser/password_store_unittest.cc
@@ -218,6 +218,7 @@ base::Time delete_end, PasswordStoreChangeListReply callback), (override)); + MOCK_METHOD(SmartBubbleStatsStore*, GetSmartBubbleStatsStore, (), (override)); }; PasswordForm MakePasswordForm(const std::string& signon_realm) {
diff --git a/components/password_manager/core/browser/test_password_store.cc b/components/password_manager/core/browser/test_password_store.cc index ef946da2..1574fac 100644 --- a/components/password_manager/core/browser/test_password_store.cc +++ b/components/password_manager/core/browser/test_password_store.cc
@@ -228,6 +228,10 @@ NOTIMPLEMENTED(); } +SmartBubbleStatsStore* TestPasswordStore::GetSmartBubbleStatsStore() { + return nullptr; +} + std::vector<std::unique_ptr<PasswordForm>> TestPasswordStore::FillMatchingLoginsByPassword( const std::u16string& plain_text_password) { @@ -241,11 +245,6 @@ return matched_forms; } -std::vector<InteractionsStats> TestPasswordStore::GetSiteStatsImpl( - const GURL& origin_domain) { - return std::vector<InteractionsStats>(); -} - void TestPasswordStore::ReportMetricsImpl(const std::string& sync_username, bool custom_passphrase_sync_enabled, BulkCheckDone bulk_check_done) { @@ -258,22 +257,6 @@ return PasswordStoreChangeList(); } -bool TestPasswordStore::RemoveStatisticsByOriginAndTimeImpl( - const base::RepeatingCallback<bool(const GURL&)>& origin_filter, - base::Time delete_begin, - base::Time delete_end) { - NOTIMPLEMENTED(); - return false; -} - -void TestPasswordStore::AddSiteStatsImpl(const InteractionsStats& stats) { - NOTIMPLEMENTED(); -} - -void TestPasswordStore::RemoveSiteStatsImpl(const GURL& origin_domain) { - NOTIMPLEMENTED(); -} - PasswordStoreChangeList TestPasswordStore::AddInsecureCredentialImpl( const InsecureCredential& insecure_credential) { InsecureCredential cred = insecure_credential;
diff --git a/components/password_manager/core/browser/test_password_store.h b/components/password_manager/core/browser/test_password_store.h index 04720fc..7c414dd 100644 --- a/components/password_manager/core/browser/test_password_store.h +++ b/components/password_manager/core/browser/test_password_store.h
@@ -109,12 +109,11 @@ base::Time delete_end, base::OnceCallback<void(bool)> sync_completion, PasswordStoreChangeListReply callback) override; + SmartBubbleStatsStore* GetSmartBubbleStatsStore() override; // PasswordStore interface std::vector<std::unique_ptr<PasswordForm>> FillMatchingLoginsByPassword( const std::u16string& plain_text_password) override; - std::vector<InteractionsStats> GetSiteStatsImpl( - const GURL& origin_domain) override; // Unused portions of PasswordStore interface void ReportMetricsImpl(const std::string& sync_username, @@ -122,12 +121,6 @@ BulkCheckDone bulk_check_done) override; PasswordStoreChangeList DisableAutoSignInForOriginsImpl( const base::RepeatingCallback<bool(const GURL&)>& origin_filter) override; - bool RemoveStatisticsByOriginAndTimeImpl( - const base::RepeatingCallback<bool(const GURL&)>& origin_filter, - base::Time delete_begin, - base::Time delete_end) override; - void AddSiteStatsImpl(const InteractionsStats& stats) override; - void RemoveSiteStatsImpl(const GURL& origin_domain) override; PasswordStoreChangeList AddInsecureCredentialImpl( const InsecureCredential& insecure_credentials) override; PasswordStoreChangeList RemoveInsecureCredentialsImpl(
diff --git a/components/pdf/browser/pdf_web_contents_helper.cc b/components/pdf/browser/pdf_web_contents_helper.cc index 6444cb86..42de471 100644 --- a/components/pdf/browser/pdf_web_contents_helper.cc +++ b/components/pdf/browser/pdf_web_contents_helper.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/memory/ptr_util.h" +#include "base/notreached.h" #include "components/pdf/browser/pdf_web_contents_helper_client.h" #include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_view.h" @@ -159,11 +160,17 @@ ConvertFromRoot(extent)); } -void PDFWebContentsHelper::OnSelectionEvent(ui::SelectionEventType event) {} +void PDFWebContentsHelper::OnSelectionEvent(ui::SelectionEventType event) { + // Should be handled by `TouchSelectionControllerClientAura`. + NOTREACHED(); +} void PDFWebContentsHelper::OnDragUpdate( const ui::TouchSelectionDraggable::Type type, - const gfx::PointF& position) {} + const gfx::PointF& position) { + // Should be handled by `TouchSelectionControllerClientAura`. + NOTREACHED(); +} std::unique_ptr<ui::TouchHandleDrawable> PDFWebContentsHelper::CreateDrawable() {
diff --git a/components/permissions/features.cc b/components/permissions/features.cc index 47bbb07..ca58bd60 100644 --- a/components/permissions/features.cc +++ b/components/permissions/features.cc
@@ -70,6 +70,13 @@ const base::Feature kRevisedOriginHandling{"PermissionsRevisedOriginHandling", base::FEATURE_ENABLED_BY_DEFAULT}; +#if defined(OS_ANDROID) +// When enabled, the Default Search Engine does not automatically receive the +// "geolocation" and "notifications" permissions. DSE only applies to Android. +const base::Feature kRevertDSEAutomaticPermissions{ + "RevertDSEAutomaticPermissions", base::FEATURE_DISABLED_BY_DEFAULT}; +#endif // defined(OS_ANDROID) + } // namespace features namespace feature_params {
diff --git a/components/permissions/features.h b/components/permissions/features.h index 53a5b10..12ad6ec 100644 --- a/components/permissions/features.h +++ b/components/permissions/features.h
@@ -8,6 +8,7 @@ #include "base/component_export.h" #include "base/feature_list.h" #include "base/metrics/field_trial_params.h" +#include "build/build_config.h" namespace permissions { namespace features { @@ -51,6 +52,11 @@ COMPONENT_EXPORT(PERMISSIONS_COMMON) extern const base::Feature kRevisedOriginHandling; +#if defined(OS_ANDROID) +COMPONENT_EXPORT(PERMISSIONS_COMMON) +extern const base::Feature kRevertDSEAutomaticPermissions; +#endif // defined(OS_ANDROID) + } // namespace features namespace feature_params {
diff --git a/components/policy/core/common/policy_loader_lacros.cc b/components/policy/core/common/policy_loader_lacros.cc index dfefdde6..11ecb51 100644 --- a/components/policy/core/common/policy_loader_lacros.cc +++ b/components/policy/core/common/policy_loader_lacros.cc
@@ -24,9 +24,11 @@ namespace policy { PolicyLoaderLacros::PolicyLoaderLacros( - scoped_refptr<base::SequencedTaskRunner> task_runner) + scoped_refptr<base::SequencedTaskRunner> task_runner, + PolicyPerProfileFilter per_profile) : AsyncPolicyLoader(task_runner, /*periodic_updates=*/false), - task_runner_(task_runner) { + task_runner_(task_runner), + per_profile_(per_profile) { auto* lacros_service = chromeos::LacrosService::Get(); const crosapi::mojom::BrowserInitParams* init_params = lacros_service->init_params(); @@ -85,8 +87,7 @@ base::WeakPtr<CloudExternalDataManager> external_data_manager; DecodeProtoFields(*(validator.payload()), external_data_manager, PolicySource::POLICY_SOURCE_CLOUD_FROM_ASH, - PolicyScope::POLICY_SCOPE_USER, &policy_map, - PolicyPerProfileFilter::kFalse); + PolicyScope::POLICY_SCOPE_USER, &policy_map, per_profile_); SetEnterpriseUsersSystemWideDefaults(&policy_map); bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) .MergeFrom(policy_map);
diff --git a/components/policy/core/common/policy_loader_lacros.h b/components/policy/core/common/policy_loader_lacros.h index 874cf285..db0e9b3 100644 --- a/components/policy/core/common/policy_loader_lacros.h +++ b/components/policy/core/common/policy_loader_lacros.h
@@ -14,22 +14,24 @@ #include "base/sequenced_task_runner.h" #include "chromeos/lacros/lacros_service.h" #include "components/policy/core/common/async_policy_loader.h" +#include "components/policy/core/common/policy_proto_decoders.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace policy { -// A policy loader for Lacros. The data is taken from Ash and the validatity of -// data is trusted, since they have been validated by Ash. This class loads only -// the user policy that has to apply browser-wide (non per_profile). +// A policy loader for Lacros. The data is taken from Ash and the validitity of +// data is trusted, since they have been validated by Ash. class POLICY_EXPORT PolicyLoaderLacros : public AsyncPolicyLoader, public chromeos::LacrosService::Observer { public: // Creates the policy loader, saving the task_runner internally. Later // task_runner is used to have in sequence the process of policy parsing and - // validation. + // validation. The |per_profile| parameter specifies which policy should be + // installed. explicit PolicyLoaderLacros( - scoped_refptr<base::SequencedTaskRunner> task_runner); + scoped_refptr<base::SequencedTaskRunner> task_runner, + PolicyPerProfileFilter per_profile); // Not copyable or movable PolicyLoaderLacros(const PolicyLoaderLacros&) = delete; PolicyLoaderLacros& operator=(const PolicyLoaderLacros&) = delete; @@ -53,6 +55,9 @@ // Task runner for running background jobs. const scoped_refptr<base::SequencedTaskRunner> task_runner_; + // The filter for policy data to install. + const PolicyPerProfileFilter per_profile_; + // Serialized blob of PolicyFetchResponse object received from the server. absl::optional<std::vector<uint8_t>> policy_fetch_response_;
diff --git a/components/policy/core/common/policy_loader_lacros_unittest.cc b/components/policy/core/common/policy_loader_lacros_unittest.cc index 93646cb..8b31f1c 100644 --- a/components/policy/core/common/policy_loader_lacros_unittest.cc +++ b/components/policy/core/common/policy_loader_lacros_unittest.cc
@@ -133,7 +133,8 @@ TEST_F(PolicyLoaderLacrosTest, BasicTest) { SetSystemWidePolicy(); - PolicyLoaderLacros loader(task_environment_.GetMainThreadTaskRunner()); + PolicyLoaderLacros loader(task_environment_.GetMainThreadTaskRunner(), + PolicyPerProfileFilter::kFalse); base::RunLoop().RunUntilIdle(); CheckOnlySystemWidePoliciesAreSet(loader.Load().get()); } @@ -141,7 +142,8 @@ TEST_F(PolicyLoaderLacrosTest, BasicTestPerProfile) { SetProfilePolicy(); - PolicyLoaderLacros loader(task_environment_.GetMainThreadTaskRunner()); + PolicyLoaderLacros loader(task_environment_.GetMainThreadTaskRunner(), + PolicyPerProfileFilter::kFalse); base::RunLoop().RunUntilIdle(); CheckOnlySystemWidePoliciesAreSet(loader.Load().get()); } @@ -153,7 +155,8 @@ chromeos::LacrosService::Get()->SetInitParamsForTests(std::move(init_params)); PolicyLoaderLacros* loader = - new PolicyLoaderLacros(task_environment_.GetMainThreadTaskRunner()); + new PolicyLoaderLacros(task_environment_.GetMainThreadTaskRunner(), + PolicyPerProfileFilter::kFalse); AsyncPolicyProvider provider(&schema_registry_, std::unique_ptr<AsyncPolicyLoader>(loader)); provider.Init(&schema_registry_); @@ -172,7 +175,8 @@ TEST_F(PolicyLoaderLacrosTest, EnterpriseDefaultsTest) { SetAllPolicy(); - PolicyLoaderLacros loader(task_environment_.GetMainThreadTaskRunner()); + PolicyLoaderLacros loader(task_environment_.GetMainThreadTaskRunner(), + PolicyPerProfileFilter::kFalse); base::RunLoop().RunUntilIdle(); CheckOnlySystemWidePoliciesAreSet(loader.Load().get());
diff --git a/components/policy/test_support/policy_testserver.py b/components/policy/test_support/policy_testserver.py index 7c982c8e..c43b440 100644 --- a/components/policy/test_support/policy_testserver.py +++ b/components/policy/test_support/policy_testserver.py
@@ -203,6 +203,8 @@ }, ] +INVALID_ENROLLMENT_TOKEN = 'invalid_enrollment_token' + POLICY_COMMON_DEFINITIONS_TYPES = [ 'StringList', 'PolicyOptions', @@ -397,6 +399,12 @@ response = self.ProcessCheckAndroidManagementRequest( rmsg.check_android_management_request, str(self.GetUniqueParam('oauth_token'))) + elif request_type == 'register_browser': + response = self.ProcessRegisterBrowserRequest( + rmsg.register_browser_request) + elif request_type == 'chrome_desktop_report': + response = self.ProcessChromeDesktopReportUploadRequest( + rmsg.chrome_desktop_report_request) elif request_type == 'app_install_report': response = self.ProcessAppInstallReportRequest( rmsg.app_install_report_request) @@ -870,6 +878,53 @@ return (200, response) + def ProcessRegisterBrowserRequest(self, msg): + """Handles a browser registration request. + + Returns: + A tuple of HTTP status code and response data to send to the client. + """ + enrollment_token = None + match = re.match('GoogleEnrollmentToken token=(\\w+)', + self.headers.get('Authorization', '')) + if match: + enrollment_token = match.group(1) + if not enrollment_token: + return (401, 'Missing enrollment token.') + + device_id = self.GetUniqueParam('deviceid') + if not device_id: + return (400, 'Parameter deviceid is missing.') + + if not msg.machine_name and not msg.device_model: + return (400, 'Either machine name or device model must be non-empty.') + + if enrollment_token == INVALID_ENROLLMENT_TOKEN: + return (401, 'Invalid enrollment token') + + dm_token = 'fake_device_management_token' + response = dm.DeviceManagementResponse() + response.register_response.device_management_token = ( + dm_token) + self.server.RegisterBrowser(dm_token, device_id, msg.machine_name) + + return (200, response) + + def ProcessChromeDesktopReportUploadRequest(self, chrome_desktop_report): + """Handles a chrome desktop report upload request. + + Returns: + A tuple of HTTP status code and response data to send to the client. + """ + # Empty responses indicate a successful upload. + chrome_desktop_report_response = dm.ChromeDesktopReportResponse() + + response = dm.DeviceManagementResponse() + response.chrome_desktop_report_response.CopyFrom( + chrome_desktop_report_response) + + return (200, response) + def SetProtoRepeatedField(self, group_message, field, field_value): assert type(field_value) == list entries = group_message.__getattribute__(field.name) @@ -1590,6 +1645,16 @@ self.WriteClientState() return self._registered_tokens[dmtoken] + def RegisterBrowser(self, dm_token, device_id, machine_name): + self._registered_tokens[dm_token] = { + 'device_id': device_id, + 'device_token': dm_token, + 'allowed_policy_types': ['google/chrome/machine-level-user', + 'google/chrome/machine-level-extension'], + 'machine_name': machine_name + } + self.WriteClientState() + def UpdateStateKeys(self, dmtoken, state_keys): """Updates the state keys for a given client.
diff --git a/components/search/ntp_features.cc b/components/search/ntp_features.cc index ebe5364b..2e4b95b 100644 --- a/components/search/ntp_features.cc +++ b/components/search/ntp_features.cc
@@ -99,6 +99,10 @@ const base::Feature kNtpDriveModule{"NtpDriveModule", base::FEATURE_DISABLED_BY_DEFAULT}; +// If enabled, Google Photos module will be shown. +const base::Feature kNtpPhotosModule{"NtpPhotosModule", + base::FEATURE_DISABLED_BY_DEFAULT}; + // If enabled, modules will be able to be reordered via dragging and dropping const base::Feature kNtpModulesDragAndDrop{"NtpModulesDragAndDrop", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/search/ntp_features.h b/components/search/ntp_features.h index 5e2a7c4..1580ab38 100644 --- a/components/search/ntp_features.h +++ b/components/search/ntp_features.h
@@ -34,6 +34,7 @@ extern const base::Feature kNtpChromeCartModule; extern const base::Feature kNtpModulesRedesigned; extern const base::Feature kNtpDriveModule; +extern const base::Feature kNtpPhotosModule; extern const base::Feature kNtpModulesDragAndDrop; extern const base::Feature kSearchSuggestChips; extern const base::Feature kDisableSearchSuggestChips;
diff --git a/components/services/storage/public/cpp/buckets/BUILD.gn b/components/services/storage/public/cpp/buckets/BUILD.gn index 61e4a671..23cb513 100644 --- a/components/services/storage/public/cpp/buckets/BUILD.gn +++ b/components/services/storage/public/cpp/buckets/BUILD.gn
@@ -4,9 +4,13 @@ public = [ "bucket_id.h", "bucket_info.h", + "constants.h", ] - sources = [ "bucket_info.cc" ] + sources = [ + "bucket_info.cc", + "constants.cc", + ] public_deps = [ "//base",
diff --git a/components/services/storage/public/cpp/buckets/bucket_info.cc b/components/services/storage/public/cpp/buckets/bucket_info.cc index 99ba78a..9ae1f838 100644 --- a/components/services/storage/public/cpp/buckets/bucket_info.cc +++ b/components/services/storage/public/cpp/buckets/bucket_info.cc
@@ -19,6 +19,7 @@ expiration(std::move(expiration)), quota(quota) {} +BucketInfo::BucketInfo() = default; BucketInfo::~BucketInfo() = default; BucketInfo::BucketInfo(const BucketInfo&) = default; @@ -26,4 +27,12 @@ BucketInfo& BucketInfo::operator=(const BucketInfo&) = default; BucketInfo& BucketInfo::operator=(BucketInfo&&) noexcept = default; +bool operator==(const BucketInfo& lhs, const BucketInfo& rhs) { + return lhs.id == rhs.id; +} + +bool operator!=(const BucketInfo& lhs, const BucketInfo& rhs) { + return !(lhs == rhs); +} + } // namespace storage
diff --git a/components/services/storage/public/cpp/buckets/bucket_info.h b/components/services/storage/public/cpp/buckets/bucket_info.h index 9e8f337..6b17d2d 100644 --- a/components/services/storage/public/cpp/buckets/bucket_info.h +++ b/components/services/storage/public/cpp/buckets/bucket_info.h
@@ -7,6 +7,7 @@ #include "base/time/time.h" #include "components/services/storage/public/cpp/buckets/bucket_id.h" +#include "components/services/storage/public/cpp/buckets/constants.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom-shared.h" #include "url/origin.h" @@ -14,6 +15,7 @@ namespace storage { struct COMPONENT_EXPORT(STORAGE_SERVICE_BUCKETS_SUPPORT) BucketInfo { + BucketInfo(); BucketInfo(BucketId bucket_id, blink::StorageKey storage_key, blink::mojom::StorageType type, @@ -28,12 +30,20 @@ BucketInfo& operator=(const BucketInfo&); BucketInfo& operator=(BucketInfo&&) noexcept; + COMPONENT_EXPORT(STORAGE_SERVICE_BUCKETS_SUPPORT) + friend bool operator==(const BucketInfo& lhs, const BucketInfo& rhs); + + COMPONENT_EXPORT(STORAGE_SERVICE_BUCKETS_SUPPORT) + friend bool operator!=(const BucketInfo& lhs, const BucketInfo& rhs); + + bool is_default() const { return name == kDefaultBucketName; } + BucketId id; blink::StorageKey storage_key; blink::mojom::StorageType type = blink::mojom::StorageType::kUnknown; std::string name; base::Time expiration; - int64_t quota; + int64_t quota = 0; }; } // namespace storage
diff --git a/components/services/storage/public/cpp/buckets/constants.cc b/components/services/storage/public/cpp/buckets/constants.cc new file mode 100644 index 0000000..a527319 --- /dev/null +++ b/components/services/storage/public/cpp/buckets/constants.cc
@@ -0,0 +1,11 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/services/storage/public/cpp/buckets/constants.h" + +namespace storage { + +const char kDefaultBucketName[] = "default"; + +} // namespace storage
diff --git a/components/services/storage/public/cpp/buckets/constants.h b/components/services/storage/public/cpp/buckets/constants.h new file mode 100644 index 0000000..3ed3f3a --- /dev/null +++ b/components/services/storage/public/cpp/buckets/constants.h
@@ -0,0 +1,18 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SERVICES_STORAGE_PUBLIC_CPP_BUCKETS_CONSTANTS_H_ +#define COMPONENTS_SERVICES_STORAGE_PUBLIC_CPP_BUCKETS_CONSTANTS_H_ + +#include "base/component_export.h" + +namespace storage { + +// Name of the default storage bucket. +COMPONENT_EXPORT(STORAGE_SERVICE_BUCKETS_SUPPORT) +extern const char kDefaultBucketName[]; + +} // namespace storage + +#endif // COMPONENTS_SERVICES_STORAGE_PUBLIC_CPP_BUCKETS_CONSTANTS_H_
diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java b/components/signin/public/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java index 945aa78..5882be8e 100644 --- a/components/signin/public/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java +++ b/components/signin/public/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
@@ -36,6 +36,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.metrics.RecordHistogram; import org.chromium.components.externalauth.ExternalAuthUtils; +import org.chromium.components.signin.metrics.FetchAccountCapabilitiesFromSystemLibraryResult; import java.io.IOException; @@ -147,6 +148,10 @@ @Override public @CapabilityResponse int hasCapability(Account account, String capability) { + RecordHistogram.recordEnumeratedHistogram( + "Signin.AccountCapabilities.GetFromSystemLibraryResult", + FetchAccountCapabilitiesFromSystemLibraryResult.API_NOT_AVAILABLE, + FetchAccountCapabilitiesFromSystemLibraryResult.MAX_VALUE + 1); return CapabilityResponse.EXCEPTION; }
diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/AccountInfoServiceProvider.java b/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/AccountInfoServiceProvider.java index 196bee00..2a67f0f 100644 --- a/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/AccountInfoServiceProvider.java +++ b/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/AccountInfoServiceProvider.java
@@ -4,6 +4,7 @@ package org.chromium.components.signin.identitymanager; +import androidx.annotation.MainThread; import androidx.annotation.VisibleForTesting; import java.util.concurrent.atomic.AtomicReference; @@ -14,14 +15,16 @@ */ public final class AccountInfoServiceProvider { private static final AtomicReference<AccountInfoService> sInstance = new AtomicReference<>(); - private static final AtomicReference<AccountInfoService> sTestingInstance = - new AtomicReference<>(); /** * Initializes the singleton {@link AccountInfoService} instance. */ + @MainThread public static void init( IdentityManager identityManager, AccountTrackerService accountTrackerService) { + if (sInstance.get() != null) { + return; + } sInstance.set(new AccountInfoServiceImpl(identityManager, accountTrackerService)); } @@ -29,9 +32,6 @@ * Gets the singleton {@link AccountInfoService} instance. */ public static AccountInfoService get() { - if (sTestingInstance.get() != null) { - return sTestingInstance.get(); - } if (sInstance.get() == null) { throw new RuntimeException("The AccountInfoService is not yet initialized!"); } @@ -40,12 +40,11 @@ @VisibleForTesting public static void setInstanceForTests(AccountInfoService accountInfoService) { - sTestingInstance.set(accountInfoService); + sInstance.set(accountInfoService); } @VisibleForTesting public static void resetForTests() { - sTestingInstance.set(null); sInstance.set(null); }
diff --git a/components/signin/public/base/signin_metrics.h b/components/signin/public/base/signin_metrics.h index c99fc42690..76d9021 100644 --- a/components/signin/public/base/signin_metrics.h +++ b/components/signin/public/base/signin_metrics.h
@@ -427,12 +427,19 @@ // // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.signin.metrics enum class FetchAccountCapabilitiesFromSystemLibraryResult { // Errors common to iOS and Android. kSuccess = 0, kErrorGeneric = 1, // Errors from 10 to 19 are reserved for Android. + kApiRequestFailed = 10, + kApiError = 11, + kApiNotPermitted = 12, + kApiUnknownCapability = 13, + kApiFailedToSync = 14, + kApiNotAvailable = 15, // Errors after 20 are reserved for iOS. kErrorMissingCapability = 20,
diff --git a/components/sync/driver/startup_controller.cc b/components/sync/driver/startup_controller.cc index 160c1a8..a954978 100644 --- a/components/sync/driver/startup_controller.cc +++ b/components/sync/driver/startup_controller.cc
@@ -107,6 +107,15 @@ } void StartupController::TryStart(bool force_immediate) { + // Post a task instead of running the startup checks directly, to guarantee + // that |start_engine_callback_| is never called synchronously from + // TryStart(). + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&StartupController::TryStartImpl, + weak_factory_.GetWeakPtr(), force_immediate)); +} + +void StartupController::TryStartImpl(bool force_immediate) { // Try starting up the sync engine if all policies are ready, otherwise wait // at most |switches::kSyncPolicyLoadTimeout|. if (!ArePoliciesReady()) {
diff --git a/components/sync/driver/startup_controller.h b/components/sync/driver/startup_controller.h index 0cd1739..d088e4d 100644 --- a/components/sync/driver/startup_controller.h +++ b/components/sync/driver/startup_controller.h
@@ -43,6 +43,10 @@ // If |force_immediate| is true, this will start sync immediately, bypassing // deferred startup and the "first setup complete" check (but *not* the // |should_start_callback_| check!). + // Note that (even in the "immediate" case), this will never directly run the + // start engine callback - that always happens as a posted task, so that + // callers have the opportunity to set up any other state as necessary before + // the engine actually starts. void TryStart(bool force_immediate); // Called when a datatype (SyncableService) has a need for sync to start @@ -86,6 +90,9 @@ kMaxValue = kFallbackTimer }; + // The actual (synchronous) implementation of TryStart(). + void TryStartImpl(bool force_immediate); + // Called when |policy_service_| is defined, but it took too long to receive // the first chrome policies. void OnFirstPoliciesLoadedTimeout();
diff --git a/components/sync/driver/startup_controller_unittest.cc b/components/sync/driver/startup_controller_unittest.cc index d2c8fbb..0d0725a 100644 --- a/components/sync/driver/startup_controller_unittest.cc +++ b/components/sync/driver/startup_controller_unittest.cc
@@ -8,12 +8,9 @@ #include <utility> #include "base/bind.h" -#include "base/command_line.h" -#include "base/run_loop.h" #include "base/test/task_environment.h" #include "components/policy/core/common/mock_policy_service.h" #include "components/policy/core/common/policy_service_impl.h" -#include "components/sync/driver/sync_driver_switches.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -21,13 +18,9 @@ class StartupControllerTest : public testing::Test { public: - StartupControllerTest() - : preferred_types_(UserTypes()), should_start_(false), started_(false) {} + StartupControllerTest() = default; void SetUp() override { - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kSyncDeferredStartupTimeoutSeconds, "0"); - policy_service_ = CreatePolicyService(); controller_ = std::make_unique<StartupController>( base::BindRepeating(&StartupControllerTest::GetPreferredDataTypes, @@ -55,17 +48,20 @@ void SetShouldStart(bool should_start) { should_start_ = should_start; } void ExpectStarted() { + task_environment_.RunUntilIdle(); EXPECT_TRUE(started()); EXPECT_EQ(StartupController::State::STARTED, controller()->GetState()); } void ExpectStartDeferred() { + task_environment_.RunUntilIdle(); EXPECT_FALSE(started()); EXPECT_EQ(StartupController::State::STARTING_DEFERRED, controller()->GetState()); } void ExpectNotStarted() { + task_environment_.RunUntilIdle(); EXPECT_FALSE(started()); EXPECT_EQ(StartupController::State::NOT_STARTED, controller()->GetState()); } @@ -75,16 +71,19 @@ StartupController* controller() { return controller_.get(); } policy::PolicyService* policy_service() { return policy_service_.get(); } + void RunDeferredTasks() { task_environment_.FastForwardUntilNoTasksRemain(); } + private: ModelTypeSet GetPreferredDataTypes() { return preferred_types_; } bool ShouldStart() { return should_start_; } void FakeStartBackend() { started_ = true; } - ModelTypeSet preferred_types_; - bool should_start_; - bool started_; + base::test::SingleThreadTaskEnvironment task_environment_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + ModelTypeSet preferred_types_ = UserTypes(); + bool should_start_ = false; + bool started_ = false; std::unique_ptr<policy::PolicyService> policy_service_; - base::test::SingleThreadTaskEnvironment task_environment_; std::unique_ptr<StartupController> controller_; }; @@ -124,7 +123,7 @@ // The fallback timer shouldn't result in another invocation of the closure // we passed to the StartupController. clear_started(); - base::RunLoop().RunUntilIdle(); + RunDeferredTasks(); EXPECT_FALSE(started()); } @@ -135,7 +134,7 @@ controller()->TryStart(/*force_immediate=*/false); ExpectStartDeferred(); - base::RunLoop().RunUntilIdle(); + RunDeferredTasks(); ExpectStarted(); } @@ -159,7 +158,7 @@ TEST_F(StartupControllerTest, FallbackTimerWaits) { controller()->TryStart(/*force_immediate=*/false); ExpectNotStarted(); - base::RunLoop().RunUntilIdle(); + RunDeferredTasks(); ExpectNotStarted(); }
diff --git a/components/sync/driver/sync_service_impl.cc b/components/sync/driver/sync_service_impl.cc index b73821a..0802ce3c 100644 --- a/components/sync/driver/sync_service_impl.cc +++ b/components/sync/driver/sync_service_impl.cc
@@ -1761,7 +1761,6 @@ if (restart) { startup_controller_->TryStart(/*force_immediate=*/true); - DCHECK(engine_); } }
diff --git a/components/sync/driver/sync_service_impl_startup_unittest.cc b/components/sync/driver/sync_service_impl_startup_unittest.cc index c8756313..c0ff0799 100644 --- a/components/sync/driver/sync_service_impl_startup_unittest.cc +++ b/components/sync/driver/sync_service_impl_startup_unittest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/run_loop.h" #include "components/sync/driver/sync_service_impl.h" #include "base/bind.h" @@ -180,6 +181,7 @@ sync_service()->GetTransportState()); SimulateTestUserSignin(); + base::RunLoop().RunUntilIdle(); // Now we're signed in, so the engine can start. Engine initialization is // immediate in this test, so we bypass the INITIALIZING state. @@ -225,6 +227,7 @@ CreateSyncService(SyncServiceImpl::MANUAL_START); sync_service()->Initialize(); + base::RunLoop().RunUntilIdle(); // SyncServiceImpl should now be active, but of course not have an access // token. @@ -331,6 +334,7 @@ // Prevent automatic (and successful) completion of engine initialization. component_factory()->AllowFakeEngineInitCompletion(false); sync_service()->Initialize(); + base::RunLoop().RunUntilIdle(); // Simulate an auth error while downloading control types. engine()->TriggerInitializationCompletion(/*success=*/false); @@ -358,6 +362,7 @@ // Calling Initialize should cause the service to immediately create and // initialize the engine, and configure the DataTypeManager. sync_service()->Initialize(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(DataTypeManager::CONFIGURED, data_type_manager()->state()); // Sync should be considered active, even though there is no refresh token. @@ -379,6 +384,7 @@ // a refresh token. UpdateCredentials(); sync_service()->Initialize(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(SyncService::TransportState::ACTIVE, sync_service()->GetTransportState()); } @@ -396,6 +402,7 @@ // configure the DataTypeManager. In this test, all of these operations are // synchronous. sync_service()->Initialize(); + base::RunLoop().RunUntilIdle(); EXPECT_NE(nullptr, data_type_manager()); EXPECT_EQ(DataTypeManager::CONFIGURED, data_type_manager()->state()); EXPECT_EQ(SyncService::TransportState::ACTIVE, @@ -408,6 +415,7 @@ SimulateTestUserSignin(); sync_service()->Initialize(); + base::RunLoop().RunUntilIdle(); ASSERT_EQ(DataTypeManager::CONFIGURED, data_type_manager()->state()); ASSERT_EQ(SyncService::TransportState::ACTIVE, sync_service()->GetTransportState()); @@ -415,6 +423,7 @@ // On SetSyncRequested(false), the sync service will immediately start up // again in transport mode. sync_service()->GetUserSettings()->SetSyncRequested(false); + base::RunLoop().RunUntilIdle(); // Sync-the-feature is still considered off. EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled()); @@ -431,6 +440,7 @@ CreateSyncService(SyncServiceImpl::MANUAL_START); sync_service()->Initialize(); + base::RunLoop().RunUntilIdle(); ASSERT_TRUE(sync_service()->IsSyncFeatureActive()); ASSERT_EQ(DataTypeManager::CONFIGURED, data_type_manager()->state()); ASSERT_EQ(SyncService::TransportState::ACTIVE, @@ -439,6 +449,7 @@ // On StopAndClear(), the sync service will immediately start up again in // transport mode. sync_service()->StopAndClear(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(DataTypeManager::CONFIGURED, data_type_manager()->state()); EXPECT_EQ(SyncService::TransportState::ACTIVE, sync_service()->GetTransportState()); @@ -450,6 +461,7 @@ // Call StopAndClear() again while the sync service is already in transport // mode. It should immediately start up again in transport mode. sync_service()->StopAndClear(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(DataTypeManager::CONFIGURED, data_type_manager()->state()); EXPECT_EQ(SyncService::TransportState::ACTIVE, sync_service()->GetTransportState()); @@ -525,6 +537,7 @@ // Initialize() should be enough to kick off Sync startup (which is instant in // this test). sync_service()->Initialize(); + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(sync_service()->IsEngineInitialized()); EXPECT_EQ(SyncService::DisableReasonSet(), sync_service()->GetDisableReasons()); @@ -536,6 +549,8 @@ // The service should stop when switching to managed mode. sync_prefs()->SetManagedForTest(true); + // Give re-startup a chance to happen (it shouldn't!). + base::RunLoop().RunUntilIdle(); // Sync was disabled due to the policy, setting SyncRequested to false and // causing DISABLE_REASON_USER_CHOICE. ASSERT_EQ(SyncService::DisableReasonSet( @@ -548,12 +563,12 @@ EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled()); EXPECT_FALSE(sync_service()->IsSyncFeatureActive()); EXPECT_EQ(1, get_controller(BOOKMARKS)->model()->clear_metadata_call_count()); - // Note that PSS no longer references |data_type_manager| after stopping. // When switching back to unmanaged, Sync-the-transport should start up // automatically, which causes (re)creation of SyncEngine and // DataTypeManager. sync_prefs()->SetManagedForTest(false); + base::RunLoop().RunUntilIdle(); ASSERT_EQ( SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE), @@ -578,6 +593,7 @@ // Prevent automatic (and successful) completion of engine initialization. component_factory()->AllowFakeEngineInitCompletion(false); sync_service()->Initialize(); + base::RunLoop().RunUntilIdle(); // Simulate a failure while downloading control types. engine()->TriggerInitializationCompletion(/*success=*/false); @@ -618,13 +634,14 @@ // Sync-the-feature still doesn't start until the user says they want it. component_factory()->AllowFakeEngineInitCompletion(false); SimulateTestUserSignin(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ( SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE), sync_service()->GetDisableReasons()); EXPECT_EQ(SyncService::TransportState::INITIALIZING, sync_service()->GetTransportState()); EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled()); - EXPECT_TRUE(engine()); + ASSERT_TRUE(engine()); // Initiate Sync (the feature) setup before the engine initializes itself in // transport mode.
diff --git a/components/sync/driver/sync_service_impl_unittest.cc b/components/sync/driver/sync_service_impl_unittest.cc index 279dddf..932038b 100644 --- a/components/sync/driver/sync_service_impl_unittest.cc +++ b/components/sync/driver/sync_service_impl_unittest.cc
@@ -53,6 +53,7 @@ #endif // BUILDFLAG(IS_CHROMEOS_ASH) using testing::_; +using testing::AnyNumber; using testing::ByMove; using testing::Not; using testing::Return; @@ -183,12 +184,20 @@ sync_prefs.SetFirstSetupComplete(); } - void InitializeForNthSync() { + void InitializeForNthSync(bool run_until_idle = true) { PopulatePrefsForNthSync(); service_->Initialize(); + if (run_until_idle) { + task_environment_.RunUntilIdle(); + } } - void InitializeForFirstSync() { service_->Initialize(); } + void InitializeForFirstSync(bool run_until_idle = true) { + service_->Initialize(); + if (run_until_idle) { + task_environment_.RunUntilIdle(); + } + } void TriggerPassphraseRequired() { service_->GetEncryptionObserverForTest()->OnPassphraseRequired( @@ -302,6 +311,7 @@ EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons()); // Sync should immediately start up in transport mode. + base::RunLoop().RunUntilIdle(); EXPECT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); EXPECT_FALSE(service()->IsSyncFeatureActive()); @@ -318,7 +328,8 @@ ASSERT_FALSE(service()->IsSyncFeatureActive()); ASSERT_FALSE(service()->IsSyncFeatureEnabled()); - // Sync-the-transport is still active. + // Sync-the-transport should become active again. + base::RunLoop().RunUntilIdle(); ASSERT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); @@ -411,6 +422,7 @@ EXPECT_EQ( SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE), service()->GetDisableReasons()); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); @@ -419,6 +431,7 @@ service()->GetUserSettings()->SetSyncRequested(true); service()->GetUserSettings()->SetFirstSetupComplete( syncer::SyncFirstSetupCompleteSource::BASIC_FLOW); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); EXPECT_TRUE(service()->GetDisableReasons().Empty()); @@ -461,7 +474,8 @@ service()->SetSyncAllowedByPlatform(false); EXPECT_FALSE(service()->IsSyncFeatureEnabled()); EXPECT_FALSE(service()->IsSyncFeatureActive()); - // Sync-the-transport should be still active. + // Sync-the-transport should become active again. + base::RunLoop().RunUntilIdle(); EXPECT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); } @@ -498,6 +512,7 @@ EXPECT_EQ( SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE), service()->GetDisableReasons()); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); EXPECT_FALSE(service()->IsSyncFeatureActive()); @@ -506,6 +521,7 @@ // Request start. Now Sync-the-feature should start again. service()->GetUserSettings()->SetSyncRequested(true); EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons()); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); EXPECT_TRUE(service()->IsSyncFeatureActive()); @@ -532,6 +548,7 @@ EXPECT_EQ( SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE), service()->GetDisableReasons()); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); EXPECT_FALSE(service()->IsSyncFeatureActive()); @@ -540,6 +557,7 @@ service()->GetUserSettings()->SetSyncRequested(true); EXPECT_TRUE(sync_prefs.IsSyncRequested()); EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons()); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); EXPECT_TRUE(service()->IsSyncFeatureActive()); @@ -615,17 +633,19 @@ TEST_F(SyncServiceImplTest, GetSyncTokenStatus) { SignIn(); CreateService(SyncServiceImpl::MANUAL_START); - InitializeForNthSync(); + InitializeForNthSync(/*run_until_idle=*/false); - // Initial status. + // Initial status: The Sync engine startup has not begun yet; no token request + // has been sent. SyncTokenStatus token_status = service()->GetSyncTokenStatusForDebugging(); ASSERT_EQ(CONNECTION_NOT_ATTEMPTED, token_status.connection_status); ASSERT_TRUE(token_status.connection_status_update_time.is_null()); - ASSERT_FALSE(token_status.token_request_time.is_null()); + ASSERT_TRUE(token_status.token_request_time.is_null()); ASSERT_TRUE(token_status.token_response_time.is_null()); ASSERT_FALSE(token_status.has_token); - // The token request will take the form of a posted task. Run it. + // Sync engine startup as well as the actual token request take the form of + // posted tasks. Run them. base::RunLoop().RunUntilIdle(); // Now we should have an access token. @@ -791,6 +811,7 @@ // Even though Sync-the-feature is disabled, there's still an (unconsented) // signed-in account, so Sync-the-transport should still be running. + base::RunLoop().RunUntilIdle(); EXPECT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); EXPECT_FALSE(service()->IsSyncFeatureEnabled()); @@ -1004,6 +1025,7 @@ service()->GetDisableReasons()); // Since ChromeOS doesn't support signout and so the account is still there // and available, Sync will restart in standalone transport mode. + base::RunLoop().RunUntilIdle(); EXPECT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); #else @@ -1201,7 +1223,8 @@ TEST_F(SyncServiceImplTestWithSyncInvalidationsServiceCreated, ShouldActivateSyncInvalidationsServiceOnSignIn) { CreateService(SyncServiceImpl::MANUAL_START); - EXPECT_CALL(*sync_invalidations_service(), SetActive(false)); + EXPECT_CALL(*sync_invalidations_service(), SetActive(false)) + .Times(AnyNumber()); InitializeForFirstSync(); EXPECT_CALL(*sync_invalidations_service(), SetActive(true)); SignIn();
diff --git a/components/test/data/explore_sites/version_schemas/v1.sql b/components/test/data/explore_sites/version_schemas/v1.sql index c6af154e..c096a6d 100644 --- a/components/test/data/explore_sites/version_schemas/v1.sql +++ b/components/test/data/explore_sites/version_schemas/v1.sql
@@ -1,5 +1,5 @@ INSERT OR REPLACE INTO meta (key, value) -VALUES ("version", 1), ("last_compatible_version", 1); +VALUES ('version', 1), ('last_compatible_version', 1); CREATE TABLE IF NOT EXISTS categories ( category_id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -38,4 +38,4 @@ INSERT INTO site_blacklist (url, date_removed) -VALUES ('http://www.example.com', 1); \ No newline at end of file +VALUES ('http://www.example.com', 1);
diff --git a/components/test/data/explore_sites/version_schemas/v2.sql b/components/test/data/explore_sites/version_schemas/v2.sql index 973006fc..cb37c22f 100644 --- a/components/test/data/explore_sites/version_schemas/v2.sql +++ b/components/test/data/explore_sites/version_schemas/v2.sql
@@ -1,5 +1,5 @@ INSERT OR REPLACE INTO meta (key, value) -VALUES ("version", 2), ("last_compatible_version", 1); +VALUES ('version', 2), ('last_compatible_version', 1); CREATE TABLE IF NOT EXISTS categories ( category_id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -42,4 +42,4 @@ INSERT INTO site_blacklist (url, date_removed) -VALUES ('http://www.example.com', 1); \ No newline at end of file +VALUES ('http://www.example.com', 1);
diff --git a/components/test/data/explore_sites/version_schemas/v3.sql b/components/test/data/explore_sites/version_schemas/v3.sql index 97c4433..c1ada93 100644 --- a/components/test/data/explore_sites/version_schemas/v3.sql +++ b/components/test/data/explore_sites/version_schemas/v3.sql
@@ -1,5 +1,5 @@ INSERT OR REPLACE INTO meta (key, value) -VALUES ("version", 3), ("last_compatible_version", 1); +VALUES ('version', 3), ('last_compatible_version', 1); CREATE TABLE IF NOT EXISTS categories ( category_id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -42,4 +42,4 @@ INSERT INTO site_blocklist (url, date_removed) -VALUES ('http://www.example.com', 1); \ No newline at end of file +VALUES ('http://www.example.com', 1);
diff --git a/components/test/data/offline_pages/prefetch/version_schemas/v1.sql b/components/test/data/offline_pages/prefetch/version_schemas/v1.sql index b78b25f..413f357 100644 --- a/components/test/data/offline_pages/prefetch/version_schemas/v1.sql +++ b/components/test/data/offline_pages/prefetch/version_schemas/v1.sql
@@ -1,5 +1,5 @@ INSERT OR REPLACE INTO meta (key, value) -VALUES ("version", 1), ("last_compatible_version", 1); +VALUES ('version', 1), ('last_compatible_version', 1); CREATE TABLE IF NOT EXISTS prefetch_items (
diff --git a/components/test/data/offline_pages/prefetch/version_schemas/v2.sql b/components/test/data/offline_pages/prefetch/version_schemas/v2.sql index 9394f4a..6c1b2a48 100644 --- a/components/test/data/offline_pages/prefetch/version_schemas/v2.sql +++ b/components/test/data/offline_pages/prefetch/version_schemas/v2.sql
@@ -1,5 +1,5 @@ INSERT OR REPLACE INTO meta (key, value) -VALUES ("version", 2), ("last_compatible_version", 1); +VALUES ('version', 2), ('last_compatible_version', 1); CREATE TABLE IF NOT EXISTS prefetch_items (
diff --git a/components/test/data/offline_pages/prefetch/version_schemas/v3.sql b/components/test/data/offline_pages/prefetch/version_schemas/v3.sql index 8b2b7c7..2e54a66 100644 --- a/components/test/data/offline_pages/prefetch/version_schemas/v3.sql +++ b/components/test/data/offline_pages/prefetch/version_schemas/v3.sql
@@ -1,5 +1,5 @@ INSERT OR REPLACE INTO meta (key, value) -VALUES ("version", 3), ("last_compatible_version", 1); +VALUES ('version', 3), ('last_compatible_version', 1); CREATE TABLE IF NOT EXISTS prefetch_items (
diff --git a/components/test/data/password_manager/affiliation_db_v1.sql b/components/test/data/password_manager/affiliation_db_v1.sql index 6d69791..2d49e270 100644 --- a/components/test/data/password_manager/affiliation_db_v1.sql +++ b/components/test/data/password_manager/affiliation_db_v1.sql
@@ -17,15 +17,15 @@ CREATE INDEX index_on_eq_class_members_set_id ON eq_class_members (set_id); INSERT INTO eq_classes(id, last_update_time) VALUES (1, 1000000); -INSERT INTO eq_class_members(facet_uri, set_id) VALUES ("https://alpha.example.com", 1); -INSERT INTO eq_class_members(facet_uri, set_id) VALUES ("https://beta.example.com", 1); -INSERT INTO eq_class_members(facet_uri, set_id) VALUES ("https://gamma.example.com", 1); +INSERT INTO eq_class_members(facet_uri, set_id) VALUES ('https://alpha.example.com', 1); +INSERT INTO eq_class_members(facet_uri, set_id) VALUES ('https://beta.example.com', 1); +INSERT INTO eq_class_members(facet_uri, set_id) VALUES ('https://gamma.example.com', 1); INSERT INTO eq_classes(id, last_update_time) VALUES (2, 2000000); -INSERT INTO eq_class_members(facet_uri, set_id) VALUES ("https://delta.example.com", 2); -INSERT INTO eq_class_members(facet_uri, set_id) VALUES ("https://epsilon.example.com", 2); +INSERT INTO eq_class_members(facet_uri, set_id) VALUES ('https://delta.example.com', 2); +INSERT INTO eq_class_members(facet_uri, set_id) VALUES ('https://epsilon.example.com', 2); INSERT INTO eq_classes(id, last_update_time) VALUES (3, 3000000); -INSERT INTO eq_class_members(facet_uri, set_id) VALUES ("android://hash@com.example.android", 3); +INSERT INTO eq_class_members(facet_uri, set_id) VALUES ('android://hash@com.example.android', 3); COMMIT;
diff --git a/components/test/data/password_manager/affiliation_db_v2.sql b/components/test/data/password_manager/affiliation_db_v2.sql index e32d02fc..ad85124 100644 --- a/components/test/data/password_manager/affiliation_db_v2.sql +++ b/components/test/data/password_manager/affiliation_db_v2.sql
@@ -21,16 +21,16 @@ CREATE INDEX index_on_eq_class_members_set_id ON eq_class_members (set_id); INSERT INTO eq_classes(id, last_update_time) VALUES (1, 1000000); -INSERT INTO eq_class_members(facet_uri, set_id) VALUES ("https://alpha.example.com", 1); -INSERT INTO eq_class_members(facet_uri, set_id) VALUES ("https://beta.example.com", 1); -INSERT INTO eq_class_members(facet_uri, set_id) VALUES ("https://gamma.example.com", 1); +INSERT INTO eq_class_members(facet_uri, set_id) VALUES ('https://alpha.example.com', 1); +INSERT INTO eq_class_members(facet_uri, set_id) VALUES ('https://beta.example.com', 1); +INSERT INTO eq_class_members(facet_uri, set_id) VALUES ('https://gamma.example.com', 1); INSERT INTO eq_classes(id, last_update_time) VALUES (2, 2000000); -INSERT INTO eq_class_members(facet_uri, set_id) VALUES ("https://delta.example.com", 2); -INSERT INTO eq_class_members(facet_uri, set_id) VALUES ("https://epsilon.example.com", 2); +INSERT INTO eq_class_members(facet_uri, set_id) VALUES ('https://delta.example.com', 2); +INSERT INTO eq_class_members(facet_uri, set_id) VALUES ('https://epsilon.example.com', 2); INSERT INTO eq_classes(id, last_update_time) VALUES (3, 3000000); INSERT INTO eq_class_members(facet_uri, facet_display_name, facet_icon_url, set_id) VALUES ( - "android://hash@com.example.android", "Test Android App", "https://example.com/icon.png", 3); + 'android://hash@com.example.android', 'Test Android App', 'https://example.com/icon.png', 3); COMMIT;
diff --git a/components/ukm/BUILD.gn b/components/ukm/BUILD.gn index 644b0ebe..df41f2f 100644 --- a/components/ukm/BUILD.gn +++ b/components/ukm/BUILD.gn
@@ -87,7 +87,8 @@ deps = [ "//base", "//components/history/core/browser", - "//components/sync", + "//components/sync/base", + "//components/sync/driver", "//google_apis", ]
diff --git a/components/ukm/observers/ukm_consent_state_observer.cc b/components/ukm/observers/ukm_consent_state_observer.cc index 8846912..f5ed2408 100644 --- a/components/ukm/observers/ukm_consent_state_observer.cc +++ b/components/ukm/observers/ukm_consent_state_observer.cc
@@ -10,7 +10,9 @@ #include "base/containers/contains.h" #include "base/feature_list.h" #include "base/metrics/histogram_macros.h" -#include "components/sync/driver/sync_user_settings.h" +#include "components/sync/base/model_type.h" +#include "components/sync/driver/sync_service.h" +#include "components/sync/driver/sync_service_utils.h" #include "components/unified_consent/url_keyed_data_collection_consent_helper.h" #include "google_apis/gaia/google_service_auth_error.h" @@ -18,6 +20,24 @@ namespace ukm { +namespace { + +bool CanUploadUkmForType(syncer::SyncService* sync_service, + syncer::ModelType model_type) { + switch (GetUploadToGoogleState(sync_service, model_type)) { + case syncer::UploadState::NOT_ACTIVE: + return false; + // INITIALIZING is considered good enough, because sync is enabled and + // |model_type| is known to be uploaded to Google, and transient errors + // don't matter here. + case syncer::UploadState::INITIALIZING: + case syncer::UploadState::ACTIVE: + return true; + } +} + +} // namespace + UkmConsentStateObserver::UkmConsentStateObserver() = default; UkmConsentStateObserver::~UkmConsentStateObserver() { @@ -38,9 +58,11 @@ DCHECK(consent_helper); ProfileState state; state.anonymized_data_collection_enabled = consent_helper->IsEnabled(); + state.extensions_enabled = - sync_service->GetPreferredDataTypes().Has(syncer::EXTENSIONS) && - sync_service->IsSyncFeatureEnabled(); + CanUploadUkmForType(sync_service, syncer::ModelType::EXTENSIONS); + state.apps_sync_enabled = + CanUploadUkmForType(sync_service, syncer::ModelType::APPS); return state; } @@ -56,27 +78,38 @@ consent_helper->AddObserver(this); consent_helpers_[sync_service] = std::move(consent_helper); sync_observations_.AddObservation(sync_service); - UpdateUkmAllowedForAllProfiles(false); + UpdateUkmAllowedForAllProfiles(/*total_purge*/ false); } -void UkmConsentStateObserver::UpdateUkmAllowedForAllProfiles(bool must_purge) { - bool all_profile_states_allow_ukm = CheckPreviousStatesAllowUkm(); - bool all_profile_states_allow_extension_ukm = - all_profile_states_allow_ukm && CheckPreviousStatesAllowExtensionUkm(); +void UkmConsentStateObserver::UpdateUkmAllowedForAllProfiles(bool total_purge) { + const bool previous_states_allow_ukm = CheckPreviousStatesAllowUkm(); + const bool previous_states_allow_apps_ukm = + previous_states_allow_ukm && CheckPreviousStatesAllowAppsUkm(); + const bool previous_states_allow_extensions_ukm = + previous_states_allow_ukm && CheckPreviousStatesAllowExtensionUkm(); UMA_HISTOGRAM_BOOLEAN("UKM.ConsentObserver.AllowedForAllProfiles", - all_profile_states_allow_ukm); + previous_states_allow_ukm); + + // Check which consents have changed. + const bool ukm_consent_changed = + previous_states_allow_ukm != ukm_allowed_for_all_profiles_; + const bool apps_consent_changed = + previous_states_allow_apps_ukm != ukm_allowed_with_apps_for_all_profiles_; + const bool extension_consent_changed = + previous_states_allow_extensions_ukm != + ukm_allowed_with_extensions_for_all_profiles_; // Any change in profile states needs to call OnUkmAllowedStateChanged so that // the new settings take effect. - if (must_purge || - (all_profile_states_allow_ukm != ukm_allowed_for_all_profiles_) || - (all_profile_states_allow_extension_ukm != - ukm_allowed_with_extensions_for_all_profiles_)) { - ukm_allowed_for_all_profiles_ = all_profile_states_allow_ukm; + if (total_purge || ukm_consent_changed || extension_consent_changed || + apps_consent_changed) { + ukm_allowed_for_all_profiles_ = previous_states_allow_ukm; + ukm_allowed_with_apps_for_all_profiles_ = previous_states_allow_apps_ukm; ukm_allowed_with_extensions_for_all_profiles_ = - all_profile_states_allow_extension_ukm; - OnUkmAllowedStateChanged(must_purge); + previous_states_allow_extensions_ukm; + + OnUkmAllowedStateChanged(total_purge); } } @@ -92,6 +125,17 @@ return true; } +bool UkmConsentStateObserver::CheckPreviousStatesAllowAppsUkm() { + if (previous_states_.empty()) + return false; + for (const auto& kv : previous_states_) { + const ProfileState& state = kv.second; + if (!state.apps_sync_enabled) + return false; + } + return true; +} + bool UkmConsentStateObserver::CheckPreviousStatesAllowExtensionUkm() { if (previous_states_.empty()) return false; @@ -133,13 +177,14 @@ DCHECK(consent_helper); ProfileState state = GetProfileState(sync, consent_helper); - // Trigger a purge if the current state no longer allows UKM. - bool must_purge = previous_state.AllowsUkm() && !state.AllowsUkm(); + // Trigger a total purge of all local UKM data if the current state no longer + // allows tracking UKM. + bool total_purge = previous_state.AllowsUkm() && !state.AllowsUkm(); - UMA_HISTOGRAM_BOOLEAN("UKM.ConsentObserver.Purge", must_purge); + UMA_HISTOGRAM_BOOLEAN("UKM.ConsentObserver.Purge", total_purge); previous_states_[sync] = state; - UpdateUkmAllowedForAllProfiles(must_purge); + UpdateUkmAllowedForAllProfiles(total_purge); } void UkmConsentStateObserver::OnSyncShutdown(syncer::SyncService* sync) { @@ -152,13 +197,17 @@ DCHECK(sync_observations_.IsObservingSource(sync)); sync_observations_.RemoveObservation(sync); previous_states_.erase(sync); - UpdateUkmAllowedForAllProfiles(/*must_purge=*/false); + UpdateUkmAllowedForAllProfiles(/*total_purge=*/false); } bool UkmConsentStateObserver::IsUkmAllowedForAllProfiles() { return ukm_allowed_for_all_profiles_; } +bool UkmConsentStateObserver::IsUkmAllowedWithAppsForAllProfiles() { + return ukm_allowed_with_apps_for_all_profiles_; +} + bool UkmConsentStateObserver::IsUkmAllowedWithExtensionsForAllProfiles() { return ukm_allowed_with_extensions_for_all_profiles_; }
diff --git a/components/ukm/observers/ukm_consent_state_observer.h b/components/ukm/observers/ukm_consent_state_observer.h index 258f46a8..714b560 100644 --- a/components/ukm/observers/ukm_consent_state_observer.h +++ b/components/ukm/observers/ukm_consent_state_observer.h
@@ -36,15 +36,21 @@ // URL-keyed anonymized data collection is enabled for all profiles. virtual bool IsUkmAllowedForAllProfiles(); + // Returns true iff sync is in a state that allows UKM to capture apps. + // This means that all profiles have APPS data type enabled for syncing. + virtual bool IsUkmAllowedWithAppsForAllProfiles(); + // Returns true iff sync is in a state that allows UKM to capture extensions. // This means that all profiles have EXTENSIONS data type enabled for syncing. virtual bool IsUkmAllowedWithExtensionsForAllProfiles(); protected: // Called after UKM consent state changed. - // If |must_purge| is true, the UKM is not allowed for some profile, and local - // data must be purged. - virtual void OnUkmAllowedStateChanged(bool must_purge) = 0; + // If |total_purge| is true, the UKM is not allowed for some profile, and all + // local data must be purged. Otherwise, more specific consents are checked + // for individual sync settings, and recorded data may be partially purged if + // we no longer have the corresponding sync consent. + virtual void OnUkmAllowedStateChanged(bool total_purge) = 0; private: // syncer::SyncServiceObserver: @@ -56,18 +62,22 @@ unified_consent::UrlKeyedDataCollectionConsentHelper* consent_helper) override; - // Recomputes |ukm_allowed_for_all_profiles_| and - // |ukm_allowed_with_extensions_for_all_profiles_| from |previous_states_|; - void UpdateUkmAllowedForAllProfiles(bool must_purge); + // Recomputes |ukm_allowed_for_all_profiles_| and other specific consents + // (e.g. Extension, ChromeOS apps) from |previous_states_|; + void UpdateUkmAllowedForAllProfiles(bool total_purge); // Returns true iff all profile states in |previous_states_| allow UKM. // If there are no profiles being observed, this returns false. bool CheckPreviousStatesAllowUkm(); // Returns true iff all profile states in |previous_states_| allow extension - // UKM. If there are no profiles are being observed, this returns false. + // UKM. If no profiles are being observed, this returns false. bool CheckPreviousStatesAllowExtensionUkm(); + // Returns true iff all profile states in |previous_states_| allow apps + // UKM. If no profiles are being observed, this returns false. + bool CheckPreviousStatesAllowAppsUkm(); + // Tracks observed sync services, for cleanup. base::ScopedMultiSourceObservation<syncer::SyncService, syncer::SyncServiceObserver> @@ -79,14 +89,14 @@ // data collection is enabled). bool AllowsUkm() const; - // Returns true if |AllowsUkm| and if sync extensions are enabled. - bool AllowsUkmWithExtension() const; - // Whether anonymized data collection is enabled. bool anonymized_data_collection_enabled = false; - // If the user has extension sync enabled. + // Whether the user has extension sync enabled. bool extensions_enabled = false; + + // Whether the user has apps sync enabled. + bool apps_sync_enabled = false; }; // Updates the UKM enabled state for a profile and then triggers an update of @@ -123,6 +133,10 @@ // Tracks if UKM is allowed on all profiles after the last state change. bool ukm_allowed_for_all_profiles_ = false; + // Tracks if apps sync was enabled on all profiles after the last state + // change. + bool ukm_allowed_with_apps_for_all_profiles_ = false; + // Tracks if extension sync was enabled on all profiles after the last state // change. bool ukm_allowed_with_extensions_for_all_profiles_ = false;
diff --git a/components/ukm/ukm_recorder_impl.cc b/components/ukm/ukm_recorder_impl.cc index 3ec1b9d..ab27a7a 100644 --- a/components/ukm/ukm_recorder_impl.cc +++ b/components/ukm/ukm_recorder_impl.cc
@@ -266,30 +266,51 @@ recording_is_continuous_ = false; } -void UkmRecorderImpl::PurgeExtensionRecordings() { +void UkmRecorderImpl::PurgeRecordingsWithUrlScheme( + const std::string& url_scheme) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // Discard all sources that have an extension URL as well as all the entries - // related to any of these sources. - std::unordered_set<SourceId> extension_source_ids; + + // Discard all sources that have a URL with the given URL scheme as well as + // all the entries associated with these sources. + std::unordered_set<SourceId> relevant_source_ids; for (const auto& kv : recordings_.sources) { - if (kv.second->url().SchemeIs(kExtensionScheme)) { - extension_source_ids.insert(kv.first); + if (kv.second->url().SchemeIs(url_scheme)) { + relevant_source_ids.insert(kv.first); } } - for (const auto source_id : extension_source_ids) { + + PurgeSourcesAndEventsBySourceIds(relevant_source_ids); + recording_is_continuous_ = false; +} + +void UkmRecorderImpl::PurgeRecordingsWithSourceIdType( + ukm::SourceIdType source_id_type) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + std::unordered_set<SourceId> relevant_source_ids; + + for (const auto& kv : recordings_.sources) { + if (GetSourceIdType(kv.first) == source_id_type) { + relevant_source_ids.insert(kv.first); + } + } + + PurgeSourcesAndEventsBySourceIds(relevant_source_ids); + recording_is_continuous_ = false; +} + +void UkmRecorderImpl::PurgeSourcesAndEventsBySourceIds( + const std::unordered_set<SourceId>& source_ids) { + for (const auto source_id : source_ids) { recordings_.sources.erase(source_id); } std::vector<mojom::UkmEntryPtr>& events = recordings_.entries; - events.erase( - std::remove_if(events.begin(), events.end(), - [&](const auto& event) { - return extension_source_ids.count(event->source_id); - }), - events.end()); - - recording_is_continuous_ = false; + events.erase(std::remove_if(events.begin(), events.end(), + [&](const auto& event) { + return source_ids.count(event->source_id); + }), + events.end()); } void UkmRecorderImpl::MarkSourceForDeletion(SourceId source_id) {
diff --git a/components/ukm/ukm_recorder_impl.h b/components/ukm/ukm_recorder_impl.h index 69ed1e9..e5593f3 100644 --- a/components/ukm/ukm_recorder_impl.h +++ b/components/ukm/ukm_recorder_impl.h
@@ -67,11 +67,16 @@ // True if sampling is enabled. bool IsSamplingEnabled() const; - // Deletes stored recordings. + // Deletes all stored recordings. void Purge(); - // Deletes stored recordings related to Chrome extensions. - void PurgeExtensionRecordings(); + // Deletes stored Sources containing URLs of the given scheme and events + // attributed with these Sources. + void PurgeRecordingsWithUrlScheme(const std::string& url_scheme); + + // Deletes stored Sources with the given Source id type and events + // attributed with these Sources. + void PurgeRecordingsWithSourceIdType(ukm::SourceIdType source_id_type); // Marks a source as no longer needed to be kept alive in memory. The source // with given id will be removed from in-memory recordings at the next @@ -113,6 +118,10 @@ // Writes recordings into a report proto, and clears recordings. void StoreRecordingsInReport(Report* report); + // Deletes Sources and Events with these source_ids. + void PurgeSourcesAndEventsBySourceIds( + const std::unordered_set<SourceId>& source_ids); + const std::map<SourceId, std::unique_ptr<UkmSource>>& sources() const { return recordings_.sources; }
diff --git a/components/ukm/ukm_recorder_impl_unittest.cc b/components/ukm/ukm_recorder_impl_unittest.cc index 187ea182..f7748a09 100644 --- a/components/ukm/ukm_recorder_impl_unittest.cc +++ b/components/ukm/ukm_recorder_impl_unittest.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/metrics/metrics_hashes.h" #include "base/test/task_environment.h" +#include "components/ukm/scheme_constants.h" #include "components/ukm/test_ukm_recorder.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_entry_builder.h" @@ -114,7 +115,7 @@ EXPECT_EQ(4U, recorder.sources().size()); EXPECT_EQ(2U, recorder.entries().size()); - recorder.PurgeExtensionRecordings(); + recorder.PurgeRecordingsWithUrlScheme(kExtensionScheme); // Recorded sources of extension scheme and related events have been cleared. EXPECT_EQ(2U, recorder.sources().size());
diff --git a/components/ukm/ukm_service.cc b/components/ukm/ukm_service.cc index 53fee732..386d38ff 100644 --- a/components/ukm/ukm_service.cc +++ b/components/ukm/ukm_service.cc
@@ -28,6 +28,7 @@ #include "components/ukm/ukm_recorder_impl.h" #include "components/ukm/ukm_rotation_scheduler.h" #include "services/metrics/public/cpp/delegating_ukm_recorder.h" +#include "services/metrics/public/cpp/ukm_source_id.h" #include "third_party/metrics_proto/ukm/report.pb.h" #include "third_party/metrics_proto/user_demographics.pb.h" #include "third_party/zlib/google/compression_utils.h" @@ -106,8 +107,9 @@ mutable_elements->DeleteSubrange(start, entries_size - start); } -void PurgeExtensionDataFromUnsentLogStore( - metrics::UnsentLogStore* ukm_log_store) { +template <typename Predicate> +void PurgeDataFromUnsentLogStore(metrics::UnsentLogStore* ukm_log_store, + Predicate source_purging_condition) { for (size_t index = 0; index < ukm_log_store->size(); index++) { // Uncompress log data from store back into a Report. const std::string& compressed_log_data = @@ -123,34 +125,28 @@ report.ParseFromString(uncompressed_log_data); DCHECK(report_parse_successful); - std::unordered_set<SourceId> extension_source_ids; + std::unordered_set<SourceId> relevant_source_ids; - // Grab all extension-related source ids. + // Grab ids of all sources satisfying the condition for purging. for (const auto& source : report.sources()) { - // Check if any URL on the source has extension scheme. It is possible - // that only one of multiple URLs does due to redirect, in this case, we - // should still purge the source. - for (const auto& url_info : source.urls()) { - if (GURL(url_info.url()).SchemeIs(kExtensionScheme)) { - extension_source_ids.insert(source.id()); - break; - } + if (source_purging_condition(source)) { + relevant_source_ids.insert(source.id()); } } - if (extension_source_ids.empty()) + if (relevant_source_ids.empty()) continue; - // Remove all extension-related sources from the report. + // Remove all relevant sources from the report. FilterReportElements( [&](const Source& element) { - return extension_source_ids.count(element.id()); + return relevant_source_ids.count(element.id()); }, report.sources(), report.mutable_sources()); - // Remove all entries originating from extension-related sources. + // Remove all entries originating from these sources. FilterReportElements( [&](const Entry& element) { - return extension_source_ids.count(element.source_id()); + return relevant_source_ids.count(element.source_id()); }, report.entries(), report.mutable_entries()); @@ -162,8 +158,8 @@ ukm_log_store->ReplaceLogAtIndex(index, reserialized_log_data, metrics::LogMetadata()); - // Reached here only if extensions were found in the log, so data should now - // be different after filtering. + // Reached here only if some Sources satisfied the condition for purging, so + // reserialized data should now be different. DCHECK(ukm_log_store->GetLogAtIndex(index) != old_compressed_log_data); } } @@ -322,14 +318,51 @@ UkmRecorderImpl::Purge(); } -void UkmService::PurgeExtensions() { +void UkmService::PurgeExtensionsData() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DVLOG(1) << "UkmService::PurgeExtensions"; + DVLOG(1) << "UkmService::PurgeExtensionsData"; // Filter out any extension-related data from the serialized logs in the + // UnsentLogStore for uploading, base on having kExtensionScheme URL scheme. + PurgeDataFromUnsentLogStore( + reporting_service_.ukm_log_store(), [&](const Source& source) { + // Check if any URL on the Source has the kExtensionScheme URL scheme. + // It is possible that only one of multiple URLs does due to redirect, + // in this case, we should still purge the source. + for (const auto& url_info : source.urls()) { + if (GURL(url_info.url()).SchemeIs(kExtensionScheme)) + return true; + } + return false; + }); + + // Purge data currently in the recordings intended for the next + // ukm::Report. + UkmRecorderImpl::PurgeRecordingsWithUrlScheme(kExtensionScheme); +} + +void UkmService::PurgeAppsData() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DVLOG(1) << "UkmService::PurgeAppsData"; + // Filter out any apps-related data from the serialized logs in the // UnsentLogStore for uploading. - PurgeExtensionDataFromUnsentLogStore(reporting_service_.ukm_log_store()); + // Also purge based on source id type, because some apps don't use app:// + // scheme. + // For example, OS Settings is an ChromeOS app with "chrome://os-settings" as + // its URL. + PurgeDataFromUnsentLogStore( + reporting_service_.ukm_log_store(), [&](const Source& source) { + if (GetSourceIdType(source.id()) == SourceIdType::APP_ID) + return true; + for (const auto& url_info : source.urls()) { + if (GURL(url_info.url()).SchemeIs(kAppScheme)) + return true; + } + return false; + }); + // Purge data currently in the recordings intended for the next ukm::Report. - UkmRecorderImpl::PurgeExtensionRecordings(); + UkmRecorderImpl::PurgeRecordingsWithUrlScheme(kAppScheme); + UkmRecorderImpl::PurgeRecordingsWithSourceIdType(SourceIdType::APP_ID); } void UkmService::ResetClientState(ResetReason reason) {
diff --git a/components/ukm/ukm_service.h b/components/ukm/ukm_service.h index 3355ddf9..c34ca81 100644 --- a/components/ukm/ukm_service.h +++ b/components/ukm/ukm_service.h
@@ -80,14 +80,18 @@ void OnAppEnterForeground(); #endif - // Records any collected data into logs, and writes to disk. + // Records all collected data into logs, and writes to disk. void Flush(); - // Deletes any unsent local data. + // Deletes all unsent local data (Sources, Events, aggregate info for + // collected event metrics, etc.). void Purge(); - // Deletes any unsent local data related to Chrome extensions. - void PurgeExtensions(); + // Deletes all unsent local data related to Chrome extensions. + void PurgeExtensionsData(); + + // Deletes all unsent local data related to Apps. + void PurgeAppsData(); // Resets the client prefs (client_id/session_id). |reason| should be passed // to provide the reason of the reset - this is only used for UMA logging. @@ -134,6 +138,7 @@ TestRegisterUkmProvidersWhenUKMFeatureEnabled); FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, PurgeExtensionDataFromUnsentLogStore); + FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, PurgeAppDataFromUnsentLogStore); // Starts metrics client initialization. void StartInitTask();
diff --git a/components/ukm/ukm_service_unittest.cc b/components/ukm/ukm_service_unittest.cc index 9b26dd6..c1a834b 100644 --- a/components/ukm/ukm_service_unittest.cc +++ b/components/ukm/ukm_service_unittest.cc
@@ -310,7 +310,7 @@ unsent_log_store->StoreLog(serialized_log, log_metadata); // Do extension purging. - service.PurgeExtensions(); + service.PurgeExtensionsData(); // Get the Report in the log store and verify extension-related data have been // filtered. @@ -323,7 +323,7 @@ Report filtered_report; filtered_report.ParseFromString(uncompressed_log_data); - // Only proto_source_1 with non-extension URL is kept. + // Only proto_source_1 with non-extension URL is kept. EXPECT_EQ(1, filtered_report.sources_size()); EXPECT_EQ(source_id_1, filtered_report.sources(0).id()); EXPECT_EQ(non_extension_url, filtered_report.sources(0).urls(0).url()); @@ -333,6 +333,91 @@ EXPECT_EQ(source_id_1, filtered_report.entries(0).source_id()); } +TEST_F(UkmServiceTest, PurgeAppDataFromUnsentLogStore) { + UkmService service(&prefs_, &client_, + std::make_unique<MockDemographicMetricsProvider>()); + auto* unsent_log_store = service.reporting_service_.ukm_log_store(); + + // Initialize a Report to be saved to the log store. + Report report; + report.set_client_id(1); + report.set_session_id(1); + report.set_report_id(1); + + // A URL from browser navigation. + std::string non_app_url = "https://www.google.ca"; + // A URL with app:// scheme. + std::string app_url = "app://mgndgikekgjfcpckkfioiadnlibdjbkf"; + // OS Settings is an app on ChromeOS without the app:// scheme. + std::string os_settings_url = "chrome://os-settings"; + + // Add sources to the Report. + // Non-app source. + Source* proto_source_1 = report.add_sources(); + SourceId source_id_1 = ConvertToSourceId(1, SourceIdType::NAVIGATION_ID); + proto_source_1->set_id(source_id_1); + proto_source_1->add_urls()->set_url(non_app_url); + // App source with app:// URL. + Source* proto_source_2 = report.add_sources(); + SourceId source_id_2 = ConvertToSourceId(2, SourceIdType::APP_ID); + proto_source_2->set_id(source_id_2); + proto_source_2->add_urls()->set_url(app_url); + // App source with non-app:// URL. + Source* proto_source_3 = report.add_sources(); + SourceId source_id_3 = ConvertToSourceId(3, SourceIdType::APP_ID); + proto_source_3->set_id(source_id_3); + proto_source_3->add_urls()->set_url(os_settings_url); + // Non-app source with app:// URL. This shouldn't happen in practice, but + // if it does, this source should be purged when app data are purged. + Source* proto_source_4 = report.add_sources(); + SourceId source_id_4 = ConvertToSourceId(4, SourceIdType::NAVIGATION_ID); + proto_source_4->set_id(source_id_4); + proto_source_4->add_urls()->set_url(app_url); + + // Add entries to each of the sources. + Entry* entry_1 = report.add_entries(); + entry_1->set_source_id(source_id_2); + Entry* entry_2 = report.add_entries(); + entry_2->set_source_id(source_id_1); + Entry* entry_3 = report.add_entries(); + entry_3->set_source_id(source_id_2); + Entry* entry_4 = report.add_entries(); + entry_4->set_source_id(source_id_3); + Entry* entry_5 = report.add_entries(); + entry_5->set_source_id(source_id_4); + + // Save the Report to the store. + std::string serialized_log; + report.SerializeToString(&serialized_log); + // Make sure that the serialized ukm report can be parsed. + ASSERT_TRUE(UkmService::LogCanBeParsed(serialized_log)); + metrics::LogMetadata log_metadata; + unsent_log_store->StoreLog(serialized_log, log_metadata); + + // Do app data purging. + service.PurgeAppsData(); + + // Get the Report in the log store and verify app-related data have been + // filtered. + unsent_log_store->StageNextLog(); + const std::string& compressed_log_data = unsent_log_store->staged_log(); + + std::string uncompressed_log_data; + // TODO(crbug/1086910): Use the utilities in log_decoder.h instead. + compression::GzipUncompress(compressed_log_data, &uncompressed_log_data); + Report filtered_report; + filtered_report.ParseFromString(uncompressed_log_data); + + // Only proto_source_1 with non-app URL is kept. + EXPECT_EQ(1, filtered_report.sources_size()); + EXPECT_EQ(source_id_1, filtered_report.sources(0).id()); + EXPECT_EQ(non_app_url, filtered_report.sources(0).urls(0).url()); + + // Only entry_2 from the non-app source is kept. + EXPECT_EQ(1, filtered_report.entries_size()); + EXPECT_EQ(source_id_1, filtered_report.entries(0).source_id()); +} + TEST_F(UkmServiceTest, SourceSerialization) { UkmService service(&prefs_, &client_, std::make_unique<MockDemographicMetricsProvider>());
diff --git a/components/vector_icons/aggregate_vector_icons.py b/components/vector_icons/aggregate_vector_icons.py index 7239690..dbe60ad 100644 --- a/components/vector_icons/aggregate_vector_icons.py +++ b/components/vector_icons/aggregate_vector_icons.py
@@ -18,7 +18,7 @@ def Error(msg): - print >> sys.stderr, msg + print(msg, file=sys.stderr) sys.exit(1)
diff --git a/components/viz/service/debugger/viz_debugger_unittest.cc b/components/viz/service/debugger/viz_debugger_unittest.cc index da7bc01..7b35264 100644 --- a/components/viz/service/debugger/viz_debugger_unittest.cc +++ b/components/viz/service/debugger/viz_debugger_unittest.cc
@@ -122,9 +122,8 @@ EXPECT_TRUE(global_dict->is_dict()); - std::string str; - global_dict->FindKey("frame")->GetAsString(&str); - base::StringToUint64(str.c_str(), &counter_); + base::StringToUint64(global_dict->FindKey("frame")->GetString().c_str(), + &counter_); static const int kNoVal = -1; int expected_version = global_dict->FindKey("version")->GetIfInt().value_or(kNoVal); @@ -141,15 +140,9 @@ for (size_t i = 0; i < list_source->GetList().size(); i++) { auto&& local_dict = list_source->GetList()[i]; StaticSource ss; - local_dict.FindKey("file")->GetAsString(&str); - ss.file = str; - - local_dict.FindKey("func")->GetAsString(&str); - ss.func = str; - - local_dict.FindKey("anno")->GetAsString(&str); - ss.anno = str; - + ss.file = local_dict.FindKey("file")->GetString(); + ss.func = local_dict.FindKey("func")->GetString(); + ss.anno = local_dict.FindKey("anno")->GetString(); ss.line = local_dict.FindKey("line")->GetIfInt().value_or(kNoVal); ss.index = local_dict.FindKey("index")->GetIfInt().value_or(kNoVal); sources_.push_back(ss); @@ -164,14 +157,13 @@ *draw_index = dict.FindKey("drawindex")->GetIfInt().value_or(kNoVal); *source_index = dict.FindKey("source_index")->GetIfInt().value_or(kNoVal); - std::string str; const base::Value* option_dict = dict.FindDictKey("option"); - option_dict->FindKey("color")->GetAsString(&str); uint32_t red; uint32_t green; uint32_t blue; - std::sscanf(str.c_str(), "#%x%x%x", &red, &green, &blue); + std::sscanf(option_dict->FindKey("color")->GetString().c_str(), "#%x%x%x", + &red, &green, &blue); option->color_r = red; option->color_g = green; @@ -215,9 +207,6 @@ func_common_call(local_dict, &draw_index, &source_index, &option); - local_dict.FindKey("text")->GetAsString(&str); - std::string text_str = str; - const base::Value* list_pos = local_dict.FindListKey("pos"); EXPECT_TRUE(list_pos->is_list()); float pos_x = list_pos->GetList()[0].GetIfDouble().value_or(kNoVal); @@ -225,7 +214,7 @@ VizDebuggerInternal::DrawTextCall text_call( draw_index, source_index, option, gfx::Vector2dF(pos_x, pos_y), - text_str); + local_dict.FindKey("text")->GetString()); draw_text_calls_.push_back(text_call); } @@ -240,11 +229,9 @@ VizDebugger::DrawOption option; func_common_call(local_dict, &draw_index, &source_index, &option); - local_dict.FindKey("value")->GetAsString(&str); - std::string log_str = str; - - VizDebuggerInternal::LogCall log_call(draw_index, source_index, option, - log_str); + VizDebuggerInternal::LogCall log_call( + draw_index, source_index, option, + local_dict.FindKey("value")->GetString()); log_calls_.push_back(log_call); }
diff --git a/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java b/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java index e984d0b..b52308b 100644 --- a/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java +++ b/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java
@@ -32,6 +32,7 @@ import org.chromium.components.externalauth.ExternalAuthUtils; import org.chromium.components.externalauth.UserRecoverableErrorHandler; import org.chromium.content_public.browser.RenderFrameHost; +import org.chromium.content_public.browser.RenderFrameHost.WebAuthSecurityChecksResults; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsStatics; import org.chromium.net.GURLUtils; @@ -129,7 +130,7 @@ } public void handleGetAssertionRequest(PublicKeyCredentialRequestOptions options, - RenderFrameHost frameHost, Origin origin, GetAssertionResponseCallback callback, + RenderFrameHost frameHost, Origin callerOrigin, GetAssertionResponseCallback callback, FidoErrorResponseCallback errorCallback) { assert mGetAssertionCallback == null && mErrorCallback == null; mGetAssertionCallback = callback; @@ -146,10 +147,11 @@ return; } - int securityCheck = - frameHost.performGetAssertionWebAuthSecurityChecks(options.relyingPartyId, origin); - if (securityCheck != AuthenticatorStatus.SUCCESS) { - returnErrorAndResetCallback(securityCheck); + WebAuthSecurityChecksResults webAuthSecurityChecksResults = + frameHost.performGetAssertionWebAuthSecurityChecks( + options.relyingPartyId, callerOrigin); + if (webAuthSecurityChecksResults.securityCheckResult != AuthenticatorStatus.SUCCESS) { + returnErrorAndResetCallback(webAuthSecurityChecksResults.securityCheckResult); return; } @@ -164,7 +166,7 @@ BrowserPublicKeyCredentialRequestOptions browserRequestOptions = new BrowserPublicKeyCredentialRequestOptions.Builder() .setPublicKeyCredentialRequestOptions(getAssertionOptions) - .setOrigin(Uri.parse(convertOriginToString(origin))) + .setOrigin(Uri.parse(convertOriginToString(callerOrigin))) .build(); Task<PendingIntent> result = mFido2ApiClient.getSignPendingIntent(browserRequestOptions);
diff --git a/components/webcrypto/algorithms/ecdsa_unittest.cc b/components/webcrypto/algorithms/ecdsa_unittest.cc index dd1bf41..ba484e5 100644 --- a/components/webcrypto/algorithms/ecdsa_unittest.cc +++ b/components/webcrypto/algorithms/ecdsa_unittest.cc
@@ -114,7 +114,7 @@ // public key (WebCrypto doesn't provide a mechanism for importing a public // key given a private key). std::unique_ptr<base::DictionaryValue> key_jwk_copy(key_jwk->DeepCopy()); - key_jwk_copy->Remove("d", nullptr); + key_jwk_copy->RemoveKey("d"); blink::WebCryptoKey public_key; ASSERT_EQ( Status::Success(),
diff --git a/components/webcrypto/algorithms/hmac_unittest.cc b/components/webcrypto/algorithms/hmac_unittest.cc index 351184b..a23463f5 100644 --- a/components/webcrypto/algorithms/hmac_unittest.cc +++ b/components/webcrypto/algorithms/hmac_unittest.cc
@@ -387,7 +387,7 @@ extractable, usages, &key)); // Pass: JWK alg missing but input algorithm specified: use input value - dict.Remove("alg", nullptr); + dict.RemoveKey("alg"); EXPECT_EQ(Status::Success(), ImportKeyJwkFromDict(dict, CreateHmacImportAlgorithmNoLength(
diff --git a/components/webcrypto/algorithms/rsa_ssa_unittest.cc b/components/webcrypto/algorithms/rsa_ssa_unittest.cc index 03c09bf8..f2d8329 100644 --- a/components/webcrypto/algorithms/rsa_ssa_unittest.cc +++ b/components/webcrypto/algorithms/rsa_ssa_unittest.cc
@@ -716,7 +716,7 @@ base::DictionaryValue dict; RestoreJwkRsaDictionary(&dict); - dict.Remove("use", nullptr); + dict.RemoveKey("use"); dict.SetString("alg", "RS256"); for (size_t i = 0; i < base::size(bad_usages); ++i) { @@ -946,7 +946,7 @@ const std::string kKtyParmName[] = {"n", "e"}; for (size_t idx = 0; idx < base::size(kKtyParmName); ++idx) { // Fail on missing parameter. - dict.Remove(kKtyParmName[idx], nullptr); + dict.RemoveKey(kKtyParmName[idx]); EXPECT_NE(Status::Success(), ImportKeyJwkFromDict(dict, algorithm, false, usages, &key)); RestoreJwkRsaDictionary(&dict);
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 2494b56..99ce190e 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1587,8 +1587,6 @@ "renderer_host/policy_container_host.h", "renderer_host/policy_container_navigation_bundle.cc", "renderer_host/policy_container_navigation_bundle.h", - "renderer_host/raw_clipboard_host_impl.cc", - "renderer_host/raw_clipboard_host_impl.h", "renderer_host/recently_destroyed_hosts.cc", "renderer_host/recently_destroyed_hosts.h", "renderer_host/render_frame_host.cc",
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index 20496d9..a29f5e6 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc
@@ -38,7 +38,6 @@ #include "content/browser/renderer_host/media/media_devices_dispatcher_host.h" #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h" #include "content/browser/renderer_host/media/video_capture_host.h" -#include "content/browser/renderer_host/raw_clipboard_host_impl.h" #include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/service_worker/service_worker_host.h" @@ -995,8 +994,6 @@ map->Add<blink::mojom::ClipboardHost>( base::BindRepeating(&ClipboardHostImpl::Create)); - map->Add<blink::mojom::RawClipboardHost>( - base::BindRepeating(&RawClipboardHostImpl::Create)); map->Add<blink::mojom::SpeculationHost>( base::BindRepeating(&SpeculationHostImpl::Bind)); GetContentClient()->browser()->RegisterBrowserInterfaceBindersForFrame(host,
diff --git a/content/browser/devtools/network_service_devtools_observer.h b/content/browser/devtools/network_service_devtools_observer.h index 1533832..b062cbbc 100644 --- a/content/browser/devtools/network_service_devtools_observer.h +++ b/content/browser/devtools/network_service_devtools_observer.h
@@ -11,7 +11,7 @@ #include "content/browser/renderer_host/frame_tree_node.h" #include "content/common/content_export.h" #include "mojo/public/cpp/bindings/pending_remote.h" -#include "services/network/public/mojom/url_request.mojom.h" +#include "services/network/public/mojom/devtools_observer.mojom.h" namespace content {
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc index cafd2f0..ab082e4 100644 --- a/content/browser/devtools/protocol/network_handler.cc +++ b/content/browser/devtools/protocol/network_handler.cc
@@ -83,6 +83,7 @@ #include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/url_loader_completion_status.h" #include "services/network/public/mojom/client_security_state.mojom-shared.h" +#include "services/network/public/mojom/devtools_observer.mojom.h" #include "services/network/public/mojom/url_response_head.mojom.h" #include "third_party/blink/public/common/loader/referrer_utils.h" #include "third_party/blink/public/mojom/navigation/navigation_params.mojom.h"
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc index 72d22a315..2329bb0 100644 --- a/content/browser/navigation_browsertest.cc +++ b/content/browser/navigation_browsertest.cc
@@ -5789,6 +5789,12 @@ WaitForLoadStop(web_contents()); EXPECT_TRUE(child->anonymous()); EXPECT_TRUE(child->current_frame_host()->anonymous()); + // An anonymous document has a storage key with a nonce. + EXPECT_TRUE(child->current_frame_host()->storage_key().nonce().has_value()); + base::UnguessableToken anonymous_nonce = + current_frame_host()->GetPage().anonymous_iframes_nonce(); + EXPECT_EQ(anonymous_nonce, + child->current_frame_host()->storage_key().nonce().value()); // Create a grandchild iframe. EXPECT_TRUE(ExecJs( @@ -5804,6 +5810,12 @@ EXPECT_FALSE(grandchild->anonymous()); EXPECT_TRUE(grandchild->current_frame_host()->anonymous()); + // The storage key's nonce is the same for all anonymous documents in the same + // page. + EXPECT_TRUE(child->current_frame_host()->storage_key().nonce().has_value()); + EXPECT_EQ(anonymous_nonce, + child->current_frame_host()->storage_key().nonce().value()); + // Now navigate the grandchild iframe. EXPECT_TRUE(ExecJs( child, JsReplace("document.getElementById('grandchild_iframe').src = $1", @@ -5811,6 +5823,11 @@ WaitForLoadStop(web_contents()); EXPECT_TRUE(grandchild->current_frame_host()->anonymous()); + // The storage key's nonce is still the same. + EXPECT_TRUE(child->current_frame_host()->storage_key().nonce().has_value()); + EXPECT_EQ(anonymous_nonce, + child->current_frame_host()->storage_key().nonce().value()); + // Remove the 'anonymous' attribute from the iframe. This propagates to the // FrameTreeNode. The RenderFrameHost, however, is updated only on navigation. EXPECT_TRUE( @@ -5818,6 +5835,9 @@ "document.getElementById('test_iframe').anonymous = false;")); EXPECT_FALSE(child->anonymous()); EXPECT_TRUE(child->current_frame_host()->anonymous()); + EXPECT_TRUE(child->current_frame_host()->storage_key().nonce().has_value()); + EXPECT_EQ(anonymous_nonce, + child->current_frame_host()->storage_key().nonce().value()); // Create another grandchild iframe. Even if the parent iframe element does // not have the 'anonymous' attribute anymore, the grandchild document is @@ -5831,6 +5851,10 @@ FrameTreeNode* grandchild2 = child->child_at(1); EXPECT_FALSE(grandchild2->anonymous()); EXPECT_TRUE(grandchild2->current_frame_host()->anonymous()); + EXPECT_TRUE( + grandchild2->current_frame_host()->storage_key().nonce().has_value()); + EXPECT_EQ(anonymous_nonce, + grandchild2->current_frame_host()->storage_key().nonce().value()); // Navigate the child iframe. Since the iframe element does not set the // 'anonymous' attribute, the resulting RenderFrameHost will not be anonymous. @@ -5841,6 +5865,27 @@ WaitForLoadStop(web_contents()); EXPECT_FALSE(child->anonymous()); EXPECT_FALSE(child->current_frame_host()->anonymous()); + EXPECT_FALSE(child->current_frame_host()->storage_key().nonce().has_value()); + + // Now navigate the whole page away. + GURL main_url_b = embedded_test_server()->GetURL( + "b.com", "/page_with_anonymous_iframe.html"); + GURL iframe_url_b = embedded_test_server()->GetURL("b.com", "/title1.html"); + EXPECT_TRUE(NavigateToURL(shell(), main_url_b)); + + // The main page has an anonymous child iframe with url `iframe_url_b`. + EXPECT_EQ(1U, main_frame()->child_count()); + FrameTreeNode* child_b = main_frame()->child_at(0); + EXPECT_EQ(iframe_url_b, child_b->current_url()); + EXPECT_TRUE(child_b->anonymous()); + EXPECT_TRUE(child_b->current_frame_host()->anonymous()); + + EXPECT_TRUE(child_b->current_frame_host()->storage_key().nonce().has_value()); + base::UnguessableToken anonymous_nonce_b = + current_frame_host()->GetPage().anonymous_iframes_nonce(); + EXPECT_NE(anonymous_nonce, anonymous_nonce_b); + EXPECT_EQ(anonymous_nonce_b, + child_b->current_frame_host()->storage_key().nonce().value()); } } // namespace content
diff --git a/content/browser/prerender/prerender_browsertest.cc b/content/browser/prerender/prerender_browsertest.cc index 3100266..41daf72 100644 --- a/content/browser/prerender/prerender_browsertest.cc +++ b/content/browser/prerender/prerender_browsertest.cc
@@ -47,6 +47,7 @@ #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/test/back_forward_cache_util.h" +#include "content/public/test/background_color_change_waiter.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" @@ -57,6 +58,7 @@ #include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_navigation_throttle.h" #include "content/public/test/test_utils.h" +#include "content/public/test/theme_change_waiter.h" #include "content/shell/browser/shell.h" #include "content/shell/browser/shell_content_browser_client.h" #include "content/test/content_browser_test_utils_internal.h" @@ -80,6 +82,8 @@ #include "ui/shell_dialogs/select_file_dialog_factory.h" #include "url/gurl.h" +using ::testing::Exactly; + namespace content { namespace { @@ -3707,5 +3711,75 @@ ukm::builders::PrerenderPageLoad::kTriggeredPrerenderName, 1); } +// Tests that background color in a prerendered page does not affect +// the primary page. +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ColorSchemeDarkInNonPrimaryPage) { + const GURL kInitialUrl = GetUrl("/empty.html"); + const GURL kPrerenderingUrl = GetUrl("/color-scheme-dark.html"); + + // Expect initial page background color to be white. + content::BackgroundColorChangeWaiter empty_page_background_waiter( + web_contents()); + + // Navigate to an initial page. + ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); + // Wait for the page background to change to white. + empty_page_background_waiter.Wait(); + + { + // Now set up a mock observer for BackgroundColorChanged, to test if the + // mocked observer executes BackgroundColorChanged for the prerendered page. + testing::NiceMock<MockWebContentsObserver> background_color_observer( + web_contents()); + EXPECT_CALL(background_color_observer, OnBackgroundColorChanged()) + .Times(Exactly(0)); + + AddPrerender(kPrerenderingUrl); + } + + content::BackgroundColorChangeWaiter prerendered_page_background_waiter( + web_contents()); + // Now set up a mock observer for BackgroundColorChanged, to test if the + // mocked observer executes BackgroundColorChanged when activating the + // prerendered page. + testing::NiceMock<MockWebContentsObserver> background_color_observer( + web_contents()); + EXPECT_CALL(background_color_observer, OnBackgroundColorChanged()) + .Times(Exactly(1)); + NavigatePrimaryPage(kPrerenderingUrl); + ASSERT_EQ(web_contents()->GetURL(), kPrerenderingUrl); + // Wait for the page background to change. + prerendered_page_background_waiter.Wait(); +} + +// Tests that theme color in a prerendered page does not affect +// the primary page. +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, + ThemeColorSchemeChangeInNonPrimaryPage) { + const GURL kInitialUrl = GetUrl("/empty.html"); + const GURL kPrerenderingUrl = GetUrl("/theme_color.html"); + + // Navigate to an initial page. + ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); + + { + // Now set up a mock observer for DidChangeThemeColor, to test if the + // mocked observer executes DidChangeThemeColor for the prerendered page. + testing::NiceMock<MockWebContentsObserver> theme_color_observer( + web_contents()); + EXPECT_CALL(theme_color_observer, DidChangeThemeColor()).Times(Exactly(0)); + + AddPrerender(kPrerenderingUrl); + } + + content::ThemeChangeWaiter theme_change_waiter(web_contents()); + testing::NiceMock<MockWebContentsObserver> theme_color_observer( + web_contents()); + EXPECT_CALL(theme_color_observer, DidChangeThemeColor()).Times(Exactly(1)); + + NavigatePrimaryPage(kPrerenderingUrl); + ASSERT_EQ(web_contents()->GetURL(), kPrerenderingUrl); + theme_change_waiter.Wait(); +} } // namespace } // namespace content
diff --git a/content/browser/renderer_host/cookie_utils.cc b/content/browser/renderer_host/cookie_utils.cc index ebdc561..28c97969 100644 --- a/content/browser/renderer_host/cookie_utils.cc +++ b/content/browser/renderer_host/cookie_utils.cc
@@ -97,6 +97,8 @@ bool samesite_none_cookie_included_by_samesite_lax = false; bool samesite_none_cookie_included_by_samesite_strict = false; + bool samesite_cookie_inclusion_changed_by_cross_site_redirect = false; + for (const network::mojom::CookieOrLineWithAccessResultPtr& cookie : cookie_details->cookie_list) { if (ShouldReportDevToolsIssueForStatus(cookie->access_result.status)) { @@ -171,6 +173,12 @@ status.HasWarningReason( net::CookieInclusionStatus:: WARN_SAMESITE_NONE_INCLUDED_BY_SAMESITE_STRICT); + + samesite_cookie_inclusion_changed_by_cross_site_redirect = + samesite_cookie_inclusion_changed_by_cross_site_redirect || + status.HasWarningReason( + net::CookieInclusionStatus:: + WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION); } breaking_context_downgrade = @@ -244,6 +252,12 @@ GetContentClient()->browser()->LogWebFeatureForCurrentPage( rfh, blink::mojom::WebFeature::kSameSiteNoneIncludedBySameSiteStrict); } + + if (samesite_cookie_inclusion_changed_by_cross_site_redirect) { + GetContentClient()->browser()->LogWebFeatureForCurrentPage( + rfh, blink::mojom::WebFeature:: + kSameSiteCookieInclusionChangedByCrossSiteRedirect); + } } } // namespace content
diff --git a/content/browser/renderer_host/page_impl.h b/content/browser/renderer_host/page_impl.h index 55459a2..fa698387 100644 --- a/content/browser/renderer_host/page_impl.h +++ b/content/browser/renderer_host/page_impl.h
@@ -88,6 +88,10 @@ return last_main_document_source_id_; } + const base::UnguessableToken& anonymous_iframes_nonce() const { + return anonymous_iframes_nonce_; + } + private: // This method is needed to ensure that PageImpl can both implement a Page's // method and define a new GetMainDocument(). Please refer to page.h for more @@ -146,6 +150,11 @@ // This page is owned by the RenderFrameHostImpl, which in turn does not // outlive the delegate (the contents). PageDelegate& delegate_; + + // Nonce to be used for initializing the storage key and the network isolation + // key of anonymous iframes which are children of this page's document. + const base::UnguessableToken anonymous_iframes_nonce_ = + base::UnguessableToken::Create(); }; } // namespace content
diff --git a/content/browser/renderer_host/raw_clipboard_host_impl.cc b/content/browser/renderer_host/raw_clipboard_host_impl.cc deleted file mode 100644 index fd95a16..0000000 --- a/content/browser/renderer_host/raw_clipboard_host_impl.cc +++ /dev/null
@@ -1,186 +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 "content/browser/renderer_host/raw_clipboard_host_impl.h" - -#include <memory> - -#include "base/bind.h" -#include "base/containers/contains.h" -#include "base/i18n/number_formatting.h" -#include "base/memory/ptr_util.h" -#include "content/browser/permissions/permission_controller_impl.h" -#include "content/browser/renderer_host/clipboard_host_impl.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/common/child_process_host.h" -#include "ipc/ipc_message.h" -#include "mojo/public/cpp/bindings/self_owned_receiver.h" -#include "third_party/blink/public/common/features.h" -#include "third_party/blink/public/mojom/clipboard/raw_clipboard.mojom.h" -#include "third_party/blink/public/mojom/permissions/permission_status.mojom-shared.h" -#include "ui/base/clipboard/clipboard.h" -#include "ui/base/clipboard/clipboard_format_type.h" -#include "ui/base/clipboard/scoped_clipboard_writer.h" -#include "ui/base/data_transfer_policy/data_transfer_endpoint.h" - -namespace content { - -void RawClipboardHostImpl::Create( - RenderFrameHost* render_frame_host, - mojo::PendingReceiver<blink::mojom::RawClipboardHost> receiver) { - DCHECK(render_frame_host); - - // Feature flags and permission should already be checked in the renderer - // process, but recheck in the browser process in case of a hijacked renderer. - if (!base::FeatureList::IsEnabled(blink::features::kRawClipboard)) { - mojo::ReportBadMessage("Raw Clipboard is not enabled."); - return; - } - - // Renderer process should already check for user activation before sending - // this request. Double check in case of compromised renderer. - if (!render_frame_host->HasTransientUserActivation()) { - // mojo::ReportBadMessage() is not appropriate here, because user - // activation may expire after the renderer check but before the browser - // check. - return; - } - - PermissionControllerImpl* permission_controller = - PermissionControllerImpl::FromBrowserContext( - render_frame_host->GetProcess()->GetBrowserContext()); - - blink::mojom::PermissionStatus status = - permission_controller->GetPermissionStatusForFrame( - PermissionType::CLIPBOARD_READ_WRITE, render_frame_host, - render_frame_host->GetLastCommittedOrigin().GetURL()); - - if (status != blink::mojom::PermissionStatus::GRANTED) { - // mojo::ReportBadMessage() is not appropriate here because the permission - // may be granted after the renderer check, but revoked before the browser - // check. - return; - } - - mojo::MakeSelfOwnedReceiver( - base::WrapUnique(new RawClipboardHostImpl( - static_cast<RenderFrameHostImpl*>(render_frame_host))), - std::move(receiver)); -} - -RawClipboardHostImpl::~RawClipboardHostImpl() { - clipboard_writer_->Reset(); -} - -RawClipboardHostImpl::RawClipboardHostImpl(RenderFrameHost* render_frame_host) - : render_frame_routing_id_( - GlobalRenderFrameHostId(render_frame_host->GetProcess()->GetID(), - render_frame_host->GetRoutingID())), - clipboard_writer_( - new ui::ScopedClipboardWriter(ui::ClipboardBuffer::kCopyPaste, - CreateDataEndpoint())) { - DCHECK(render_frame_host); -} - -void RawClipboardHostImpl::ReadAvailableFormatNames( - ReadAvailableFormatNamesCallback callback) { - if (!HasTransientUserActivation()) - return; - std::vector<std::u16string> raw_types = - ui::Clipboard::GetForCurrentThread() - ->ReadAvailablePlatformSpecificFormatNames( - ui::ClipboardBuffer::kCopyPaste, CreateDataEndpoint().get()); - std::move(callback).Run(raw_types); -} - -void RawClipboardHostImpl::Read(const std::u16string& format, - ReadCallback callback) { - if (!HasTransientUserActivation()) - return; - if (format.size() >= kMaxFormatSize) { - mojo::ReportBadMessage("Requested format string length too long."); - return; - } - - std::string result; - ui::Clipboard::GetForCurrentThread()->ReadData( - ui::ClipboardFormatType::GetType(base::UTF16ToUTF8(format)), - CreateDataEndpoint().get(), &result); - base::span<const uint8_t> span( - reinterpret_cast<const uint8_t*>(result.data()), result.size()); - mojo_base::BigBuffer buffer = mojo_base::BigBuffer(span); - std::move(callback).Run(std::move(buffer)); -} - -void RawClipboardHostImpl::Write(const std::u16string& format, - mojo_base::BigBuffer data) { - if (!HasTransientUserActivation()) - return; - if (format.size() >= kMaxFormatSize) { - mojo::ReportBadMessage("Target format string length too long."); - return; - } - if (data.size() >= kMaxDataSize) { - mojo::ReportBadMessage("Write data too large."); - return; - } - - // Windows / X11 clipboards enter an unrecoverable state after registering - // some amount of unique formats, and there's no way to un-register these - // formats. For these clipboards, use a conservative limit to avoid - // registering too many formats, as: - // (1) Other native applications may also register clipboard formats. - // (2) |registered_formats| only persists over one Chrome Clipboard session. - // (3) Chrome also registers other clipboard formats. - // - // The limit is based on Windows, which has the smallest limit, at 0x4000. - // Windows represents clipboard formats using values in 0xC000 - 0xFFFF. - // Therefore, Windows supports at most 0x4000 registered formats. Reference: - // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclipboardformata - static constexpr int kMaxWindowsClipboardFormats = 0x4000; - static constexpr int kMaxRegisteredFormats = kMaxWindowsClipboardFormats / 4; - static base::NoDestructor<std::set<std::u16string>> registered_formats; - if (!base::Contains(*registered_formats, format)) { - if (registered_formats->size() >= kMaxRegisteredFormats) - return; - registered_formats->emplace(format); - } - - clipboard_writer_->WriteData(format, std::move(data)); -} - -void RawClipboardHostImpl::CommitWrite() { - clipboard_writer_ = std::make_unique<ui::ScopedClipboardWriter>( - ui::ClipboardBuffer::kCopyPaste, CreateDataEndpoint()); -} - -std::unique_ptr<ui::DataTransferEndpoint> -RawClipboardHostImpl::CreateDataEndpoint() { - RenderFrameHostImpl* render_frame_host = - RenderFrameHostImpl::FromID(render_frame_routing_id_); - if (!render_frame_host || - render_frame_host->GetBrowserContext()->IsOffTheRecord()) - return nullptr; - - return std::make_unique<ui::DataTransferEndpoint>( - render_frame_host->GetLastCommittedOrigin(), - render_frame_host->HasTransientUserActivation()); -} - -bool RawClipboardHostImpl::HasTransientUserActivation() const { - RenderFrameHostImpl* render_frame_host = - RenderFrameHostImpl::FromID(render_frame_routing_id_); - if (!render_frame_host) - return false; - - // Renderer process should already check for user activation before sending - // this request. Double check in case of compromised renderer. - // mojo::ReportBadMessage() is not appropriate here, because user activation - // may expire after the renderer check but before the browser check. - return render_frame_host->HasTransientUserActivation(); -} - -} // namespace content
diff --git a/content/browser/renderer_host/raw_clipboard_host_impl.h b/content/browser/renderer_host/raw_clipboard_host_impl.h deleted file mode 100644 index c3723ce..0000000 --- a/content/browser/renderer_host/raw_clipboard_host_impl.h +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_RENDERER_HOST_RAW_CLIPBOARD_HOST_IMPL_H_ -#define CONTENT_BROWSER_RENDERER_HOST_RAW_CLIPBOARD_HOST_IMPL_H_ - -#include "content/browser/renderer_host/render_frame_host_impl.h" -#include "mojo/public/cpp/base/big_buffer.h" -#include "mojo/public/cpp/bindings/receiver.h" -#include "third_party/blink/public/mojom/clipboard/raw_clipboard.mojom.h" -#include "ui/base/clipboard/clipboard.h" - -namespace ui { -class ScopedClipboardWriter; -} // namespace ui - -namespace content { - -class RenderFrameHost; - -// Instances destroy themselves when the blink::mojom::RawClipboardHost is -// disconnected, and this can only be used on the frame and sequence it's -// created on. -class CONTENT_EXPORT RawClipboardHostImpl - : public blink::mojom::RawClipboardHost { - public: - static void Create( - RenderFrameHost* render_frame_host, - mojo::PendingReceiver<blink::mojom::RawClipboardHost> receiver); - RawClipboardHostImpl(const RawClipboardHostImpl&) = delete; - RawClipboardHostImpl& operator=(const RawClipboardHostImpl&) = delete; - ~RawClipboardHostImpl() override; - - private: - explicit RawClipboardHostImpl(RenderFrameHost* render_frame_host); - - // mojom::RawClipboardHost. - void ReadAvailableFormatNames( - ReadAvailableFormatNamesCallback callback) override; - void Read(const std::u16string& format, ReadCallback callback) override; - void Write(const std::u16string& format, mojo_base::BigBuffer data) override; - void CommitWrite() override; - - std::unique_ptr<ui::DataTransferEndpoint> CreateDataEndpoint(); - bool HasTransientUserActivation() const; - - // The render frame is not owned. - const GlobalRenderFrameHostId render_frame_routing_id_; - - std::unique_ptr<ui::ScopedClipboardWriter> clipboard_writer_; -}; - -} // namespace content - -#endif // CONTENT_BROWSER_RENDERER_HOST_RAW_CLIPBOARD_HOST_IMPL_H_
diff --git a/content/browser/renderer_host/render_frame_host_android.cc b/content/browser/renderer_host/render_frame_host_android.cc index aa3b7ed..acf1c40a 100644 --- a/content/browser/renderer_host/render_frame_host_android.cc +++ b/content/browser/renderer_host/render_frame_host_android.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/android/callback_android.h" +#include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/android/unguessable_token_android.h" #include "base/bind.h" @@ -186,15 +187,18 @@ return render_frame_host_->GetProcess()->IsBlocked(); } -jint RenderFrameHostAndroid::PerformGetAssertionWebAuthSecurityChecks( +ScopedJavaLocalRef<jobject> +RenderFrameHostAndroid::PerformGetAssertionWebAuthSecurityChecks( JNIEnv* env, const base::android::JavaParamRef<jobject>&, const base::android::JavaParamRef<jstring>& relying_party_id, const base::android::JavaParamRef<jobject>& effective_origin) const { url::Origin origin = url::Origin::FromJavaObject(effective_origin); - return static_cast<int32_t>( + std::pair<blink::mojom::AuthenticatorStatus, bool> results = render_frame_host_->PerformGetAssertionWebAuthSecurityChecks( - ConvertJavaStringToUTF8(env, relying_party_id), origin)); + ConvertJavaStringToUTF8(env, relying_party_id), origin); + return Java_RenderFrameHostImpl_createWebAuthSecurityChecksResults( + env, static_cast<jint>(results.first), results.second); } jint RenderFrameHostAndroid::PerformMakeCredentialWebAuthSecurityChecks(
diff --git a/content/browser/renderer_host/render_frame_host_android.h b/content/browser/renderer_host/render_frame_host_android.h index d847f5b..1bc7a70 100644 --- a/content/browser/renderer_host/render_frame_host_android.h +++ b/content/browser/renderer_host/render_frame_host_android.h
@@ -77,7 +77,8 @@ jboolean IsProcessBlocked(JNIEnv* env, const base::android::JavaParamRef<jobject>&) const; - jint PerformGetAssertionWebAuthSecurityChecks( + base::android::ScopedJavaLocalRef<jobject> + PerformGetAssertionWebAuthSecurityChecks( JNIEnv* env, const base::android::JavaParamRef<jobject>&, const base::android::JavaParamRef<jstring>&,
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 461d3c2a..d022018 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -3503,7 +3503,6 @@ void RenderFrameHostImpl::SetLastCommittedOrigin(const url::Origin& origin) { last_committed_origin_ = origin; - SetStorageKey(blink::StorageKey(origin)); } void RenderFrameHostImpl::SetLastCommittedOriginForTesting( @@ -3623,6 +3622,14 @@ new_frame_origin, net::IsolationInfo::RequestType::kOther); SetLastCommittedOrigin(new_frame_origin); + // TODO(https://crbug.com/1199077): Initialize the StorageKey also with the + // top frame origin. + SetStorageKey(anonymous() + ? blink::StorageKey::CreateWithNonce( + new_frame_origin, + GetMainFrame()->GetPage().anonymous_iframes_nonce()) + : blink::StorageKey(new_frame_origin)); + // Apply private network request policy according to our new origin. if (GetContentClient()->browser()->ShouldAllowInsecurePrivateNetworkRequests( GetBrowserContext(), new_frame_origin)) { @@ -10115,6 +10122,15 @@ required_csp_ = navigation_request->TakeRequiredCSP(); anonymous_ = navigation_request->anonymous(); + // TODO(https://crbug.com/1199077): Initialize the StorageKey also with the + // top frame origin. + blink::StorageKey storage_key_to_commit = + anonymous() ? blink::StorageKey::CreateWithNonce( + GetLastCommittedOrigin(), + GetMainFrame()->GetPage().anonymous_iframes_nonce()) + : blink::StorageKey(GetLastCommittedOrigin()); + SetStorageKey(storage_key_to_commit); + coep_reporter_ = navigation_request->TakeCoepReporter(); if (coep_reporter_) { mojo::PendingRemote<blink::mojom::ReportingObserver> remote; @@ -11520,27 +11536,23 @@ frame_tree_node_->SetIsAdSubframe(is_ad_subframe); } -blink::mojom::AuthenticatorStatus +std::pair<blink::mojom::AuthenticatorStatus, bool> RenderFrameHostImpl::PerformGetAssertionWebAuthSecurityChecks( const std::string& relying_party_id, const url::Origin& effective_origin) { - bool is_cross_origin; + bool is_cross_origin = true; // Will be reset in ValidateAncestorOrigins(). blink::mojom::AuthenticatorStatus status = GetWebAuthRequestSecurityChecker()->ValidateAncestorOrigins( effective_origin, WebAuthRequestSecurityChecker::RequestType::kGetAssertion, &is_cross_origin); if (status != blink::mojom::AuthenticatorStatus::SUCCESS) { - return status; + return std::make_pair(status, is_cross_origin); } status = GetWebAuthRequestSecurityChecker()->ValidateDomainAndRelyingPartyID( effective_origin, relying_party_id); - if (status != blink::mojom::AuthenticatorStatus::SUCCESS) { - return status; - } - - return blink::mojom::AuthenticatorStatus::SUCCESS; + return std::make_pair(status, is_cross_origin); } blink::mojom::AuthenticatorStatus
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index 02376a0e..f34a0c2 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -392,7 +392,8 @@ bool Reload() override; bool IsDOMContentLoaded() override; void UpdateIsAdSubframe(bool is_ad_subframe) override; - blink::mojom::AuthenticatorStatus PerformGetAssertionWebAuthSecurityChecks( + std::pair<blink::mojom::AuthenticatorStatus, bool> + PerformGetAssertionWebAuthSecurityChecks( const std::string& relying_party_id, const url::Origin& effective_origin) override; blink::mojom::AuthenticatorStatus PerformMakeCredentialWebAuthSecurityChecks(
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc index 0effa4a..f748b76b 100644 --- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -5840,4 +5840,40 @@ EXPECT_FALSE(main_rfh->child_at(0)->anonymous()); } +// Check that a page's anonymous_iframes_nonce is re-initialized after +// navigations. +IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, + NewAnonymousNonceOnNavigation) { + GURL main_url = embedded_test_server()->GetURL("/title1.html"); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + + base::UnguessableToken first_nonce = + web_contents()->GetMainFrame()->GetPage().anonymous_iframes_nonce(); + EXPECT_TRUE(first_nonce); + + // Same-document navigation does not change the nonce. + EXPECT_TRUE(NavigateToURL(shell(), main_url.Resolve("#here"))); + EXPECT_EQ( + first_nonce, + web_contents()->GetMainFrame()->GetPage().anonymous_iframes_nonce()); + + // Cross-document same-site navigation creates a new nonce. + EXPECT_TRUE( + NavigateToURL(shell(), embedded_test_server()->GetURL("/title2.html"))); + base::UnguessableToken second_nonce = + web_contents()->GetMainFrame()->GetPage().anonymous_iframes_nonce(); + EXPECT_TRUE(second_nonce); + EXPECT_NE(first_nonce, second_nonce); + + // Cross-document cross-site navigation creates a new nonce. + EXPECT_TRUE(NavigateToURL( + shell(), embedded_test_server()->GetURL("b.com", "/title1.html"))); + EXPECT_NE( + first_nonce, + web_contents()->GetMainFrame()->GetPage().anonymous_iframes_nonce()); + EXPECT_NE( + second_nonce, + web_contents()->GetMainFrame()->GetPage().anonymous_iframes_nonce()); +} + } // namespace content
diff --git a/content/browser/renderer_host/render_frame_host_impl_unittest.cc b/content/browser/renderer_host/render_frame_host_impl_unittest.cc index a0aa59c0..a908830 100644 --- a/content/browser/renderer_host/render_frame_host_impl_unittest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_unittest.cc
@@ -301,9 +301,11 @@ content::RenderFrameHostTester::For(main_test_rfh()) ->AppendChild("child")); EXPECT_FALSE(child_frame->anonymous()); + EXPECT_FALSE(child_frame->storage_key().nonce().has_value()); child_frame->frame_tree_node()->set_anonymous(true); EXPECT_FALSE(child_frame->anonymous()); + EXPECT_FALSE(child_frame->storage_key().nonce().has_value()); // A navigation in the anonymous iframe commits an anonymous RFH. std::unique_ptr<NavigationSimulator> navigation = @@ -313,12 +315,18 @@ child_frame = static_cast<TestRenderFrameHost*>(navigation->GetFinalRenderFrameHost()); EXPECT_TRUE(child_frame->anonymous()); + EXPECT_TRUE(child_frame->storage_key().nonce().has_value()); // A child of an anonymous RFH is anonymous. auto* grandchild_frame = static_cast<TestRenderFrameHost*>( content::RenderFrameHostTester::For(child_frame) ->AppendChild("grandchild")); EXPECT_TRUE(grandchild_frame->anonymous()); + EXPECT_TRUE(child_frame->storage_key().nonce().has_value()); + + // The two anonymous RFH's storage keys should have the same nonce. + EXPECT_EQ(child_frame->storage_key().nonce().value(), + grandchild_frame->storage_key().nonce().value()); } } // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 2e65349..93d2c89 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2027,6 +2027,8 @@ // Ask the RWH to drop reference to us. host()->ViewDestroyed(); + // Dismiss any visible touch selection handles or touch selection menu. + selection_controller_->HideAndDisallowShowingAutomatically(); selection_controller_.reset(); selection_controller_client_.reset();
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index adc1a591..2e36ccb 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -5517,17 +5517,23 @@ RenderFrameHostImpl* render_frame_host, const LoadCommittedDetails& details, const mojom::DidCommitProvisionalLoadParams& params) { + // The render_frame_host is always a main frame. + DCHECK(render_frame_host->is_main_frame()); OPTIONAL_TRACE_EVENT1("content,navigation", "WebContentsImpl::DidNavigateMainFramePostCommit", "render_frame_host", render_frame_host); + bool is_primary_main_frame = render_frame_host->IsInPrimaryMainFrame(); + if (details.is_navigation_to_different_page()) { - // Clear the status bubble. This is a workaround for a bug where WebKit - // doesn't let us know that the cursor left an element during a - // transition (this is also why the mouse cursor remains as a hand after - // clicking on a link); see bugs 1184641 and 980803. We don't want to - // clear the bubble when a user navigates to a named anchor in the same - // page. - ClearTargetURL(); + if (is_primary_main_frame) { + // Clear the status bubble. This is a workaround for a bug where WebKit + // doesn't let us know that the cursor left an element during a + // transition (this is also why the mouse cursor remains as a hand after + // clicking on a link); see bugs 1184641 and 980803. We don't want to + // clear the bubble when a user navigates to a named anchor in the same + // page. + ClearTargetURL(); + } RenderWidgetHostViewBase* rwhvb = static_cast<RenderWidgetHostViewBase*>( render_frame_host->GetMainFrame()->GetView()); @@ -5535,8 +5541,8 @@ rwhvb->OnDidNavigateMainFrameToNewPage(); } - if (delegate_) - delegate_->DidNavigateMainFramePostCommit(this); + if (is_primary_main_frame && delegate_) + delegate_->DidNavigatePrimaryMainFramePostCommit(this); PageImpl& page = render_frame_host->GetPage(); if (page.IsPrimary()) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostImpl.java b/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostImpl.java index 1f69627..2fb410ec 100644 --- a/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostImpl.java
@@ -176,14 +176,23 @@ } @Override - public int performGetAssertionWebAuthSecurityChecks( + public WebAuthSecurityChecksResults performGetAssertionWebAuthSecurityChecks( String relyingPartyId, Origin effectiveOrigin) { - if (mNativeRenderFrameHostAndroid == 0) return AuthenticatorStatus.UNKNOWN_ERROR; + if (mNativeRenderFrameHostAndroid == 0) { + return new WebAuthSecurityChecksResults( + AuthenticatorStatus.UNKNOWN_ERROR, false /*unused*/); + } return RenderFrameHostImplJni.get().performGetAssertionWebAuthSecurityChecks( mNativeRenderFrameHostAndroid, RenderFrameHostImpl.this, relyingPartyId, effectiveOrigin); } + @CalledByNative + private static WebAuthSecurityChecksResults createWebAuthSecurityChecksResults( + @AuthenticatorStatus.EnumType int securityCheckResult, boolean isCrossOrigin) { + return new WebAuthSecurityChecksResults(securityCheckResult, isCrossOrigin); + } + @Override public int performMakeCredentialWebAuthSecurityChecks( String relyingPartyId, Origin effectiveOrigin, boolean isPaymentCredentialCreation) { @@ -226,8 +235,9 @@ void terminateRendererDueToBadMessage( long nativeRenderFrameHostAndroid, RenderFrameHostImpl caller, int reason); boolean isProcessBlocked(long nativeRenderFrameHostAndroid, RenderFrameHostImpl caller); - int performGetAssertionWebAuthSecurityChecks(long nativeRenderFrameHostAndroid, - RenderFrameHostImpl caller, String relyingPartyId, Origin effectiveOrigin); + WebAuthSecurityChecksResults performGetAssertionWebAuthSecurityChecks( + long nativeRenderFrameHostAndroid, RenderFrameHostImpl caller, + String relyingPartyId, Origin effectiveOrigin); int performMakeCredentialWebAuthSecurityChecks(long nativeRenderFrameHostAndroid, RenderFrameHostImpl caller, String relyingPartyId, Origin effectiveOrigin, boolean isPaymentCredentialCreation);
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/RenderFrameHost.java b/content/public/android/java/src/org/chromium/content_public/browser/RenderFrameHost.java index c4cbf2f..503e8cb 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/RenderFrameHost.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/RenderFrameHost.java
@@ -7,6 +7,7 @@ import androidx.annotation.Nullable; import org.chromium.base.Callback; +import org.chromium.blink.mojom.AuthenticatorStatus; import org.chromium.mojo.bindings.Interface; import org.chromium.url.GURL; import org.chromium.url.Origin; @@ -15,6 +16,25 @@ * The RenderFrameHost Java wrapper to allow communicating with the native RenderFrameHost object. */ public interface RenderFrameHost { + /** The results of {@link #GetAssertionWebAuthSecurityChecks}. */ + final class WebAuthSecurityChecksResults { + public final boolean isCrossOrigin; + public final @AuthenticatorStatus.EnumType int securityCheckResult; + + /** + * Creates an instance of this class. + * @param securityCheckResult The status code indicating the result of the GetAssertion + * request security checks. + * @param isCrossOrigin Whether the given origin is cross-origin with any frame in the + * current frame's ancestor chain. + */ + public WebAuthSecurityChecksResults( + @AuthenticatorStatus.EnumType int securityCheckResult, boolean isCrossOrigin) { + this.securityCheckResult = securityCheckResult; + this.isCrossOrigin = isCrossOrigin; + } + } + /** * Get the last committed URL of the frame. * @@ -112,9 +132,12 @@ * therefore have to provide its own effective origin. The return value is a code corresponding * to the AuthenticatorStatus mojo enum. * - * @return Status code indicating the result of the GetAssertion request security checks. + * @return An object containing (1) the status code indicating the result of the GetAssertion + * request security checks. (2) whether the effectiveOrigin is a cross-origin with any + * frame in this frame's ancestor chain. */ - int performGetAssertionWebAuthSecurityChecks(String relyingPartyId, Origin effectiveOrigin); + WebAuthSecurityChecksResults performGetAssertionWebAuthSecurityChecks( + String relyingPartyId, Origin effectiveOrigin); /** * Runs security checks associated with a Web Authentication MakeCredential request for the
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h index fd1e113a..8527109c2 100644 --- a/content/public/browser/render_frame_host.h +++ b/content/public/browser/render_frame_host.h
@@ -6,6 +6,7 @@ #define CONTENT_PUBLIC_BROWSER_RENDER_FRAME_HOST_H_ #include <string> +#include <utility> #include <vector> #include "base/callback_forward.h" @@ -879,7 +880,11 @@ // from the browser process, this may be different. // |is_payment_credential_creation| indicates whether MakeCredential is making // a payment credential. - virtual blink::mojom::AuthenticatorStatus + // |PerformGetAssertionWebAuthSecurityChecks| returns a security check result + // and a boolean representing whether the given origin is cross-origin with + // any frame in this frame's ancestor chain. This extra cross-origin bit is + // relevant in case callers need it for crypto signature. + virtual std::pair<blink::mojom::AuthenticatorStatus, bool> PerformGetAssertionWebAuthSecurityChecks( const std::string& relying_party_id, const url::Origin& effective_origin) = 0;
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index 0574d39..7d1575f 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h
@@ -388,8 +388,8 @@ virtual void RendererResponsive(WebContents* source, RenderWidgetHost* render_widget_host) {} - // Invoked when a main fram navigation occurs. - virtual void DidNavigateMainFramePostCommit(WebContents* source) {} + // Invoked when a primary main frame navigation occurs. + virtual void DidNavigatePrimaryMainFramePostCommit(WebContents* source) {} // Returns a pointer to a service to manage JavaScript dialogs. May return // nullptr in which case dialogs aren't shown.
diff --git a/content/public/test/android/BUILD.gn b/content/public/test/android/BUILD.gn index 63111ab..c739c62f 100644 --- a/content/public/test/android/BUILD.gn +++ b/content/public/test/android/BUILD.gn
@@ -27,6 +27,7 @@ "//services/service_manager/public/java:service_manager_java", "//third_party/android_support_test_runner:runner_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/blink/public/mojom:android_mojo_bindings_java", "//third_party/hamcrest:hamcrest_java", "//third_party/junit:junit", "//ui/android:ui_java",
diff --git a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/mock/MockRenderFrameHost.java b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/mock/MockRenderFrameHost.java index ab7e00a2..389b4a3 100644 --- a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/mock/MockRenderFrameHost.java +++ b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/mock/MockRenderFrameHost.java
@@ -5,6 +5,7 @@ package org.chromium.content_public.browser.test.mock; import org.chromium.base.Callback; +import org.chromium.blink.mojom.AuthenticatorStatus; import org.chromium.content_public.browser.GlobalRenderFrameHostId; import org.chromium.content_public.browser.LifecycleState; import org.chromium.content_public.browser.PermissionsPolicyFeature; @@ -68,9 +69,9 @@ } @Override - public int performGetAssertionWebAuthSecurityChecks( + public WebAuthSecurityChecksResults performGetAssertionWebAuthSecurityChecks( String relyingPartyId, Origin effectiveOrigin) { - return 0; + return new WebAuthSecurityChecksResults(AuthenticatorStatus.SUCCESS, false); } @Override
diff --git a/content/shell/browser/shell.cc b/content/shell/browser/shell.cc index 5e586f4..e07d7d307 100644 --- a/content/shell/browser/shell.cc +++ b/content/shell/browser/shell.cc
@@ -558,8 +558,8 @@ } #if defined(OS_MAC) -void Shell::DidNavigateMainFramePostCommit(WebContents* contents) { - g_platform->DidNavigateMainFramePostCommit(this, contents); +void Shell::DidNavigatePrimaryMainFramePostCommit(WebContents* contents) { + g_platform->DidNavigatePrimaryMainFramePostCommit(this, contents); } bool Shell::HandleKeyboardEvent(WebContents* source,
diff --git a/content/shell/browser/shell.h b/content/shell/browser/shell.h index dac7019..e0da61c8 100644 --- a/content/shell/browser/shell.h +++ b/content/shell/browser/shell.h
@@ -141,7 +141,7 @@ JavaScriptDialogManager* GetJavaScriptDialogManager( WebContents* source) override; #if defined(OS_MAC) - void DidNavigateMainFramePostCommit(WebContents* contents) override; + void DidNavigatePrimaryMainFramePostCommit(WebContents* contents) override; bool HandleKeyboardEvent(WebContents* source, const NativeWebKeyboardEvent& event) override; #endif
diff --git a/content/shell/browser/shell_platform_delegate.h b/content/shell/browser/shell_platform_delegate.h index 6e7641273..fa4fa73 100644 --- a/content/shell/browser/shell_platform_delegate.h +++ b/content/shell/browser/shell_platform_delegate.h
@@ -106,8 +106,8 @@ // Activate (make key) the native window, and focus the web contents. virtual void ActivateContents(Shell* shell, WebContents* contents); - virtual void DidNavigateMainFramePostCommit(Shell* shell, - WebContents* contents); + virtual void DidNavigatePrimaryMainFramePostCommit(Shell* shell, + WebContents* contents); virtual bool HandleKeyboardEvent(Shell* shell, WebContents* source,
diff --git a/content/shell/browser/shell_platform_delegate_mac.mm b/content/shell/browser/shell_platform_delegate_mac.mm index 89edca7..0846768 100644 --- a/content/shell/browser/shell_platform_delegate_mac.mm +++ b/content/shell/browser/shell_platform_delegate_mac.mm
@@ -333,7 +333,7 @@ [NSApp activateIgnoringOtherApps:YES]; } -void ShellPlatformDelegate::DidNavigateMainFramePostCommit( +void ShellPlatformDelegate::DidNavigatePrimaryMainFramePostCommit( Shell* shell, WebContents* contents) {}
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 6512b75..9f7ce6c 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -323,8 +323,6 @@ "mock_overscroll_observer.h", "mock_platform_notification_service.cc", "mock_platform_notification_service.h", - "mock_raw_clipboard_host.cc", - "mock_raw_clipboard_host.h", "mock_render_widget_host_delegate.cc", "mock_render_widget_host_delegate.h", "mock_ssl_host_state_delegate.cc",
diff --git a/content/test/data/color-scheme-dark.html b/content/test/data/color-scheme-dark.html new file mode 100644 index 0000000..c617bec --- /dev/null +++ b/content/test/data/color-scheme-dark.html
@@ -0,0 +1,3 @@ +<head> + <meta name="color-scheme" content="dark"> +</head>
diff --git a/content/test/data/conversions/databases/version_4.sql b/content/test/data/conversions/databases/version_4.sql index 0e740c9..87c43673 100644 --- a/content/test/data/conversions/databases/version_4.sql +++ b/content/test/data/conversions/databases/version_4.sql
@@ -32,8 +32,8 @@ -- Add some conversions to test 0-credit deletion in version 5. INSERT INTO conversions (conversion_id, conversion_data, conversion_time, report_time, attribution_credit) VALUES - (1, "a", 2, 3, 5), - (2, "b", 7, 11, 0), - (3, "c", 13, 17, 19); + (1, 'a', 2, 3, 5), + (2, 'b', 7, 11, 0), + (3, 'c', 13, 17, 19); COMMIT;
diff --git a/content/test/data/page_with_anonymous_iframe.html b/content/test/data/page_with_anonymous_iframe.html new file mode 100644 index 0000000..436fc4c --- /dev/null +++ b/content/test/data/page_with_anonymous_iframe.html
@@ -0,0 +1,9 @@ +<html> +<head></head> +<body> + <img src="image.jpg"/> + <p>This page has an anonymous iframe. Yay for iframes! + <p><iframe src="title1.html" id="test_iframe" name="test_iframe" anonymous> + </iframe> +</body> +</html>
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index cb59ce6..27912720 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -392,6 +392,7 @@ crbug.com/1044638 [ mac amd ] conformance2/rendering/framebuffer-texture-level1.html [ RetryOnFailure ] crbug.com/1214931 [ mojave amd-0x6821 angle-opengl passthrough ] deqp/functional/gles3/shadertexturefunction/texturesize.html [ RetryOnFailure ] +crbug.com/1230781 [ mac amd-0x6821 ] conformance/canvas/to-data-url-test.html [ Failure ] # The transformfeedback tests are specialized for two different AMD # GPUs because of different failure modes on each.
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt index 4a7bcdb..5aa334d 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -448,6 +448,7 @@ crbug.com/1203167 [ mac amd angle-disabled ] conformance/extensions/oes-texture-float-with-video.html [ RetryOnFailure ] crbug.com/1203167 [ mac amd angle-opengl ] conformance/extensions/oes-texture-float-with-video.html [ RetryOnFailure ] crbug.com/1203167 [ mac amd angle-metal ] conformance/extensions/oes-texture-float-with-video.html [ RetryOnFailure ] +crbug.com/1230781 [ mac amd-0x6821 ] conformance/canvas/to-data-url-test.html [ Failure ] # TODO(kbr): uncomment the following expectation after test has # been made more robust.
diff --git a/content/test/mock_raw_clipboard_host.cc b/content/test/mock_raw_clipboard_host.cc deleted file mode 100644 index 6e0e507..0000000 --- a/content/test/mock_raw_clipboard_host.cc +++ /dev/null
@@ -1,97 +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 "content/test/mock_raw_clipboard_host.h" - -#include <string> - -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "content/test/mock_clipboard_host.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/features.h" -#include "third_party/blink/public/mojom/clipboard/raw_clipboard.mojom.h" - -namespace content { - -MockRawClipboardHost::~MockRawClipboardHost() = default; - -MockRawClipboardHost::MockRawClipboardHost( - MockClipboardHost* mock_clipboard_host) - : mock_clipboard_host_(mock_clipboard_host) { - EXPECT_TRUE(mock_clipboard_host_); -} - -void MockRawClipboardHost::Bind( - mojo::PendingReceiver<blink::mojom::RawClipboardHost> receiver) { - if (!base::FeatureList::IsEnabled(blink::features::kRawClipboard)) - return; - - receivers_.Add(this, std::move(receiver)); -} - -void MockRawClipboardHost::Reset() { - EXPECT_TRUE(mock_clipboard_host_); - mock_clipboard_host_->Reset(); - raw_data_map_.clear(); - needs_reset_ = false; -} - -void MockRawClipboardHost::ReadAvailableFormatNames( - ReadAvailableFormatNamesCallback callback) { - std::vector<std::u16string> format_names; - for (const auto& item : raw_data_map_) - format_names.emplace_back(item.first); - std::move(callback).Run(format_names); -} - -void MockRawClipboardHost::Read(const std::u16string& format, - ReadCallback callback) { - const auto it = raw_data_map_.find(format); - if (it == raw_data_map_.end()) - return; - - mojo_base::BigBuffer buffer = mojo_base::BigBuffer( - base::make_span(it->second.data(), it->second.size())); - std::move(callback).Run(std::move(buffer)); -} - -void MockRawClipboardHost::Write(const std::u16string& format, - mojo_base::BigBuffer data) { - if (needs_reset_) - Reset(); - // Simulate the underlying platform copying this data. - std::vector<uint8_t> data_copy(data.data(), data.data() + data.size()); - - // Provide one commonly-used format on some platforms, where the platforms - // automatically convert between certain format names, for use in testing. - // Platforms often provide many converted formats, so not all converted-to - // formats are provided. - static constexpr char16_t kPlatformTextFormat[] = -#if defined(OS_WIN) - u"CF_TEXT"; -#elif defined(USE_X11) - u"text/plain"; -#else - u""; -#endif - - if (format == kPlatformTextFormat) { - EXPECT_TRUE(mock_clipboard_host_); - std::u16string text = base::UTF8ToUTF16(base::StringPiece( - reinterpret_cast<const char*>(data_copy.data()), data_copy.size())); - mock_clipboard_host_->WriteText(text); - } - raw_data_map_[format] = data_copy; -} - -void MockRawClipboardHost::CommitWrite() { - // As the RawClipboardHost is an extension of ClipboardHost, - // RawClipboardHost will make ClipboardHost commit, but not vice versa. - EXPECT_TRUE(mock_clipboard_host_); - mock_clipboard_host_->CommitWrite(); - needs_reset_ = true; -} - -} // namespace content
diff --git a/content/test/mock_raw_clipboard_host.h b/content/test/mock_raw_clipboard_host.h deleted file mode 100644 index c7ea774..0000000 --- a/content/test/mock_raw_clipboard_host.h +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_TEST_MOCK_RAW_CLIPBOARD_HOST_H_ -#define CONTENT_TEST_MOCK_RAW_CLIPBOARD_HOST_H_ - -#include "mojo/public/cpp/base/big_buffer.h" -#include "mojo/public/cpp/bindings/receiver_set.h" -#include "third_party/blink/public/mojom/clipboard/raw_clipboard.mojom.h" - -namespace content { - -class MockClipboardHost; - -// Emulates platform-specific clipboard behavior, such as type conversions -// (ex. CF_TEXT on Windows MockRawClipboardHost to normal text on the -// associated MockClipboardHost). -class MockRawClipboardHost : public blink::mojom::RawClipboardHost { - public: - // |mock_clipboard_host| must outlive the newly created MockRawClipboardHost - // instance. - explicit MockRawClipboardHost(MockClipboardHost* mock_clipboard_host); - MockRawClipboardHost(const MockRawClipboardHost&) = delete; - MockRawClipboardHost& operator=(const MockRawClipboardHost&) = delete; - ~MockRawClipboardHost() override; - - void Bind(mojo::PendingReceiver<blink::mojom::RawClipboardHost> receiver); - // Clears all clipboard data. - void Reset(); - - // blink::mojom::RawClipboardHost - void ReadAvailableFormatNames( - ReadAvailableFormatNamesCallback callback) override; - void Read(const std::u16string& format, ReadCallback callback) override; - void Write(const std::u16string& format, mojo_base::BigBuffer data) override; - void CommitWrite() override; - - private: - mojo::ReceiverSet<blink::mojom::RawClipboardHost> receivers_; - // The associated sanitized clipboard, for emulating platform-specific - // clipboard type conversions. Owned by WebTestContentBrowserClient. - MockClipboardHost* const mock_clipboard_host_; - std::map<std::u16string, std::vector<uint8_t>> raw_data_map_; - // Tracks whether a commit has happened since the last write. After a - // sequence of writes are committed, future writes should clear the clipboard - // before continuing to write. - bool needs_reset_ = false; -}; - -} // namespace content - -#endif // CONTENT_TEST_MOCK_RAW_CLIPBOARD_HOST_H_
diff --git a/content/web_test/browser/web_test_content_browser_client.cc b/content/web_test/browser/web_test_content_browser_client.cc index 60ebbac..c6872573 100644 --- a/content/web_test/browser/web_test_content_browser_client.cc +++ b/content/web_test/browser/web_test_content_browser_client.cc
@@ -38,7 +38,6 @@ #include "content/test/mock_badge_service.h" #include "content/test/mock_clipboard_host.h" #include "content/test/mock_platform_notification_service.h" -#include "content/test/mock_raw_clipboard_host.h" #include "content/web_test/browser/fake_bluetooth_chooser.h" #include "content/web_test/browser/fake_bluetooth_chooser_factory.h" #include "content/web_test/browser/fake_bluetooth_delegate.h" @@ -249,8 +248,6 @@ void WebTestContentBrowserClient::ResetMockClipboardHosts() { if (mock_clipboard_host_) mock_clipboard_host_->Reset(); - if (mock_raw_clipboard_host_) - mock_raw_clipboard_host_->Reset(); } void WebTestContentBrowserClient::SetScreenOrientationChanged( @@ -481,9 +478,6 @@ map->Add<mojom::MojoWebTestHelper>(base::BindRepeating(&BindWebTestHelper)); map->Add<blink::mojom::ClipboardHost>(base::BindRepeating( &WebTestContentBrowserClient::BindClipboardHost, base::Unretained(this))); - map->Add<blink::mojom::RawClipboardHost>( - base::BindRepeating(&WebTestContentBrowserClient::BindRawClipboardHost, - base::Unretained(this))); map->Add<blink::mojom::BadgeService>(base::BindRepeating( &WebTestContentBrowserClient::BindBadgeService, base::Unretained(this))); map->Add<blink::test::mojom::CookieManagerAutomation>(base::BindRepeating( @@ -521,18 +515,6 @@ mock_clipboard_host_->Bind(std::move(receiver)); } -void WebTestContentBrowserClient::BindRawClipboardHost( - RenderFrameHost* render_frame_host, - mojo::PendingReceiver<blink::mojom::RawClipboardHost> receiver) { - if (!mock_clipboard_host_) - mock_clipboard_host_ = std::make_unique<MockClipboardHost>(); - if (!mock_raw_clipboard_host_) { - mock_raw_clipboard_host_ = - std::make_unique<MockRawClipboardHost>(mock_clipboard_host_.get()); - } - mock_raw_clipboard_host_->Bind(std::move(receiver)); -} - void WebTestContentBrowserClient::BindBadgeService( RenderFrameHost* render_frame_host, mojo::PendingReceiver<blink::mojom::BadgeService> receiver) {
diff --git a/content/web_test/browser/web_test_content_browser_client.h b/content/web_test/browser/web_test_content_browser_client.h index c07dcf6..427656a 100644 --- a/content/web_test/browser/web_test_content_browser_client.h +++ b/content/web_test/browser/web_test_content_browser_client.h
@@ -20,7 +20,6 @@ #include "services/service_manager/public/cpp/binder_registry.h" #include "third_party/blink/public/mojom/badging/badging.mojom.h" #include "third_party/blink/public/mojom/clipboard/clipboard.mojom.h" -#include "third_party/blink/public/mojom/clipboard/raw_clipboard.mojom.h" #include "third_party/blink/public/mojom/cookie_manager/cookie_manager_automation.mojom-forward.h" #include "third_party/blink/public/mojom/permissions/permission_automation.mojom-forward.h" #include "third_party/blink/public/mojom/storage_access/storage_access_automation.mojom-forward.h" @@ -38,7 +37,6 @@ class MockBadgeService; class MockClipboardHost; class MockPlatformNotificationService; -class MockRawClipboardHost; class WebTestBrowserContext; class WebTestContentBrowserClient : public ShellContentBrowserClient { @@ -127,9 +125,6 @@ void BindClipboardHost( RenderFrameHost* render_frame_host, mojo::PendingReceiver<blink::mojom::ClipboardHost> receiver); - void BindRawClipboardHost( - RenderFrameHost* render_frame_host, - mojo::PendingReceiver<blink::mojom::RawClipboardHost> receiver); void BindBadgeService( RenderFrameHost* render_frame_host, @@ -160,7 +155,6 @@ std::unique_ptr<FakeBluetoothChooserFactory> fake_bluetooth_chooser_factory_; std::unique_ptr<FakeBluetoothDelegate> fake_bluetooth_delegate_; std::unique_ptr<MockClipboardHost> mock_clipboard_host_; - std::unique_ptr<MockRawClipboardHost> mock_raw_clipboard_host_; std::unique_ptr<MockBadgeService> mock_badge_service_; mojo::UniqueReceiverSet<blink::test::mojom::CookieManagerAutomation> cookie_managers_;
diff --git a/content/web_test/browser/web_test_shell_platform_delegate.h b/content/web_test/browser/web_test_shell_platform_delegate.h index 82d2422d..59e8635 100644 --- a/content/web_test/browser/web_test_shell_platform_delegate.h +++ b/content/web_test/browser/web_test_shell_platform_delegate.h
@@ -42,7 +42,8 @@ void ResizeWebContent(Shell* shell, const gfx::Size& content_size) override; #if defined(OS_MAC) void ActivateContents(Shell* shell, WebContents* top_contents) override; - void DidNavigateMainFramePostCommit(Shell*, WebContents* contents) override; + void DidNavigatePrimaryMainFramePostCommit(Shell*, + WebContents* contents) override; bool HandleKeyboardEvent(Shell* shell, WebContents* source, const NativeWebKeyboardEvent& event) override;
diff --git a/content/web_test/browser/web_test_shell_platform_delegate_mac.mm b/content/web_test/browser/web_test_shell_platform_delegate_mac.mm index 66b2609..f4a9ed7 100644 --- a/content/web_test/browser/web_test_shell_platform_delegate_mac.mm +++ b/content/web_test/browser/web_test_shell_platform_delegate_mac.mm
@@ -179,11 +179,12 @@ activated_headless_shell_ = shell; } -void WebTestShellPlatformDelegate::DidNavigateMainFramePostCommit( +void WebTestShellPlatformDelegate::DidNavigatePrimaryMainFramePostCommit( Shell* shell, WebContents* contents) { if (!IsHeadless()) { - ShellPlatformDelegate::DidNavigateMainFramePostCommit(shell, contents); + ShellPlatformDelegate::DidNavigatePrimaryMainFramePostCommit(shell, + contents); return; }
diff --git a/device/bluetooth/chromeos/bluetooth_utils.cc b/device/bluetooth/chromeos/bluetooth_utils.cc index 0c309e2..76b8840 100644 --- a/device/bluetooth/chromeos/bluetooth_utils.cc +++ b/device/bluetooth/chromeos/bluetooth_utils.cc
@@ -248,7 +248,7 @@ void RecordUserInitiatedReconnectionAttemptResult( absl::optional<ConnectionFailureReason> failure_reason, - BluetoothUiSurface surface) { + UserInitiatedReconnectionUISurfaces surface) { bool success = !failure_reason.has_value(); std::string base_histogram_name = "Bluetooth.ChromeOS.UserInitiatedReconnectionAttempt.Result"; @@ -256,7 +256,9 @@ base::UmaHistogramBoolean(base_histogram_name, success); std::string surface_name = - (surface == BluetoothUiSurface::kSettings ? "Settings" : "SystemTray"); + (surface == UserInitiatedReconnectionUISurfaces::kSettings + ? "Settings" + : "SystemTray"); base::UmaHistogramBoolean(base_histogram_name + "." + surface_name, success); if (!success) { @@ -269,7 +271,7 @@ } void RecordDeviceSelectionDuration(base::TimeDelta duration, - BluetoothUiSurface surface, + DeviceSelectionUISurfaces surface, bool was_paired, BluetoothTransport transport) { // Throw out longtail results of the user taking longer than @@ -284,7 +286,8 @@ RecordDeviceSelectionDuration(base_histogram_name, duration); std::string surface_name = - (surface == BluetoothUiSurface::kSettings ? "Settings" : "SystemTray"); + (surface == DeviceSelectionUISurfaces::kSettings ? "Settings" + : "SystemTray"); std::string surface_histogram_name = base_histogram_name + "." + surface_name; RecordDeviceSelectionDuration(surface_histogram_name, duration);
diff --git a/device/bluetooth/chromeos/bluetooth_utils.h b/device/bluetooth/chromeos/bluetooth_utils.h index b345db44..046fbdc 100644 --- a/device/bluetooth/chromeos/bluetooth_utils.h +++ b/device/bluetooth/chromeos/bluetooth_utils.h
@@ -25,11 +25,15 @@ KNOWN, }; -enum class BluetoothUiSurface { +enum class DeviceSelectionUISurfaces { kSettings, kSystemTray, }; +enum class UserInitiatedReconnectionUISurfaces { + kSettings, + kSystemTray, +}; // This enum is tied directly to a UMA enum defined in // //tools/metrics/histograms/enums.xml, and should always reflect it (do not // change one without changing the other). @@ -60,13 +64,13 @@ // Record outcome of user attempting to reconnect to a previously paired device. DEVICE_BLUETOOTH_EXPORT void RecordUserInitiatedReconnectionAttemptResult( absl::optional<ConnectionFailureReason> failure_reason, - BluetoothUiSurface surface); + UserInitiatedReconnectionUISurfaces surface); // Record how long it took for a user to find and select the device they wished // to connect to. DEVICE_BLUETOOTH_EXPORT void RecordDeviceSelectionDuration( base::TimeDelta duration, - BluetoothUiSurface surface, + DeviceSelectionUISurfaces surface, bool was_paired, BluetoothTransport transport);
diff --git a/extensions/browser/api/bluetooth/bluetooth_private_api.cc b/extensions/browser/api/bluetooth/bluetooth_private_api.cc index 282d59f..d197ca96 100644 --- a/extensions/browser/api/bluetooth/bluetooth_private_api.cc +++ b/extensions/browser/api/bluetooth/bluetooth_private_api.cc
@@ -705,7 +705,7 @@ if (success || IsActualConnectionFailure(result)) { device::RecordUserInitiatedReconnectionAttemptResult( success ? absl::nullopt : GetConnectionFailureReason(result), - device::BluetoothUiSurface::kSettings); + device::UserInitiatedReconnectionUISurfaces::kSettings); } #endif // BUILDFLAG(IS_CHROMEOS_ASH) @@ -730,7 +730,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) device::RecordDeviceSelectionDuration( base::TimeDelta::FromMilliseconds(params_->selection_duration_ms), - device::BluetoothUiSurface::kSettings, params_->was_paired, + device::DeviceSelectionUISurfaces::kSettings, params_->was_paired, GetBluetoothTransport(params_->transport)); #endif // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/extensions/browser/api/system_display/system_display_apitest.cc b/extensions/browser/api/system_display/system_display_apitest.cc index bf4ff474..e632c8e 100644 --- a/extensions/browser/api/system_display/system_display_apitest.cc +++ b/extensions/browser/api/system_display/system_display_apitest.cc
@@ -63,29 +63,7 @@ DISALLOW_COPY_AND_ASSIGN(SystemDisplayApiTest); }; -IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest, GetDisplayInfo) { - ASSERT_TRUE(RunAppTest("system/display/info")) << message_; -} - -#if !BUILDFLAG(IS_CHROMEOS_ASH) - -IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest, SetDisplay) { - scoped_refptr<SystemDisplaySetDisplayPropertiesFunction> set_info_function( - new SystemDisplaySetDisplayPropertiesFunction()); - - set_info_function->set_has_callback(true); - - EXPECT_EQ( - SystemDisplayCrOSRestrictedFunction::kCrosOnlyError, - api_test_utils::RunFunctionAndReturnError( - set_info_function.get(), "[\"display_id\", {}]", browser_context())); - - std::unique_ptr<base::DictionaryValue> set_info = - provider_->GetSetInfoValue(); - EXPECT_FALSE(set_info); -} - -#else // !BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) // TODO(stevenjb): Add API tests for {GS}etDisplayLayout. That code currently // lives in src/chrome but should be getting moved soon. @@ -348,6 +326,6 @@ } } -#endif // !BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) } // namespace extensions
diff --git a/gpu/command_buffer/build_raster_cmd_buffer.py b/gpu/command_buffer/build_raster_cmd_buffer.py index de0bf1a2..f0832ff 100755 --- a/gpu/command_buffer/build_raster_cmd_buffer.py +++ b/gpu/command_buffer/build_raster_cmd_buffer.py
@@ -141,6 +141,15 @@ 'viz::ResourceFormat::ETC1', ], }, + 'gpu::raster::MsaaMode': { + 'type': 'gpu::raster::MsaaMode', + 'is_complete': True, + 'valid': [ + 'gpu::raster::MsaaMode::kNoMSAA', + 'gpu::raster::MsaaMode::kMSAA', + 'gpu::raster::MsaaMode::kDMSAA', + ], + }, } # A function info object specifies the type and other special data for the
diff --git a/gpu/command_buffer/client/BUILD.gn b/gpu/command_buffer/client/BUILD.gn index eec19c8..f8078b8 100644 --- a/gpu/command_buffer/client/BUILD.gn +++ b/gpu/command_buffer/client/BUILD.gn
@@ -204,6 +204,7 @@ "//base", "//components/viz/common:resource_format", "//gpu/command_buffer/common", + "//gpu/command_buffer/common:raster", "//skia:skia", "//ui/gfx:buffer_types", ]
diff --git a/gpu/command_buffer/client/raster_cmd_helper_autogen.h b/gpu/command_buffer/client/raster_cmd_helper_autogen.h index ea43381..f04db3db 100644 --- a/gpu/command_buffer/client/raster_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/raster_cmd_helper_autogen.h
@@ -91,6 +91,7 @@ void BeginRasterCHROMIUMImmediate(GLuint sk_color, GLboolean needs_clear, GLuint msaa_sample_count, + gpu::raster::MsaaMode msaa_mode, GLboolean can_use_lcd_text, const GLbyte* mailbox) { const uint32_t size = @@ -99,8 +100,8 @@ GetImmediateCmdSpaceTotalSize<raster::cmds::BeginRasterCHROMIUMImmediate>( size); if (c) { - c->Init(sk_color, needs_clear, msaa_sample_count, can_use_lcd_text, - mailbox); + c->Init(sk_color, needs_clear, msaa_sample_count, msaa_mode, + can_use_lcd_text, mailbox); } }
diff --git a/gpu/command_buffer/client/raster_implementation.cc b/gpu/command_buffer/client/raster_implementation.cc index c52227671..64d0b4bb 100644 --- a/gpu/command_buffer/client/raster_implementation.cc +++ b/gpu/command_buffer/client/raster_implementation.cc
@@ -1308,13 +1308,15 @@ GLuint sk_color, GLboolean needs_clear, GLuint msaa_sample_count, + MsaaMode msaa_mode, GLboolean can_use_lcd_text, const gfx::ColorSpace& color_space, const GLbyte* mailbox) { DCHECK(!raster_properties_); - helper_->BeginRasterCHROMIUMImmediate( - sk_color, needs_clear, msaa_sample_count, can_use_lcd_text, mailbox); + helper_->BeginRasterCHROMIUMImmediate(sk_color, needs_clear, + msaa_sample_count, msaa_mode, + can_use_lcd_text, mailbox); raster_properties_.emplace(sk_color, can_use_lcd_text, color_space.ToSkColorSpace());
diff --git a/gpu/command_buffer/client/raster_implementation.h b/gpu/command_buffer/client/raster_implementation.h index a2445b2..bbc24062 100644 --- a/gpu/command_buffer/client/raster_implementation.h +++ b/gpu/command_buffer/client/raster_implementation.h
@@ -140,6 +140,7 @@ void BeginRasterCHROMIUM(GLuint sk_color, GLboolean needs_clear, GLuint msaa_sample_count, + MsaaMode msaa_mode, GLboolean can_use_lcd_text, const gfx::ColorSpace& color_space, const GLbyte* mailbox) override;
diff --git a/gpu/command_buffer/client/raster_implementation_gles.cc b/gpu/command_buffer/client/raster_implementation_gles.cc index 1db20329..4721307 100644 --- a/gpu/command_buffer/client/raster_implementation_gles.cc +++ b/gpu/command_buffer/client/raster_implementation_gles.cc
@@ -211,6 +211,7 @@ GLuint sk_color, GLboolean needs_clear, GLuint msaa_sample_count, + MsaaMode msaa_mode, GLboolean can_use_lcd_text, const gfx::ColorSpace& color_space, const GLbyte* mailbox) {
diff --git a/gpu/command_buffer/client/raster_implementation_gles.h b/gpu/command_buffer/client/raster_implementation_gles.h index 09fc602..2cc30bb 100644 --- a/gpu/command_buffer/client/raster_implementation_gles.h +++ b/gpu/command_buffer/client/raster_implementation_gles.h
@@ -83,6 +83,7 @@ void BeginRasterCHROMIUM(GLuint sk_color, GLboolean needs_clear, GLuint msaa_sample_count, + MsaaMode msaa_mode, GLboolean can_use_lcd_text, const gfx::ColorSpace& color_space, const GLbyte* mailbox) override;
diff --git a/gpu/command_buffer/client/raster_interface.h b/gpu/command_buffer/client/raster_interface.h index 4b569dc..1bdd177 100644 --- a/gpu/command_buffer/client/raster_interface.h +++ b/gpu/command_buffer/client/raster_interface.h
@@ -11,6 +11,7 @@ #include "base/containers/span.h" #include "components/viz/common/resources/resource_format.h" #include "gpu/command_buffer/client/interface_base.h" +#include "gpu/command_buffer/common/raster_cmd_enums.h" #include "gpu/command_buffer/common/sync_token.h" #include "third_party/skia/include/core/SkImageInfo.h" #include "third_party/skia/include/core/SkYUVAInfo.h" @@ -74,9 +75,12 @@ const gpu::Mailbox yuva_plane_mailboxes[]) = 0; // OOP-Raster + + // msaa_sample_count has no effect unless msaa_mode is set to kMSAA virtual void BeginRasterCHROMIUM(GLuint sk_color, GLboolean needs_clear, GLuint msaa_sample_count, + MsaaMode msaa_mode, GLboolean can_use_lcd_text, const gfx::ColorSpace& color_space, const GLbyte* mailbox) = 0;
diff --git a/gpu/command_buffer/common/BUILD.gn b/gpu/command_buffer/common/BUILD.gn index e8d71ac..936b345 100644 --- a/gpu/command_buffer/common/BUILD.gn +++ b/gpu/command_buffer/common/BUILD.gn
@@ -161,6 +161,7 @@ visibility = [ "//gpu/*" ] sources = [ + "raster_cmd_enums.h", "raster_cmd_format.cc", "raster_cmd_format.h", "raster_cmd_format_autogen.h",
diff --git a/gpu/command_buffer/common/raster_cmd_enums.h b/gpu/command_buffer/common/raster_cmd_enums.h new file mode 100644 index 0000000..fa510e5 --- /dev/null +++ b/gpu/command_buffer/common/raster_cmd_enums.h
@@ -0,0 +1,22 @@ +// Copyright (c) 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_COMMON_RASTER_CMD_ENUMS_H_ +#define GPU_COMMAND_BUFFER_COMMON_RASTER_CMD_ENUMS_H_ + +#include <stdint.h> + +namespace gpu { +namespace raster { + +enum MsaaMode : uint32_t { + kNoMSAA, + kMSAA, // legacy + kDMSAA, // new and improved +}; + +} // namespace raster +} // namespace gpu + +#endif
diff --git a/gpu/command_buffer/common/raster_cmd_format.h b/gpu/command_buffer/common/raster_cmd_format.h index e43a51f9..5af4902 100644 --- a/gpu/command_buffer/common/raster_cmd_format.h +++ b/gpu/command_buffer/common/raster_cmd_format.h
@@ -19,6 +19,7 @@ #include "gpu/command_buffer/common/constants.h" #include "gpu/command_buffer/common/gl2_types.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/common/raster_cmd_enums.h" #include "gpu/command_buffer/common/raster_cmd_ids.h" #include "ui/gfx/buffer_types.h"
diff --git a/gpu/command_buffer/common/raster_cmd_format_autogen.h b/gpu/command_buffer/common/raster_cmd_format_autogen.h index 7d02570b..ef98b2b46 100644 --- a/gpu/command_buffer/common/raster_cmd_format_autogen.h +++ b/gpu/command_buffer/common/raster_cmd_format_autogen.h
@@ -391,12 +391,14 @@ void Init(GLuint _sk_color, GLboolean _needs_clear, GLuint _msaa_sample_count, + gpu::raster::MsaaMode _msaa_mode, GLboolean _can_use_lcd_text, const GLbyte* _mailbox) { SetHeader(); sk_color = _sk_color; needs_clear = _needs_clear; msaa_sample_count = _msaa_sample_count; + msaa_mode = _msaa_mode; can_use_lcd_text = _can_use_lcd_text; memcpy(ImmediateDataAddress(this), _mailbox, ComputeDataSize()); } @@ -405,11 +407,12 @@ GLuint _sk_color, GLboolean _needs_clear, GLuint _msaa_sample_count, + gpu::raster::MsaaMode _msaa_mode, GLboolean _can_use_lcd_text, const GLbyte* _mailbox) { static_cast<ValueType*>(cmd)->Init(_sk_color, _needs_clear, - _msaa_sample_count, _can_use_lcd_text, - _mailbox); + _msaa_sample_count, _msaa_mode, + _can_use_lcd_text, _mailbox); const uint32_t size = ComputeSize(); return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); } @@ -418,11 +421,12 @@ uint32_t sk_color; uint32_t needs_clear; uint32_t msaa_sample_count; + uint32_t msaa_mode; uint32_t can_use_lcd_text; }; -static_assert(sizeof(BeginRasterCHROMIUMImmediate) == 20, - "size of BeginRasterCHROMIUMImmediate should be 20"); +static_assert(sizeof(BeginRasterCHROMIUMImmediate) == 24, + "size of BeginRasterCHROMIUMImmediate should be 24"); static_assert(offsetof(BeginRasterCHROMIUMImmediate, header) == 0, "offset of BeginRasterCHROMIUMImmediate header should be 0"); static_assert(offsetof(BeginRasterCHROMIUMImmediate, sk_color) == 4, @@ -432,9 +436,11 @@ static_assert( offsetof(BeginRasterCHROMIUMImmediate, msaa_sample_count) == 12, "offset of BeginRasterCHROMIUMImmediate msaa_sample_count should be 12"); +static_assert(offsetof(BeginRasterCHROMIUMImmediate, msaa_mode) == 16, + "offset of BeginRasterCHROMIUMImmediate msaa_mode should be 16"); static_assert( - offsetof(BeginRasterCHROMIUMImmediate, can_use_lcd_text) == 16, - "offset of BeginRasterCHROMIUMImmediate can_use_lcd_text should be 16"); + offsetof(BeginRasterCHROMIUMImmediate, can_use_lcd_text) == 20, + "offset of BeginRasterCHROMIUMImmediate can_use_lcd_text should be 20"); struct RasterCHROMIUM { typedef RasterCHROMIUM ValueType;
diff --git a/gpu/command_buffer/common/raster_cmd_format_test_autogen.h b/gpu/command_buffer/common/raster_cmd_format_test_autogen.h index 628d09e..414cd09 100644 --- a/gpu/command_buffer/common/raster_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/raster_cmd_format_test_autogen.h
@@ -160,7 +160,8 @@ *GetBufferAs<cmds::BeginRasterCHROMIUMImmediate>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLboolean>(12), - static_cast<GLuint>(13), static_cast<GLboolean>(14), data); + static_cast<GLuint>(13), static_cast<gpu::raster::MsaaMode>(14), + static_cast<GLboolean>(15), data); EXPECT_EQ(static_cast<uint32_t>(cmds::BeginRasterCHROMIUMImmediate::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)), @@ -168,7 +169,8 @@ EXPECT_EQ(static_cast<GLuint>(11), cmd.sk_color); EXPECT_EQ(static_cast<GLboolean>(12), cmd.needs_clear); EXPECT_EQ(static_cast<GLuint>(13), cmd.msaa_sample_count); - EXPECT_EQ(static_cast<GLboolean>(14), cmd.can_use_lcd_text); + EXPECT_EQ(static_cast<gpu::raster::MsaaMode>(14), cmd.msaa_mode); + EXPECT_EQ(static_cast<GLboolean>(15), cmd.can_use_lcd_text); CheckBytesWrittenMatchesExpectedSize( next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); }
diff --git a/gpu/command_buffer/raster_cmd_buffer_functions.txt b/gpu/command_buffer/raster_cmd_buffer_functions.txt index 4281ce2..2051ebbd 100644 --- a/gpu/command_buffer/raster_cmd_buffer_functions.txt +++ b/gpu/command_buffer/raster_cmd_buffer_functions.txt
@@ -23,7 +23,7 @@ GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusKHR (void); // Extension CHROMIUM_raster_transport -GL_APICALL void GL_APIENTRY glBeginRasterCHROMIUM (GLuint sk_color, GLboolean needs_clear, GLuint msaa_sample_count, GLboolean can_use_lcd_text, const GLbyte* mailbox); +GL_APICALL void GL_APIENTRY glBeginRasterCHROMIUM (GLuint sk_color, GLboolean needs_clear, GLuint msaa_sample_count, gpu::raster::MsaaMode msaa_mode, GLboolean can_use_lcd_text, const GLbyte* mailbox); GL_APICALL void GL_APIENTRY glRasterCHROMIUM (GLuint raster_shm_id, GLuint raster_shm_offset, GLuint raster_shm_size, GLuint font_shm_id, GLuint font_shm_offset, GLuint font_shm_size); GL_APICALL void GL_APIENTRY glEndRasterCHROMIUM (void); GL_APICALL void GL_APIENTRY glCreateTransferCacheEntryINTERNAL (GLuint entry_type, GLuint entry_id, GLuint handle_shm_id, GLuint handle_shm_offset, GLuint data_shm_id, GLuint data_shm_offset, GLuint data_size);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index db5b813..fbfa2f0 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -13675,7 +13675,9 @@ ClearScheduleCALayerState(); if (supports_async_swap_) { - TRACE_EVENT_ASYNC_BEGIN0("gpu", "AsyncSwapBuffers", c.swap_id()); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( + "gpu", "AsyncSwapBuffers", + TRACE_ID_WITH_SCOPE("AsyncSwapBuffers", c.swap_id())); client()->OnSwapBuffers(c.swap_id(), c.flags); surface_->PostSubBufferAsync( @@ -17029,7 +17031,9 @@ api()->glFlushFn(); } } else if (supports_async_swap_) { - TRACE_EVENT_ASYNC_BEGIN0("gpu", "AsyncSwapBuffers", swap_id); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( + "gpu", "AsyncSwapBuffers", + TRACE_ID_WITH_SCOPE("AsyncSwapBuffers", swap_id)); client()->OnSwapBuffers(swap_id, flags); surface_->SwapBuffersAsync( @@ -17049,7 +17053,9 @@ void GLES2DecoderImpl::FinishAsyncSwapBuffers( uint64_t swap_id, gfx::SwapCompletionResult result) { - TRACE_EVENT_ASYNC_END0("gpu", "AsyncSwapBuffers", swap_id); + TRACE_EVENT_NESTABLE_ASYNC_END0( + "gpu", "AsyncSwapBuffers", + TRACE_ID_WITH_SCOPE("AsyncSwapBuffers", swap_id)); FinishSwapBuffers(result.swap_result); } @@ -17512,8 +17518,8 @@ return error::kNoError; } - TRACE_EVENT_ASYNC_BEGIN0("cc", "GLES2DecoderImpl::DescheduleUntilFinished", - this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( + "cc", "GLES2DecoderImpl::DescheduleUntilFinished", TRACE_ID_LOCAL(this)); client()->OnDescheduleUntilFinished(); return error::kDeferLaterCommands; } @@ -17607,8 +17613,8 @@ if (!deschedule_until_finished_fences_[0]->HasCompleted()) return; - TRACE_EVENT_ASYNC_END0("cc", "GLES2DecoderImpl::DescheduleUntilFinished", - this); + TRACE_EVENT_NESTABLE_ASYNC_END0( + "cc", "GLES2DecoderImpl::DescheduleUntilFinished", TRACE_ID_LOCAL(this)); deschedule_until_finished_fences_.erase( deschedule_until_finished_fences_.begin()); client()->OnRescheduleAfterFinished();
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc index 4d517d8..85bdd3dd 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -2773,8 +2773,9 @@ return; } - TRACE_EVENT_ASYNC_END0( - "cc", "GLES2DecoderPassthroughImpl::DescheduleUntilFinished", this); + TRACE_EVENT_NESTABLE_ASYNC_END0( + "cc", "GLES2DecoderPassthroughImpl::DescheduleUntilFinished", + TRACE_ID_LOCAL(this)); deschedule_until_finished_fences_.erase( deschedule_until_finished_fences_.begin()); client()->OnRescheduleAfterFinished(); @@ -3015,7 +3016,9 @@ const char* function_name, uint64_t swap_id, gfx::SwapCompletionResult result) { - TRACE_EVENT_ASYNC_END0("gpu", "AsyncSwapBuffers", swap_id); + TRACE_EVENT_NESTABLE_ASYNC_END0( + "gpu", "AsyncSwapBuffers", + TRACE_ID_WITH_SCOPE("AsyncSwapBuffers", swap_id)); CheckSwapBuffersResult(result.swap_result, function_name); }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc index c020431..9be8ad4 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -3859,7 +3859,9 @@ client()->OnSwapBuffers(swap_id, flags); if (surface_->SupportsAsyncSwap()) { - TRACE_EVENT_ASYNC_BEGIN0("gpu", "AsyncSwapBuffers", swap_id); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( + "gpu", "AsyncSwapBuffers", + TRACE_ID_WITH_SCOPE("AsyncSwapBuffers", swap_id)); surface_->SwapBuffersAsync( base::BindOnce( &GLES2DecoderPassthroughImpl::CheckSwapBuffersAsyncResult, @@ -4470,7 +4472,9 @@ client()->OnSwapBuffers(swap_id, flags); if (surface_->SupportsAsyncSwap()) { - TRACE_EVENT_ASYNC_BEGIN0("gpu", "AsyncSwapBuffers", swap_id); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( + "gpu", "AsyncSwapBuffers", + TRACE_ID_WITH_SCOPE("AsyncSwapBuffers", swap_id)); surface_->PostSubBufferAsync( x, y, width, height, base::BindOnce( @@ -4776,8 +4780,9 @@ return error::kNoError; } - TRACE_EVENT_ASYNC_BEGIN0( - "cc", "GLES2DecoderPassthroughImpl::DescheduleUntilFinished", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( + "cc", "GLES2DecoderPassthroughImpl::DescheduleUntilFinished", + TRACE_ID_LOCAL(this)); client()->OnDescheduleUntilFinished(); return error::kDeferLaterCommands; } @@ -5067,7 +5072,9 @@ client()->OnSwapBuffers(swap_id, flags); if (surface_->SupportsAsyncSwap()) { - TRACE_EVENT_ASYNC_BEGIN0("gpu", "AsyncSwapBuffers", swap_id); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( + "gpu", "AsyncSwapBuffers", + TRACE_ID_WITH_SCOPE("AsyncSwapBuffers", swap_id)); surface_->CommitOverlayPlanesAsync( base::BindOnce( &GLES2DecoderPassthroughImpl::CheckSwapBuffersAsyncResult,
diff --git a/gpu/command_buffer/service/raster_cmd_validation_autogen.h b/gpu/command_buffer/service/raster_cmd_validation_autogen.h index 0ee7672f..0de3156 100644 --- a/gpu/command_buffer/service/raster_cmd_validation_autogen.h +++ b/gpu/command_buffer/service/raster_cmd_validation_autogen.h
@@ -35,6 +35,12 @@ ValueValidator<GLenum> texture_parameter; ValueValidator<GLenum> texture_wrap_mode; ValueValidator<gfx::BufferUsage> gfx_buffer_usage; +class GpuRasterMsaaModeValidator { + public: + bool IsValid(const gpu::raster::MsaaMode value) const; +}; +GpuRasterMsaaModeValidator gpu_raster_msaa_mode; + ValueValidator<viz::ResourceFormat> viz_resource_format; #endif // GPU_COMMAND_BUFFER_SERVICE_RASTER_CMD_VALIDATION_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h index db3a13f8..4c34cae7 100644 --- a/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h
@@ -71,6 +71,17 @@ gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, }; +bool Validators::GpuRasterMsaaModeValidator::IsValid( + const gpu::raster::MsaaMode value) const { + switch (value) { + case gpu::raster::MsaaMode::kNoMSAA: + case gpu::raster::MsaaMode::kMSAA: + case gpu::raster::MsaaMode::kDMSAA: + return true; + } + return false; +} + static const viz::ResourceFormat valid_viz_resource_format_table[] = { viz::ResourceFormat::RGBA_8888, viz::ResourceFormat::RGBA_4444, viz::ResourceFormat::BGRA_8888, viz::ResourceFormat::ALPHA_8,
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc index 6814eb55..ccf30bb 100644 --- a/gpu/command_buffer/service/raster_decoder.cc +++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -743,6 +743,7 @@ void DoBeginRasterCHROMIUM(GLuint sk_color, GLboolean needs_clear, GLuint msaa_sample_count, + MsaaMode msaa_mode, GLboolean can_use_lcd_text, const volatile GLbyte* key); void DoRasterCHROMIUM(GLuint raster_shm_id, @@ -872,6 +873,7 @@ bool supports_oop_raster_ = false; bool use_passthrough_ = false; bool use_ddl_ = false; + bool use_ddl_in_current_raster_session_ = false; // The current decoder error communicates the decoder error through command // processing functions that do not return the error value. Should be set @@ -3327,6 +3329,7 @@ void RasterDecoderImpl::DoBeginRasterCHROMIUM(GLuint sk_color, GLboolean needs_clear, GLuint msaa_sample_count, + MsaaMode msaa_mode, GLboolean can_use_lcd_text, const volatile GLbyte* key) { // Workaround for https://crbug.com/906453: Flush before BeginRaster (the @@ -3373,21 +3376,41 @@ DCHECK(!raster_canvas_); shared_context_state_->set_need_context_state_reset(true); + SkColorType sk_color_type = viz::ResourceFormatToClosestSkColorType( + /*gpu_compositing=*/true, shared_image_->format()); + + int final_msaa_count; + uint32_t flags; + switch (msaa_mode) { + default: + case kNoMSAA: + final_msaa_count = 0; + flags = 0; + use_ddl_in_current_raster_session_ = use_ddl_; + break; + case kMSAA: + // If we can't match requested MSAA samples, don't use MSAA. + final_msaa_count = std::max(static_cast<int>(msaa_sample_count), 0); + if (final_msaa_count > + gr_context()->maxSurfaceSampleCountForColorType(sk_color_type)) + final_msaa_count = 0; + flags = 0; + use_ddl_in_current_raster_session_ = use_ddl_; + break; + case kDMSAA: + final_msaa_count = 1; + flags = SkSurfaceProps::kDynamicMSAA_Flag; + // DMSAA is not compatible with DDL + use_ddl_in_current_raster_session_ = false; + break; + } + // Use unknown pixel geometry to disable LCD text. - uint32_t flags = 0; SkSurfaceProps surface_props(flags, kUnknown_SkPixelGeometry); if (can_use_lcd_text) { surface_props = skia::LegacyDisplayGlobals::GetSkSurfaceProps(flags); } - SkColorType sk_color_type = viz::ResourceFormatToClosestSkColorType( - /*gpu_compositing=*/true, shared_image_->format()); - // If we can't match requested MSAA samples, don't use MSAA. - int final_msaa_count = std::max(static_cast<int>(msaa_sample_count), 0); - if (final_msaa_count > - gr_context()->maxSurfaceSampleCountForColorType(sk_color_type)) - final_msaa_count = 0; - std::vector<GrBackendSemaphore> begin_semaphores; DCHECK(end_semaphores_.empty()); DCHECK(!scoped_shared_image_write_); @@ -3412,7 +3435,7 @@ DCHECK(result); } - if (use_ddl_) { + if (use_ddl_in_current_raster_session_) { SkSurfaceCharacterization characterization; bool result = sk_surface_->characterize(&characterization); DCHECK(result) << "Failed to characterize raster SkSurface."; @@ -3532,7 +3555,7 @@ } bool RasterDecoderImpl::EnsureDDLReadyForRaster() { - DCHECK(use_ddl_); + DCHECK(use_ddl_in_current_raster_session_); DCHECK_EQ(current_decoder_error_, error::kNoError); if (!ddl_) { @@ -3569,7 +3592,7 @@ shared_context_state_->set_need_context_state_reset(true); raster_canvas_ = nullptr; - if (use_ddl_) { + if (use_ddl_in_current_raster_session_) { if (!EnsureDDLReadyForRaster()) { // This decoder error indicates that this command has not finished // executing. The decoder will yield and re-execute this command when it
diff --git a/gpu/command_buffer/service/raster_decoder_autogen.h b/gpu/command_buffer/service/raster_decoder_autogen.h index 55b562b..610a1dc 100644 --- a/gpu/command_buffer/service/raster_decoder_autogen.h +++ b/gpu/command_buffer/service/raster_decoder_autogen.h
@@ -114,6 +114,8 @@ GLuint sk_color = static_cast<GLuint>(c.sk_color); GLboolean needs_clear = static_cast<GLboolean>(c.needs_clear); GLuint msaa_sample_count = static_cast<GLuint>(c.msaa_sample_count); + gpu::raster::MsaaMode msaa_mode = + static_cast<gpu::raster::MsaaMode>(c.msaa_mode); GLboolean can_use_lcd_text = static_cast<GLboolean>(c.can_use_lcd_text); uint32_t mailbox_size; if (!gles2::GLES2Util::ComputeDataSize<GLbyte, 16>(1, &mailbox_size)) { @@ -128,7 +130,7 @@ if (mailbox == nullptr) { return error::kOutOfBounds; } - DoBeginRasterCHROMIUM(sk_color, needs_clear, msaa_sample_count, + DoBeginRasterCHROMIUM(sk_color, needs_clear, msaa_sample_count, msaa_mode, can_use_lcd_text, mailbox); return error::kNoError; }
diff --git a/gpu/command_buffer/service/scheduler.cc b/gpu/command_buffer/service/scheduler.cc index 0b99abb..2d8cae1 100644 --- a/gpu/command_buffer/service/scheduler.cc +++ b/gpu/command_buffer/service/scheduler.cc
@@ -166,11 +166,13 @@ return; enabled_ = enabled; if (enabled) { - TRACE_EVENT_ASYNC_BEGIN1("gpu", "SequenceEnabled", this, "sequence_id", - sequence_id_.GetUnsafeValue()); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("gpu", "SequenceEnabled", + TRACE_ID_LOCAL(this), "sequence_id", + sequence_id_.GetUnsafeValue()); } else { - TRACE_EVENT_ASYNC_END1("gpu", "SequenceEnabled", this, "sequence_id", - sequence_id_.GetUnsafeValue()); + TRACE_EVENT_NESTABLE_ASYNC_END1("gpu", "SequenceEnabled", + TRACE_ID_LOCAL(this), "sequence_id", + sequence_id_.GetUnsafeValue()); } scheduler_->TryScheduleSequence(this); } @@ -572,7 +574,8 @@ std::push_heap(scheduling_queue.begin(), scheduling_queue.end(), &SchedulingState::Comparator); if (!thread_state.running) { - TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("gpu", "Scheduler::Running", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("gpu", "Scheduler::Running", + TRACE_ID_LOCAL(this)); thread_state.running = true; run_next_task_scheduled_ = base::TimeTicks::Now(); task_runner->PostTask(FROM_HERE, base::BindOnce(&Scheduler::RunNextTask, @@ -622,7 +625,8 @@ { auto& scheduling_queue = RebuildSchedulingQueueIfNeeded(task_runner); if (scheduling_queue.empty()) { - TRACE_EVENT_NESTABLE_ASYNC_END0("gpu", "Scheduler::Running", this); + TRACE_EVENT_NESTABLE_ASYNC_END0("gpu", "Scheduler::Running", + TRACE_ID_LOCAL(this)); per_thread_state_map_[task_runner].running = false; return; } @@ -711,7 +715,8 @@ // Avoid scheduling another RunNextTask if we're done with all tasks. auto& scheduling_queue = RebuildSchedulingQueueIfNeeded(task_runner); if (scheduling_queue.empty()) { - TRACE_EVENT_NESTABLE_ASYNC_END0("gpu", "Scheduler::Running", this); + TRACE_EVENT_NESTABLE_ASYNC_END0("gpu", "Scheduler::Running", + TRACE_ID_LOCAL(this)); per_thread_state_map_[task_runner].running = false; return; }
diff --git a/gpu/ipc/client/raster_in_process_context_tests.cc b/gpu/ipc/client/raster_in_process_context_tests.cc index d8ad7b20..eb60e38 100644 --- a/gpu/ipc/client/raster_in_process_context_tests.cc +++ b/gpu/ipc/client/raster_in_process_context_tests.cc
@@ -107,7 +107,8 @@ // Call BeginRasterCHROMIUM. ri_->BeginRasterCHROMIUM( /*sk_color=*/0, /*needs_clear=*/true, /*msaa_sample_count=*/0, - /*can_use_lcd_text=*/false, color_space, mailbox.name); + gpu::raster::kNoMSAA, /*can_use_lcd_text=*/false, color_space, + mailbox.name); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), ri_->GetError()); // Should flag an error this command is not allowed between a Begin and
diff --git a/headless/test/headless_policy_browsertest.h b/headless/test/headless_policy_browsertest.h index 1617f56..31d4c9a 100644 --- a/headless/test/headless_policy_browsertest.h +++ b/headless/test/headless_policy_browsertest.h
@@ -23,10 +23,11 @@ virtual void SetPolicy() {} void SetUp() override { - mock_provider_ = - std::make_unique<policy::MockConfigurationPolicyProvider>(); - EXPECT_CALL(*mock_provider_.get(), IsInitializationComplete(testing::_)) - .WillRepeatedly(testing::Return(false)); + mock_provider_ = std::make_unique< + testing::NiceMock<policy::MockConfigurationPolicyProvider>>(); + mock_provider_->SetDefaultReturns( + /*is_initialization_complete_return=*/false, + /*is_first_policy_load_complete_return=*/false); policy::BrowserPolicyConnectorBase::SetPolicyProviderForTesting( mock_provider_.get()); SetPolicy();
diff --git a/infra/config/generated/commit-queue.cfg b/infra/config/generated/commit-queue.cfg index a670409c..9d5c7dd 100644 --- a/infra/config/generated/commit-queue.cfg +++ b/infra/config/generated/commit-queue.cfg
@@ -1098,6 +1098,9 @@ location_regexp: ".+/[+]/chromeos/dbus/chromebox_for_meetings/.+" location_regexp: ".+/[+]/chromeos/services/chromebox_for_meetings/.+" location_regexp: ".+/[+]/chrome/browser/chromeos/chromebox_for_meetings/.+" + location_regexp: ".+/[+]/chrome/browser/resources/chromeos/chromebox_for_meetings/.+" + location_regexp: ".+/[+]/chrome/browser/ui/webui/chromeos/chromebox_for_meetings/.+" + location_regexp: ".+/[+]/chrome/test/data/webui/chromeos/chromebox_for_meetings/.+" location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" }
diff --git a/infra/config/generated/cq-builders.md b/infra/config/generated/cq-builders.md index 7b150bc0..bf94a07 100644 --- a/infra/config/generated/cq-builders.md +++ b/infra/config/generated/cq-builders.md
@@ -287,6 +287,9 @@ * [`//chromeos/dbus/chromebox_for_meetings/.+`](https://cs.chromium.org/chromium/src/chromeos/dbus/chromebox_for_meetings/) * [`//chromeos/services/chromebox_for_meetings/.+`](https://cs.chromium.org/chromium/src/chromeos/services/chromebox_for_meetings/) * [`//chrome/browser/chromeos/chromebox_for_meetings/.+`](https://cs.chromium.org/chromium/src/chrome/browser/chromeos/chromebox_for_meetings/) + * [`//chrome/browser/resources/chromeos/chromebox_for_meetings/.+`](https://cs.chromium.org/chromium/src/chrome/browser/resources/chromeos/chromebox_for_meetings/) + * [`//chrome/browser/ui/webui/chromeos/chromebox_for_meetings/.+`](https://cs.chromium.org/chromium/src/chrome/browser/ui/webui/chromeos/chromebox_for_meetings/) + * [`//chrome/test/data/webui/chromeos/chromebox_for_meetings/.+`](https://cs.chromium.org/chromium/src/chrome/test/data/webui/chromeos/chromebox_for_meetings/) * [linux_chromium_dbg_ng](https://ci.chromium.org/p/chromium/builders/try/linux_chromium_dbg_ng) ([definition](https://cs.chromium.org/search?q=package:%5Echromium$+file:/cq.star$+-file:/beta/+-file:/stable/+linux_chromium_dbg_ng)) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+linux_chromium_dbg_ng))
diff --git a/infra/config/generated/cq-usage/full.cfg b/infra/config/generated/cq-usage/full.cfg index cb61eef3..33fe9a8 100644 --- a/infra/config/generated/cq-usage/full.cfg +++ b/infra/config/generated/cq-usage/full.cfg
@@ -329,6 +329,9 @@ location_regexp: ".+/[+]/chromeos/dbus/chromebox_for_meetings/.+" location_regexp: ".+/[+]/chromeos/services/chromebox_for_meetings/.+" location_regexp: ".+/[+]/chrome/browser/chromeos/chromebox_for_meetings/.+" + location_regexp: ".+/[+]/chrome/browser/resources/chromeos/chromebox_for_meetings/.+" + location_regexp: ".+/[+]/chrome/browser/ui/webui/chromeos/chromebox_for_meetings/.+" + location_regexp: ".+/[+]/chrome/test/data/webui/chromeos/chromebox_for_meetings/.+" location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" }
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index 404f3005..413d6a10 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -15596,10 +15596,6 @@ build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { - key: "chromium.isolate.use_new_lib" - value: 50 - } - experiments { key: "chromium.resultdb.result_sink" value: 100 } @@ -24325,10 +24321,6 @@ build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { - key: "chromium.isolate.use_new_lib" - value: 50 - } - experiments { key: "chromium.resultdb.result_sink" value: 100 } @@ -33980,12 +33972,11 @@ name: "fuchsia-official" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" + dimensions: "builder:fuchsia-official" dimensions: "cores:32" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" @@ -59314,7 +59305,7 @@ ' ],' ' "branch_script": "infra/config/scripts/branch.py",' ' "recipe": "branch_configuration/tester",' - ' "verification_scripts": [' + ' "starlark_entry_points": [' ' "infra/config/main.star",' ' "infra/config/dev.star"' ' ]'
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star index c095fa9..2fada4e3 100644 --- a/infra/config/subprojects/chromium/ci.star +++ b/infra/config/subprojects/chromium/ci.star
@@ -1497,6 +1497,7 @@ ci.chromium_builder( name = "fuchsia-official", branch_selector = branches.STANDARD_MILESTONE, + builderless = False, main_console_view = "main", console_view_entry = [ consoles.console_view_entry( @@ -5815,10 +5816,6 @@ cq_mirrors_console_view = "mirrors", main_console_view = "main", os = os.MAC_10_15, - experiments = { - # TODO(crbug.com/1225524): remove this. - "chromium.isolate.use_new_lib": 50, - }, ) ci.mac_builder( @@ -6430,10 +6427,6 @@ cores = 32, main_console_view = "main", os = os.WINDOWS_ANY, - experiments = { - # TODO(crbug.com/1225524): remove this. - "chromium.isolate.use_new_lib": 50, - }, ) ci.win_builder(
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star index 02c372a..090ea54 100644 --- a/infra/config/subprojects/chromium/try.star +++ b/infra/config/subprojects/chromium/try.star
@@ -890,6 +890,9 @@ ".+/[+]/chromeos/dbus/chromebox_for_meetings/.+", ".+/[+]/chromeos/services/chromebox_for_meetings/.+", ".+/[+]/chrome/browser/chromeos/chromebox_for_meetings/.+", + ".+/[+]/chrome/browser/resources/chromeos/chromebox_for_meetings/.+", + ".+/[+]/chrome/browser/ui/webui/chromeos/chromebox_for_meetings/.+", + ".+/[+]/chrome/test/data/webui/chromeos/chromebox_for_meetings/.+", ], ), ) @@ -2181,7 +2184,7 @@ "branch_types": [branch_type.DESKTOP_EXTENDED_STABLE, branch_type.CROS_LTS], }, ], - "verification_scripts": ["infra/config/main.star", "infra/config/dev.star"], + "starlark_entry_points": ["infra/config/main.star", "infra/config/dev.star"], }, tryjob = try_.job( location_regexp = [r".+/[+]/infra/config/.+"],
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 2ddaf0c..4b0b967 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1611,10 +1611,10 @@ Try again </message> <message name="IDS_IOS_PRIVACY_POLICY" desc="The label to access the privacy policy, displayed in the application settings, with no product name. [Length: 30em] [iOS only]"> - Privacy Notice + Google Privacy Policy </message> <message name="IDS_IOS_PRIVACY_POLICY_URL" translateable="false"> - http://www.google.com/intl/[GRITLANGCODE]/chrome/browser/privacy/ + https://policies.google.com/privacy </message> <message name="IDS_IOS_PROGRESS_BAR_ACCESSIBILITY" desc="Text read by voice over to inform the user about the progress of the page load. [Read by Text To Speech]."> Page load progress bar, <ph name="EMAIL">$1<ex>20%</ex></ph> loaded.
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PRIVACY_POLICY.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PRIVACY_POLICY.png.sha1 new file mode 100644 index 0000000..5e12730d --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PRIVACY_POLICY.png.sha1
@@ -0,0 +1 @@ +8b98a54113e3351642f96936014586ab3f4ffe75 \ No newline at end of file
diff --git a/ios/chrome/browser/passwords/password_controller_egtest.mm b/ios/chrome/browser/passwords/password_controller_egtest.mm index b6eb9ea..b86c221c 100644 --- a/ios/chrome/browser/passwords/password_controller_egtest.mm +++ b/ios/chrome/browser/passwords/password_controller_egtest.mm
@@ -109,13 +109,8 @@ #pragma mark - Tests // Tests that save password prompt is shown on new login. -- (void)testSavePromptAppearsOnFormSubmission { -#if TARGET_IPHONE_SIMULATOR - // TODO(crbug.com/1194134): Reenable this test. - if ([ChromeEarlGrey isIPadIdiom]) { - EARL_GREY_TEST_SKIPPED(@"Skipped for iPad (test is flaky)"); - } -#endif +// TODO(crbug.com/1192446): Reenable this test. +- (void)DISABLED_testSavePromptAppearsOnFormSubmission { [self loadLoginPage]; // Simulate user interacting with fields.
diff --git a/ios/chrome/browser/signin/BUILD.gn b/ios/chrome/browser/signin/BUILD.gn index 1f9672a..2b97eed 100644 --- a/ios/chrome/browser/signin/BUILD.gn +++ b/ios/chrome/browser/signin/BUILD.gn
@@ -127,6 +127,7 @@ "chrome_identity_service_observer_bridge_unittest.mm", "gaia_auth_fetcher_ios_ns_url_session_bridge_unittests.mm", "gaia_auth_fetcher_ios_unittest.mm", + "pattern_account_restriction_unittest.mm", "signin_browser_state_info_updater_unittest.mm", "user_approved_account_list_manager_unittest.mm", ]
diff --git a/ios/chrome/browser/signin/pattern_account_restriction_unittest.mm b/ios/chrome/browser/signin/pattern_account_restriction_unittest.mm new file mode 100644 index 0000000..cb6c087 --- /dev/null +++ b/ios/chrome/browser/signin/pattern_account_restriction_unittest.mm
@@ -0,0 +1,78 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/signin/pattern_account_restriction.h" + +#include "base/values.h" +#import "testing/gtest_mac.h" +#import "testing/platform_test.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { +const std::string email1 = "foo@gmail.com"; +const std::string email2 = "foo2@google.com"; +const std::string email3 = "foo3@chromium.com"; +} // namespace + +class PatternAccountRestrictionTest : public PlatformTest {}; + +// Tests that the PatternAccountRestriction filters email correctly when +// restrictions are set. +TEST_F(PatternAccountRestrictionTest, FilterEmailsWithRestrictions) { + base::ListValue value; + value.AppendString("*gmail.com"); + value.AppendString("*google.com"); + auto restriction = PatternAccountRestrictionFromValue(&value); + + CHECK_EQ(restriction->IsAccountRestricted(email1), false); + CHECK_EQ(restriction->IsAccountRestricted(email2), false); + CHECK_EQ(restriction->IsAccountRestricted(email3), true); +} + +// Tests that the PatternAccountRestriction does not filter emails when +// restrictions are not set. +TEST_F(PatternAccountRestrictionTest, FilterEmailsWithoutRestriction) { + base::ListValue value; + auto restriction = PatternAccountRestrictionFromValue(&value); + + CHECK_EQ(restriction->IsAccountRestricted(email1), false); + CHECK_EQ(restriction->IsAccountRestricted(email2), false); + CHECK_EQ(restriction->IsAccountRestricted(email3), false); +} + +// Tests that the pattern created by PatternFromString(chunk) correctlty matches +// the given email. The wildcard character '*' matches zero or more arbitrary +// characters.The escape character is '\', so to match actual '*' or '\' +// characters, put a '\' in front of them. +TEST_F(PatternAccountRestrictionTest, PatternMatchChunck) { + auto pattern = PatternFromString("*gmail.com"); + CHECK_EQ(pattern->Match(email1), true); + CHECK_EQ(pattern->Match(email2), false); + CHECK_EQ(pattern->Match(email3), false); + + pattern = PatternFromString("gmail.com"); + CHECK_EQ(pattern->Match(email1), false); + CHECK_EQ(pattern->Match(email2), false); + CHECK_EQ(pattern->Match(email3), false); + + pattern = PatternFromString("foo*"); + CHECK_EQ(pattern->Match(email1), true); + CHECK_EQ(pattern->Match(email2), true); + CHECK_EQ(pattern->Match(email3), true); + + // "foo\\*@gmail.com" is actually "foo\*@gmail.com". The escape character '\' + // is doubled here because it's also an escape character for std::string. + pattern = PatternFromString("foo\\*@gmail.com"); + CHECK_EQ(pattern->Match(email1), false); + CHECK_EQ(pattern->Match("foo*@gmail.com"), true); + + // "foo\\\\*" is "actually foo\\*". + pattern = PatternFromString("foo\\\\*"); + CHECK_EQ(pattern->Match(email1), false); + // "foo\\@gmail.com" is actually "foo\@gmail.com". + CHECK_EQ(pattern->Match("foo\\@gmail.com"), true); +}
diff --git a/ios/chrome/browser/ui/activity_services/activities/BUILD.gn b/ios/chrome/browser/ui/activity_services/activities/BUILD.gn index 501a0406..6f74ceb 100644 --- a/ios/chrome/browser/ui/activity_services/activities/BUILD.gn +++ b/ios/chrome/browser/ui/activity_services/activities/BUILD.gn
@@ -77,6 +77,7 @@ "//ios/chrome/browser/ui/bookmarks:test_support", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/util", + "//ios/chrome/browser/ui/util:url_with_title", "//ios/web/public/test", "//testing/gtest", "//third_party/ocmock",
diff --git a/ios/chrome/browser/ui/activity_services/activities/bookmark_activity.mm b/ios/chrome/browser/ui/activity_services/activities/bookmark_activity.mm index 77508092..1829eac 100644 --- a/ios/chrome/browser/ui/activity_services/activities/bookmark_activity.mm +++ b/ios/chrome/browser/ui/activity_services/activities/bookmark_activity.mm
@@ -9,7 +9,7 @@ #import "components/bookmarks/browser/bookmark_model.h" #import "components/bookmarks/common/bookmark_pref_names.h" #import "components/prefs/pref_service.h" -#import "ios/chrome/browser/ui/commands/bookmark_page_command.h" +#import "ios/chrome/browser/ui/commands/bookmark_add_command.h" #import "ios/chrome/browser/ui/commands/bookmarks_commands.h" #import "ios/chrome/browser/ui/commands/browser_commands.h" #import "ios/chrome/grit/ios_strings.h" @@ -94,8 +94,8 @@ } - (void)performActivity { - BookmarkPageCommand* command = - [[BookmarkPageCommand alloc] initWithURL:self.URL title:self.title]; + BookmarkAddCommand* command = + [[BookmarkAddCommand alloc] initWithURL:self.URL title:self.title]; [self.handler bookmarkPage:command]; [self activityDidFinish:YES]; }
diff --git a/ios/chrome/browser/ui/activity_services/activities/bookmark_activity_unittest.mm b/ios/chrome/browser/ui/activity_services/activities/bookmark_activity_unittest.mm index 98eb76fe..b5af5ccc 100644 --- a/ios/chrome/browser/ui/activity_services/activities/bookmark_activity_unittest.mm +++ b/ios/chrome/browser/ui/activity_services/activities/bookmark_activity_unittest.mm
@@ -10,8 +10,9 @@ #include "components/prefs/pref_registry_simple.h" #include "components/prefs/testing_pref_service.h" #include "ios/chrome/browser/ui/bookmarks/bookmark_ios_unittest.h" -#include "ios/chrome/browser/ui/commands/bookmark_page_command.h" +#include "ios/chrome/browser/ui/commands/bookmark_add_command.h" #include "ios/chrome/browser/ui/commands/bookmarks_commands.h" +#import "ios/chrome/browser/ui/util/url_with_title.h" #include "ios/chrome/grit/ios_strings.h" #import "third_party/ocmock/OCMock/OCMock.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -115,14 +116,14 @@ EXPECT_TRUE([editBookmarkString isEqualToString:activity.activityTitle]); } -TEST_F(BookmarkActivityTest, PerformActivity_BookmarkPageCommand) { +TEST_F(BookmarkActivityTest, PerformActivity_BookmarkAddCommand) { GURL testUrl("https://example.com/"); BookmarkActivity* activity = CreateActivity(testUrl); [[mocked_handler_ expect] - bookmarkPage:[OCMArg checkWithBlock:^BOOL(BookmarkPageCommand* value) { - EXPECT_EQ(testUrl, value.URL); - EXPECT_EQ(kTestTitle, value.title); + bookmarkPage:[OCMArg checkWithBlock:^BOOL(BookmarkAddCommand* value) { + EXPECT_EQ(testUrl, value.URLs.firstObject.URL); + EXPECT_EQ(kTestTitle, value.URLs.firstObject.title); return YES; }]];
diff --git a/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_view_controller.mm b/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_view_controller.mm index 1f8de3b7..a7faac15 100644 --- a/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_view_controller.mm
@@ -103,7 +103,8 @@ scrollView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:scrollView]; [NSLayoutConstraint activateConstraints:@[ - [scrollView.topAnchor constraintEqualToAnchor:self.view.topAnchor], + [scrollView.topAnchor + constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], [scrollView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor], [scrollView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], [scrollView.trailingAnchor
diff --git a/ios/chrome/browser/ui/autofill/card_expiration_date_fix_flow_view_bridge.mm b/ios/chrome/browser/ui/autofill/card_expiration_date_fix_flow_view_bridge.mm index d938f4f..e809c7f5 100644 --- a/ios/chrome/browser/ui/autofill/card_expiration_date_fix_flow_view_bridge.mm +++ b/ios/chrome/browser/ui/autofill/card_expiration_date_fix_flow_view_bridge.mm
@@ -14,7 +14,6 @@ #import "ios/chrome/browser/ui/list_model/list_model.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_text_edit_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h" -#import "ios/chrome/browser/ui/util/label_link_controller.h" #import "ios/chrome/browser/ui/util/rtl_geometry.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h"
diff --git a/ios/chrome/browser/ui/autofill/card_name_fix_flow_view_bridge.mm b/ios/chrome/browser/ui/autofill/card_name_fix_flow_view_bridge.mm index 739e45e..7abf45b 100644 --- a/ios/chrome/browser/ui/autofill/card_name_fix_flow_view_bridge.mm +++ b/ios/chrome/browser/ui/autofill/card_name_fix_flow_view_bridge.mm
@@ -13,7 +13,6 @@ #import "ios/chrome/browser/ui/list_model/list_model.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_text_edit_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h" -#import "ios/chrome/browser/ui/util/label_link_controller.h" #import "ios/chrome/browser/ui/util/rtl_geometry.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h"
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm b/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm index 1152b48..33a82683 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm
@@ -425,7 +425,8 @@ // Test the input accessory bar is present when undocking then docking the // keyboard. -- (void)testInputAccessoryBarIsPresentAfterUndockingKeyboard { +// TODO(crbug.com/1218869): Re-enable this test. +- (void)DISABLED_testInputAccessoryBarIsPresentAfterUndockingKeyboard { if (![ChromeEarlGrey isIPadIdiom]) { EARL_GREY_TEST_SKIPPED(@"Test not applicable for iPhone."); }
diff --git a/ios/chrome/browser/ui/bubble/bubble_view_controller_presenter.mm b/ios/chrome/browser/ui/bubble/bubble_view_controller_presenter.mm index 159a5d5..7ecf10d 100644 --- a/ios/chrome/browser/ui/bubble/bubble_view_controller_presenter.mm +++ b/ios/chrome/browser/ui/bubble/bubble_view_controller_presenter.mm
@@ -132,6 +132,10 @@ self.bubbleViewController.view.frame = [self frameForBubbleInRect:parentView.bounds atAnchorPoint:anchorPointInParent]; + // If the bubble's frame is not set, we abandon this IPH attempt. + if (CGRectIsEmpty(self.bubbleViewController.view.frame)) { + return; + } [parentView addSubview:self.bubbleViewController.view]; [self.bubbleViewController animateContentIn]; @@ -265,8 +269,10 @@ // partially off screen and not look good. This is most likely a result of // an incorrect value for |alignment| (such as a trailing aligned bubble // anchored to an element on the leading edge of the screen). - DCHECK(bubbleSize.width <= maxBubbleSize.width); - DCHECK(bubbleSize.height <= maxBubbleSize.height); + if (bubbleSize.width > maxBubbleSize.width || + bubbleSize.height > maxBubbleSize.height) { + return CGRectNull; + } CGRect bubbleFrame = bubble_util::BubbleFrame(anchorPoint, bubbleSize, self.arrowDirection, self.alignment, CGRectGetWidth(rect));
diff --git a/ios/chrome/browser/ui/commands/BUILD.gn b/ios/chrome/browser/ui/commands/BUILD.gn index 7cb2cc2..c2ffbcd 100644 --- a/ios/chrome/browser/ui/commands/BUILD.gn +++ b/ios/chrome/browser/ui/commands/BUILD.gn
@@ -8,8 +8,8 @@ sources = [ "activity_service_commands.h", "application_commands.h", - "bookmark_page_command.h", - "bookmark_page_command.mm", + "bookmark_add_command.h", + "bookmark_add_command.mm", "bookmarks_commands.h", "browser_commands.h", "browser_coordinator_commands.h",
diff --git a/ios/chrome/browser/ui/commands/bookmark_add_command.h b/ios/chrome/browser/ui/commands/bookmark_add_command.h new file mode 100644 index 0000000..5cf5f15 --- /dev/null +++ b/ios/chrome/browser/ui/commands/bookmark_add_command.h
@@ -0,0 +1,31 @@ +// 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 IOS_CHROME_BROWSER_UI_COMMANDS_BOOKMARK_ADD_COMMAND_H_ +#define IOS_CHROME_BROWSER_UI_COMMANDS_BOOKMARK_ADD_COMMAND_H_ + +#import <Foundation/Foundation.h> + +class GURL; +@class URLWithTitle; + +// An object of this class will contain the data needed to execute any bookmark +// command for one or more pages. +@interface BookmarkAddCommand : NSObject + +// Initializes a command object with the page's |URL| and |title|. +- (instancetype)initWithURL:(const GURL&)URL + title:(NSString*)title NS_DESIGNATED_INITIALIZER; + +// Initializes a command object with multiple pages |UrlWithTitle|. +- (instancetype)initWithURLs:(NSArray<URLWithTitle*>*)URL + NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +@property(nonatomic, readonly) NSArray<URLWithTitle*>* URLs; + +@end + +#endif // IOS_CHROME_BROWSER_UI_COMMANDS_BOOKMARK_ADD_COMMAND_H_
diff --git a/ios/chrome/browser/ui/commands/bookmark_add_command.mm b/ios/chrome/browser/ui/commands/bookmark_add_command.mm new file mode 100644 index 0000000..8163148 --- /dev/null +++ b/ios/chrome/browser/ui/commands/bookmark_add_command.mm
@@ -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. + +#import "ios/chrome/browser/ui/commands/bookmark_add_command.h" + +#import "ios/chrome/browser/ui/util/url_with_title.h" +#import "url/gurl.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface BookmarkAddCommand () + +@property(nonatomic, strong) NSArray<URLWithTitle*>* URLs; + +@end + +@implementation BookmarkAddCommand + +@synthesize URLs = _URLs; + +- (instancetype)initWithURL:(const GURL&)URL title:(NSString*)title { + if (self = [super init]) { + _URLs = @[ [[URLWithTitle alloc] initWithURL:URL title:title] ]; + } + return self; +} + +- (instancetype)initWithURLs:(NSArray<URLWithTitle*>*)URLs { + if (self = [super init]) { + _URLs = [URLs copy]; + } + return self; +} + +@end
diff --git a/ios/chrome/browser/ui/commands/bookmark_page_command.h b/ios/chrome/browser/ui/commands/bookmark_page_command.h deleted file mode 100644 index 899aa3bd..0000000 --- a/ios/chrome/browser/ui/commands/bookmark_page_command.h +++ /dev/null
@@ -1,27 +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 IOS_CHROME_BROWSER_UI_COMMANDS_BOOKMARK_PAGE_COMMAND_H_ -#define IOS_CHROME_BROWSER_UI_COMMANDS_BOOKMARK_PAGE_COMMAND_H_ - -#import <Foundation/Foundation.h> - -class GURL; - -// Command to handle a bookmark request for a given page. The page will be -// bookmarked unless it already is. In that case, the "edit bookmark" flow -// will be triggered. -@interface BookmarkPageCommand : NSObject - -// Initializes a command object with the page's |URL| and |title|. -- (instancetype)initWithURL:(const GURL&)URL - title:(NSString*)title NS_DESIGNATED_INITIALIZER; -- (instancetype)init NS_UNAVAILABLE; - -@property(nonatomic, readonly) const GURL& URL; -@property(copy, nonatomic, readonly) NSString* title; - -@end - -#endif // IOS_CHROME_BROWSER_UI_COMMANDS_BOOKMARK_PAGE_COMMAND_H_
diff --git a/ios/chrome/browser/ui/commands/bookmark_page_command.mm b/ios/chrome/browser/ui/commands/bookmark_page_command.mm deleted file mode 100644 index d4d113f4..0000000 --- a/ios/chrome/browser/ui/commands/bookmark_page_command.mm +++ /dev/null
@@ -1,25 +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. - -#import "ios/chrome/browser/ui/commands/bookmark_page_command.h" - -#import "url/gurl.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@implementation BookmarkPageCommand { - GURL _URL; -} - -- (instancetype)initWithURL:(const GURL&)URL title:(NSString*)title { - if (self = [super init]) { - _URL = URL; - _title = title; - } - return self; -} - -@end
diff --git a/ios/chrome/browser/ui/commands/bookmarks_commands.h b/ios/chrome/browser/ui/commands/bookmarks_commands.h index 3669e786..08e6e78 100644 --- a/ios/chrome/browser/ui/commands/bookmarks_commands.h +++ b/ios/chrome/browser/ui/commands/bookmarks_commands.h
@@ -8,15 +8,16 @@ #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> -#import "ios/chrome/browser/ui/commands/bookmark_page_command.h" +#import "ios/chrome/browser/ui/commands/bookmark_add_command.h" @class ReadingListAddCommand; // Protocol for commands arounds Bookmarks manipulation. @protocol BookmarksCommands <NSObject> -// Bookmarks the page detailed in |command|'s data. -- (void)bookmarkPage:(BookmarkPageCommand*)command; +// Bookmarks the page detailed in |command|'s data unless it's already +// bookmarked, in that case the "edit bookmark" flow will be triggered. +- (void)bookmarkPage:(BookmarkAddCommand*)command; @end
diff --git a/ios/chrome/browser/ui/sharing/sharing_coordinator.mm b/ios/chrome/browser/ui/sharing/sharing_coordinator.mm index 48073c8..662c151 100644 --- a/ios/chrome/browser/ui/sharing/sharing_coordinator.mm +++ b/ios/chrome/browser/ui/sharing/sharing_coordinator.mm
@@ -16,7 +16,7 @@ #import "ios/chrome/browser/ui/activity_services/requirements/activity_service_presentation.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_edit_coordinator.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_mediator.h" -#import "ios/chrome/browser/ui/commands/bookmark_page_command.h" +#import "ios/chrome/browser/ui/commands/bookmark_add_command.h" #import "ios/chrome/browser/ui/commands/bookmarks_commands.h" #import "ios/chrome/browser/ui/commands/command_dispatcher.h" #import "ios/chrome/browser/ui/commands/qr_generation_commands.h" @@ -144,9 +144,11 @@ #pragma mark - BookmarksCommands -- (void)bookmarkPage:(BookmarkPageCommand*)command { +- (void)bookmarkPage:(BookmarkAddCommand*)command { DCHECK(command); - DCHECK(command.URL.is_valid()); + GURL URL = command.URLs.firstObject.URL; + NSString* title = command.URLs.firstObject.title; + DCHECK(URL.is_valid()); ChromeBrowserState* browserState = self.browser->GetBrowserState(); bookmarks::BookmarkModel* bookmarkModel = @@ -156,7 +158,7 @@ } const BookmarkNode* node = - bookmarkModel->GetMostRecentlyAddedUserNodeForURL(command.URL); + bookmarkModel->GetMostRecentlyAddedUserNodeForURL(URL); if (node) { // Trigger the Edit bookmark scenario. [self editBookmark:node]; @@ -174,7 +176,7 @@ } const BookmarkNode* newNode = - bookmarkModel->GetMostRecentlyAddedUserNodeForURL(command.URL); + bookmarkModel->GetMostRecentlyAddedUserNodeForURL(URL); DCHECK(newNode); if (newNode) { [weakSelf editBookmark:newNode]; @@ -182,9 +184,7 @@ }; MDCSnackbarMessage* snackbarMessage = - [mediator addBookmarkWithTitle:command.title - URL:command.URL - editAction:editAction]; + [mediator addBookmarkWithTitle:title URL:URL editAction:editAction]; [handler showSnackbarMessage:snackbarMessage]; } }
diff --git a/ios/chrome/browser/ui/sharing/sharing_coordinator_unittest.mm b/ios/chrome/browser/ui/sharing/sharing_coordinator_unittest.mm index 4e38c40..7a07ceef 100644 --- a/ios/chrome/browser/ui/sharing/sharing_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/sharing/sharing_coordinator_unittest.mm
@@ -22,7 +22,7 @@ #import "ios/chrome/browser/ui/bookmarks/bookmark_edit_coordinator.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_ios_unittest.h" -#import "ios/chrome/browser/ui/commands/bookmark_page_command.h" +#import "ios/chrome/browser/ui/commands/bookmark_add_command.h" #import "ios/chrome/browser/ui/commands/bookmarks_commands.h" #import "ios/chrome/browser/ui/commands/command_dispatcher.h" #import "ios/chrome/browser/ui/commands/generate_qr_code_command.h" @@ -293,17 +293,18 @@ GURL test_url("https://wwww.chromium.org"); NSString* test_title = @"Test Title"; - BookmarkPageCommand* command = - [[BookmarkPageCommand alloc] initWithURL:test_url title:test_title]; + BookmarkAddCommand* command = + [[BookmarkAddCommand alloc] initWithURL:test_url title:test_title]; - ASSERT_EQ(nil, - bookmark_model_->GetMostRecentlyAddedUserNodeForURL(command.URL)); + ASSERT_EQ(nil, bookmark_model_->GetMostRecentlyAddedUserNodeForURL( + command.URLs.firstObject.URL)); auto handler = static_cast<id<BookmarksCommands>>(coordinator); [handler bookmarkPage:command]; const BookmarkNode* bookmark = - bookmark_model_->GetMostRecentlyAddedUserNodeForURL(command.URL); + bookmark_model_->GetMostRecentlyAddedUserNodeForURL( + command.URLs.firstObject.URL); ASSERT_NE(nil, bookmark); EXPECT_EQ(test_url, bookmark->url()); @@ -336,12 +337,12 @@ AddBookmark(bookmark_model_->mobile_node(), @"Some Other Title"); NSString* test_title = @"Test Title"; - BookmarkPageCommand* command = - [[BookmarkPageCommand alloc] initWithURL:bookmark->url() - title:test_title]; + BookmarkAddCommand* command = + [[BookmarkAddCommand alloc] initWithURL:bookmark->url() + title:test_title]; - ASSERT_EQ(bookmark, - bookmark_model_->GetMostRecentlyAddedUserNodeForURL(command.URL)); + ASSERT_EQ(bookmark, bookmark_model_->GetMostRecentlyAddedUserNodeForURL( + command.URLs.firstObject.URL)); auto handler = static_cast<id<BookmarksCommands>>(coordinator);
diff --git a/ios/chrome/browser/ui/translate/translate_infobar_view.mm b/ios/chrome/browser/ui/translate/translate_infobar_view.mm index 7917cfc..f9188c8 100644 --- a/ios/chrome/browser/ui/translate/translate_infobar_view.mm +++ b/ios/chrome/browser/ui/translate/translate_infobar_view.mm
@@ -17,7 +17,6 @@ #import "ios/chrome/browser/ui/translate/translate_infobar_language_tab_strip_view_delegate.h" #import "ios/chrome/browser/ui/translate/translate_infobar_view_constants.h" #import "ios/chrome/browser/ui/translate/translate_infobar_view_delegate.h" -#import "ios/chrome/browser/ui/util/label_link_controller.h" #import "ios/chrome/browser/ui/util/layout_guide_names.h" #import "ios/chrome/browser/ui/util/named_guide.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
diff --git a/ios/chrome/browser/ui/util/BUILD.gn b/ios/chrome/browser/ui/util/BUILD.gn index 5a8af4ca..73de8c4 100644 --- a/ios/chrome/browser/ui/util/BUILD.gn +++ b/ios/chrome/browser/ui/util/BUILD.gn
@@ -8,14 +8,10 @@ source_set("util") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ - "CRUILabel+AttributeUtils.h", - "CRUILabel+AttributeUtils.mm", "accessibility_close_menu_button.h", "accessibility_close_menu_button.mm", "animation_util.h", "animation_util.mm", - "core_text_util.h", - "core_text_util.mm", "dynamic_type_util.h", "dynamic_type_util.mm", "force_touch_long_press_gesture_recognizer.h", @@ -24,14 +20,8 @@ "i18n_string.mm", "keyboard_observer_helper.h", "keyboard_observer_helper.mm", - "label_link_controller.h", - "label_link_controller.mm", - "label_observer.h", - "label_observer.mm", "layout_guide_names.h", "layout_guide_names.mm", - "manual_text_framer.h", - "manual_text_framer.mm", "named_guide.h", "named_guide.mm", "named_guide_util.h", @@ -48,10 +38,6 @@ "reversed_animation.mm", "rtl_geometry.h", "rtl_geometry.mm", - "text_frame.h", - "text_frame.mm", - "text_region_mapper.h", - "text_region_mapper.mm", "top_view_controller.h", "top_view_controller.mm", "transparent_link_button.h", @@ -116,17 +102,11 @@ configs += [ "//build/config/compiler:enable_arc" ] testonly = true sources = [ - "CRUILabel+AttributeUtils_unittest.mm", - "core_text_util_unittest.mm", "force_touch_long_press_gesture_recognizer_unittest.mm", - "label_link_controller_unittest.mm", - "label_observer_unittest.mm", - "manual_text_framer_unittest.mm", "named_guide_unittest.mm", "optional_property_animator_unittest.mm", "pasteboard_util_unittest.mm", "terms_util_unittest.mm", - "text_region_mapper_unittest.mm", "ui_util_unittest.mm", "uikit_ui_util_unittest.mm", ]
diff --git a/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.h b/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.h deleted file mode 100644 index 2e1a95d..0000000 --- a/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_UTIL_CRUILABEL_ATTRIBUTEUTILS_H_ -#define IOS_CHROME_BROWSER_UI_UTIL_CRUILABEL_ATTRIBUTEUTILS_H_ - -#import <UIKit/UIKit.h> - -@interface UILabel (CRUILabelAttributeUtils) -// The line height for the text in the receiver. -// Make sure to create a LabelObserver for this label and start observing before -// setting this property. When the last LabelObserver is removed for a label -// where this property is set, there is no expected behavior for the line -// height on further text changes -- it may be retained or overwritten. -// -// TODO(crbug.com/980510) : When iOS12 support is removed, determine if this -// property is still needed, or if (under iOS13+) setting the line height -// in a paragraph style persits across label frame changes. -// -@property(nonatomic, assign, setter=cr_setLineHeight:) CGFloat cr_lineHeight; - -@end - -#endif // IOS_CHROME_BROWSER_UI_UTIL_CRUILABEL_ATTRIBUTEUTILS_H_
diff --git a/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.mm b/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.mm deleted file mode 100644 index f1c1fe88..0000000 --- a/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.mm +++ /dev/null
@@ -1,79 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.h" - -#import <objc/runtime.h> - -#include "base/check_op.h" -#import "ios/chrome/browser/ui/util/label_observer.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { -// They key under which to associate the line height with the label. -const void* const kLineHeightKey = &kLineHeightKey; -// Creates an NSNumber from |line_height| and associates it with |label|. -void SetAssociatedLineHeight(CGFloat line_height, UILabel* label) { - objc_setAssociatedObject(label, kLineHeightKey, @(line_height), - OBJC_ASSOCIATION_RETAIN_NONATOMIC); -} -// Returns the line height associated with |label|. -CGFloat GetAssociatedLineHeight(UILabel* label) { - return [objc_getAssociatedObject(label, kLineHeightKey) floatValue]; -} -} - -@implementation UILabel (CRUILabelAttributeUtils) - -// If there's no text in the label, the line height is whatever is stored in the -// associated value. -- (CGFloat)cr_lineHeight { - if (!self.text.length || !self.attributedText.string.length) - return GetAssociatedLineHeight(self); - NSParagraphStyle* style = - [self.attributedText attribute:NSParagraphStyleAttributeName - atIndex:0 - effectiveRange:nullptr]; - return style.maximumLineHeight; -} - -- (void)cr_setLineHeight:(CGFloat)lineHeight { - DCHECK_GT(lineHeight, 0.0); - // If this is the first time the line height is being set, register the - // LabelObserverAction. - if (!GetAssociatedLineHeight(self)) { - LabelObserver* observer = [LabelObserver observerForLabel:self]; - [observer addTextChangedAction:^(UILabel* label) { - label.cr_lineHeight = GetAssociatedLineHeight(label); - }]; - } - - // Store the new line height as an associated object. - SetAssociatedLineHeight(lineHeight, self); - - // If there's no text yet, there's nothing that can be done. The - // LabelObserverAction will call this selector again upon changes to the text. - if (!self.text.length || !self.attributedText.string.length) - return; - - NSMutableAttributedString* newString = [self.attributedText mutableCopy]; - DCHECK([newString length]); - NSParagraphStyle* style = [newString attribute:NSParagraphStyleAttributeName - atIndex:0 - effectiveRange:nullptr]; - if (!style) - style = [NSParagraphStyle defaultParagraphStyle]; - NSMutableParagraphStyle* newStyle = [style mutableCopy]; - [newStyle setMinimumLineHeight:lineHeight]; - [newStyle setMaximumLineHeight:lineHeight]; - [newString addAttribute:NSParagraphStyleAttributeName - value:newStyle - range:NSMakeRange(0, [newString length])]; - self.attributedText = newString; -} - -@end
diff --git a/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils_unittest.mm b/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils_unittest.mm deleted file mode 100644 index 0d436bf..0000000 --- a/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils_unittest.mm +++ /dev/null
@@ -1,131 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.h" - -#import "ios/chrome/browser/ui/util/label_observer.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/gtest_mac.h" -#include "testing/platform_test.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { -class UILabelAttributeUtilsTest : public PlatformTest { - protected: - void SetUp() override { - PlatformTest::SetUp(); - _scopedLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - _observer = [LabelObserver observerForLabel:_scopedLabel]; - [_observer startObserving]; - } - - ~UILabelAttributeUtilsTest() override { [_observer stopObserving]; } - - void CheckLabelLineHeight(CGFloat expected_height) { - UILabel* label = _scopedLabel; - EXPECT_NE(nil, label.attributedText); - NSParagraphStyle* style = - [label.attributedText attribute:NSParagraphStyleAttributeName - atIndex:0 - effectiveRange:nullptr]; - EXPECT_NE(nil, style); - EXPECT_EQ(expected_height, style.maximumLineHeight); - EXPECT_EQ(expected_height, label.cr_lineHeight); - } - UILabel* _scopedLabel; - LabelObserver* _observer; -}; -} // namespace - -TEST_F(UILabelAttributeUtilsTest, TwoObservers) { - UILabel* label = _scopedLabel; - label.text = @"sample text"; - - NSMutableAttributedString* textWithLineHeight = - [[NSMutableAttributedString alloc] - initWithString:@"attributed sample text"]; - NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init]; - style.maximumLineHeight = 15.0; - [textWithLineHeight addAttribute:NSParagraphStyleAttributeName - value:style - range:NSMakeRange(0, [textWithLineHeight length])]; - - // Add a second observer. - LabelObserver* secondObserver = [LabelObserver observerForLabel:label]; - [secondObserver startObserving]; - - // Modify the line height with two observers. - label.cr_lineHeight = 18.0; - CheckLabelLineHeight(18.0); - [secondObserver stopObserving]; - secondObserver = nil; - - // Even when one observer is stopped, the second is still observing. - label.cr_lineHeight = 21.0; - CheckLabelLineHeight(21.0); - - // Once both are stopped, the height isn't persisted when the text changes. - [_observer stopObserving]; - label.cr_lineHeight = 25.0; - label.attributedText = textWithLineHeight; - CheckLabelLineHeight(15.0); -} - -TEST_F(UILabelAttributeUtilsTest, SettingTests) { - UILabel* label = _scopedLabel; - - // A label should have a line height of 0 if nothing has been specified yet. - EXPECT_EQ(0.0, label.cr_lineHeight); - - label.text = @"sample text"; - label.cr_lineHeight = 20.0; - CheckLabelLineHeight(20.0); - label.text = @"longer sample text"; - CheckLabelLineHeight(20.0); - - NSMutableAttributedString* string = [[NSMutableAttributedString alloc] - initWithString:@"attributed sample text"]; - label.attributedText = [string copy]; - CheckLabelLineHeight(20.0); - [string addAttribute:NSForegroundColorAttributeName - value:[UIColor brownColor] - range:NSMakeRange(0, [string length])]; - label.attributedText = [string copy]; - CheckLabelLineHeight(20.0); - NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init]; - style.maximumLineHeight = 15.0; - [string addAttribute:NSParagraphStyleAttributeName - value:style - range:NSMakeRange(0, [string length])]; - label.attributedText = [string copy]; - CheckLabelLineHeight(20.0); -} - -TEST_F(UILabelAttributeUtilsTest, NullTextTest) { - UILabel* label = _scopedLabel; - - label.cr_lineHeight = 19.0; - EXPECT_EQ(19.0, label.cr_lineHeight); - label.text = @"sample text"; - CheckLabelLineHeight(19.0); -} - -TEST_F(UILabelAttributeUtilsTest, NullAttrTextTest) { - UILabel* label = _scopedLabel; - NSMutableAttributedString* string = [[NSMutableAttributedString alloc] - initWithString:@"attributed sample text"]; - NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init]; - style.maximumLineHeight = 15.0; - [string addAttribute:NSParagraphStyleAttributeName - value:style - range:NSMakeRange(0, [string length])]; - - label.cr_lineHeight = 19.0; - EXPECT_EQ(19.0, label.cr_lineHeight); - label.attributedText = string; - CheckLabelLineHeight(19.0); -}
diff --git a/ios/chrome/browser/ui/util/core_text_util.h b/ios/chrome/browser/ui/util/core_text_util.h deleted file mode 100644 index 803c03f..0000000 --- a/ios/chrome/browser/ui/util/core_text_util.h +++ /dev/null
@@ -1,85 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_UTIL_CORE_TEXT_UTIL_H_ -#define IOS_CHROME_BROWSER_UI_UTIL_CORE_TEXT_UTIL_H_ - -#import <CoreText/CoreText.h> -#import <UIKit/UIKit.h> - -#import "base/mac/scoped_cftyperef.h" - -@class ManualTextFramer; - -namespace core_text_util { - -// Uses CTFrameSetter to create a CTFrameRef corresponding to |string| drawn -// within the path described by |bounds|. -base::ScopedCFTypeRef<CTFrameRef> CreateTextFrameForStringInBounds( - NSAttributedString* string, - CGRect bounds); - -// The CTFrames returned by CTFameSetter sometimes erroneously frame the same -// portion of the original string twice. In addition, these CTFrames may have -// innacurate ranges for RTL languages. This function returns true if the -// string range for |text_frame| returned by CTFrameGetVisibleStringRange() is -// properly framed with no repeats and if the string range length of -// |text_frame| matches the string range length of the frame generated by -// |manual_framer|, which more accurately handles creating string ranges for RTL -// strings. |string| is the attributed string from which |text_frame| and -// |manual_framer| were created. -bool IsTextFrameValid(CTFrameRef text_frame, - ManualTextFramer* manual_framer, - NSAttributedString* string); - -// Returns the width of the typographic bounds for |line|, excluding trailing -// whitespace. -CGFloat GetTrimmedLineWidth(CTLineRef line); - -// Returns the width of the typographic bounds for the glyphs in |range| for -// |run|. -CGFloat GetRunWidthWithRange(CTRunRef run, CFRange range); - -// Returns the width of the typographic bounds for the glyph in |run| at -// |glyph_idx|. -CGFloat GetGlyphWidth(CTRunRef run, CFIndex glyph_idx); - -// Returns the index of the first glyph in the leading direction in |range| for -// |run| that corresponds with a character that is a member of |set|. |string| -// is the string from which |run| was created, and is used to map from glyphs to -// characters. Returns kCFNotFound if no glyphs are found. -CFIndex GetGlyphIdxForCharInSet(CTRunRef run, - CFRange range, - NSAttributedString* string, - NSCharacterSet* set); - -// Returns the index of the character corresponding with the glyph at -// |glyph_idx| in |run|. -NSUInteger GetStringIdxForGlyphIdx(CTRunRef run, CFIndex glyph_idx); - -// Returns the string range associated with |run|. -NSRange GetStringRangeForRun(CTRunRef run); - -// Enumerates each attributes dictionary for |range| in |string| and executes -// |block| on the dictionary. -typedef void (^AttributesBlock)(NSDictionary* attributes); -void EnumerateAttributesInString(NSAttributedString* string, - NSRange range, - AttributesBlock block); - -// Returns the line height for |range| in |string|. -CGFloat GetLineHeight(NSAttributedString* string, NSRange range); - -// Returns the line spacing for |range| in |string|. -CGFloat GetLineSpacing(NSAttributedString* string, NSRange range); - -// Returns the effective text alignment for |string|. -NSTextAlignment GetEffectiveTextAlignment(NSAttributedString* string); - -// Returns the effective writing direction for |string|. -NSWritingDirection GetEffectiveWritingDirection(NSAttributedString* string); - -} // namespace core_text_util - -#endif // IOS_CHROME_BROWSER_UI_UTIL_CORE_TEXT_UTIL_H_
diff --git a/ios/chrome/browser/ui/util/core_text_util.mm b/ios/chrome/browser/ui/util/core_text_util.mm deleted file mode 100644 index d0a1e4c..0000000 --- a/ios/chrome/browser/ui/util/core_text_util.mm +++ /dev/null
@@ -1,229 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/util/core_text_util.h" - -#import <UIKit/UIKit.h> - -#include "base/check_op.h" -#include "base/mac/foundation_util.h" -#import "ios/chrome/browser/ui/util/manual_text_framer.h" -#import "ios/chrome/browser/ui/util/text_frame.h" -#import "ios/chrome/browser/ui/util/unicode_util.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace core_text_util { - -namespace { -// Returns the range within |string| for which |text_frame|'s glyph information -// is non-repeating. -CFRange GetValidRangeForTextFrame(CTFrameRef text_frame, - NSAttributedString* string) { - DCHECK(text_frame); - DCHECK(string.length); - CFRange range = CFRangeMake(0, 0); - bool is_rtl = - GetEffectiveWritingDirection(string) == NSWritingDirectionRightToLeft; - for (id line_id in base::mac::CFToNSCast(CTFrameGetLines(text_frame))) { - CTLineRef line = (__bridge CTLineRef)(line_id); - NSArray* runs = base::mac::CFToNSCast(CTLineGetGlyphRuns(line)); - NSInteger run_idx = is_rtl ? runs.count - 1 : 0; - while (run_idx >= 0 && run_idx < static_cast<NSInteger>(runs.count)) { - CTRunRef run = (__bridge CTRunRef)(runs[run_idx]); - CFRange run_range = CTRunGetStringRange(run); - if (run_range.location == range.location + range.length) - range.length += run_range.length; - else - break; - run_idx += is_rtl ? -1 : 1; - } - } - return range; -} -} // namespace - -base::ScopedCFTypeRef<CTFrameRef> CreateTextFrameForStringInBounds( - NSAttributedString* string, - CGRect bounds) { - base::ScopedCFTypeRef<CTFramesetterRef> frame_setter( - CTFramesetterCreateWithAttributedString(base::mac::NSToCFCast(string))); - DCHECK(frame_setter); - base::ScopedCFTypeRef<CGPathRef> path(CGPathCreateWithRect(bounds, nullptr)); - DCHECK(path); - base::ScopedCFTypeRef<CTFrameRef> text_frame( - CTFramesetterCreateFrame(frame_setter, CFRangeMake(0, 0), path, nullptr)); - DCHECK(text_frame); - return text_frame; -} - -bool IsTextFrameValid(CTFrameRef text_frame, - ManualTextFramer* manual_framer, - NSAttributedString* string) { - DCHECK(text_frame); - DCHECK(manual_framer); - CFRange visible_range = CTFrameGetVisibleStringRange(text_frame); - CFRange valid_range = GetValidRangeForTextFrame(text_frame, string); - NSRange unsigned_visible_range; - // If |visible_range| has invalid values, return early. - if (!base::mac::CFRangeToNSRange(visible_range, &unsigned_visible_range)) - return false; - NSRange manual_range = manual_framer.textFrame.framedRange; - return visible_range.location == valid_range.location && - visible_range.length == valid_range.length && - manual_range.length == unsigned_visible_range.length; -} - -CGFloat GetTrimmedLineWidth(CTLineRef line) { - DCHECK(line); - return CTLineGetTypographicBounds(line, nullptr, nullptr, nullptr) - - CTLineGetTrailingWhitespaceWidth(line); -} - -CGFloat GetRunWidthWithRange(CTRunRef run, CFRange range) { - DCHECK(run); - CFIndex glyph_count = CTRunGetGlyphCount(run); - if (range.location < 0 || range.location >= glyph_count || - range.location + range.length > glyph_count || !range.length) { - return 0; - } - return CTRunGetTypographicBounds(run, range, nullptr, nullptr, nullptr); -} - -CGFloat GetGlyphWidth(CTRunRef run, CFIndex glyph_idx) { - return GetRunWidthWithRange(run, CFRangeMake(glyph_idx, 1)); -} - -CFIndex GetGlyphIdxForCharInSet(CTRunRef run, - CFRange range, - NSAttributedString* string, - NSCharacterSet* set) { - DCHECK(run); - CFIndex glyph_count = CTRunGetGlyphCount(run); - DCHECK_LT(range.location, glyph_count); - DCHECK_LE(range.location + range.length, glyph_count); - DCHECK(string.length); - DCHECK(set); - BOOL isRTL = - GetEffectiveWritingDirection(string) == NSWritingDirectionRightToLeft; - CFIndex glyph_idx = - isRTL ? range.location + range.length - 1 : range.location; - CFIndex string_idx = GetStringIdxForGlyphIdx(run, glyph_idx); - while (![set characterIsMember:[string.string characterAtIndex:string_idx]]) { - glyph_idx += isRTL ? -1 : 1; - string_idx = GetStringIdxForGlyphIdx(run, glyph_idx); - if (string_idx == NSNotFound) - return kCFNotFound; - } - return glyph_idx; -} - -NSUInteger GetStringIdxForGlyphIdx(CTRunRef run, CFIndex glyph_idx) { - DCHECK(run); - if (glyph_idx < 0 || glyph_idx >= CTRunGetGlyphCount(run)) - return NSNotFound; - CFIndex string_idx; - CTRunGetStringIndices(run, CFRangeMake(glyph_idx, 1), &string_idx); - return static_cast<NSUInteger>(string_idx); -} - -NSRange GetStringRangeForRun(CTRunRef run) { - DCHECK(run); - NSRange stringRange; - if (base::mac::CFRangeToNSRange(CTRunGetStringRange(run), &stringRange)) - return stringRange; - return NSMakeRange(NSNotFound, 0); -} - -void EnumerateAttributesInString(NSAttributedString* string, - NSRange range, - AttributesBlock block) { - DCHECK(string.length); - DCHECK_LT(range.location, string.length); - DCHECK_LE(range.location + range.length, string.length); - DCHECK(block); - NSUInteger char_idx = range.location; - NSRange effectiveRange = NSMakeRange(0, 0); - while (char_idx < range.location + range.length) { - NSDictionary* attributes = - [string attributesAtIndex:char_idx effectiveRange:&effectiveRange]; - block(attributes); - char_idx += range.length; - } -} - -CGFloat GetLineHeight(NSAttributedString* string, NSRange range) { - __block CGFloat line_height = 0; - AttributesBlock block = ^(NSDictionary* attributes) { - NSParagraphStyle* style = attributes[NSParagraphStyleAttributeName]; - CGFloat run_line_height = 0; - UIFont* font = attributes[NSFontAttributeName]; - if (!font) - font = [UIFont systemFontOfSize:[UIFont systemFontSize]]; - DCHECK(font); - run_line_height = font.ascender - font.descender; - if (style.lineHeightMultiple > 0) - run_line_height *= style.lineHeightMultiple; - if (style.minimumLineHeight > 0) - run_line_height = std::max(run_line_height, style.minimumLineHeight); - if (style.maximumLineHeight > 0) - run_line_height = std::min(run_line_height, style.maximumLineHeight); - line_height = std::max(line_height, run_line_height); - }; - EnumerateAttributesInString(string, range, block); - return line_height; -} - -CGFloat GetLineSpacing(NSAttributedString* string, NSRange range) { - __block CGFloat line_spacing = 0; - AttributesBlock block = ^(NSDictionary* attributes) { - NSParagraphStyle* style = attributes[NSParagraphStyleAttributeName]; - line_spacing = std::max(line_spacing, style.lineSpacing); - }; - EnumerateAttributesInString(string, range, block); - return line_spacing; -} - -NSTextAlignment GetEffectiveTextAlignment(NSAttributedString* string) { - DCHECK(string.length); - NSTextAlignment alignment = NSTextAlignmentLeft; - NSParagraphStyle* style = [string attribute:NSParagraphStyleAttributeName - atIndex:0 - effectiveRange:nullptr]; - if (style) { - alignment = style.alignment; - if (alignment == NSTextAlignmentNatural || - alignment == NSTextAlignmentJustified) { - NSWritingDirection direction = GetEffectiveWritingDirection(string); - alignment = direction == NSWritingDirectionRightToLeft - ? NSTextAlignmentRight - : NSTextAlignmentLeft; - } - } - return alignment; -} - -NSWritingDirection GetEffectiveWritingDirection(NSAttributedString* string) { - DCHECK(string.length); - // Search for unicode bidirectionality characters within |string|. - NSWritingDirection direction = - unicode_util::UnicodeWritingDirectionForString(string.string); - if (direction == NSWritingDirectionNatural) { - // If there are no characters with bidirectionality information, default to - // NSWritingDirectionLeftToRight. - direction = NSWritingDirectionLeftToRight; - } - NSParagraphStyle* style = [string attribute:NSParagraphStyleAttributeName - atIndex:0 - effectiveRange:nullptr]; - if (style && style.baseWritingDirection != NSWritingDirectionNatural) { - // Use the NSParagraphStyle's writing direction if specified. - direction = style.baseWritingDirection; - } - return direction; -} - -} // namespace core_text_util
diff --git a/ios/chrome/browser/ui/util/core_text_util_unittest.mm b/ios/chrome/browser/ui/util/core_text_util_unittest.mm deleted file mode 100644 index 911f315..0000000 --- a/ios/chrome/browser/ui/util/core_text_util_unittest.mm +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/util/core_text_util.h" - -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/gtest_mac.h" -#include "testing/platform_test.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { - -// TODO(crbug.com/601772): Add tests for other core_text_util tests. - -using CoreTextUtilTest = PlatformTest; - -// Tests that the minimum line height attribute is reflected in GetLineHeight(). -TEST_F(CoreTextUtilTest, MinLineHeightText) { - CGFloat min_line_height = 30.0; - NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init]; - [style setMinimumLineHeight:min_line_height]; - NSMutableAttributedString* str = [[NSMutableAttributedString alloc] - initWithString:@"test" - attributes:@{NSParagraphStyleAttributeName : style}]; - ASSERT_EQ(min_line_height, - core_text_util::GetLineHeight(str, NSMakeRange(0, [str length]))); -} - -// Tests that the maximum line height attribute is reflected in GetLineHeight(). -TEST_F(CoreTextUtilTest, MaxLineHeightText) { - CGFloat max_line_height = 10.0; - NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init]; - [style setMaximumLineHeight:max_line_height]; - NSMutableAttributedString* str = [[NSMutableAttributedString alloc] - initWithString:@"test" - attributes:@{NSParagraphStyleAttributeName : style}]; - ASSERT_EQ(max_line_height, - core_text_util::GetLineHeight(str, NSMakeRange(0, [str length]))); -} - -// Tests that the line height multiple attribute is reflected in -// GetLineHeight(). -TEST_F(CoreTextUtilTest, LineHeightMultipleTest) { - UIFont* font = [UIFont systemFontOfSize:20.0]; - CGFloat font_line_height = font.ascender - font.descender; - CGFloat line_height_multiple = 2.0; - NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init]; - [style setLineHeightMultiple:line_height_multiple]; - NSMutableAttributedString* str = [[NSMutableAttributedString alloc] - initWithString:@"test" - attributes:@{ - NSParagraphStyleAttributeName : style, - NSFontAttributeName : font - }]; - ASSERT_EQ(font_line_height * line_height_multiple, - core_text_util::GetLineHeight(str, NSMakeRange(0, [str length]))); -} - -} // namespace
diff --git a/ios/chrome/browser/ui/util/label_link_controller.h b/ios/chrome/browser/ui/util/label_link_controller.h deleted file mode 100644 index 2259101..0000000 --- a/ios/chrome/browser/ui/util/label_link_controller.h +++ /dev/null
@@ -1,84 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_UTIL_LABEL_LINK_CONTROLLER_H_ -#define IOS_CHROME_BROWSER_UI_UTIL_LABEL_LINK_CONTROLLER_H_ - -#import <UIKit/UIKit.h> -#include "ios/chrome/browser/procedural_block_types.h" - -class GURL; - -// A LabelLinkController manages a UILabel instance that is to have tappable -// substrings ("links"). The controller handles styling the link areas (if -// desired), and installs a gesture recognizer on the label that will trigger if -// the specified regions are tapped. Multiple regions of the label may be -// defined as links, and they may trigger different actions. -// Each LabelLinkController calls a single action (a block that takes a GURL -// parameter) for all taps; different links are defined by having different -// URLs associated with them. -// The LabelLinkController observes (via KVO) changes in the label's size, style -// and text. If the label's bounds or style change, the controller recomputes -// the link areas. If the text changes, all of the defined links for the label -// are cleared (since they are presumed to be meaningless). -// To prevent spurious recomputation of link areas, it is best to apply any -// text manipulations and styling to the label before initializing a -// LabelLinkController with it. -@interface LabelLinkController : NSObject - -// If |showTapAreas| is true in a debug build, the tappable regions of the label -// will have colored rectangles around them, with different colors for each URL, -// and a darker outline around the exact text that the tappable region is for. -// In non-debug builds, setting this property has no effect. -@property(nonatomic, assign) BOOL showTapAreas; - -// Sets the link color for any defined links, updating the controlled label's -// attributed text accordingly. -@property(nonatomic, copy) UIColor* linkColor; - -// Sets the link underline style for any defined links, updating the controlled -// label's attributed text accordingly. -@property(nonatomic, assign) NSUnderlineStyle linkUnderlineStyle; - -// Sets the link font for any defined links, updating the controlled label's -// attributed text accordingly. -@property(nonatomic, strong) UIFont* linkFont; - -// Creates a new controller for |label|, keeping a strong reference. |action| is -// the block called for any tapped link. -- (instancetype)initWithLabel:(UILabel*)label - action:(ProceduralBlockWithURL)action; - -// Adds a link to the controlled label at |range| in the label's text, which -// will call the receiver's action block when tapped, passing in |url|. -// |accessibilityID| is set to the button over the link. -- (void)addLinkWithRange:(NSRange)range - url:(GURL)url - accessibilityID:(NSString*)accessibilityID; - -// Calls |[self addLinkWithRange:range url:url accessibilityID:nil]|. -- (void)addLinkWithRange:(NSRange)range url:(GURL)url; - -@end - -@interface LabelLinkController (Testing) - -// Testing interface for LabelLinkController. - -// This is the class that will be instantiated to do text mapping; by default -// it is CoreTextMapper, but tests can assign to this property to do dependency -// injection. -@property(nonatomic, assign) Class textMapperClass; -// Returns the tap rects generated by the controller that are associated with -// |url|. -- (NSArray*)tapRectsForURL:(GURL)url; -// Return all button frames. -- (NSArray*)buttonFrames; -// Simulates a tap in the controlled label at |point|. No touch events are -// generated, but |action| should be invoked if |point| is inside a tap rect. -- (void)tapLabelAtPoint:(CGPoint)point; - -@end - -#endif // IOS_CHROME_BROWSER_UI_UTIL_LABEL_LINK_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/util/label_link_controller.mm b/ios/chrome/browser/ui/util/label_link_controller.mm deleted file mode 100644 index 64b31a8c..0000000 --- a/ios/chrome/browser/ui/util/label_link_controller.mm +++ /dev/null
@@ -1,445 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/util/label_link_controller.h" - -#include <map> -#include <vector> - -#include "base/check_op.h" -#include "base/mac/foundation_util.h" -#import "base/strings/sys_string_conversions.h" -#include "ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.h" -#import "ios/chrome/browser/ui/util/label_observer.h" -#import "ios/chrome/browser/ui/util/text_region_mapper.h" -#import "ios/chrome/browser/ui/util/transparent_link_button.h" -#include "ios/chrome/browser/ui/util/ui_util.h" -#import "net/base/mac/url_conversions.h" -#include "url/gurl.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -#pragma mark - LinkData - -// Object encapsulating the range of a link and the frames corresponding with -// that range. -@interface LinkData : NSObject - -// Designated initializer. -- (instancetype)initWithRange:(NSRange)range NS_DESIGNATED_INITIALIZER; -- (instancetype)init NS_UNAVAILABLE; - -// The range passed on initialization. -@property(nonatomic, readonly) NSRange range; - -// The frames calculated for |_range|. -@property(nonatomic, strong) NSArray* frames; - -// Accessibility identifier for the link button. -@property(nonatomic, copy) NSString* accessibilityID; - -@end - -@implementation LinkData - -- (instancetype)initWithRange:(NSRange)range { - if ((self = [super init])) { - DCHECK_NE(range.location, static_cast<NSUInteger>(NSNotFound)); - DCHECK_NE(range.length, 0U); - _range = range; - } - return self; -} - -@end - -#pragma mark - LabelLinkController - -@interface LabelLinkController () -// Private property exposed publically in testing interface. -@property(nonatomic, weak) Class textMapperClass; - -// The original attributed text set on the label. This may be different from -// the label's |attributedText| property, as additional style attributes may be -// introduced for links. -@property(nonatomic, strong, readonly) NSAttributedString* originalLabelText; - -// The array of TransparentLinkButtons inserted above the label. -@property(nonatomic, strong, readonly) NSMutableArray* linkButtons; - -// Adds LabelObserverActions to the LabelObserver corresponding to |_label|. -- (void)addLabelObserverActions; - -// Clears all defined links and any data associated with them. Update the -// original attributed text from the controlled label. -- (void)reset; - -// Handle a change to the label that changes the positioning of glyphs but not -// any styling of those glyphs. Forces a recomputation of the tap regions, and -// recreates any tap buttons. -- (void)labelLayoutInvalidated; - -// Handle a change to the label that changes the glyph style. This forces all of -// the link-specific styling applied by this class to be regenerated (which -// itself will again re-trigger this method), and because any kind of style -// change may alter the position of glyphs, this forces a layout invalidation. -- (void)labelStyleInvalidated; - -// Updates the attributed string content of the controlled label to -// have the designated link colors and styles. -// No-op if no links are defined. -- (void)updateStyles; - -// If the controlled label's bounds have changed from the last time tap rects -// were updated, determine which regions in the label should be tappable. -- (void)updateTapRects; - -// Creates a new text mapper instance with the current label bounds and -// attributed text. -- (void)resetTextMapper; - -// Clear any tap buttons that have been created, removing them from their -// superview if necessary. -- (void)clearTapButtons; - -// Updates the tap buttons as detailed below. This method is called every time -// tap rects are updated, as well as every time |_label|'s superview changes. -// If there are no tap buttons defined, but there are known tap rects, and -// |_label| has a superview, then tap buttons are created and added to that -// view. -// If there are tap buttons, and |_label| has no superview, then the tap buttons -// are cleared. -// If there are tap buttons, but they are not subviews of |_label|'s superview -// (if _label's superview has changed since the buttons were created), then -// the tap buttons are migrated into the new superview. -- (void)updateTapButtons; - -@end - -@implementation LabelLinkController { - // Ivars immutable for the lifetime of the object. - ProceduralBlockWithURL _action; - UILabel* _label; - UITapGestureRecognizer* _linkTapRecognizer; - - // Ivars that reset when label text changes. - NSMutableDictionary* _linkDataForURLs; - CGRect _lastLabelFrame; - - // Ivars that reset when text or bounds change. - id<TextRegionMapper> _textMapper; - - // Internal tracking. - BOOL _justUpdatedStyles; - LabelObserver* _labelObserver; -} - -@synthesize showTapAreas = _showTapAreas; -@synthesize textMapperClass = _textMapperClass; -@synthesize linkUnderlineStyle = _linkUnderlineStyle; -@synthesize linkButtons = _linkButtons; -@synthesize originalLabelText = _originalLabelText; -@synthesize linkFont = _linkFont; -@synthesize linkColor = _linkColor; - -- (instancetype)initWithLabel:(UILabel*)label - action:(ProceduralBlockWithURL)action { - if ((self = [super init])) { - DCHECK(label); - _label = label; - _action = [action copy]; - _linkUnderlineStyle = NSUnderlineStyleNone; - [self reset]; - - _labelObserver = [LabelObserver observerForLabel:_label]; - [_labelObserver startObserving]; - [self addLabelObserverActions]; - - self.textMapperClass = [CoreTextRegionMapper class]; - _linkButtons = [[NSMutableArray alloc] init]; - } - return self; -} - -- (void)addLabelObserverActions { - __weak LabelLinkController* weakSelf = self; - [_labelObserver addStyleChangedAction:^(UILabel* label) { - // One of the style properties has been changed, which will silently - // update the label's attributedText. - if (!weakSelf) - return; - LabelLinkController* strongSelf = weakSelf; - [strongSelf labelStyleInvalidated]; - }]; - [_labelObserver addTextChangedAction:^(UILabel* label) { - if (!weakSelf) - return; - LabelLinkController* strongSelf = weakSelf; - NSString* originalText = [[strongSelf originalLabelText] string]; - if ([label.text isEqualToString:originalText]) { - // The actual text of the label didn't change, so this was a change to - // the string attributes only. - [strongSelf labelStyleInvalidated]; - } else { - // The label text has changed, so start everything from scratch. - [strongSelf reset]; - } - }]; - [_labelObserver addLayoutChangedAction:^(UILabel* label) { - if (!weakSelf) - return; - LabelLinkController* strongSelf = weakSelf; - [strongSelf labelLayoutInvalidated]; - NSArray* linkButtons = [strongSelf linkButtons]; - // If this layout change corresponds to |label|'s moving to a new superview, - // update the tap buttons so that they are inserted above |label| in the new - // hierarchy. - if (linkButtons.count && label.superview != [linkButtons[0] superview]) - [strongSelf updateTapButtons]; - }]; -} - -- (void)dealloc { - [self clearTapButtons]; - [_labelObserver stopObserving]; -} - -- (void)addLinkWithRange:(NSRange)range url:(GURL)url { - [self addLinkWithRange:range url:url accessibilityID:nil]; -} - -- (void)addLinkWithRange:(NSRange)range - url:(GURL)url - accessibilityID:(NSString*)accessibilityID { - DCHECK(url.is_valid()); - if (!_linkDataForURLs) - _linkDataForURLs = [[NSMutableDictionary alloc] init]; - NSURL* key = net::NSURLWithGURL(url); - LinkData* linkData = [[LinkData alloc] initWithRange:range]; - linkData.accessibilityID = accessibilityID; - [_linkDataForURLs setObject:linkData forKey:key]; - [self updateStyles]; -} - -- (void)setLinkColor:(UIColor*)linkColor { - _linkColor = [linkColor copy]; - [self updateStyles]; -} - -- (void)setLinkUnderlineStyle:(NSUnderlineStyle)underlineStyle { - _linkUnderlineStyle = underlineStyle; - [self updateStyles]; -} - -- (void)setLinkFont:(UIFont*)linkFont { - _linkFont = linkFont; - [self updateStyles]; -} - -- (void)setShowTapAreas:(BOOL)showTapAreas { -#ifndef NDEBUG - for (TransparentLinkButton* button in _linkButtons) { - button.debug = showTapAreas; - } -#endif // NDEBUG - _showTapAreas = showTapAreas; -} - -#pragma mark - internal methods - -- (void)reset { - _originalLabelText = [[_label attributedText] copy]; - _textMapper = nil; - _lastLabelFrame = CGRectZero; - _linkDataForURLs = nil; -} - -- (void)labelLayoutInvalidated { - _textMapper = nil; - [self updateTapRects]; -} - -- (void)labelStyleInvalidated { - // If the style invalidation was triggered by this class updating link styles, - // then the original label text is still correct, but the tap rects still need - // to be updated. Otherwise, update the original label text, and then update - // styles. This will set |_justUpdatedStyles| and trigger another call to - // this method via KVO. - if (_justUpdatedStyles) { - // TODO(crbug.com/664648): Remove _justUpdatedStyles due to bug that - // prevents proper style updates after successive label format changes. - _justUpdatedStyles = NO; - } else if (![_originalLabelText isEqual:[_label attributedText]]) { - _originalLabelText = [[_label attributedText] copy]; - [self updateStyles]; - } - _lastLabelFrame = CGRectZero; - [self labelLayoutInvalidated]; -} - -- (void)updateStyles { - if (![_linkDataForURLs count]) - return; - - __block NSMutableAttributedString* labelText = - [_originalLabelText mutableCopy]; - [_linkDataForURLs enumerateKeysAndObjectsUsingBlock:^( - NSURL* key, LinkData* linkData, BOOL* stop) { - if (_linkColor) { - [labelText addAttribute:NSForegroundColorAttributeName - value:_linkColor - range:linkData.range]; - } - if (_linkUnderlineStyle != NSUnderlineStyleNone) { - [labelText addAttribute:NSUnderlineStyleAttributeName - value:@(_linkUnderlineStyle) - range:linkData.range]; - } - if (_linkFont) { - [labelText addAttribute:NSFontAttributeName - value:_linkFont - range:linkData.range]; - } - }]; - _justUpdatedStyles = YES; - [_label setAttributedText:labelText]; - _textMapper = nil; -} - -- (void)updateTapRects { - // Don't update if the label hasn't changed size or position. - if (CGRectEqualToRect([_label frame], _lastLabelFrame)) - return; - // Don't update if there are no links. - if (![_linkDataForURLs count]) - return; - - _lastLabelFrame = [_label frame]; - [self clearTapButtons]; - - // If the label bounds are zero in either dimension, no rects are possible. - if (0.0 == _lastLabelFrame.size.width || 0.0 == _lastLabelFrame.size.height) - return; - - if (!_textMapper) - [self resetTextMapper]; - - for (LinkData* linkData in [_linkDataForURLs allValues]) { - NSMutableArray* frames = [[NSMutableArray alloc] init]; - NSArray* rects = [_textMapper rectsForRange:linkData.range]; - for (NSUInteger rectIdx = 0; rectIdx < [rects count]; ++rectIdx) { - CGRect frame = [rects[rectIdx] CGRectValue]; - frame = [[_label superview] convertRect:frame fromView:_label]; - [frames addObject:[NSValue valueWithCGRect:frame]]; - } - linkData.frames = frames; - } - [self updateTapButtons]; -} - -- (void)resetTextMapper { - DCHECK([self.textMapperClass conformsToProtocol:@protocol(TextRegionMapper)]); - _textMapper = [[self.textMapperClass alloc] - initWithAttributedString:[_label attributedText] - bounds:[_label bounds]]; -} - -- (void)clearTapButtons { - for (TransparentLinkButton* button in _linkButtons) { - [button removeFromSuperview]; - } - [_linkButtons removeAllObjects]; -} - -- (void)updateTapButtons { - // If the label has no superview, clear any existing buttons. - if (![_label superview]) { - [self clearTapButtons]; - return; - } else if ([_linkButtons count]) { - // If the buttons are currently in some view other than the label's - // superview, repatriate them. - if (base::mac::ObjCCast<TransparentLinkButton>(_linkButtons[0]).superview != - [_label superview]) { - for (TransparentLinkButton* button in _linkButtons) { - CGRect newFrame = - [[_label superview] convertRect:button.frame fromView:button]; - [[_label superview] insertSubview:button aboveSubview:_label]; - button.frame = newFrame; - } - } - } - // If there are no buttons, make some and put them in the label's superview. - if (![_linkButtons count] && _linkDataForURLs) { - [_linkDataForURLs enumerateKeysAndObjectsUsingBlock:^( - NSURL* key, LinkData* linkData, BOOL* stop) { - GURL URL = net::GURLWithNSURL(key); - NSString* accessibilityLabel = - [[_label text] substringWithRange:linkData.range]; - // Only pass along line height if there are more than one layouts that - // can overlap. - CGFloat lineHeightLimit = - [_linkDataForURLs count] > 1 ? _label.cr_lineHeight : 0; - NSArray* buttons = - [TransparentLinkButton buttonsForLinkFrames:linkData.frames - URL:URL - lineHeight:lineHeightLimit - accessibilityLabel:accessibilityLabel - accessibilityID:linkData.accessibilityID]; - for (TransparentLinkButton* button in buttons) { -#ifndef NDEBUG - button.debug = self.showTapAreas; -#endif // NDEBUG - [button addTarget:self - action:@selector(linkButtonTapped:) - forControlEvents:UIControlEventTouchUpInside]; - [[_label superview] insertSubview:button aboveSubview:_label]; - [_linkButtons addObject:button]; - } - }]; - } -} - -#pragma mark - Tap Handlers - -- (void)linkButtonTapped:(id)sender { - TransparentLinkButton* button = - base::mac::ObjCCast<TransparentLinkButton>(sender); - _action(button.URL); -} - -#pragma mark - Test facilitators - -- (NSArray*)tapRectsForURL:(GURL)url { - NSURL* key = net::NSURLWithGURL(url); - LinkData* linkData = [_linkDataForURLs objectForKey:key]; - return linkData.frames; -} - -- (NSArray*)buttonFrames { - NSMutableArray* array = - [NSMutableArray arrayWithCapacity:[_linkButtons count]]; - for (TransparentLinkButton* button in _linkButtons) { - [array addObject:[NSValue valueWithCGRect:button.frame]]; - } - return array; -} - -- (void)tapLabelAtPoint:(CGPoint)point { - [_linkDataForURLs enumerateKeysAndObjectsUsingBlock:^( - NSURL* key, LinkData* linkData, BOOL* stop) { - for (NSValue* frameValue in linkData.frames) { - CGRect frame = [frameValue CGRectValue]; - if (CGRectContainsPoint(frame, point)) { - _action(net::GURLWithNSURL(key)); - *stop = YES; - break; - } - } - }]; -} - -@end
diff --git a/ios/chrome/browser/ui/util/label_link_controller_unittest.mm b/ios/chrome/browser/ui/util/label_link_controller_unittest.mm deleted file mode 100644 index 6e9e4a3..0000000 --- a/ios/chrome/browser/ui/util/label_link_controller_unittest.mm +++ /dev/null
@@ -1,356 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/util/label_link_controller.h" - -#include "ios/chrome/browser/ui/util/text_region_mapper.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/gtest_mac.h" -#include "testing/platform_test.h" -#include "url/gurl.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -// A simple text region mapper that just returns the mapped bounds for -// any range. -@interface SimpleTextRegionMapper : NSObject<TextRegionMapper> -@end - -@implementation SimpleTextRegionMapper { - CGRect _bounds; -} - -- (instancetype)initWithAttributedString:(NSAttributedString*)string - bounds:(CGRect)bounds { - if ((self = [super init])) { - _bounds = bounds; - } - return self; -} - -- (NSArray*)rectsForRange:(NSRange)range { - return @[ [NSValue valueWithCGRect:_bounds] ]; -} - -@end - -#define EXPECT_UICOLOR_EQ(A, B) EXPECT_NSEQ([A description], [B description]) - -namespace { - -class LabelLinkControllerTest : public PlatformTest { - protected: - LabelLinkControllerTest() { - label_container_ = [[UIView alloc] initWithFrame:CGRectZero]; - label_ = [[UILabel alloc] initWithFrame:CGRectZero]; - [label_container_ addSubview:label_]; - } - - void setLabelAttrString(NSString* str) { - str_ = [[NSAttributedString alloc] initWithString:str]; - [label_ setAttributedText:str_]; - } - - void setLabelAttrStringWithAttr(NSString* str, NSString* attr, id value) { - str_ = [[NSAttributedString alloc] initWithString:str - attributes:@{attr : value}]; - [label_ setAttributedText:str_]; - } - - UIView* label_container_; - UILabel* label_; - NSAttributedString* str_; -}; - -TEST_F(LabelLinkControllerTest, TapTest) { - setLabelAttrString(@"link tap test"); - [label_ sizeToFit]; - NSRange linkRange = NSMakeRange(5, 3); // "tap". - - GURL url = GURL("http://www.google.com"); - __block NSInteger taps = 0; - LabelLinkController* llc = - [[LabelLinkController alloc] initWithLabel:label_ - action:^(const GURL& tappedUrl) { - EXPECT_EQ(tappedUrl, url); - taps++; - }]; - [llc setTextMapperClass:[SimpleTextRegionMapper class]]; - [llc addLinkWithRange:linkRange url:url]; - NSArray* rects = [llc tapRectsForURL:url]; - ASSERT_EQ(1UL, [rects count]); - CGRect rect = [rects[0] CGRectValue]; - - CGPoint tapPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); - [llc tapLabelAtPoint:tapPoint]; - EXPECT_EQ(1, taps); -} - -TEST_F(LabelLinkControllerTest, LinkColorTest) { - setLabelAttrStringWithAttr(@"link color test", NSForegroundColorAttributeName, - [UIColor blueColor]); - [label_ sizeToFit]; - NSRange linkRange = NSMakeRange(5, 5); // "color". - - LabelLinkController* llc = - [[LabelLinkController alloc] initWithLabel:label_ action:nullptr]; - [llc setTextMapperClass:[SimpleTextRegionMapper class]]; - [llc addLinkWithRange:linkRange url:GURL("http://www.google.com")]; - - // That shouldn't have changed the label's attributes. - NSDictionary* attrs = - [[label_ attributedText] attributesAtIndex:linkRange.location - effectiveRange:nullptr]; - EXPECT_UICOLOR_EQ(attrs[NSForegroundColorAttributeName], [UIColor blueColor]); - - [llc setLinkColor:[UIColor redColor]]; - // That should only change the attributes at the link location - attrs = [[label_ attributedText] attributesAtIndex:linkRange.location - effectiveRange:nullptr]; - EXPECT_UICOLOR_EQ(attrs[NSForegroundColorAttributeName], [UIColor redColor]); - - attrs = [[label_ attributedText] attributesAtIndex:0 effectiveRange:nullptr]; - EXPECT_UICOLOR_EQ(attrs[NSForegroundColorAttributeName], [UIColor blueColor]); - - [llc setLinkColor:[UIColor yellowColor]]; - // There shouldn't be a red foreground color attribute any more. - attrs = [[label_ attributedText] attributesAtIndex:linkRange.location - effectiveRange:nullptr]; - EXPECT_UICOLOR_EQ(attrs[NSForegroundColorAttributeName], - [UIColor yellowColor]); -} - -TEST_F(LabelLinkControllerTest, LinkUnderlineTest) { - setLabelAttrStringWithAttr(@"link underline test", - NSUnderlineStyleAttributeName, - @(NSUnderlineStyleSingle)); - [label_ sizeToFit]; - NSRange linkRange = NSMakeRange(5, 9); // "underline". - - LabelLinkController* llc = - [[LabelLinkController alloc] initWithLabel:label_ action:nullptr]; - [llc setTextMapperClass:[SimpleTextRegionMapper class]]; - [llc addLinkWithRange:linkRange url:GURL("http://www.google.com")]; - - // That shouldn't have changed the label's attributes. - NSDictionary* attrs = - [[label_ attributedText] attributesAtIndex:linkRange.location - effectiveRange:nullptr]; - EXPECT_NSEQ(attrs[NSUnderlineStyleAttributeName], @(NSUnderlineStyleSingle)); - - [llc setLinkUnderlineStyle:NSUnderlineStyleDouble]; - // That should only change the attributes at the link location - attrs = [[label_ attributedText] attributesAtIndex:linkRange.location - effectiveRange:nullptr]; - EXPECT_NSEQ(attrs[NSUnderlineStyleAttributeName], @(NSUnderlineStyleDouble)); - - attrs = [[label_ attributedText] attributesAtIndex:0 effectiveRange:nullptr]; - EXPECT_NSEQ(attrs[NSUnderlineStyleAttributeName], @(NSUnderlineStyleSingle)); - - [llc setLinkUnderlineStyle:NSUnderlineStyleThick]; - // There shouldn't be a red foreground color attribute any more. - attrs = [[label_ attributedText] attributesAtIndex:linkRange.location - effectiveRange:nullptr]; - EXPECT_NSEQ(attrs[NSUnderlineStyleAttributeName], @(NSUnderlineStyleThick)); - - [llc setLinkUnderlineStyle:NSUnderlineStyleNone]; - // Should see the underlying underline style. - attrs = [[label_ attributedText] attributesAtIndex:linkRange.location - effectiveRange:nullptr]; - EXPECT_NSEQ(attrs[NSUnderlineStyleAttributeName], @(NSUnderlineStyleSingle)); -} - -TEST_F(LabelLinkControllerTest, BoundsChangeTest) { - setLabelAttrString(@"bounds change test"); - [label_ sizeToFit]; - NSRange linkRange = NSMakeRange(7, 6); // "change". - - LabelLinkController* llc = - [[LabelLinkController alloc] initWithLabel:label_ action:nullptr]; - [llc setTextMapperClass:[SimpleTextRegionMapper class]]; - GURL url = GURL("http://www.google.com"); - [llc addLinkWithRange:linkRange url:url]; - - NSArray* rects = [llc tapRectsForURL:url]; - ASSERT_EQ(1UL, [rects count]); - NSValue* rect = rects[0]; - EXPECT_TRUE(CGRectContainsRect([rect CGRectValue], [label_ bounds])); - - // Change the label bounds, expect the links to be recomputed. - // (SimpleTextRegionMapper just maps all ranges to the label bounds). - CGRect newFrame = CGRectMake(0, 0, 200, 200); - [label_ setFrame:newFrame]; - rects = [llc tapRectsForURL:url]; - ASSERT_EQ(1UL, [rects count]); - NSValue* newRect = rects[0]; - EXPECT_NSNE(rect, newRect); - EXPECT_TRUE(CGRectContainsRect([newRect CGRectValue], newFrame)); -} - -TEST_F(LabelLinkControllerTest, AttributedTextChangeTest) { - setLabelAttrString(@"attributed text change test"); - [label_ sizeToFit]; - NSRange linkRange = NSMakeRange(16, 6); // "change". - - LabelLinkController* llc = - [[LabelLinkController alloc] initWithLabel:label_ action:nullptr]; - [llc setTextMapperClass:[SimpleTextRegionMapper class]]; - GURL url = GURL("http://www.google.com"); - [llc addLinkWithRange:linkRange url:url]; - - NSArray* rects = [llc tapRectsForURL:url]; - EXPECT_EQ(1UL, [rects count]); - - setLabelAttrString(@"crazy new attributed text"); - // Expect all links to be gone. - rects = [llc tapRectsForURL:url]; - EXPECT_EQ(0UL, [rects count]); -} - -TEST_F(LabelLinkControllerTest, TextChangeTest) { - [label_ setText:@"text change test"]; - [label_ sizeToFit]; - NSRange linkRange = NSMakeRange(5, 6); // "change". - - LabelLinkController* llc = - [[LabelLinkController alloc] initWithLabel:label_ action:nullptr]; - [llc setTextMapperClass:[SimpleTextRegionMapper class]]; - GURL url = GURL("http://www.google.com"); - [llc addLinkWithRange:linkRange url:url]; - - NSArray* rects = [llc tapRectsForURL:url]; - EXPECT_EQ(1UL, [rects count]); - - [label_ setText:@"crazy new text"]; - // Expect all links to be gone. - rects = [llc tapRectsForURL:url]; - EXPECT_EQ(0UL, [rects count]); -} - -TEST_F(LabelLinkControllerTest, LabelStyleInitTest) { - [label_ setText:@"style init test"]; - [label_ sizeToFit]; - NSRange linkRange = NSMakeRange(6, 5); // "init". - - // Don't use an injected text mapper for this test. - LabelLinkController* llc = - [[LabelLinkController alloc] initWithLabel:label_ action:nullptr]; - GURL url = GURL("http://www.google.com"); - [llc addLinkWithRange:linkRange url:url]; - - NSArray* rects = [llc tapRectsForURL:url]; - ASSERT_EQ(1UL, [rects count]); - - CGRect linkRect = [rects[0] CGRectValue]; - - // Make a new label and controller with a very large font size, and - // compute the same tap rect. It should be different from the rect computed - // above. - label_ = [[UILabel alloc] initWithFrame:CGRectZero]; - [label_ setText:@"style init test"]; - [label_ setFont:[UIFont systemFontOfSize:40]]; - [label_ sizeToFit]; - llc = [[LabelLinkController alloc] initWithLabel:label_ action:nullptr]; - url = GURL("http://www.google.com"); - [llc addLinkWithRange:linkRange url:url]; - rects = [llc tapRectsForURL:url]; - ASSERT_EQ(1UL, [rects count]); - CGRect newLinkRect = [rects[0] CGRectValue]; - - EXPECT_NSNE(NSStringFromCGRect(linkRect), NSStringFromCGRect(newLinkRect)); -} - -TEST_F(LabelLinkControllerTest, LabelStylePropertyChangeTest) { - [label_ setText:@"style change test"]; - // Choose a size large enough so that the full text can be laid out with both - // fonts in this test. - CGSize labelSize = CGSizeMake(400, 50); - [label_ setFrame:{CGPointZero, labelSize}]; - - NSRange linkRange = NSMakeRange(6, 6); // "change". - - // Don't use an injected text mapper for this test. - LabelLinkController* llc = - [[LabelLinkController alloc] initWithLabel:label_ action:nullptr]; - GURL url = GURL("http://www.google.com"); - [llc addLinkWithRange:linkRange url:url]; - - NSArray* rects = [llc tapRectsForURL:url]; - ASSERT_EQ(1UL, [rects count]); - NSValue* smallTextRect = rects[0]; - - [label_ setFont:[UIFont systemFontOfSize:40]]; - // Expect all links to be changed. - rects = [llc tapRectsForURL:url]; - ASSERT_EQ(1UL, [rects count]); - EXPECT_NSNE(smallTextRect, rects[0]); -} - -// Tests if the accessibility identifier is correctly set to the link button. -TEST_F(LabelLinkControllerTest, AccessibilityIdentifier) { - [label_ setText:@"accessibility identifier"]; - // Choose a size large enough so that the full text can be laid out with both - // fonts in this test. - CGSize labelSize = CGSizeMake(400, 50); - [label_ setFrame:{CGPointZero, labelSize}]; - - NSRange linkRange = NSMakeRange(14, 4); // "iden". - - // Don't use an injected text mapper for this test. - LabelLinkController* llc = - [[LabelLinkController alloc] initWithLabel:label_ action:nullptr]; - GURL url = GURL("http://www.google.com"); - NSString* accessibilityID = @"GoogleLink"; - [llc addLinkWithRange:linkRange url:url accessibilityID:accessibilityID]; - - UIView* linkButton = nil; - NSMutableArray* views = [NSMutableArray arrayWithObject:label_.superview]; - while (views.count) { - UIView* view = [views objectAtIndex:0]; - [views removeObjectAtIndex:0]; - [views addObjectsFromArray:view.subviews]; - if ([view.accessibilityIdentifier isEqualToString:accessibilityID]) { - linkButton = view; - break; - } - } - EXPECT_NE(nil, linkButton); -} - -TEST_F(LabelLinkControllerTest, LinkMaximumHeightTest) { - NSMutableParagraphStyle* newStyle = - [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - CGFloat lineHeight = 20; - [newStyle setMinimumLineHeight:lineHeight]; - [newStyle setMaximumLineHeight:lineHeight]; - setLabelAttrStringWithAttr(@"first line test\nsecond line test.", - NSParagraphStyleAttributeName, newStyle); - CGRect newFrame = CGRectMake(0, 0, 200, 100); - [label_ setFrame:newFrame]; - [label_ setFont:[UIFont systemFontOfSize:14]]; - NSRange firstLinkRange = NSMakeRange(0, 5); // "first". - NSRange secondLinkRange = NSMakeRange(16, 6); // "second". - LabelLinkController* llc = - [[LabelLinkController alloc] initWithLabel:label_ action:nullptr]; - GURL firsturl = GURL("http://www.google.com"); - GURL secondurl = GURL("http://www.cnn.com"); - - // Test that a single link is expanded to 44. - [llc addLinkWithRange:firstLinkRange url:firsturl]; - NSArray* rects = [llc buttonFrames]; - ASSERT_EQ(1UL, [rects count]); - ASSERT_EQ(44.0, CGRectGetHeight([rects[0] CGRectValue])); - - // Test that multiple links overlap by only .25 of |lineHeight|. - [llc addLinkWithRange:secondLinkRange url:secondurl]; - rects = [llc buttonFrames]; - ASSERT_EQ(2UL, [rects count]); - CGRect intersection = - CGRectIntersection([rects[0] CGRectValue], [rects[1] CGRectValue]); - ASSERT_EQ(.25 * lineHeight, CGRectGetHeight(intersection)); -} - -} // namespace
diff --git a/ios/chrome/browser/ui/util/label_observer.h b/ios/chrome/browser/ui/util/label_observer.h deleted file mode 100644 index 23ec5a1..0000000 --- a/ios/chrome/browser/ui/util/label_observer.h +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_UTIL_LABEL_OBSERVER_H_ -#define IOS_CHROME_BROWSER_UI_UTIL_LABEL_OBSERVER_H_ - -#import <UIKit/UIKit.h> - -// Class that observes changes to UILabel properties via KVO. This allows -// various classes that manage a UILabel's style via NSAttributedStrings to -// reapply their styling in response to property changes that would invalidate -// the attributed text. This class also synchronizes notifications of style -// invalidation so that property changes that occur as the result of a -// LabelObserverAction do not trigger other actions. -@interface LabelObserver : NSObject - -// Returns the LabelObserver for |label|, laziliy instantiating one if -// necessary. LabelObservers are associated with label but must be kept alive by -// the caller. |-startObserving| must be called before the |label| is observed. -+ (instancetype)observerForLabel:(UILabel*)label; - -// LabelObservers should be created via |+observerForLabel:|. -- (instancetype)init NS_UNAVAILABLE; - -// Starts observing the label. For each call to this function, |-stopObserving| -// should be called before |label| is deallocated. -- (void)startObserving; - -// Stops observing the label. The label stops being observed once the number of -// call to this function match the number of call to |-startObserving|. When -// observation of a label ends, none of its attributes are changed, and none -// of the registered actions are called. -- (void)stopObserving; - -// Block type that takes a label. Blocks registered for a label will be called -// when property values are updated. -typedef void (^LabelObserverAction)(UILabel* label); - -// Registers |action| to be called when stylistic properties on the observed -// label are changed. Style changes include changes to the label's font, -// textColor, textAlignment, lineBreakMode, shadowColor, or shadowOffset. -- (void)addStyleChangedAction:(LabelObserverAction)action; - -// Registers |action| to be called when the observed label's layout has changed. -// Layout changes include changes to the label's bounds, frame, or superview, as -// well as changes to its center, which doesn't affect the label's layout -// internally but does affect its position in its superview. -- (void)addLayoutChangedAction:(LabelObserverAction)action; - -// Registers |action| to be called when the observed label's text has changed. -// Text changes include changes to the label's text or attributedText. -- (void)addTextChangedAction:(LabelObserverAction)action; - -@end - -#endif // IOS_CHROME_BROWSER_UI_UTIL_LABEL_OBSERVER_H_
diff --git a/ios/chrome/browser/ui/util/label_observer.mm b/ios/chrome/browser/ui/util/label_observer.mm deleted file mode 100644 index 3fe4738..0000000 --- a/ios/chrome/browser/ui/util/label_observer.mm +++ /dev/null
@@ -1,227 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/util/label_observer.h" - -#import <objc/runtime.h> - -#include <ostream> - -#include "base/notreached.h" -#include "base/strings/sys_string_conversions.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { -// The key under which LabelObservers are associated with their labels. -const void* const kLabelObserverKey = &kLabelObserverKey; -// Attempts to convert |value| to a string. -NSString* GetStringValue(id value) { - if ([value isKindOfClass:[NSString class]]) - return static_cast<NSString*>(value); - if ([value respondsToSelector:@selector(string)]) - return [value performSelector:@selector(string)]; - return nil; -} -} - -@interface LabelObserver () { - // The label being observed. - __weak UILabel* _label; - // Arrays used to store registered actions. - NSMutableArray* _styleActions; - NSMutableArray* _layoutActions; - NSMutableArray* _textActions; -} - -// Whether or not observer actions are currently being executed. This is used -// to prevent infinite loops caused by a LinkObserverAction updating a -// property on |_label|. -@property(nonatomic, assign, getter=isRespondingToKVO) BOOL respondingToKVO; - -// The number of times this observer has been asked to observe the label. When -// reaching zero, the label stops being observed. -@property(nonatomic, assign) NSInteger observingCount; - -// Initializes a LabelObserver that observes |label|. -- (instancetype)initWithLabel:(UILabel*)label NS_DESIGNATED_INITIALIZER; - -// Adds |self| as observer for the |_label|. -- (void)registerAsObserver; - -// Removes |self| as observer for the |_label|. -- (void)removeObserver; - -// Performs all LabelObserverActions in |actions|. -- (void)performActions:(NSArray*)actions; - -// Takes |_label|'s values for each key from |styleKeys| and uses them to -// construct a uniformly attributed value to use for |_label|'s attributedText. -- (void)resetLabelAttributes; - -@end - -// Properties of UILabel that, when changed, will cause the label's attributed -// text to change. -static NSSet* styleKeys; -// Properties of UILabel that invalidate the layout of the label if they change. -static NSSet* layoutKeys; -// Properties of UILabel that may invalidate the text of the label if they -// change. -static NSSet* textKeys; - -@implementation LabelObserver - -@synthesize respondingToKVO = _respondingToKVO; -@synthesize observingCount = _observingCount; - -+ (void)initialize { - if (self == [LabelObserver class]) { - styleKeys = [[NSSet alloc] initWithArray:@[ - @"font", @"textColor", @"textAlignment", @"lineBreakMode", @"shadowColor", - @"shadowOffset" - ]]; - layoutKeys = [[NSSet alloc] - initWithArray:@[ @"bounds", @"frame", @"superview", @"center" ]]; - textKeys = [[NSSet alloc] initWithArray:@[ @"text", @"attributedText" ]]; - } -} - -- (instancetype)initWithLabel:(UILabel*)label { - if ((self = [super init])) { - DCHECK(label); - _label = label; - [self resetLabelAttributes]; - } - return self; -} - -- (void)dealloc { - objc_setAssociatedObject(_label, kLabelObserverKey, nil, - OBJC_ASSOCIATION_ASSIGN); -} - -#pragma mark - Public interface - -+ (instancetype)observerForLabel:(UILabel*)label { - if (!label) - return nil; - id observer = objc_getAssociatedObject(label, kLabelObserverKey); - if (!observer) { - observer = [[LabelObserver alloc] initWithLabel:label]; - objc_setAssociatedObject(label, kLabelObserverKey, observer, - OBJC_ASSOCIATION_ASSIGN); - } - return observer; -} - -- (void)startObserving { - if (self.observingCount == 0) { - [self registerAsObserver]; - } - self.observingCount++; -} - -- (void)stopObserving { - if (self.observingCount == 0) - return; - - self.observingCount--; - if (self.observingCount == 0) { - [self removeObserver]; - } -} - -- (void)addStyleChangedAction:(LabelObserverAction)action { - DCHECK(action); - if (!_styleActions) - _styleActions = [[NSMutableArray alloc] init]; - LabelObserverAction actionCopy = [action copy]; - [_styleActions addObject:actionCopy]; -} - -- (void)addLayoutChangedAction:(LabelObserverAction)action { - DCHECK(action); - if (!_layoutActions) - _layoutActions = [[NSMutableArray alloc] init]; - LabelObserverAction actionCopy = [action copy]; - [_layoutActions addObject:actionCopy]; -} - -- (void)addTextChangedAction:(LabelObserverAction)action { - DCHECK(action); - if (!_textActions) - _textActions = [[NSMutableArray alloc] init]; - LabelObserverAction actionCopy = [action copy]; - [_textActions addObject:actionCopy]; -} - -#pragma mark - - -- (void)registerAsObserver { - for (NSSet* keySet in @[ styleKeys, layoutKeys, textKeys ]) { - for (NSString* key in keySet) { - [_label addObserver:self - forKeyPath:key - options:NSKeyValueObservingOptionNew - context:nullptr]; - } - } -} - -- (void)removeObserver { - for (NSSet* keySet in @[ styleKeys, layoutKeys, textKeys ]) { - for (NSString* key in keySet) { - [_label removeObserver:self forKeyPath:key]; - } - }; -} - -- (void)performActions:(NSArray*)actions { - for (LabelObserverAction action in actions) - action(_label); -} - -- (void)resetLabelAttributes { - if ([_label attributedText] || ![_label text]) - return; - NSMutableDictionary* labelStyle = - [NSMutableDictionary dictionaryWithCapacity:styleKeys.count]; - for (NSString* property in styleKeys) - labelStyle[property] = [_label valueForKey:property]; - NSAttributedString* attributedText = - [[NSAttributedString alloc] initWithString:[_label text]]; - [_label setAttributedText:attributedText]; - for (NSString* property in styleKeys) - [_label setValue:labelStyle[property] forKey:property]; -} - -- (void)observeValueForKeyPath:(NSString*)key - ofObject:(id)object - change:(NSDictionary*)change - context:(void*)context { - if (self.respondingToKVO) - return; - self.respondingToKVO = YES; - DCHECK_EQ(object, _label); - if ([styleKeys containsObject:key]) { - [self performActions:_styleActions]; - } else if ([layoutKeys containsObject:key]) { - [self performActions:_layoutActions]; - } else if ([textKeys containsObject:key]) { - NSString* oldText = GetStringValue(change[NSKeyValueChangeOldKey]); - NSString* newText = GetStringValue(change[NSKeyValueChangeNewKey]); - if (![oldText isEqualToString:newText]) - [self resetLabelAttributes]; - [self performActions:_textActions]; - } else { - NOTREACHED() << "Unexpected label key <" << base::SysNSStringToUTF8(key) - << "> observed"; - } - self.respondingToKVO = NO; -} - -@end
diff --git a/ios/chrome/browser/ui/util/label_observer_unittest.mm b/ios/chrome/browser/ui/util/label_observer_unittest.mm deleted file mode 100644 index bccf4e72..0000000 --- a/ios/chrome/browser/ui/util/label_observer_unittest.mm +++ /dev/null
@@ -1,91 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ios/chrome/browser/ui/util/label_observer.h" - -#include "base/time/time.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/gtest_mac.h" -#include "testing/platform_test.h" -#include "url/gurl.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { - -class LabelObserverTest : public PlatformTest { - protected: - LabelObserverTest() { - label_ = [[UILabel alloc] initWithFrame:CGRectZero]; - observer_ = [LabelObserver observerForLabel:label_]; - [observer_ startObserving]; - } - - ~LabelObserverTest() override { [observer_ stopObserving]; } - - UILabel* label() { return label_; } - LabelObserver* observer() { return observer_; } - - UILabel* label_; - LabelObserver* observer_; -}; - -// Tests that all types of LabelObserverActions are successfully called. -TEST_F(LabelObserverTest, SimpleTest) { - __block BOOL text_action_called = NO; - [observer() addTextChangedAction:^(UILabel* label) { - text_action_called = YES; - }]; - label().text = @"text"; - EXPECT_TRUE(text_action_called); - __block BOOL layout_action_called = NO; - [observer() addLayoutChangedAction:^(UILabel* label) { - layout_action_called = YES; - }]; - [label() sizeToFit]; - EXPECT_TRUE(layout_action_called); - __block BOOL style_action_called = NO; - [observer() addStyleChangedAction:^(UILabel* label) { - style_action_called = YES; - }]; - label().textColor = [UIColor blueColor]; - EXPECT_TRUE(style_action_called); -} - -// Tests that a LabelObserverAction that causes another KVO callback does not -// get called twice -TEST_F(LabelObserverTest, CallCountTest) { - __block NSUInteger text_action_call_count = 0; - [observer() addTextChangedAction:^(UILabel* label) { - ++text_action_call_count; - label.text = [label.text stringByAppendingString:@"x"]; - }]; - label().text = @"x"; - EXPECT_EQ(1U, text_action_call_count); - EXPECT_NSEQ(label().text, @"xx"); -} - -// Tests that LabelObserverActions are called in the same order in which they -// are added. -TEST_F(LabelObserverTest, ObserverActionOrderTest) { - __block BOOL first_action_called = NO; - __block BOOL second_action_called = NO; - [observer() addTextChangedAction:^(UILabel* label) { - EXPECT_FALSE(first_action_called); - EXPECT_FALSE(second_action_called); - first_action_called = YES; - }]; - [observer() addTextChangedAction:^(UILabel* label) { - EXPECT_TRUE(first_action_called); - EXPECT_FALSE(second_action_called); - second_action_called = YES; - }]; - label().text = @"test"; - EXPECT_TRUE(first_action_called); - EXPECT_TRUE(second_action_called); -} - -} // namespace
diff --git a/ios/chrome/browser/ui/util/manual_text_framer.h b/ios/chrome/browser/ui/util/manual_text_framer.h deleted file mode 100644 index 1a719dd..0000000 --- a/ios/chrome/browser/ui/util/manual_text_framer.h +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_UTIL_MANUAL_TEXT_FRAMER_H_ -#define IOS_CHROME_BROWSER_UI_UTIL_MANUAL_TEXT_FRAMER_H_ - -#import <CoreText/CoreText.h> -#import <Foundation/Foundation.h> - -@protocol TextFrame; - -// Object encapsulating the manual framing of an attributed string within a -// bounding rect. -// Known limitations: -// - Justified-aligned text is not supported. -// - Hyphenation is never attempted, regardless of NSParagraphStyle's -// |hyphenationFactor|. -@interface ManualTextFramer : NSObject - -// Creates an instance that frames |string| within |bounds|. -- (instancetype)initWithString:(NSAttributedString*)string - inBounds:(CGRect)bounds NS_DESIGNATED_INITIALIZER; -- (instancetype)init NS_UNAVAILABLE; - -// Manually Frames the paragraph within the bounds provided upon initialization. -// Calling this method populates |textFrame|. -- (void)frameText; - -// The TextFrame created by |-frameText|. Will be nil before |-frameText| is -// called. -@property(strong, nonatomic, readonly) id<TextFrame> textFrame; - -@end - -#endif // IOS_CHROME_BROWSER_UI_UTIL_MANUAL_TEXT_FRAMER_H_
diff --git a/ios/chrome/browser/ui/util/manual_text_framer.mm b/ios/chrome/browser/ui/util/manual_text_framer.mm deleted file mode 100644 index 20b0239..0000000 --- a/ios/chrome/browser/ui/util/manual_text_framer.mm +++ /dev/null
@@ -1,629 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/util/manual_text_framer.h" - -#import <UIKit/UIKit.h> - -#include "base/check_op.h" -#include "base/mac/foundation_util.h" -#include "base/notreached.h" -#import "ios/chrome/browser/ui/util/core_text_util.h" -#import "ios/chrome/browser/ui/util/text_frame.h" -#import "ios/chrome/browser/ui/util/unicode_util.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -// NOTE: When RTL text is laid out into glyph runs, the glyphs appear in the -// visual order in which they appear on screen. In other words, the glyphs are -// arranged in the reverse order of their corresponding characters in the -// original string. - -namespace { -// Aligns |value| to the nearest pixel value, rounding by the function indicated -// by |function|. AlignmentFunction::CEIL should be used to align size values, -// while AlignmentFunction::FLOOR should be used to align location values. -enum class AlignmentFunction : short { CEIL = 0, FLOOR }; -CGFloat AlignValueToPixel(CGFloat value, AlignmentFunction function) { - static CGFloat scale = [[UIScreen mainScreen] scale]; - return function == AlignmentFunction::CEIL ? ceil(value * scale) / scale - : floor(value * scale) / scale; -} - -// Returns an NSArray of NSAttributedStrings corresponding to newline-separated -// paragraphs within |string|. -NSArray* GetParagraphStringsForString(NSAttributedString* string) { - NSMutableArray* paragraph_strings = [NSMutableArray array]; - NSCharacterSet* newline_char_set = [NSCharacterSet newlineCharacterSet]; - NSUInteger string_length = string.string.length; - NSRange remaining_range = NSMakeRange(0, string_length); - while (remaining_range.location < string_length) { - NSRange newline_range = - [string.string rangeOfCharacterFromSet:newline_char_set - options:0 - range:remaining_range]; - NSRange paragraph_range = NSMakeRange(0, 0); - if (newline_range.location == NSNotFound) { - // There's no newline in the remaining portion of the string. - paragraph_range = remaining_range; - remaining_range = NSMakeRange(string_length, 0); - } else { - // A newline character was encountered. Compute approximate text lines - // for the substring within |remaining_range| up to the newline. - NSUInteger newline_end = newline_range.location + newline_range.length; - paragraph_range = NSMakeRange(remaining_range.location, - newline_end - remaining_range.location); - remaining_range.location = newline_end; - remaining_range.length = string_length - remaining_range.location; - } - // Create an attributed substring for the current paragraph and add it to - // |paragraphs|. - [paragraph_strings - addObject:[string attributedSubstringFromRange:paragraph_range]]; - } - return paragraph_strings; -} -} // namespace - -#pragma mark - ManualTextFrame - -// A TextFrame implementation that is manually created by ManualTextFramer. -@interface ManualTextFrame : NSObject<TextFrame> { - // Backing objects for properties of the same name. - NSAttributedString* _string; - NSMutableArray* _lines; -} - -// Designated initializer. -- (instancetype)initWithString:(NSAttributedString*)string - inBounds:(CGRect)bounds NS_DESIGNATED_INITIALIZER; -- (instancetype)init NS_UNAVAILABLE; - -// Creates a FramedLine out of |line|, |stringRange|, and |origin|, then adds it -// to |lines|. -- (void)addFramedLineWithLine:(CTLineRef)line - stringRange:(NSRange)stringRange - origin:(CGPoint)origin; - -// Redefine property as readwrite. -@property(nonatomic, readwrite) NSRange framedRange; - -@end - -@implementation ManualTextFrame - -@synthesize framedRange = _framedRange; -@synthesize bounds = _bounds; - -- (instancetype)initWithString:(NSAttributedString*)string - inBounds:(CGRect)bounds { - if ((self = [super init])) { - DCHECK(string.string.length); - _string = string; - _bounds = bounds; - _lines = [[NSMutableArray alloc] init]; - } - return self; -} - -#pragma mark Accessors - -- (NSAttributedString*)string { - return _string; -} - -- (NSArray*)lines { - return _lines; -} - -#pragma mark Private - -- (void)addFramedLineWithLine:(CTLineRef)line - stringRange:(NSRange)stringRange - origin:(CGPoint)origin { - FramedLine* framedLine = [[FramedLine alloc] initWithLine:line - stringRange:stringRange - origin:origin]; - [_lines addObject:framedLine]; -} - -@end - -#pragma mark - ManualTextFramer Private Interface - -@interface ManualTextFramer () - -// The string passed upon initialization. -@property(strong, nonatomic, readonly) NSAttributedString* string; - -// The bounds passed upon initialization. -@property(nonatomic, readonly) CGRect bounds; - -// The width of the bounds passed upon initialization. -@property(nonatomic, readonly) CGFloat boundingWidth; - -// The remaining height into which text can be framed. -@property(nonatomic, assign) CGFloat remainingHeight; - -// The text frame constructed by |-frameText|. -@property(strong, nonatomic, readonly) ManualTextFrame* manualTextFrame; - -// Creates a ManualTextFrame and assigns it to |_manualTextFrame|. Returns YES -// if a new text frame was successfully created. -- (BOOL)setupManualTextFrame; - -@end - -#pragma mark - ParagraphFramer - -// ManualTextFramer subclass that frames a single paragraph. A paragraph is -// defined as an NSAttributedString which contains either zero newlines or one -// newline as its last character. -@interface ParagraphFramer : ManualTextFramer { - // Backing objects for properties of the same name. - base::ScopedCFTypeRef<CTLineRef> _line; -} - -// The CTLine created from |string|. -@property(nonatomic, readonly) CTLineRef line; - -// The effective text alignment for |line|. -@property(nonatomic, readonly) NSTextAlignment effectiveAlignment; - -// Character set containing characters that are appropriate for line endings. -// These characters include whitespaces and newlines (denoting a word boundary), -// in addition to line-ending characters like hyphens, em dashes, and en dashes. -@property(strong, nonatomic, readonly) NSCharacterSet* lineEndSet; - -// The index of the current run that is being framed. Setting |runIdx| also -// updates |currentRun| and |currentGlyphCount|. -@property(nonatomic, assign) CFIndex runIdx; - -// The CTRun corresponding with |runIdx| in |line|. -@property(nonatomic, readonly) CTRunRef currentRun; - -// The glyph count in |currentRun|. -@property(nonatomic, readonly) CFIndex currentGlyphCount; - -// The number of glyphs in |currentRun| that have been successfully framed. -@property(nonatomic, assign) CFIndex framedGlyphCount; - -// The range in |string| that has successfully been framed for the current line. -@property(nonatomic, assign) NSRange currentLineRange; - -// The width of the typographic bounds for the glyphs framed on the current -// line. This is the width of the substring of |string| corresponding to -// |currentLineRange|. -@property(nonatomic, assign) CGFloat currentLineWidth; - -// The width of the trailing whitespace for the current line. This whitespace -// is not counted against the line width if it's the end of the line, but needs -// to be added in if non-whitespace characters from subsequent runs fit on the -// same line. -@property(nonatomic, assign) CGFloat currentWhitespaceWidth; - -// Whether the paragraph's writing direction is in RTL. -@property(nonatomic, readonly) BOOL isRTL; - -// Either 1 or -1 depending on |isRTL|. -@property(nonatomic, readonly) CFIndex incrementAmount; - -// Glyphs are laid out differently for RTL and LTR languages (see note at top of -// file). These functions return a range with |range|'s length incremented or -// decremented and an updated location that would include the next glyph in the -// trailing direction. -- (CFRange)incrementRange:(CFRange)range byAmount:(CFIndex)amount; -- (CFRange)incrementRange:(CFRange)range; -- (CFRange)decrementRange:(CFRange)range; - -// Updates |range| such that its trailing glyph index is |trailingGlyphIdx|. -- (CFRange)updateRange:(CFRange)range - forTrailingGlyphIdx:(CFIndex)trailingGlyphIdx; - -// Returns the index of the trailing glyph in |range| for |currentRun|. -- (CFIndex)trailingGlyphIdxForRange:(CFRange)range; - -// Returns the index of the leading or trailing glyph in |currentRun|. -- (CFIndex)trailingGlyphIdxForCurrentRun; - -// Manually frames the glyphs in |currentRun| following |framedGlyphCount|. -// This function updates |framedGlyphCount|, |currentLineWidth|, and -// |currentLineRange|. -- (void)frameCurrentRun; - -// Returns the character associated with the glyph at |glyphIdx| in -// |currentRun|. -- (unichar)charForGlyphAtIdx:(CFIndex)glyphIdx; - -// Returns the index within the original string corresponding to the glyph at -// |glyphIdx| in |currentRun|. -- (CFIndex)stringIdxForGlyphAtIdx:(CFIndex)glyphIdx; - -// Returns YES if |runIdx| is within the range of |line|'s glyph runs array. -- (BOOL)runIdxIsValid:(CFIndex)runIdx; - -// Returns YES if |glyphIdx| is within [0, |currentGlyphCount|). -- (BOOL)glyphIdxIsValid:(CFIndex)glyphIdx; - -// Creates a line from |currentLineRange| and adds it to |lines|. -- (void)addCurrentLine; - -// Returns the baselines origin for the current line. This function depends on -// |currentLineRange|, |currentLineWidth|, and |remainingHeight|, and must be -// called before updating those bookkeeping variables when adding the line. -- (CGPoint)originForCurrentLine; -@end - -@implementation ParagraphFramer - -@synthesize effectiveAlignment = _effectiveTextAlignment; -@synthesize runIdx = _runIdx; -@synthesize currentRun = _currentRun; -@synthesize currentGlyphCount = _currentGlyphCount; -@synthesize framedGlyphCount = _framedGlyphCount; -@synthesize currentLineRange = _currentLineRange; -@synthesize currentLineWidth = _currentLineWidth; -@synthesize currentWhitespaceWidth = _currentWhitespaceWidth; -@synthesize isRTL = _isRTL; -@synthesize lineEndSet = _lineEndSet; - -- (instancetype)initWithString:(NSAttributedString*)string - inBounds:(CGRect)bounds { - if ((self = [super initWithString:string inBounds:bounds])) { - NSRange newlineRange = [string.string - rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet]]; - DCHECK(newlineRange.location == NSNotFound || - newlineRange.location == string.string.length - 1); - CTLineRef line = - CTLineCreateWithAttributedString(base::mac::NSToCFCast(string)); - _line.reset(line); - _effectiveTextAlignment = core_text_util::GetEffectiveTextAlignment(string); - NSWritingDirection direction = - core_text_util::GetEffectiveWritingDirection(string); - _isRTL = direction == NSWritingDirectionRightToLeft; - } - return self; -} - -- (void)frameText { - if (![self setupManualTextFrame]) - return; - self.runIdx = - self.isRTL ? CFArrayGetCount(CTLineGetGlyphRuns(self.line)) - 1 : 0; - while (self.currentRun) { - NSRange runStringRange = - core_text_util::GetStringRangeForRun(self.currentRun); - DCHECK_NE(runStringRange.location, static_cast<NSUInteger>(NSNotFound)); - DCHECK_NE(runStringRange.length, 0U); - CGFloat runLineHeight = - core_text_util::GetLineHeight(self.string, runStringRange); - // Count of the number of times the framing process (-frameCurrentRun) has - // "stalled" -- run without changing the total number of glyphs framed. In - // some cases the process may stall once at the end of a run, but if it - // stalls twice, it won't make any further progress and should halt. - NSUInteger stallCount = 0; - // Loop as long as framed glyph count is less that the total glyph count, - // and the framer is making progress. - while (self.framedGlyphCount < self.currentGlyphCount && stallCount < 2U) { - // Stop framing glyphs if there is not enough vertical space for the run. - if (self.remainingHeight < runLineHeight) - break; - CFIndex initialFramedGlyphCount = self.framedGlyphCount; - [self frameCurrentRun]; - if (self.framedGlyphCount == initialFramedGlyphCount) - stallCount++; - if (self.framedGlyphCount < self.currentGlyphCount) { - // The entire run didn't fit onto the current line, so create a CTLine - // from |currentLineRange| and add it to |lines|. - [self addCurrentLine]; - } - } - self.runIdx += self.incrementAmount; - } - // Add the final line. - [self addCurrentLine]; - // Update |manualTextFrame|'s |framedRange|. - self.manualTextFrame.framedRange = - NSMakeRange(0, self.currentLineRange.location); -} - -#pragma mark Accessors - -- (CTLineRef)line { - return _line.get(); -} - -- (NSCharacterSet*)lineEndSet { - if (!_lineEndSet) { - NSMutableCharacterSet* lineEndSet = - [NSMutableCharacterSet whitespaceAndNewlineCharacterSet]; - [lineEndSet addCharactersInString:@"-\u2013\u2014"]; - [lineEndSet removeCharactersInString:@"\u00A0"]; - _lineEndSet = lineEndSet; - } - return _lineEndSet; -} - -- (void)setRunIdx:(CFIndex)runIdx { - _runIdx = runIdx; - self.framedGlyphCount = 0; - if ([self runIdxIsValid:runIdx]) { - NSArray* runs = base::mac::CFToNSCast(CTLineGetGlyphRuns(self.line)); - _currentRun = (__bridge CTRunRef)(runs[_runIdx]); - _currentGlyphCount = CTRunGetGlyphCount(self.currentRun); - } else { - _currentRun = nullptr; - _currentGlyphCount = 0; - } -} - -- (CFIndex)incrementAmount { - return self.isRTL ? -1 : 1; -} - -#pragma mark Private - -- (CFRange)incrementRange:(CFRange)range byAmount:(CFIndex)amount { - CFRange incrementedRange = range; - incrementedRange.length += amount; - if (self.isRTL) - incrementedRange.location += self.incrementAmount * amount; - return incrementedRange; -} - -- (CFRange)incrementRange:(CFRange)range { - return [self incrementRange:range byAmount:1]; -} - -- (CFRange)decrementRange:(CFRange)range { - return [self incrementRange:range byAmount:-1]; -} - -- (CFRange)updateRange:(CFRange)range - forTrailingGlyphIdx:(CFIndex)trailingGlyphIdx { - DCHECK(self.isRTL ? trailingGlyphIdx <= range.location + range.length - : trailingGlyphIdx >= range.location); - DCHECK([self glyphIdxIsValid:trailingGlyphIdx]); - CFIndex currentTrailingGlyphIdx = [self trailingGlyphIdxForRange:range]; - CFIndex updateAmount = self.isRTL - ? currentTrailingGlyphIdx - trailingGlyphIdx - : trailingGlyphIdx - currentTrailingGlyphIdx; - return [self incrementRange:range byAmount:updateAmount]; -} - -- (CFIndex)trailingGlyphIdxForRange:(CFRange)range { - if (self.isRTL) - return range.location; - return range.location + range.length - 1; -} - -- (CFIndex)trailingGlyphIdxForCurrentRun { - return self.isRTL ? 0 : self.currentGlyphCount - 1; -} - -- (void)frameCurrentRun { - DCHECK(self.currentRun); - DCHECK_LT(self.framedGlyphCount, self.currentGlyphCount); - DCHECK_LT(self.currentLineWidth, self.boundingWidth); - - // Calculate the range that will fit in the remaining portion of the line. - NSCharacterSet* whitespaceSet = - [NSCharacterSet whitespaceAndNewlineCharacterSet]; - CFIndex startGlyphIdx = self.isRTL - ? self.currentGlyphCount - self.framedGlyphCount - : self.framedGlyphCount; - CFRange remainingRunRange = - CFRangeMake(self.isRTL ? 0 : startGlyphIdx, - self.currentGlyphCount - self.framedGlyphCount); - CFRange range = CFRangeMake(startGlyphIdx, 0); - while (remainingRunRange.length > 0) { - // Find the range for the next word that can be added to the line. If no - // delimiters were found, frame the rest of the run. - CFIndex delimIdx = core_text_util::GetGlyphIdxForCharInSet( - self.currentRun, remainingRunRange, self.string, self.lineEndSet); - if (delimIdx == kCFNotFound) - delimIdx = [self trailingGlyphIdxForCurrentRun]; - CFRange wordGlyphRange = - [self updateRange:remainingRunRange forTrailingGlyphIdx:delimIdx]; - CFIndex wordFramedGlyphCount = wordGlyphRange.length; - // Trim any whitespace and record its width. - CGFloat wordTrailingWhitespaceWidth = 0.0; - if ([whitespaceSet characterIsMember:[self charForGlyphAtIdx:delimIdx]]) { - wordTrailingWhitespaceWidth = - core_text_util::GetGlyphWidth(self.currentRun, delimIdx); - wordGlyphRange = [self decrementRange:wordGlyphRange]; - } - // Check if the word will fit on the line. - CGFloat wordWidth = - core_text_util::GetRunWidthWithRange(self.currentRun, wordGlyphRange); - CGFloat cumulativeLineWidth = - self.currentLineWidth + self.currentWhitespaceWidth + wordWidth; - if (cumulativeLineWidth <= self.boundingWidth) { - // The word at |wordGlyphRange| fits on the line. - self.currentLineWidth = cumulativeLineWidth; - self.framedGlyphCount += wordFramedGlyphCount; - self.currentWhitespaceWidth = wordTrailingWhitespaceWidth; - remainingRunRange.length -= wordFramedGlyphCount; - if (!self.isRTL) - remainingRunRange.location += wordFramedGlyphCount; - range = [self incrementRange:range byAmount:wordFramedGlyphCount]; - } else { - break; - } - } - // Early return if no glyphs were framed. - if (!range.length) - return; - // Use the string index of the next glyph to determine the string range for - // the current line, since a glyph may correspond with multiple characters - // when ligatures are used. - CFIndex nextGlyphIdx = - [self trailingGlyphIdxForRange:range] + self.incrementAmount; - CFIndex nextGlyphStringIdx; - if ([self glyphIdxIsValid:nextGlyphIdx]) { - nextGlyphStringIdx = [self stringIdxForGlyphAtIdx:nextGlyphIdx]; - } else { - CFRange runStringRange = CTRunGetStringRange(self.currentRun); - nextGlyphStringIdx = runStringRange.location + runStringRange.length; - } - self.currentLineRange = - NSMakeRange(self.currentLineRange.location, - nextGlyphStringIdx - self.currentLineRange.location); -} - -- (unichar)charForGlyphAtIdx:(CFIndex)glyphIdx { - DCHECK([self glyphIdxIsValid:glyphIdx]); - return [self.string.string - characterAtIndex:[self stringIdxForGlyphAtIdx:glyphIdx]]; -} - -- (CFIndex)stringIdxForGlyphAtIdx:(CFIndex)glyphIdx { - DCHECK([self glyphIdxIsValid:glyphIdx]); - CFIndex stringIdx = 0; - CTRunGetStringIndices(self.currentRun, CFRangeMake(glyphIdx, 1), &stringIdx); - return stringIdx; -} - -- (BOOL)runIdxIsValid:(CFIndex)runIdx { - NSArray* runs = base::mac::CFToNSCast(CTLineGetGlyphRuns(self.line)); - return runIdx >= 0 && runIdx < static_cast<CFIndex>(runs.count); -} - -- (BOOL)glyphIdxIsValid:(CFIndex)glyphIdx { - return glyphIdx >= 0 && glyphIdx < self.currentGlyphCount; -} - -- (void)addCurrentLine { - // Don't attempt to add a line if |currentLineRange| is empty. - if (!self.currentLineRange.length) - return; - // Add the new line and its corresponding string range and baseline origin. - NSAttributedString* currentLineString = - [self.string attributedSubstringFromRange:self.currentLineRange]; - CTLineRef currentLine = CTLineCreateWithAttributedString( - base::mac::NSToCFCast(currentLineString)); - [self.manualTextFrame addFramedLineWithLine:currentLine - stringRange:self.currentLineRange - origin:[self originForCurrentLine]]; - CFRelease(currentLine); - // Update bookkeeping variables for next line. - CGFloat usedHeight = - core_text_util::GetLineHeight(self.string, self.currentLineRange) + - core_text_util::GetLineSpacing(self.string, self.currentLineRange); - self.currentLineRange = NSMakeRange( - self.currentLineRange.location + self.currentLineRange.length, 0); - self.currentLineWidth = 0; - self.currentWhitespaceWidth = 0; - self.remainingHeight -= usedHeight; -} - -- (CGPoint)originForCurrentLine { - CGPoint origin = CGPointZero; - CGFloat alignedWidth = - AlignValueToPixel(self.currentLineWidth, AlignmentFunction::CEIL); - switch (self.effectiveAlignment) { - case NSTextAlignmentLeft: - // Left-aligned lines begin at 0.0. - break; - case NSTextAlignmentRight: - origin.x = AlignValueToPixel(self.boundingWidth - alignedWidth, - AlignmentFunction::FLOOR); - break; - case NSTextAlignmentCenter: - origin.x = AlignValueToPixel((self.boundingWidth - alignedWidth) / 2.0, - AlignmentFunction::FLOOR); - break; - default: - // Only left, right, and center effective alignment is supported. - NOTREACHED(); - break; - } - UIFont* font = [self.string attribute:NSFontAttributeName - atIndex:self.currentLineRange.location - effectiveRange:nullptr]; - CGFloat lineHeight = - core_text_util::GetLineHeight(self.string, self.currentLineRange); - origin.y = - AlignValueToPixel(self.remainingHeight - lineHeight - font.descender, - AlignmentFunction::FLOOR); - return origin; -} - -@end - -#pragma mark - ManualTextFramer - -@implementation ManualTextFramer - -@synthesize bounds = _bounds; -@synthesize boundingWidth = _boundingWidth; -@synthesize remainingHeight = _remainingHeight; -@synthesize string = _string; -@synthesize manualTextFrame = _manualTextFrame; - -- (instancetype)initWithString:(NSAttributedString*)string - inBounds:(CGRect)bounds { - if ((self = [super init])) { - DCHECK(string.string.length); - _string = string; - _bounds = bounds; - _boundingWidth = CGRectGetWidth(bounds); - _remainingHeight = CGRectGetHeight(bounds); - } - return self; -} - -- (void)frameText { - if (![self setupManualTextFrame]) - return; - NSRange framedRange = NSMakeRange(0, 0); - NSArray* paragraphs = GetParagraphStringsForString(self.string); - NSUInteger stringRangeOffset = 0; - for (NSAttributedString* paragraph in paragraphs) { - // Frame each paragraph using a ParagraphFramer, then update bookkeeping - // variables for the top-level ManualTextFramer. - CGRect remainingBounds = - CGRectMake(0, 0, self.boundingWidth, self.remainingHeight); - ParagraphFramer* framer = - [[ParagraphFramer alloc] initWithString:paragraph - inBounds:remainingBounds]; - [framer frameText]; - id<TextFrame> frame = [framer textFrame]; - DCHECK(frame); - framedRange.length += frame.framedRange.length; - CGFloat paragraphHeight = 0.0; - for (FramedLine* line in frame.lines) { - NSRange lineRange = line.stringRange; - lineRange.location += stringRangeOffset; - [self.manualTextFrame addFramedLineWithLine:line.line - stringRange:lineRange - origin:line.origin]; - paragraphHeight += core_text_util::GetLineHeight(self.string, lineRange) + - core_text_util::GetLineSpacing(self.string, lineRange); - } - self.remainingHeight -= paragraphHeight; - stringRangeOffset += paragraph.string.length; - } - self.manualTextFrame.framedRange = framedRange; -} - -#pragma mark Accessors - -- (id<TextFrame>)textFrame { - return _manualTextFrame; -} - -#pragma mark Private - -- (BOOL)setupManualTextFrame { - if (_manualTextFrame) - return NO; - _manualTextFrame = - [[ManualTextFrame alloc] initWithString:self.string inBounds:self.bounds]; - return YES; -} - -@end
diff --git a/ios/chrome/browser/ui/util/manual_text_framer_unittest.mm b/ios/chrome/browser/ui/util/manual_text_framer_unittest.mm deleted file mode 100644 index ed5d2011..0000000 --- a/ios/chrome/browser/ui/util/manual_text_framer_unittest.mm +++ /dev/null
@@ -1,310 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ios/chrome/browser/ui/util/manual_text_framer.h" - -#import <MaterialComponents/MaterialTypography.h> - -#include "base/mac/foundation_util.h" -#include "base/time/time.h" -#import "ios/chrome/browser/ui/util/core_text_util.h" -#import "ios/chrome/browser/ui/util/text_frame.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/gtest_mac.h" -#include "testing/platform_test.h" -#include "url/gurl.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { -void ExpectNearPoint(CGFloat value1, CGFloat value2) { - EXPECT_NEAR(value1, value2, 1); -} - -class ManualTextFramerTest : public PlatformTest { - protected: - ManualTextFramerTest() { - attributes_ = [[NSMutableDictionary alloc] init]; - string_ = [[NSMutableAttributedString alloc] init]; - } - - NSString* text() { return [string_ string]; } - NSRange text_range() { return NSMakeRange(0, [string_ length]); } - id<TextFrame> text_frame() { return static_cast<id<TextFrame>>(text_frame_); } - - void SetText(NSString* text) { - DCHECK(text.length); - [[string_ mutableString] setString:text]; - } - - void FrameTextInBounds(CGRect bounds) { - ManualTextFramer* manual_framer = - [[ManualTextFramer alloc] initWithString:string_ inBounds:bounds]; - [manual_framer frameText]; - id frame = [manual_framer textFrame]; - text_frame_ = frame; - } - - UIFont* TypographyFontWithSize(CGFloat size) { - return [[MDCTypography fontLoader] regularFontOfSize:size]; - } - - NSParagraphStyle* CreateParagraphStyle(CGFloat line_height, - NSTextAlignment alignment, - NSLineBreakMode line_break_mode) { - NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init]; - style.alignment = alignment; - style.lineBreakMode = line_break_mode; - style.minimumLineHeight = line_height; - style.maximumLineHeight = line_height; - return style; - } - - NSMutableDictionary* attributes() { return attributes_; } - - void ApplyAttributesForRange(NSRange range) { - [string_ setAttributes:attributes_ range:range]; - } - - void CheckForLineCountAndFramedRange(NSUInteger line_count, - NSRange framed_range) { - EXPECT_EQ(line_count, text_frame().lines.count); - EXPECT_EQ(framed_range.location, text_frame().framedRange.location); - EXPECT_EQ(framed_range.length, text_frame().framedRange.length); - } - - NSMutableDictionary* attributes_; - NSMutableAttributedString* string_; - id<TextFrame> text_frame_; -}; - -// Tests that newline characters cause an attributed string to be laid out on -// multiple lines. -TEST_F(ManualTextFramerTest, NewlineTest) { - SetText(@"line one\nline two\nline three"); - attributes()[NSFontAttributeName] = TypographyFontWithSize(14.0); - attributes()[NSParagraphStyleAttributeName] = CreateParagraphStyle( - 20.0, NSTextAlignmentNatural, NSLineBreakByWordWrapping); - ApplyAttributesForRange(text_range()); - CGRect bounds = CGRectMake(0, 0, 500, 500); - FrameTextInBounds(bounds); - CheckForLineCountAndFramedRange(3, text_range()); -} - -// Tests that strings with no spaces fail correctly. -TEST_F(ManualTextFramerTest, NoSpacesText) { - // "St. Mary's church in the hollow of the white hazel near the the rapid - // whirlpool of Llantysilio of the red cave." - SetText( - @"Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch"); - attributes()[NSFontAttributeName] = TypographyFontWithSize(16.0); - attributes()[NSParagraphStyleAttributeName] = CreateParagraphStyle( - 20.0, NSTextAlignmentNatural, NSLineBreakByWordWrapping); - ApplyAttributesForRange(text_range()); - CGRect bounds = CGRectMake(0, 0, 200, 60); - FrameTextInBounds(bounds); - CheckForLineCountAndFramedRange(0, NSMakeRange(0, 0)); -} - -// Tests that unbreakable spaces are accounted for. -TEST_F(ManualTextFramerTest, UnbreakableSpace) { - SetText(@"This is a long text with\u00A0unbreakable\u00A0spaces"); - attributes()[NSFontAttributeName] = TypographyFontWithSize(16.0); - attributes()[NSParagraphStyleAttributeName] = CreateParagraphStyle( - 20.0, NSTextAlignmentNatural, NSLineBreakByWordWrapping); - ApplyAttributesForRange(text_range()); - CGRect bounds = CGRectMake(0, 0, 200, 60); - FrameTextInBounds(bounds); - ASSERT_EQ(2UL, text_frame().lines.count); - FramedLine* line = text_frame().lines[1]; - EXPECT_TRUE(NSEqualRanges(NSMakeRange(20, 23), line.stringRange)); -} - -// Tests that multiple newlines are accounted for. Only the first three -// newlines should be added to |lines_|. -TEST_F(ManualTextFramerTest, MultipleNewlineTest) { - SetText(@"\n\n\ntext"); - attributes()[NSParagraphStyleAttributeName] = CreateParagraphStyle( - 20.0, NSTextAlignmentNatural, NSLineBreakByWordWrapping); - ApplyAttributesForRange(text_range()); - CGRect bounds = CGRectMake(0, 0, 500, 60); - FrameTextInBounds(bounds); - CheckForLineCountAndFramedRange(3, NSMakeRange(0, 3)); -} - -// Tests that the framed range for text that will be rendered with ligatures is -// corresponds with the actual range of the text. -TEST_F(ManualTextFramerTest, LigatureTest) { - SetText(@"fffi"); - attributes()[NSFontAttributeName] = TypographyFontWithSize(14.0); - attributes()[NSParagraphStyleAttributeName] = CreateParagraphStyle( - 20.0, NSTextAlignmentNatural, NSLineBreakByWordWrapping); - ApplyAttributesForRange(text_range()); - CGRect bounds = CGRectMake(0, 0, 500, 20); - FrameTextInBounds(bounds); - CheckForLineCountAndFramedRange(1, text_range()); -} - -// Tests that ManualTextFramer correctly frames Å -TEST_F(ManualTextFramerTest, DiacriticTest) { - SetText(@"A\u030A"); - attributes()[NSFontAttributeName] = TypographyFontWithSize(14.0); - attributes()[NSParagraphStyleAttributeName] = CreateParagraphStyle( - 20.0, NSTextAlignmentNatural, NSLineBreakByWordWrapping); - ApplyAttributesForRange(text_range()); - CGRect bounds = CGRectMake(0, 0, 500, 20); - FrameTextInBounds(bounds); - CheckForLineCountAndFramedRange(1, text_range()); -} - -// String text, attributes, and bounds are chosen to match the "Terms of -// Service" text in WelcomeToChromeView, as the text is not properly framed by -// CTFrameSetter. http://crbug.com/537212 -TEST_F(ManualTextFramerTest, TOSTextTest) { - CGRect bounds = CGRectMake(0, 0, 300.0, 40.0); - NSString* const kTOSLinkText = @"Terms of Service"; - NSString* const kTOSText = - @"By using this application, you agree to Chrome’s Terms of Service."; - SetText(kTOSText); - attributes()[NSFontAttributeName] = TypographyFontWithSize(14.0); - attributes()[NSParagraphStyleAttributeName] = CreateParagraphStyle( - 20.0, NSTextAlignmentCenter, NSLineBreakByTruncatingTail); - attributes()[NSForegroundColorAttributeName] = [UIColor blackColor]; - ApplyAttributesForRange(text_range()); - attributes()[NSForegroundColorAttributeName] = [UIColor blueColor]; - ApplyAttributesForRange([kTOSText rangeOfString:kTOSLinkText]); - FrameTextInBounds(bounds); - CheckForLineCountAndFramedRange(2, text_range()); -} - -// Tests that the origin of a left-aligned single line is correct. -TEST_F(ManualTextFramerTest, SimpleOriginTest) { - SetText(@"test"); - UIFont* font = TypographyFontWithSize(14.0); - attributes()[NSFontAttributeName] = font; - CGFloat line_height = 20.0; - attributes()[NSParagraphStyleAttributeName] = CreateParagraphStyle( - line_height, NSTextAlignmentLeft, NSLineBreakByWordWrapping); - ApplyAttributesForRange(text_range()); - CGRect bounds = CGRectMake(0, 0, 500, 21); - FrameTextInBounds(bounds); - CheckForLineCountAndFramedRange(1, text_range()); - FramedLine* line = [text_frame().lines firstObject]; - EXPECT_EQ(0, line.origin.x); - ExpectNearPoint(CGRectGetHeight(bounds) - line_height - font.descender, - line.origin.y); -} - -// Tests that lines that are laid out in RTL are right aligned. -TEST_F(ManualTextFramerTest, OriginRTLTest) { - if (@available(iOS 15, *)) { - // TODO(crbug.com/1220239): Fix for TextInput2 changes in iOS15. - return; - } - SetText(@"\u0641\u064e\u0628\u064e\u0642\u064e\u064a\u0652\u062a\u064f\u0020" - @"\u0645\u064f\u062a\u064e\u0627\u0628\u0650\u0639\u064e\u0627\u064b" - @"\u0020\u0028\u0634\u064f\u063a\u0652\u0644\u0650\u064a\u0029\u0020" - @"\u0644\u064e\u0639\u064e\u0644\u064e\u0643\u0650\u0020\u062a\u064e" - @"\u062a\u064e\u0639\u064e\u0644\u0651\u064e\u0645\u064e\u0020\u0627" - @"\u0644\u062d\u0650\u0631\u0652\u0635\u064e\u0020\u0639\u064e\u0644" - @"\u064e\u0649\u0020\u0627\u0644\u0648\u064e\u0642\u0652\u062a\u0650" - @"\u0020\u002e\u0020\u0641\u064e\u0627\u0644\u062d\u064e\u064a\u064e" - @"\u0627\u0629\u064f"); - attributes()[NSFontAttributeName] = TypographyFontWithSize(14.0); - attributes()[NSParagraphStyleAttributeName] = CreateParagraphStyle( - 20.0, NSTextAlignmentNatural, NSLineBreakByWordWrapping); - ApplyAttributesForRange(text_range()); - // The bounds width is chosen so that the RTL string above can be completely - // laid out into three lines. - CGRect bounds = CGRectMake(0, 0, 115.0, 60.0); - FrameTextInBounds(bounds); - CheckForLineCountAndFramedRange(3, text_range()); - for (FramedLine* line in text_frame().lines) { - ExpectNearPoint( - CGRectGetMaxX(bounds), - line.origin.x + core_text_util::GetTrimmedLineWidth(line.line)); - } -} - -TEST_F(ManualTextFramerTest, CJKLineBreakTest) { - // Example from our strings. Framer will put “触摸搜索” on one line, and then - // fail to frame the second. - // clang-format off - SetText(@"“触摸搜索”会将所选字词和当前页面(作为上下文)一起发送给 Google 搜索。" - @"您可以在设置中停用此功能。"); - // clang-format on - attributes()[NSFontAttributeName] = TypographyFontWithSize(16.0); - attributes()[NSParagraphStyleAttributeName] = CreateParagraphStyle( - 16 * 1.15, NSTextAlignmentNatural, NSLineBreakByWordWrapping); - ApplyAttributesForRange(text_range()); - CGRect bounds = CGRectMake(0, 0, 300.0, 65.0); - FrameTextInBounds(bounds); - CheckForLineCountAndFramedRange(3, NSMakeRange(0, 53)); - - // Example without any space-ish characters: - SetText(@"会将所选字词和当前页面(作为上下文)一起发送给Google搜索。" - @"您可以在设置中停用此功能。"); - attributes()[NSFontAttributeName] = TypographyFontWithSize(16.0); - attributes()[NSParagraphStyleAttributeName] = CreateParagraphStyle( - 16 * 1.15, NSTextAlignmentNatural, NSLineBreakByWordWrapping); - ApplyAttributesForRange(text_range()); - FrameTextInBounds(bounds); - CheckForLineCountAndFramedRange(2, NSMakeRange(0, 45)); -} - -// Tests that paragraphs with NSTextAlignmentCenter are actually centered. -TEST_F(ManualTextFramerTest, CenterAlignedTest) { - SetText(@"xxxx\nyyy\nwww"); - attributes()[NSFontAttributeName] = TypographyFontWithSize(14.0); - attributes()[NSParagraphStyleAttributeName] = CreateParagraphStyle( - 20.0, NSTextAlignmentCenter, NSLineBreakByWordWrapping); - ApplyAttributesForRange(text_range()); - CGRect bounds = CGRectMake(0, 0, 200.0, 60.0); - FrameTextInBounds(bounds); - CheckForLineCountAndFramedRange(3, text_range()); - for (FramedLine* line in text_frame().lines) { - ExpectNearPoint(CGRectGetMidX(bounds) - - 0.5 * core_text_util::GetTrimmedLineWidth(line.line), - line.origin.x); - } -} - -// Tests that words with a large line height will not be framed if they don't -// fit in the bounding height. -TEST_F(ManualTextFramerTest, LargeLineHeightTest) { - SetText(@"the last word is very LARGE"); - attributes()[NSFontAttributeName] = TypographyFontWithSize(14.0); - attributes()[NSParagraphStyleAttributeName] = CreateParagraphStyle( - 20.0, NSTextAlignmentCenter, NSLineBreakByWordWrapping); - ApplyAttributesForRange(text_range()); - attributes()[NSParagraphStyleAttributeName] = CreateParagraphStyle( - 500.0, NSTextAlignmentCenter, NSLineBreakByWordWrapping); - ApplyAttributesForRange(NSMakeRange(22, 5)); // "LARGE" - CGRect bounds = CGRectMake(0, 0, 500, 20.0); - FrameTextInBounds(bounds); - CheckForLineCountAndFramedRange(1, NSMakeRange(0, 22)); -} - -// Tests a preexisting error condition in which a BiDi string containing Arabic -// is correctly laid out (crbug.com/584549). -TEST_F(ManualTextFramerTest, RTLTest) { - SetText(@"\u0642\u062F\u0020\u064A\u0633\u062A\u062E\u062F\u0645\u0020\u0047" - "\u006F\u006F\u0067\u006C\u0065\u0020\u0043\u0068\u0072\u006F\u006D" - "\u0065\u0020\u062E\u062F\u0645\u0627\u062A\u0020\u0627\u0644\u0648" - "\u064A\u0628\u0020\u0644\u062A\u062D\u0633\u064A\u0646\u0020\u062A" - "\u062C\u0631\u0628\u0629\u0020\u0627\u0644\u062A\u0635\u0641\u062D" - "\u002E\u0020\u0648\u064A\u0645\u0643\u0646\u0643\u0020\u0628\u0634" - "\u0643\u0644\u0020\u0627\u062E\u062A\u064A\u0627\u0631\u064A\u0020" - "\u062A\u0639\u0637\u064A\u0644\u0020\u0647\u0630\u0647\u0020\u0627" - "\u0644\u062E\u062F\u0645\u0627\u062A\u002E"); - attributes()[NSFontAttributeName] = [UIFont systemFontOfSize:20.0]; - ApplyAttributesForRange(text_range()); - CGRect bounds = CGRectMake(0, 0, 500, 100); - FrameTextInBounds(bounds); - CheckForLineCountAndFramedRange(2, text_range()); -} - -} // namespace
diff --git a/ios/chrome/browser/ui/util/text_frame.h b/ios/chrome/browser/ui/util/text_frame.h deleted file mode 100644 index dac27eb..0000000 --- a/ios/chrome/browser/ui/util/text_frame.h +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_UTIL_TEXT_FRAME_H_ -#define IOS_CHROME_BROWSER_UI_UTIL_TEXT_FRAME_H_ - -#import <CoreText/CoreText.h> -#import <UIKit/UIKit.h> - -// An object encapsulating a line of text that has been framed within a bounding -// rect. -@interface FramedLine : NSObject - -// Designated initializer. -- (instancetype)initWithLine:(CTLineRef)line - stringRange:(NSRange)stringRange - origin:(CGPoint)origin NS_DESIGNATED_INITIALIZER; -- (instancetype)init NS_UNAVAILABLE; - -// The CTLine that was framed. -@property(nonatomic, readonly) CTLineRef line; -// The range within the original string that corresponds with |line|. CTLines -// created by ManualTextFramers report string ranges with 0 for their locations, -// so the actual range is stored here separately. -@property(nonatomic, readonly) NSRange stringRange; -// The baseline origin (in Quartz coordinates) of the line within its bounds. -@property(nonatomic, readonly) CGPoint origin; - -// Returns the offset into |line| of the glyph corresponding with the character -// in the original string at |stringLocation|. Returns kCFNotFound if -// |stringLocation| is outside of |stringRange|. -- (CFIndex)lineOffsetForStringLocation:(NSUInteger)stringLocation; - -@end - -// Protocol for objects that contain NSAttributedStrings laid out within a -// bounding rect. -@protocol TextFrame<NSObject> - -// The string that was framed within |bounds|. -@property(nonatomic, readonly) NSAttributedString* string; -// The range of |string| that was successfully framed. -@property(nonatomic, readonly) NSRange framedRange; -// An NSArray of FramedLines corresponding to |string| as laid out in |bounds|. -@property(nonatomic, readonly) NSArray* lines; -// The bounds in which |string| is laid out. -@property(nonatomic, readonly) CGRect bounds; - -@end - -// A TextFrame implementation that is backed by a CTFrameRef. -@interface CoreTextTextFrame : NSObject<TextFrame> - -// Designated initializer. -- (instancetype)initWithString:(NSAttributedString*)string - bounds:(CGRect)bounds - frame:(CTFrameRef)frame NS_DESIGNATED_INITIALIZER; -- (instancetype)init NS_UNAVAILABLE; - -@end - -#endif // IOS_CHROME_BROWSER_UI_UTIL_TEXT_FRAME_H_
diff --git a/ios/chrome/browser/ui/util/text_frame.mm b/ios/chrome/browser/ui/util/text_frame.mm deleted file mode 100644 index 966e03c3..0000000 --- a/ios/chrome/browser/ui/util/text_frame.mm +++ /dev/null
@@ -1,148 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/util/text_frame.h" - -#include "base/check_op.h" -#include "base/mac/foundation_util.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -#pragma mark - FramedLine - -@implementation FramedLine { - // Backing object for property of the same name. - id _line; -} - -@synthesize stringRange = _stringRange; -@synthesize origin = _origin; - -- (instancetype)initWithLine:(CTLineRef)line - stringRange:(NSRange)stringRange - origin:(CGPoint)origin { - if ((self = [super init])) { - DCHECK(line); - // CTLines created by ManualTextFramers all have zero for their string range - // locations, but its length should be equal to |stringRange|. - NSRange lineRange; - if (!base::mac::CFRangeToNSRange(CTLineGetStringRange(line), &lineRange)) { - return nil; - } - DCHECK_EQ(lineRange.length, stringRange.length); - _line = (__bridge id)(line); - _stringRange = stringRange; - _origin = origin; - } - return self; -} - -- (NSString*)description { - return [NSString stringWithFormat:@"%@ line:%@, stringRange:%@, origin:%@", - [super description], _line, - NSStringFromRange(_stringRange), - NSStringFromCGPoint(_origin)]; -} - -- (CFIndex)lineOffsetForStringLocation:(NSUInteger)stringLocation { - if (stringLocation < self.stringRange.location || - stringLocation >= self.stringRange.location + self.stringRange.length) { - return kCFNotFound; - } - NSRange lineRange; - if (!base::mac::CFRangeToNSRange(CTLineGetStringRange(self.line), &lineRange)) - return kCFNotFound; - return lineRange.location + (stringLocation - self.stringRange.location); -} - -#pragma mark Accessors - -- (CTLineRef)line { - return (__bridge CTLineRef)(_line); -} - -@end - -#pragma mark - CoreTextTextFrame - -@interface CoreTextTextFrame () { - // Backing object for property of the same name. - NSAttributedString* _string; - id _frame; - NSMutableArray* _lines; -} - -// The CTFrameRef passed on initializaton. -@property(nonatomic, readonly) CTFrameRef frame; - -// Populates |lines| using |frame|. -- (void)createFramedLines; - -@end - -@implementation CoreTextTextFrame - -@synthesize bounds = _bounds; - -- (instancetype)initWithString:(NSAttributedString*)string - bounds:(CGRect)bounds - frame:(CTFrameRef)frame { - if ((self = [super self])) { - DCHECK(string.string.length); - _string = string; - _bounds = bounds; - DCHECK(frame); - _frame = (__bridge id)(frame); - } - return self; -} - -#pragma mark Accessors - -- (NSAttributedString*)string { - return _string; -} - -- (NSRange)framedRange { - NSRange range; - CFRange cfRange = CTFrameGetVisibleStringRange(self.frame); - if (base::mac::CFRangeToNSRange(cfRange, &range)) - return range; - return NSMakeRange(NSNotFound, 0); -} - -- (NSArray*)lines { - if (!_lines) - [self createFramedLines]; - return _lines; -} - -- (CTFrameRef)frame { - return (__bridge CTFrameRef)(_frame); -} - -#pragma mark Private - -- (void)createFramedLines { - NSArray* lines = base::mac::CFToNSCast(CTFrameGetLines(self.frame)); - CGPoint origins[lines.count]; - CTFrameGetLineOrigins(self.frame, CFRangeMake(0, 0), origins); - _lines = [[NSMutableArray alloc] initWithCapacity:lines.count]; - for (NSUInteger line_idx = 0; line_idx < lines.count; ++line_idx) { - CTLineRef line = (__bridge CTLineRef)(lines[line_idx]); - NSRange stringRange; - CFRange cfStringRange = CTLineGetStringRange(line); - if (!base::mac::CFRangeToNSRange(cfStringRange, &stringRange)) - break; - FramedLine* framedLine = - [[FramedLine alloc] initWithLine:line - stringRange:stringRange - origin:origins[line_idx]]; - [_lines addObject:framedLine]; - } -} - -@end
diff --git a/ios/chrome/browser/ui/util/text_region_mapper.h b/ios/chrome/browser/ui/util/text_region_mapper.h deleted file mode 100644 index b0bc98a..0000000 --- a/ios/chrome/browser/ui/util/text_region_mapper.h +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_UTIL_TEXT_REGION_MAPPER_H_ -#define IOS_CHROME_BROWSER_UI_UTIL_TEXT_REGION_MAPPER_H_ - -#import <UIKit/UIKit.h> - -// A TextRegionMapper is a utility class that can, given an attributed string -// and bounds that the string will be rendered in, return the regions (rects) -// that ranges of the string occupy when rendered in the given bounds. - -// For testing purposes the class interface is defined as a protocol. - -@protocol TextRegionMapper<NSObject> -// Create a new mapper. The mapper can be used repeatedly as long as the -// string and its bounds do not change; if they do, another mapper must be -// created. -- (instancetype)initWithAttributedString:(NSAttributedString*)string - bounds:(CGRect)bounds; - -// Returns an array of (NSValue-boxed) CGRects which enclose the regions inside -// |bounds| that the characters of |string|'s substring at |range| occupy. If -// the string is spread across several lines, a given range might occupy several -// disjoint rects. -// Note that the rect encloses only the region occupied by the glyphs, not any -// leading or other space padding. -// If |range| is partially or wholly outside of the range of |string|, an -// empty array is returned. -- (NSArray*)rectsForRange:(NSRange)range; - -@end - -// The actual class implementation works by typesetting the text using CoreText. -@interface CoreTextRegionMapper : NSObject<TextRegionMapper> - -- (instancetype)initWithAttributedString:(NSAttributedString*)string - bounds:(CGRect)bounds - NS_DESIGNATED_INITIALIZER; - -- (instancetype)init NS_UNAVAILABLE; - -@end - -#endif // IOS_CHROME_BROWSER_UI_UTIL_TEXT_REGION_MAPPER_H_
diff --git a/ios/chrome/browser/ui/util/text_region_mapper.mm b/ios/chrome/browser/ui/util/text_region_mapper.mm deleted file mode 100644 index c8ae9c4..0000000 --- a/ios/chrome/browser/ui/util/text_region_mapper.mm +++ /dev/null
@@ -1,100 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/util/text_region_mapper.h" - -#import <CoreText/CoreText.h> -#import <QuartzCore/QuartzCore.h> - -#include "base/check_op.h" -#include "base/i18n/rtl.h" -#include "base/mac/foundation_util.h" -#import "ios/chrome/browser/ui/util/core_text_util.h" -#import "ios/chrome/browser/ui/util/manual_text_framer.h" -#import "ios/chrome/browser/ui/util/text_frame.h" -#include "ios/chrome/browser/ui/util/ui_util.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@interface CoreTextRegionMapper () - -// The TextFrame used to calculate rects. -@property(strong, nonatomic, readonly) id<TextFrame> textFrame; - -@end - -@implementation CoreTextRegionMapper - -@synthesize textFrame = _textFrame; - -- (instancetype)initWithAttributedString:(NSAttributedString*)string - bounds:(CGRect)bounds { - if ((self = [super init])) { - base::ScopedCFTypeRef<CTFrameRef> ctFrame = - core_text_util::CreateTextFrameForStringInBounds(string, bounds); - ManualTextFramer* framer = - [[ManualTextFramer alloc] initWithString:string inBounds:bounds]; - [framer frameText]; - if (core_text_util::IsTextFrameValid(ctFrame, framer, string)) { - _textFrame = [[CoreTextTextFrame alloc] initWithString:string - bounds:bounds - frame:ctFrame]; - } else { - // Use ManualTextFramer if |ctFrame| is invalid. - _textFrame = [framer textFrame]; - } - DCHECK(self.textFrame); - } - return self; -} - -- (NSArray*)rectsForRange:(NSRange)range { - NSRange framedRange = self.textFrame.framedRange; - if (!range.length || range.location + range.length > framedRange.length) - return @[]; - - NSMutableArray* rects = [NSMutableArray array]; - // CoreText uses Quartz coordinates, so they will need to be flipped back to - // UIKit-space. - CGAffineTransform transformForCoreText = CGAffineTransformScale( - CGAffineTransformMakeTranslation(0, self.textFrame.bounds.size.height), - 1.f, -1.f); - - CGFloat ascent = 0.0f; // height of text above the baseline. - CGFloat descent = 0.0f; // height of text below the baseline. - - // Find any parts of the link on each line. - for (FramedLine* line in self.textFrame.lines) { - CGFloat lineWidth = static_cast<CGFloat>( - CTLineGetTypographicBounds(line.line, &ascent, &descent, nullptr)); - if (!lineWidth) - break; - - NSRange overlap = NSIntersectionRange(range, line.stringRange); - if (overlap.length > 0) { - // Some of the range is on this line; find where it starts and ends. - CFIndex stringOffset = - [line lineOffsetForStringLocation:overlap.location]; - DCHECK_NE(stringOffset, kCFNotFound); - CGFloat start = - CTLineGetOffsetForStringIndex(line.line, stringOffset, nullptr); - CGFloat end = CTLineGetOffsetForStringIndex( - line.line, stringOffset + overlap.length, nullptr); - CGRect flippedRangeRect = - CGRectMake(line.origin.x + start, - line.origin.y - descent, // Lower extent of text. - end - start, // Length of link text. - ascent + descent); // Total height of text. - // Flip to UIKit coordinates. - CGRect rangeRect = - CGRectApplyAffineTransform(flippedRangeRect, transformForCoreText); - [rects addObject:[NSValue valueWithCGRect:rangeRect]]; - } - } - return rects; -} - -@end
diff --git a/ios/chrome/browser/ui/util/text_region_mapper_unittest.mm b/ios/chrome/browser/ui/util/text_region_mapper_unittest.mm deleted file mode 100644 index 5802206..0000000 --- a/ios/chrome/browser/ui/util/text_region_mapper_unittest.mm +++ /dev/null
@@ -1,142 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import <UIKit/UIKit.h> - -#import <MaterialComponents/MaterialTypography.h> - -#include "base/mac/foundation_util.h" -#include "ios/chrome/browser/ui/util/text_region_mapper.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/gtest_mac.h" -#include "testing/platform_test.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { -class TextRegionMapperTest : public PlatformTest { - protected: - void InitMapper(NSAttributedString* string, CGRect bounds) { - _string = [string copy]; - _textMapper = - [[CoreTextRegionMapper alloc] initWithAttributedString:_string - bounds:bounds]; - } - - CGRect RectAtIndex(NSArray* array, NSUInteger index) { - NSValue* value = base::mac::ObjCCastStrict<NSValue>(array[index]); - return [value CGRectValue]; - } - - NSDictionary* AttributesForTextAlignment(NSTextAlignment alignment) { - NSMutableParagraphStyle* style = - [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy]; - [style setAlignment:alignment]; - return @{NSParagraphStyleAttributeName : style}; - } - - NSAttributedString* _string; - CoreTextRegionMapper* _textMapper; -}; -} - -TEST_F(TextRegionMapperTest, SimpleTextTest) { - CGRect bounds = CGRectMake(0, 0, 500, 100); - NSString* string = @"Simple Test"; - InitMapper([[NSAttributedString alloc] initWithString:string], bounds); - - // Simple case: a single word in a string in a large bounding rect. - // Rect bounding word should be inside bounding rect, and should be - // wider than it is tall. - NSRange range = NSMakeRange(0, 6); // "Simple". - NSArray* rects = [_textMapper rectsForRange:range]; - ASSERT_EQ(1UL, [rects count]); - CGRect rect = RectAtIndex(rects, 0); - EXPECT_TRUE(CGRectContainsRect(bounds, rect)); - EXPECT_GT(CGRectGetWidth(rect), CGRectGetHeight(rect)); - - // Range that ends at end of string still generates a rect. - range = NSMakeRange(9, 2); - rects = [_textMapper rectsForRange:range]; - ASSERT_EQ(1UL, [rects count]); - rect = RectAtIndex(rects, 0); - EXPECT_TRUE(CGRectContainsRect(bounds, rect)); - - // Simple null cases: range of zero length, range outside of string. - range = NSMakeRange(6, 0); - rects = [_textMapper rectsForRange:range]; - EXPECT_EQ(0UL, [rects count]) << "Range has length 0."; - - range = NSMakeRange([_string length] + 1, 5); - rects = [_textMapper rectsForRange:range]; - EXPECT_EQ(0UL, [rects count]) << "Range starts beyond string."; - - range = NSMakeRange([_string length] - 2, 3); - rects = [_textMapper rectsForRange:range]; - EXPECT_EQ(0UL, [rects count]) << "Range ends beyond string."; -} - -TEST_F(TextRegionMapperTest, TextAlignmentTest) { - CGRect bounds = CGRectMake(0, 0, 500, 100); - NSAttributedString* string; - string = [[NSAttributedString alloc] - initWithString:@"Simple Test" - attributes:AttributesForTextAlignment(NSTextAlignmentLeft)]; - InitMapper(string, bounds); - - // First word of left-aligned string should at the left edge of the bounds. - NSRange range = NSMakeRange(0, 6); // "Simple". - NSArray* rects = [_textMapper rectsForRange:range]; - ASSERT_EQ(1UL, [rects count]); - CGRect rect = RectAtIndex(rects, 0); - EXPECT_TRUE(CGRectContainsRect(bounds, rect)); - EXPECT_GT(CGRectGetWidth(rect), CGRectGetHeight(rect)); - EXPECT_EQ(CGRectGetMinX(rect), CGRectGetMinX(bounds)); - - string = [[NSAttributedString alloc] - initWithString:@"Simple Test" - attributes:AttributesForTextAlignment(NSTextAlignmentRight)]; - InitMapper(string, bounds); - - // Last word of right-aligned string should at the right edge of the bounds. - range = NSMakeRange(6, 5); // "Test". - rects = [_textMapper rectsForRange:range]; - ASSERT_EQ(1UL, [rects count]); - rect = RectAtIndex(rects, 0); - EXPECT_TRUE(CGRectContainsRect(bounds, rect)); - EXPECT_GT(CGRectGetWidth(rect), CGRectGetHeight(rect)); - EXPECT_EQ(CGRectGetMaxX(rect), CGRectGetMaxX(bounds)); -} - -TEST_F(TextRegionMapperTest, CJKTest) { - CGRect bounds = CGRectMake(0, 0, 345, 65); - // clang-format off - NSString* CJKString = - @"“触摸搜索”会将所选字词和当前页面(作为上下文)一起发送给 Google 搜索。" - @"您可以在设置中停用此功能。"; - // clang-format on - NSMutableDictionary* attributes = [NSMutableDictionary - dictionaryWithDictionary:AttributesForTextAlignment(NSTextAlignmentLeft)]; - attributes[NSFontAttributeName] = - [[MDCTypography fontLoader] regularFontOfSize:16]; - NSAttributedString* string = - [[NSAttributedString alloc] initWithString:CJKString - attributes:attributes]; - InitMapper(string, bounds); - - NSRange range = NSMakeRange(0, 6); // "“触摸搜索”". - NSArray* rects = [_textMapper rectsForRange:range]; - ASSERT_EQ(1UL, [rects count]); -} - -/* - Further unit tests should cover additional cases: - - In several languages. - - Range split across line break == two rects - - Bidi text with text range across scripts gets two rects. - - Various string attributions. - - Isolate buggy CoreText case. -*/
diff --git a/ios/web/common/features.mm b/ios/web/common/features.mm index c7f0a011..efb73c2 100644 --- a/ios/web/common/features.mm +++ b/ios/web/common/features.mm
@@ -35,7 +35,7 @@ "EnablePersistentDownloads", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kUseJSForErrorPage{"UseJSForErrorPage", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kUseDefaultUserAgentInWebClient{ "UseDefaultUserAgentInWebClient", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ios/web/web_state/error_page_inttest.mm b/ios/web/web_state/error_page_inttest.mm index ed646613..79f7a56 100644 --- a/ios/web/web_state/error_page_inttest.mm +++ b/ios/web/web_state/error_page_inttest.mm
@@ -169,7 +169,7 @@ if (base::FeatureList::IsEnabled(features::kUseJSForErrorPage)) { // TODO(crbug.com/1153261): this test should be fixed in newer versions of // WebKit. - if (@available(iOS 14.4, *)) { + if (@available(iOS 15, *)) { } else { return; }
diff --git a/ios/web/web_state/web_state_impl_unittest.mm b/ios/web/web_state/web_state_impl_unittest.mm index 1da78d7..1858f75 100644 --- a/ios/web/web_state/web_state_impl_unittest.mm +++ b/ios/web/web_state/web_state_impl_unittest.mm
@@ -1089,6 +1089,10 @@ })); session_storage = web_state_->BuildSessionStorage(); EXPECT_EQ(0, session_storage.lastCommittedItemIndex); + + // Wait for the error to be displayed. + EXPECT_TRUE(web::test::WaitForWebViewContainingText( + web_state_.get(), "error", base::test::ios::kWaitForJSCompletionTimeout)); } // Tests that CanTakeSnapshot() is false when a JavaScript dialog is being
diff --git a/ios/web/web_state/web_state_unittest.mm b/ios/web/web_state/web_state_unittest.mm index 000a7caf..4b8116d1 100644 --- a/ios/web/web_state/web_state_unittest.mm +++ b/ios/web/web_state/web_state_unittest.mm
@@ -605,6 +605,10 @@ EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForPageLoadTimeout, ^{ return !navigation_manager->GetPendingItem() && !web_state_ptr->IsLoading(); })); + + // Wait for the error to be displayed. + EXPECT_TRUE(web::test::WaitForWebViewContainingText( + web_state_ptr, "error", base::test::ios::kWaitForJSCompletionTimeout)); } // Verifies that calling NavigationManager::LoadURLWithParams() does not stop @@ -707,6 +711,10 @@ EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForPageLoadTimeout, ^{ return !navigation_manager->GetPendingItem() && !web_state_ptr->IsLoading(); })); + + // Wait for the error to be displayed. + EXPECT_TRUE(web::test::WaitForWebViewContainingText( + web_state_ptr, "error", base::test::ios::kWaitForJSCompletionTimeout)); } // Verifies that each page title is restored.
diff --git a/ios/web/webui/url_data_manager_ios_backend.mm b/ios/web/webui/url_data_manager_ios_backend.mm index 86f40e8..24b097d 100644 --- a/ios/web/webui/url_data_manager_ios_backend.mm +++ b/ios/web/webui/url_data_manager_ios_backend.mm
@@ -246,8 +246,9 @@ } void URLRequestChromeJob::Start() { - TRACE_EVENT_ASYNC_BEGIN1("browser", "DataManager:Request", this, "URL", - request_->url().possibly_invalid_spec()); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("browser", "DataManager:Request", + TRACE_ID_LOCAL(this), "URL", + request_->url().possibly_invalid_spec()); if (!request_) return; @@ -339,7 +340,8 @@ } void URLRequestChromeJob::DataAvailable(base::RefCountedMemory* bytes) { - TRACE_EVENT_ASYNC_END0("browser", "DataManager:Request", this); + TRACE_EVENT_NESTABLE_ASYNC_END0("browser", "DataManager:Request", + TRACE_ID_LOCAL(this)); if (bytes) { data_ = bytes; if (pending_buf_.get()) {
diff --git a/media/audio/audio_output_device_thread_callback.cc b/media/audio/audio_output_device_thread_callback.cc index 37a8808..c6f8b16 100644 --- a/media/audio/audio_output_device_thread_callback.cc +++ b/media/audio/audio_output_device_thread_callback.cc
@@ -71,7 +71,8 @@ // that we have some data, we'll get another one after the device is awake and // ingesting data, which is what we want to track with this trace. if (callback_num_ == 2) - TRACE_EVENT_ASYNC_END0("audio", "StartingPlayback", this); + TRACE_EVENT_NESTABLE_ASYNC_END0("audio", "StartingPlayback", + TRACE_ID_LOCAL(this)); // Update the audio-delay measurement, inform about the number of skipped // frames, and ask client to render audio. Since |output_bus_| is wrapping
diff --git a/media/base/audio_buffer.cc b/media/base/audio_buffer.cc index 69795da..ee85332 100644 --- a/media/base/audio_buffer.cc +++ b/media/base/audio_buffer.cc
@@ -389,6 +389,20 @@ return; } + if (sample_format_ == kSampleFormatPlanarS32) { + // Format is planar signed32. Convert each value into float and insert into + // output channel data. + for (int ch = 0; ch < channel_count_; ++ch) { + const int32_t* source_data = + reinterpret_cast<const int32_t*>(channel_data_[ch]) + + source_frame_offset; + float* dest_data = dest->channel(ch) + dest_frame_offset; + for (int i = 0; i < frames_to_copy; ++i) + dest_data[i] = SignedInt32SampleTypeTraits::ToFloat(source_data[i]); + } + return; + } + const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); const int frame_size = channel_count_ * bytes_per_channel; const uint8_t* source_data = data_.get() + source_frame_offset * frame_size;
diff --git a/media/base/audio_buffer_unittest.cc b/media/base/audio_buffer_unittest.cc index a3ec83b69..37b1ec4 100644 --- a/media/base/audio_buffer_unittest.cc +++ b/media/base/audio_buffer_unittest.cc
@@ -418,6 +418,37 @@ 1.0f / std::numeric_limits<int16_t>::max()); } +TEST(AudioBufferTest, ReadS32Planar) { + const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; + const int channels = ChannelLayoutToChannelCount(channel_layout); + const int frames = 20; + constexpr float kIncrement = + 1.0f / static_cast<float>(std::numeric_limits<int32_t>::max()); + constexpr float kStart = kIncrement; + const base::TimeDelta start_time; + scoped_refptr<AudioBuffer> buffer = + MakeAudioBuffer<int32_t>(kSampleFormatPlanarS32, channel_layout, channels, + kSampleRate, 1, 1, frames, start_time); + std::unique_ptr<AudioBus> bus = AudioBus::Create(channels, frames); + buffer->ReadFrames(10, 0, 0, bus.get()); + VerifyBus(bus.get(), 10, kStart, kIncrement); + + // Read all the frames backwards, one by one. ch[0] should be 20, 19, ... + bus->Zero(); + for (int i = frames - 1; i >= 0; --i) + buffer->ReadFrames(1, i, i, bus.get()); + VerifyBus(bus.get(), frames, kStart, kIncrement); + + // Read 0 frames with different offsets. Existing data in AudioBus should be + // unchanged. + buffer->ReadFrames(0, 0, 0, bus.get()); + VerifyBus(bus.get(), frames, kStart, kIncrement); + buffer->ReadFrames(0, 0, 10, bus.get()); + VerifyBus(bus.get(), frames, kStart, kIncrement); + buffer->ReadFrames(0, 10, 0, bus.get()); + VerifyBus(bus.get(), frames, kStart, kIncrement); +} + TEST(AudioBufferTest, ReadF32Planar) { const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0; const int channels = ChannelLayoutToChannelCount(channel_layout);
diff --git a/media/base/decode_status.cc b/media/base/decode_status.cc index af52c1b8d..b6f46f3 100644 --- a/media/base/decode_status.cc +++ b/media/base/decode_status.cc
@@ -41,17 +41,18 @@ base::TimeDelta timestamp) : trace_name_(trace_name) { DCHECK(trace_name_); - TRACE_EVENT_ASYNC_BEGIN2("media", trace_name_, this, "is_key_frame", - is_key_frame, "timestamp_us", - timestamp.InMicroseconds()); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN2("media", trace_name_, TRACE_ID_LOCAL(this), + "is_key_frame", is_key_frame, + "timestamp_us", timestamp.InMicroseconds()); } ScopedDecodeTrace::ScopedDecodeTrace(const char* trace_name, const DecoderBuffer& buffer) : trace_name_(trace_name) { DCHECK(trace_name_); - TRACE_EVENT_ASYNC_BEGIN1("media", trace_name_, this, "decoder_buffer", - buffer.AsHumanReadableString(/*verbose=*/true)); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( + "media", trace_name_, TRACE_ID_LOCAL(this), "decoder_buffer", + buffer.AsHumanReadableString(/*verbose=*/true)); } ScopedDecodeTrace::~ScopedDecodeTrace() { @@ -62,8 +63,9 @@ void ScopedDecodeTrace::EndTrace(const Status& status) { DCHECK(!closed_); closed_ = true; - TRACE_EVENT_ASYNC_END1("media", trace_name_, this, "status", - GetDecodeStatusString(status.code())); + TRACE_EVENT_NESTABLE_ASYNC_END1("media", trace_name_, TRACE_ID_LOCAL(this), + "status", + GetDecodeStatusString(status.code())); } } // namespace media
diff --git a/media/base/scoped_async_trace.cc b/media/base/scoped_async_trace.cc index cb525c79..c76e83f7 100644 --- a/media/base/scoped_async_trace.cc +++ b/media/base/scoped_async_trace.cc
@@ -22,11 +22,11 @@ } ScopedAsyncTrace::ScopedAsyncTrace(const char* name) : name_(name) { - TRACE_EVENT_ASYNC_BEGIN0(kCategory, name_, this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(kCategory, name_, TRACE_ID_LOCAL(this)); } ScopedAsyncTrace::~ScopedAsyncTrace() { - TRACE_EVENT_ASYNC_END0(kCategory, name_, this); + TRACE_EVENT_NESTABLE_ASYNC_END0(kCategory, name_, TRACE_ID_LOCAL(this)); } } // namespace media
diff --git a/media/base/test_helpers.cc b/media/base/test_helpers.cc index 3858e86f..3f2d500 100644 --- a/media/base/test_helpers.cc +++ b/media/base/test_helpers.cc
@@ -329,8 +329,7 @@ static_cast<int>(frames)); output->set_timestamp(timestamp); - const bool is_planar = - format == kSampleFormatPlanarS16 || format == kSampleFormatPlanarF32; + const bool is_planar = IsPlanar(format); // Values in channel 0 will be: // start
diff --git a/media/capture/content/android/thread_safe_capture_oracle.cc b/media/capture/content/android/thread_safe_capture_oracle.cc index ec0b4c41..e1d3788 100644 --- a/media/capture/content/android/thread_safe_capture_oracle.cc +++ b/media/capture/content/android/thread_safe_capture_oracle.cc
@@ -127,9 +127,10 @@ base::saturated_cast<int>(attenuated_utilization * 100.0 + 0.5)); } - TRACE_EVENT_ASYNC_BEGIN2("gpu.capture", "Capture", output_buffer.id, - "frame_number", frame_number, "trigger", - VideoCaptureOracle::EventAsString(event)); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN2( + "gpu.capture", "Capture", + TRACE_ID_WITH_SCOPE("Capture", output_buffer.id), "frame_number", + frame_number, "trigger", VideoCaptureOracle::EventAsString(event)); std::unique_ptr<VideoCaptureBufferHandle> output_buffer_access = output_buffer.handle_provider->GetHandleForInProcessAccess(); @@ -214,9 +215,11 @@ const bool should_deliver_frame = oracle_.CompleteCapture(capture->frame_number, success, &reference_time); - TRACE_EVENT_ASYNC_END2("gpu.capture", "Capture", capture->buffer.id, - "success", should_deliver_frame, "timestamp", - (reference_time - base::TimeTicks()).InMicroseconds()); + TRACE_EVENT_NESTABLE_ASYNC_END2( + "gpu.capture", "Capture", + TRACE_ID_WITH_SCOPE("Capture", capture->buffer.id), "success", + should_deliver_frame, "timestamp", + (reference_time - base::TimeTicks()).InMicroseconds()); if (!should_deliver_frame || !client_) return;
diff --git a/media/capture/video/chromeos/video_capture_jpeg_decoder_impl.cc b/media/capture/video/chromeos/video_capture_jpeg_decoder_impl.cc index 6b16b2c..f953a28 100644 --- a/media/capture/video/chromeos/video_capture_jpeg_decoder_impl.cc +++ b/media/capture/video/chromeos/video_capture_jpeg_decoder_impl.cc
@@ -61,8 +61,10 @@ media::VideoCaptureDevice::Client::Buffer out_buffer) { DCHECK(decoder_); - TRACE_EVENT_ASYNC_BEGIN0("jpeg", "VideoCaptureJpegDecoderImpl decoding", - next_task_id_); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( + "jpeg", "VideoCaptureJpegDecoderImpl decoding", + TRACE_ID_WITH_SCOPE("VideoCaptureJpegDecoderImpl decoding", + next_task_id_)); TRACE_EVENT0("jpeg", "VideoCaptureJpegDecoderImpl::DecodeCapturedData"); // TODO(kcwu): enqueue decode requests in case decoding is not fast enough @@ -188,8 +190,9 @@ std::move(decode_done_closure_).Run(); - TRACE_EVENT_ASYNC_END0("jpeg", "VideoCaptureJpegDecoderImpl decoding", - task_id); + TRACE_EVENT_NESTABLE_ASYNC_END0( + "jpeg", "VideoCaptureJpegDecoderImpl decoding", + TRACE_ID_WITH_SCOPE("VideoCaptureJpegDecoderImpl decoding", task_id)); } void VideoCaptureJpegDecoderImpl::NotifyError(
diff --git a/media/cast/sender/audio_encoder.cc b/media/cast/sender/audio_encoder.cc index c5b221f..e7fda97 100644 --- a/media/cast/sender/audio_encoder.cc +++ b/media/cast/sender/audio_encoder.cc
@@ -147,19 +147,19 @@ audio_frame->rtp_timestamp = frame_rtp_timestamp_; audio_frame->reference_time = frame_capture_time_; - TRACE_EVENT_ASYNC_BEGIN2("cast.stream", "Audio Encode", audio_frame.get(), - "frame_id", frame_id_.lower_32_bits(), - "rtp_timestamp", - frame_rtp_timestamp_.lower_32_bits()); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN2( + "cast.stream", "Audio Encode", TRACE_ID_LOCAL(audio_frame.get()), + "frame_id", frame_id_.lower_32_bits(), "rtp_timestamp", + frame_rtp_timestamp_.lower_32_bits()); if (EncodeFromFilledBuffer(&audio_frame->data)) { // Compute encoder utilization as the real-world time elapsed divided // by the signal duration. audio_frame->encoder_utilization = (base::TimeTicks::Now() - start_time) / frame_duration_; - TRACE_EVENT_ASYNC_END1("cast.stream", "Audio Encode", audio_frame.get(), - "encoder_utilization", - audio_frame->encoder_utilization); + TRACE_EVENT_NESTABLE_ASYNC_END1( + "cast.stream", "Audio Encode", TRACE_ID_LOCAL(audio_frame.get()), + "encoder_utilization", audio_frame->encoder_utilization); audio_frame->encode_completion_time = cast_environment_->Clock()->NowTicks();
diff --git a/media/cast/sender/frame_sender.cc b/media/cast/sender/frame_sender.cc index 30b32cc..79c13d3 100644 --- a/media/cast/sender/frame_sender.cc +++ b/media/cast/sender/frame_sender.cc
@@ -325,10 +325,10 @@ target_playout_delay_.InMilliseconds(); } - TRACE_EVENT_ASYNC_BEGIN1("cast.stream", - is_audio_ ? "Audio Transport" : "Video Transport", - frame_id.lower_32_bits(), "rtp_timestamp", - encoded_frame->rtp_timestamp.lower_32_bits()); + const char* name = is_audio_ ? "Audio Transport" : "Video Transport"; + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( + "cast.stream", name, TRACE_ID_WITH_SCOPE(name, frame_id.lower_32_bits()), + "rtp_timestamp", encoded_frame->rtp_timestamp.lower_32_bits()); transport_sender_->InsertFrame(ssrc_, *encoded_frame); } @@ -421,10 +421,11 @@ // This is a good place to match the trace for frame ids // since this ensures we not only track frame ids that are // implicitly ACKed, but also handles duplicate ACKs - TRACE_EVENT_ASYNC_END1( - "cast.stream", is_audio_ ? "Audio Transport" : "Video Transport", - latest_acked_frame_id_.lower_32_bits(), "RTT_usecs", - current_round_trip_time_.InMicroseconds()); + const char* name = is_audio_ ? "Audio Transport" : "Video Transport"; + TRACE_EVENT_NESTABLE_ASYNC_END1( + "cast.stream", name, + TRACE_ID_WITH_SCOPE(name, latest_acked_frame_id_.lower_32_bits()), + "RTT_usecs", current_round_trip_time_.InMicroseconds()); } while (latest_acked_frame_id_ < cast_feedback.ack_frame_id); transport_sender_->CancelSendingFrames(ssrc_, frames_to_cancel); OnCancelSendingFrames();
diff --git a/media/cast/sender/video_sender.cc b/media/cast/sender/video_sender.cc index 6e3949ee..490449c 100644 --- a/media/cast/sender/video_sender.cc +++ b/media/cast/sender/video_sender.cc
@@ -250,9 +250,9 @@ frame_to_encode, reference_time, base::BindOnce(&VideoSender::OnEncodedVideoFrame, AsWeakPtr(), frame_to_encode, bitrate))) { - TRACE_EVENT_ASYNC_BEGIN1("cast.stream", "Video Encode", - frame_to_encode.get(), "rtp_timestamp", - rtp_timestamp.lower_32_bits()); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( + "cast.stream", "Video Encode", TRACE_ID_LOCAL(frame_to_encode.get()), + "rtp_timestamp", rtp_timestamp.lower_32_bits()); frames_in_encoder_++; duration_in_encoder_ += duration_added_by_next_frame; last_enqueued_frame_rtp_timestamp_ = rtp_timestamp; @@ -306,10 +306,10 @@ last_reported_encoder_utilization_ = encoded_frame->encoder_utilization; last_reported_lossy_utilization_ = encoded_frame->lossy_utilization; - TRACE_EVENT_ASYNC_END2("cast.stream", "Video Encode", video_frame.get(), - "encoder_utilization", - last_reported_encoder_utilization_, - "lossy_utilization", last_reported_lossy_utilization_); + TRACE_EVENT_NESTABLE_ASYNC_END2( + "cast.stream", "Video Encode", TRACE_ID_LOCAL(video_frame.get()), + "encoder_utilization", last_reported_encoder_utilization_, + "lossy_utilization", last_reported_lossy_utilization_); // Report the resource utilization for processing this frame. Take the // greater of the two utilization values and attenuate them such that the
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index 1be6f88..a9db3e7 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -400,7 +400,6 @@ "//testing/gtest", "//ui/android:ui_java", "//ui/base", - "//ui/display/manager", "//ui/gfx", "//ui/gfx:test_support", "//ui/gfx/geometry",
diff --git a/media/gpu/DEPS b/media/gpu/DEPS index 1c3e548..f8a66ffc 100644 --- a/media/gpu/DEPS +++ b/media/gpu/DEPS
@@ -10,7 +10,6 @@ "+third_party/webrtc/common_video", "+ui/base", "+ui/display/display_switches.h", - "+ui/display/manager", "+ui/display/types", "+ui/platform_window", "+components/viz/common/gpu/vulkan_context_provider.h",
diff --git a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc index 9510c31..53aa2d6 100644 --- a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
@@ -1137,7 +1137,8 @@ VLOGF(2); DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); DCHECK_EQ(state_, kDecoding); - TRACE_EVENT_ASYNC_BEGIN0("media,gpu", "V4L2SVDA Resolution Change", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media,gpu", "V4L2SVDA Resolution Change", + TRACE_ID_LOCAL(this)); DCHECK(!surface_set_change_pending_); surface_set_change_pending_ = true; NewEventPending(); @@ -1197,7 +1198,8 @@ surface_set_change_pending_ = false; VLOGF(2) << "Surface set change finished"; - TRACE_EVENT_ASYNC_END0("media,gpu", "V4L2SVDA Resolution Change", this); + TRACE_EVENT_NESTABLE_ASYNC_END0("media,gpu", "V4L2SVDA Resolution Change", + TRACE_ID_LOCAL(this)); return true; } @@ -1764,7 +1766,8 @@ void V4L2SliceVideoDecodeAccelerator::InitiateFlush() { VLOGF(2); DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); - TRACE_EVENT_ASYNC_BEGIN0("media,gpu", "V4L2SVDA Flush", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media,gpu", "V4L2SVDA Flush", + TRACE_ID_LOCAL(this)); // This will trigger output for all remaining surfaces in the decoder. // However, not all of them may be decoded yet (they would be queued @@ -1825,7 +1828,8 @@ child_task_runner_->PostTask( FROM_HERE, base::BindOnce(&Client::NotifyFlushDone, client_)); - TRACE_EVENT_ASYNC_END0("media,gpu", "V4L2SVDA Flush", this); + TRACE_EVENT_NESTABLE_ASYNC_END0("media,gpu", "V4L2SVDA Flush", + TRACE_ID_LOCAL(this)); return true; } @@ -1841,7 +1845,8 @@ void V4L2SliceVideoDecodeAccelerator::ResetTask() { VLOGF(2); DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); - TRACE_EVENT_ASYNC_BEGIN0("media,gpu", "V4L2SVDA Reset", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media,gpu", "V4L2SVDA Reset", + TRACE_ID_LOCAL(this)); if (IsDestroyPending()) return; @@ -1904,7 +1909,8 @@ child_task_runner_->PostTask( FROM_HERE, base::BindOnce(&Client::NotifyResetDone, client_)); - TRACE_EVENT_ASYNC_END0("media,gpu", "V4L2SVDA Reset", this); + TRACE_EVENT_NESTABLE_ASYNC_END0("media,gpu", "V4L2SVDA Reset", + TRACE_ID_LOCAL(this)); return true; }
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc index aa2b26ae..b943f35 100644 --- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -1617,7 +1617,8 @@ return; } - TRACE_EVENT_ASYNC_BEGIN0("media,gpu", "V4L2VDA::FlushTask", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media,gpu", "V4L2VDA::FlushTask", + TRACE_ID_LOCAL(this)); // We don't support stacked flushing. DCHECK(!decoder_flushing_); @@ -1688,7 +1689,8 @@ } void V4L2VideoDecodeAccelerator::NofityFlushDone() { - TRACE_EVENT_ASYNC_END0("media,gpu", "V4L2VDA::FlushTask", this); + TRACE_EVENT_NESTABLE_ASYNC_END0("media,gpu", "V4L2VDA::FlushTask", + TRACE_ID_LOCAL(this)); decoder_delay_bitstream_buffer_id_ = -1; decoder_flushing_ = false; VLOGF(2) << "returning flush"; @@ -1737,7 +1739,8 @@ return; } - TRACE_EVENT_ASYNC_BEGIN0("media,gpu", "V4L2VDA::ResetTask", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media,gpu", "V4L2VDA::ResetTask", + TRACE_ID_LOCAL(this)); decoder_current_bitstream_buffer_.reset(); while (!decoder_input_queue_.empty()) @@ -1813,7 +1816,8 @@ return; } - TRACE_EVENT_ASYNC_END0("media,gpu", "V4L2VDA::ResetTask", this); + TRACE_EVENT_NESTABLE_ASYNC_END0("media,gpu", "V4L2VDA::ResetTask", + TRACE_ID_LOCAL(this)); // Start poll thread if NotifyFlushDoneIfNeeded has not already. if (!device_poll_thread_.IsRunning()) {
diff --git a/media/gpu/windows/dxva_video_decode_accelerator_win.cc b/media/gpu/windows/dxva_video_decode_accelerator_win.cc index c796396d..237b23d8 100644 --- a/media/gpu/windows/dxva_video_decode_accelerator_win.cc +++ b/media/gpu/windows/dxva_video_decode_accelerator_win.cc
@@ -1887,7 +1887,8 @@ break; // No more retries needed. } - TRACE_EVENT_ASYNC_END0("gpu", "DXVAVideoDecodeAccelerator.Decoding", this); + TRACE_EVENT_NESTABLE_ASYNC_END0("gpu", "DXVAVideoDecodeAccelerator.Decoding", + TRACE_ID_LOCAL(this)); TRACE_COUNTER1("DXVA_Decoding", "TotalPacketsBeforeDecode", inputs_before_decode_); @@ -2375,8 +2376,8 @@ current_color_space_ = color_space; if (!inputs_before_decode_) { - TRACE_EVENT_ASYNC_BEGIN0("gpu", "DXVAVideoDecodeAccelerator.Decoding", - this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( + "gpu", "DXVAVideoDecodeAccelerator.Decoding", TRACE_ID_LOCAL(this)); } inputs_before_decode_++; hr = decoder_->ProcessInput(0, sample.Get(), 0);
diff --git a/media/renderers/audio_renderer_impl.cc b/media/renderers/audio_renderer_impl.cc index 445479f9..3053692 100644 --- a/media/renderers/audio_renderer_impl.cc +++ b/media/renderers/audio_renderer_impl.cc
@@ -277,7 +277,8 @@ void AudioRendererImpl::Flush(base::OnceClosure callback) { DVLOG(1) << __func__; DCHECK(task_runner_->BelongsToCurrentThread()); - TRACE_EVENT_ASYNC_BEGIN0("media", "AudioRendererImpl::Flush", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media", "AudioRendererImpl::Flush", + TRACE_ID_LOCAL(this)); // Flush |sink_| now. |sink_| must only be accessed on |task_runner_| and not // be called under |lock_|. @@ -365,7 +366,8 @@ DCHECK(init_cb); DCHECK(state_ == kUninitialized || state_ == kFlushed); DCHECK(sink_); - TRACE_EVENT_ASYNC_BEGIN0("media", "AudioRendererImpl::Initialize", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media", "AudioRendererImpl::Initialize", + TRACE_ID_LOCAL(this)); // If we are re-initializing playback (e.g. switching media tracks), stop the // sink first. @@ -679,14 +681,16 @@ void AudioRendererImpl::FinishInitialization(PipelineStatus status) { DCHECK(init_cb_); - TRACE_EVENT_ASYNC_END1("media", "AudioRendererImpl::Initialize", this, - "status", PipelineStatusToString(status)); + TRACE_EVENT_NESTABLE_ASYNC_END1("media", "AudioRendererImpl::Initialize", + TRACE_ID_LOCAL(this), "status", + PipelineStatusToString(status)); std::move(init_cb_).Run(status); } void AudioRendererImpl::FinishFlush() { DCHECK(flush_cb_); - TRACE_EVENT_ASYNC_END0("media", "AudioRendererImpl::Flush", this); + TRACE_EVENT_NESTABLE_ASYNC_END0("media", "AudioRendererImpl::Flush", + TRACE_ID_LOCAL(this)); std::move(flush_cb_).Run(); }
diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc index 7357ba4..d64e0b43 100644 --- a/media/renderers/renderer_impl.cc +++ b/media/renderers/renderer_impl.cc
@@ -136,7 +136,8 @@ DCHECK_EQ(state_, STATE_UNINITIALIZED); DCHECK(init_cb); DCHECK(client); - TRACE_EVENT_ASYNC_BEGIN0("media", "RendererImpl::Initialize", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media", "RendererImpl::Initialize", + TRACE_ID_LOCAL(this)); client_ = client; media_resource_ = media_resource; @@ -211,7 +212,8 @@ DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(!flush_cb_); DCHECK(!(pending_audio_track_change_ || pending_video_track_change_)); - TRACE_EVENT_ASYNC_BEGIN0("media", "RendererImpl::Flush", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media", "RendererImpl::Flush", + TRACE_ID_LOCAL(this)); if (state_ == STATE_FLUSHED) { flush_cb_ = BindToCurrentLoop(std::move(flush_cb)); @@ -360,14 +362,16 @@ void RendererImpl::FinishInitialization(PipelineStatus status) { DCHECK(init_cb_); - TRACE_EVENT_ASYNC_END1("media", "RendererImpl::Initialize", this, "status", - PipelineStatusToString(status)); + TRACE_EVENT_NESTABLE_ASYNC_END1("media", "RendererImpl::Initialize", + TRACE_ID_LOCAL(this), "status", + PipelineStatusToString(status)); std::move(init_cb_).Run(status); } void RendererImpl::FinishFlush() { DCHECK(flush_cb_); - TRACE_EVENT_ASYNC_END0("media", "RendererImpl::Flush", this); + TRACE_EVENT_NESTABLE_ASYNC_END0("media", "RendererImpl::Flush", + TRACE_ID_LOCAL(this)); std::move(flush_cb_).Run(); }
diff --git a/media/renderers/video_renderer_impl.cc b/media/renderers/video_renderer_impl.cc index 83497d5..ad1e16b 100644 --- a/media/renderers/video_renderer_impl.cc +++ b/media/renderers/video_renderer_impl.cc
@@ -162,7 +162,8 @@ const TimeSource::WallClockTimeCB& wall_clock_time_cb, PipelineStatusCallback init_cb) { DCHECK(task_runner_->BelongsToCurrentThread()); - TRACE_EVENT_ASYNC_BEGIN0("media", "VideoRendererImpl::Initialize", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media", "VideoRendererImpl::Initialize", + TRACE_ID_LOCAL(this)); base::AutoLock auto_lock(lock_); DCHECK(stream); @@ -314,14 +315,16 @@ void VideoRendererImpl::FinishInitialization(PipelineStatus status) { DCHECK(init_cb_); - TRACE_EVENT_ASYNC_END1("media", "VideoRendererImpl::Initialize", this, - "status", PipelineStatusToString(status)); + TRACE_EVENT_NESTABLE_ASYNC_END1("media", "VideoRendererImpl::Initialize", + TRACE_ID_LOCAL(this), "status", + PipelineStatusToString(status)); std::move(init_cb_).Run(status); } void VideoRendererImpl::FinishFlush() { DCHECK(flush_cb_); - TRACE_EVENT_ASYNC_END0("media", "VideoRendererImpl::Flush", this); + TRACE_EVENT_NESTABLE_ASYNC_END0("media", "VideoRendererImpl::Flush", + TRACE_ID_LOCAL(this)); std::move(flush_cb_).Run(); }
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc index fe2b5b23..b373365 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -860,8 +860,10 @@ } } - TRACE_EVENT_ASYNC_END0("media", "CopyVideoFrameToGpuMemoryBuffers", - video_frame->timestamp().InNanoseconds() /* id */); + TRACE_EVENT_NESTABLE_ASYNC_END0( + "media", "CopyVideoFrameToGpuMemoryBuffers", + TRACE_ID_WITH_SCOPE("CopyVideoFrameToGpuMemoryBuffers", + video_frame->timestamp().InNanoseconds())); media_task_runner_->PostTask( FROM_HERE, @@ -936,8 +938,10 @@ base::BindOnce(&PoolImpl::OnCopiesDone, this, /*copy_failed=*/false, video_frame, frame_resources)); - TRACE_EVENT_ASYNC_BEGIN0("media", "CopyVideoFrameToGpuMemoryBuffers", - video_frame->timestamp().InNanoseconds() /* id */); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( + "media", "CopyVideoFrameToGpuMemoryBuffers", + TRACE_ID_WITH_SCOPE("CopyVideoFrameToGpuMemoryBuffers", + video_frame->timestamp().InNanoseconds())); // Post all the async tasks. for (size_t i = 0; i < num_planes; i += planes_per_copy) { gfx::GpuMemoryBuffer* buffer =
diff --git a/net/cert/internal/trust_store_chrome_unittest.cc b/net/cert/internal/trust_store_chrome_unittest.cc index 5aa54f2..2502a56 100644 --- a/net/cert/internal/trust_store_chrome_unittest.cc +++ b/net/cert/internal/trust_store_chrome_unittest.cc
@@ -38,8 +38,8 @@ return parsed; } -const base::FilePath kCertDirPath = - GetTestNetDataDirectory().AppendASCII("ssl/chrome_root_store/testdata"); +const base::FilePath kCertDirPath = GetTestNetDataDirectory().AppendASCII( + "ssl/chrome_root_store/testdata/certs"); const char kCertInStoreFile1[] = "568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5.pem";
diff --git a/net/cookies/canonical_cookie.cc b/net/cookies/canonical_cookie.cc index 89c17d9..d3fe589 100644 --- a/net/cookies/canonical_cookie.cc +++ b/net/cookies/canonical_cookie.cc
@@ -63,6 +63,7 @@ #include "net/base/url_util.h" #include "net/cookies/cookie_constants.h" #include "net/cookies/cookie_inclusion_status.h" +#include "net/cookies/cookie_options.h" #include "net/cookies/cookie_util.h" #include "net/cookies/parsed_cookie.h" #include "url/gurl.h" @@ -194,7 +195,7 @@ CookieSameSite samesite, CookieEffectiveSameSite effective_samesite, bool is_secure, - CookieOptions::SameSiteCookieContext same_site_context, + const CookieOptions::SameSiteCookieContext& same_site_context, CookieInclusionStatus* status, bool is_cookie_being_set) { if (samesite == CookieSameSite::UNSPECIFIED && @@ -256,8 +257,48 @@ } } - // If there are reasons to exclude the cookie other than the new SameSite - // rules, don't warn about the cookie at all. + // Apply warning for whether inclusion was changed by considering redirects + // for the SameSite context calculation. This does not look at the actual + // inclusion or exclusion, but only at whether the inclusion differs between + // considering redirects and not. + using ContextDowngradeType = CookieOptions::SameSiteCookieContext:: + ContextMetadata::ContextDowngradeType; + const auto& metadata = same_site_context.GetMetadataForCurrentSchemefulMode(); + bool apply_cross_site_redirect_downgrade_warning = false; + switch (effective_samesite) { + case CookieEffectiveSameSite::STRICT_MODE: + // Strict contexts are all normalized to lax for cookie writes, so a + // strict-to-{lax,cross} downgrade cannot occur for response cookies. + apply_cross_site_redirect_downgrade_warning = + is_cookie_being_set ? metadata.cross_site_redirect_downgrade == + ContextDowngradeType::kLaxToCross + : (metadata.cross_site_redirect_downgrade == + ContextDowngradeType::kStrictToLax || + metadata.cross_site_redirect_downgrade == + ContextDowngradeType::kStrictToCross); + break; + case CookieEffectiveSameSite::LAX_MODE: + case CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE: + // Note that a lax-to-cross downgrade can only happen for response + // cookies, because a laxly same-site context only happens for a safe + // top-level cross-site request, which cannot be downgraded due to a + // cross-site redirect to a non-top-level or unsafe cross-site request. + apply_cross_site_redirect_downgrade_warning = + metadata.cross_site_redirect_downgrade == + (is_cookie_being_set ? ContextDowngradeType::kLaxToCross + : ContextDowngradeType::kStrictToCross); + break; + default: + break; + } + if (apply_cross_site_redirect_downgrade_warning) { + status->AddWarningReason( + CookieInclusionStatus:: + WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION); + } + + // If there are reasons to exclude the cookie other than SameSite, don't warn + // about the cookie at all. status->MaybeClearSameSiteWarning(); } @@ -922,16 +963,14 @@ break; } case CookieSamePartyStatus::kNoSamePartyEnforcement: + // Only apply SameSite-related warnings if SameParty is not in effect. + ApplySameSiteCookieWarningToStatus( + SameSite(), effective_same_site, IsSecure(), + options.same_site_cookie_context(), &status, + false /* is_cookie_being_set */); break; } - // TODO(chlily): Apply warning if SameSite-by-default is enabled but - // params.access_semantics is LEGACY? - ApplySameSiteCookieWarningToStatus(SameSite(), effective_same_site, - IsSecure(), - options.same_site_cookie_context(), - &status, false /* is_cookie_being_set */); - if (status.IsInclude()) { UMA_HISTOGRAM_ENUMERATION("Cookie.IncludedRequestEffectiveSameSite", effective_same_site, @@ -984,6 +1023,13 @@ status.GetBreakingDowngradeMetricsEnumValue(url)); } + if (status.HasWarningReason( + CookieInclusionStatus:: + WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION)) { + UMA_HISTOGRAM_ENUMERATION( + "Cookie.CrossSiteRedirectDowngradeChangesInclusion.Read", SameSite()); + } + return CookieAccessResult(effective_same_site, status, params.access_semantics, is_allowed_to_access_secure_cookies); @@ -1153,14 +1199,14 @@ break; } case CookieSamePartyStatus::kNoSamePartyEnforcement: + // Only apply SameSite-related warnings if SameParty is not in effect. + ApplySameSiteCookieWarningToStatus( + SameSite(), access_result.effective_same_site, IsSecure(), + options.same_site_cookie_context(), &access_result.status, + true /* is_cookie_being_set */); break; } - ApplySameSiteCookieWarningToStatus( - SameSite(), access_result.effective_same_site, IsSecure(), - options.same_site_cookie_context(), &access_result.status, - true /* is_cookie_being_set */); - if (access_result.status.IsInclude()) { UMA_HISTOGRAM_ENUMERATION("Cookie.IncludedResponseEffectiveSameSite", access_result.effective_same_site, @@ -1203,6 +1249,13 @@ } } + if (access_result.status.HasWarningReason( + CookieInclusionStatus:: + WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION)) { + UMA_HISTOGRAM_ENUMERATION( + "Cookie.CrossSiteRedirectDowngradeChangesInclusion.Write", SameSite()); + } + return access_result; }
diff --git a/net/cookies/canonical_cookie_unittest.cc b/net/cookies/canonical_cookie_unittest.cc index 771c9cfe..bbb34e7 100644 --- a/net/cookies/canonical_cookie_unittest.cc +++ b/net/cookies/canonical_cookie_unittest.cc
@@ -1838,6 +1838,138 @@ MatchesCookieAccessResult(net::IsInclude(), _, _, true)); } +// Test that the CookieInclusionStatus warning for inclusion changed by +// cross-site redirect context downgrade is applied correctly. +TEST(CanonicalCookieTest, IncludeForRequestURL_RedirectDowngradeWarning) { + using Context = CookieOptions::SameSiteCookieContext; + using ContextType = Context::ContextType; + + Context::ContextMetadata strict_lax_downgrade_metadata, + strict_cross_downgrade_metadata; + strict_lax_downgrade_metadata.cross_site_redirect_downgrade = + Context::ContextMetadata::ContextDowngradeType::kStrictToLax; + strict_cross_downgrade_metadata.cross_site_redirect_downgrade = + Context::ContextMetadata::ContextDowngradeType::kStrictToCross; + + GURL url("https://www.example.test/test"); + GURL insecure_url("http://www.example.test/test"); + + const struct { + ContextType context_type; + Context::ContextMetadata metadata; + CookieSameSite samesite; + bool expect_cross_site_redirect_warning; + } kTestCases[] = { + // Strict-to-lax downgrade. + {ContextType::SAME_SITE_STRICT, strict_lax_downgrade_metadata, + CookieSameSite::STRICT_MODE, true}, + {ContextType::SAME_SITE_LAX, strict_lax_downgrade_metadata, + CookieSameSite::STRICT_MODE, true}, + {ContextType::SAME_SITE_STRICT, strict_lax_downgrade_metadata, + CookieSameSite::LAX_MODE, false}, + {ContextType::SAME_SITE_LAX, strict_lax_downgrade_metadata, + CookieSameSite::LAX_MODE, false}, + {ContextType::SAME_SITE_STRICT, strict_lax_downgrade_metadata, + CookieSameSite::NO_RESTRICTION, false}, + {ContextType::SAME_SITE_LAX, strict_lax_downgrade_metadata, + CookieSameSite::NO_RESTRICTION, false}, + + // Strict-to-cross downgrade. + {ContextType::SAME_SITE_STRICT, strict_cross_downgrade_metadata, + CookieSameSite::STRICT_MODE, true}, + {ContextType::CROSS_SITE, strict_cross_downgrade_metadata, + CookieSameSite::STRICT_MODE, true}, + {ContextType::SAME_SITE_STRICT, strict_cross_downgrade_metadata, + CookieSameSite::LAX_MODE, true}, + {ContextType::CROSS_SITE, strict_cross_downgrade_metadata, + CookieSameSite::LAX_MODE, true}, + {ContextType::SAME_SITE_STRICT, strict_cross_downgrade_metadata, + CookieSameSite::NO_RESTRICTION, false}, + {ContextType::CROSS_SITE, strict_cross_downgrade_metadata, + CookieSameSite::NO_RESTRICTION, false}, + }; + + for (bool consider_redirects : {true, false}) { + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeatureState( + features::kCookieSameSiteConsidersRedirectChain, consider_redirects); + + for (CookieAccessSemantics semantics : + {CookieAccessSemantics::LEGACY, CookieAccessSemantics::NONLEGACY}) { + // There are no downgrade warnings for undowngraded contexts. + for (ContextType context_type : + {ContextType::SAME_SITE_STRICT, ContextType::SAME_SITE_LAX, + ContextType::SAME_SITE_LAX_METHOD_UNSAFE, + ContextType::CROSS_SITE}) { + for (CookieSameSite samesite : + {CookieSameSite::UNSPECIFIED, CookieSameSite::NO_RESTRICTION, + CookieSameSite::LAX_MODE, CookieSameSite::STRICT_MODE}) { + std::unique_ptr<CanonicalCookie> cookie = + CanonicalCookie::CreateUnsafeCookieForTesting( + "A", "1", "www.example.test", "/test", base::Time::Now(), + base::Time(), base::Time(), /*secure=*/true, + /*httponly=*/false, samesite, COOKIE_PRIORITY_DEFAULT, + /*same_party=*/false); + + CookieOptions options; + options.set_same_site_cookie_context(Context(context_type)); + + EXPECT_FALSE( + cookie + ->IncludeForRequestURL( + url, options, + CookieAccessParams( + semantics, + /*delegate_treats_url_as_trustworthy=*/false, + CookieSamePartyStatus::kNoSamePartyEnforcement)) + .status.HasWarningReason( + CookieInclusionStatus:: + WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION)); + } + } + + for (const auto& test : kTestCases) { + std::unique_ptr<CanonicalCookie> cookie = + CanonicalCookie::CreateUnsafeCookieForTesting( + "A", "1", "www.example.test", "/test", base::Time::Now(), + base::Time(), base::Time(), /*secure=*/true, /*httponly=*/false, + test.samesite, COOKIE_PRIORITY_DEFAULT, /*same_party=*/false); + + CookieOptions options; + options.set_same_site_cookie_context( + Context(test.context_type, test.context_type, test.metadata, + test.metadata)); + EXPECT_EQ( + cookie + ->IncludeForRequestURL( + url, options, + CookieAccessParams( + semantics, + /*delegate_treats_url_as_trustworthy=*/false, + CookieSamePartyStatus::kNoSamePartyEnforcement)) + .status.HasWarningReason( + CookieInclusionStatus:: + WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION), + test.expect_cross_site_redirect_warning); + + // SameSite warnings not applied if other exclusion reasons apply (e.g. + // non-https with Secure attribute). + EXPECT_FALSE( + cookie + ->IncludeForRequestURL( + insecure_url, options, + CookieAccessParams( + semantics, + /*delegate_treats_url_as_trustworthy=*/false, + CookieSamePartyStatus::kNoSamePartyEnforcement)) + .status.HasWarningReason( + CookieInclusionStatus:: + WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION)); + } + } + } +} + TEST(CanonicalCookieTest, MultipleExclusionReasons) { GURL url("http://www.not-secure.com/foo"); base::Time creation_time = base::Time::Now(); @@ -4216,4 +4348,114 @@ } } +// Test that the CookieInclusionStatus warning for inclusion changed by +// cross-site redirect context downgrade is applied correctly. +TEST(CanonicalCookieTest, IsSetPermittedInContext_RedirectDowngradeWarning) { + using Context = CookieOptions::SameSiteCookieContext; + using ContextType = Context::ContextType; + + GURL url("https://www.example.test/test"); + GURL insecure_url("http://www.example.test/test"); + + // Test cases to be used with a lax-to-cross context downgrade. + const struct { + ContextType context_type; + CookieSameSite samesite; + bool expect_cross_site_redirect_warning; + } kTestCases[] = { + {ContextType::SAME_SITE_LAX, CookieSameSite::STRICT_MODE, true}, + {ContextType::CROSS_SITE, CookieSameSite::STRICT_MODE, true}, + {ContextType::SAME_SITE_LAX, CookieSameSite::LAX_MODE, true}, + {ContextType::CROSS_SITE, CookieSameSite::LAX_MODE, true}, + {ContextType::SAME_SITE_LAX, CookieSameSite::NO_RESTRICTION, false}, + {ContextType::CROSS_SITE, CookieSameSite::NO_RESTRICTION, false}, + }; + + for (bool consider_redirects : {true, false}) { + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeatureState( + features::kCookieSameSiteConsidersRedirectChain, consider_redirects); + + for (CookieAccessSemantics semantics : + {CookieAccessSemantics::LEGACY, CookieAccessSemantics::NONLEGACY}) { + // There are no downgrade warnings for undowngraded contexts. + for (ContextType context_type : {ContextType::SAME_SITE_LAX, + ContextType::SAME_SITE_LAX_METHOD_UNSAFE, + ContextType::CROSS_SITE}) { + for (CookieSameSite samesite : + {CookieSameSite::UNSPECIFIED, CookieSameSite::NO_RESTRICTION, + CookieSameSite::LAX_MODE, CookieSameSite::STRICT_MODE}) { + std::unique_ptr<CanonicalCookie> cookie = + CanonicalCookie::CreateUnsafeCookieForTesting( + "A", "1", "www.example.test", "/test", base::Time::Now(), + base::Time(), base::Time(), /*secure=*/true, + /*httponly=*/false, samesite, COOKIE_PRIORITY_DEFAULT, + /*same_party=*/false); + + CookieOptions options; + options.set_same_site_cookie_context(Context(context_type)); + + EXPECT_FALSE( + cookie + ->IsSetPermittedInContext( + url, options, + CookieAccessParams( + semantics, + /*delegate_treats_url_as_trustworthy=*/false, + CookieSamePartyStatus::kNoSamePartyEnforcement), + kCookieableSchemes) + .status.HasWarningReason( + CookieInclusionStatus:: + WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION)); + } + } + + for (const auto& test : kTestCases) { + std::unique_ptr<CanonicalCookie> cookie = + CanonicalCookie::CreateUnsafeCookieForTesting( + "A", "1", "www.example.test", "/test", base::Time::Now(), + base::Time(), base::Time(), /*secure=*/true, /*httponly=*/false, + test.samesite, COOKIE_PRIORITY_DEFAULT, /*same_party=*/false); + + Context::ContextMetadata lax_cross_downgrade_metadata; + lax_cross_downgrade_metadata.cross_site_redirect_downgrade = + Context::ContextMetadata::ContextDowngradeType::kLaxToCross; + CookieOptions options; + options.set_same_site_cookie_context(Context( + test.context_type, test.context_type, lax_cross_downgrade_metadata, + lax_cross_downgrade_metadata)); + + EXPECT_EQ( + cookie + ->IsSetPermittedInContext( + url, options, + CookieAccessParams( + semantics, + /*delegate_treats_url_as_trustworthy=*/false, + CookieSamePartyStatus::kNoSamePartyEnforcement), + kCookieableSchemes) + .status.HasWarningReason( + CookieInclusionStatus:: + WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION), + test.expect_cross_site_redirect_warning); + + // SameSite warnings not applied if other exclusion reasons apply (e.g. + // non-https with Secure attribute). + EXPECT_FALSE( + cookie + ->IsSetPermittedInContext( + insecure_url, options, + CookieAccessParams( + semantics, + /*delegate_treats_url_as_trustworthy=*/false, + CookieSamePartyStatus::kNoSamePartyEnforcement), + kCookieableSchemes) + .status.HasWarningReason( + CookieInclusionStatus:: + WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION)); + } + } + } +} + } // namespace net
diff --git a/net/cookies/cookie_constants.h b/net/cookies/cookie_constants.h index b94216e..4a345897 100644 --- a/net/cookies/cookie_constants.h +++ b/net/cookies/cookie_constants.h
@@ -31,13 +31,17 @@ // information about same site cookie restrictions. // These values are allowed for the SameSite field of a cookie. They mostly // correspond to CookieEffectiveSameSite values. -// Note: Don't renumber, as these values are persisted to a database. +// Note: Don't renumber, as these values are persisted to a database and +// recorded to histograms. enum class CookieSameSite { UNSPECIFIED = -1, NO_RESTRICTION = 0, LAX_MODE = 1, STRICT_MODE = 2, // Reserved 3 (was EXTENDED_MODE), next number is 4. + + // Keep last, used for histograms. + kMaxValue = STRICT_MODE }; // These are the enforcement modes that may be applied to a cookie when deciding
diff --git a/net/cookies/cookie_inclusion_status.cc b/net/cookies/cookie_inclusion_status.cc index cc4617d..6dd16f47 100644 --- a/net/cookies/cookie_inclusion_status.cc +++ b/net/cookies/cookie_inclusion_status.cc
@@ -88,24 +88,19 @@ EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX, EXCLUDE_SAMESITE_NONE_INSECURE, }) != 0u) { - RemoveWarningReason( - CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT); - RemoveWarningReason(CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE); - RemoveWarningReason( - CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE); + RemoveWarningReason(WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT); + RemoveWarningReason(WARN_SAMESITE_NONE_INSECURE); + RemoveWarningReason(WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE); } if (!ShouldRecordDowngradeMetrics()) { - RemoveWarningReason( - CookieInclusionStatus::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE); - RemoveWarningReason( - CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE); - RemoveWarningReason( - CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE); - RemoveWarningReason( - CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE); - RemoveWarningReason( - CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE); + RemoveWarningReason(WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE); + RemoveWarningReason(WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE); + RemoveWarningReason(WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE); + RemoveWarningReason(WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE); + RemoveWarningReason(WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE); + + RemoveWarningReason(WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION); } } @@ -272,6 +267,8 @@ "WARN_SAMESITE_NONE_INCLUDED_BY_SAMESITE_LAX"}, {WARN_SAMESITE_NONE_INCLUDED_BY_SAMESITE_STRICT, "WARN_SAMESITE_NONE_INCLUDED_BY_SAMESITE_STRICT"}, + {WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION, + "WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION"}, }) { if (HasWarningReason(reason.first)) base::StrAppend(&out, {reason.second, ", "});
diff --git a/net/cookies/cookie_inclusion_status.h b/net/cookies/cookie_inclusion_status.h index 53a658f..cd911de 100644 --- a/net/cookies/cookie_inclusion_status.h +++ b/net/cookies/cookie_inclusion_status.h
@@ -203,6 +203,18 @@ // if it had been SameSite=Strict. WARN_SAMESITE_NONE_INCLUDED_BY_SAMESITE_STRICT = 17, + // The cookie would have been included prior to the spec change considering + // redirects in the SameSite context calculation + // (https://github.com/httpwg/http-extensions/pull/1348) + // but would have been excluded after the spec change, due to a cross-site + // redirect causing the SameSite context calculation to be downgraded. + // This is applied if and only if the cookie's inclusion was changed by + // considering redirect chains (and is applied regardless of which context + // was actually used for the inclusion decision). This is not applied if + // the context was downgraded but the cookie would have been + // included/excluded in both cases. + WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION = 18, + // This should be kept last. NUM_WARNING_REASONS }; @@ -268,8 +280,8 @@ void RemoveExclusionReasons(const std::vector<ExclusionReason>& reasons); // If the cookie would have been excluded for reasons other than - // SAMESITE_UNSPECIFIED_TREATED_AS_LAX or SAMESITE_NONE_INSECURE, don't bother - // warning about it (clear the warning). + // SameSite-related reasons, don't bother warning about it (clear the + // warning). void MaybeClearSameSiteWarning(); // Whether to record the breaking downgrade metrics if the cookie is included
diff --git a/net/cookies/cookie_options.cc b/net/cookies/cookie_options.cc index 7401ef9..6c66264 100644 --- a/net/cookies/cookie_options.cc +++ b/net/cookies/cookie_options.cc
@@ -73,13 +73,8 @@ bool CookieOptions::SameSiteCookieContext::CompleteEquivalenceForTesting( const SameSiteCookieContext& other) const { - bool metadata_equal = metadata_.affected_by_bugfix_1166211 == - other.metadata().affected_by_bugfix_1166211; - bool schemeful_metadata_equal = - schemeful_metadata_.affected_by_bugfix_1166211 == - other.schemeful_metadata().affected_by_bugfix_1166211; - - return *this == other && metadata_equal && schemeful_metadata_equal; + return (*this == other) && (metadata() == other.metadata()) && + (schemeful_metadata() == other.schemeful_metadata()); } bool operator==(const CookieOptions::SameSiteCookieContext& lhs, @@ -93,7 +88,23 @@ return !(lhs == rhs); } -// Keep default values in sync with content/public/common/cookie_manager.mojom. +bool operator==( + const CookieOptions::SameSiteCookieContext::ContextMetadata& lhs, + const CookieOptions::SameSiteCookieContext::ContextMetadata& rhs) { + return std::tie(lhs.affected_by_bugfix_1166211, + lhs.cross_site_redirect_downgrade) == + std::tie(rhs.affected_by_bugfix_1166211, + rhs.cross_site_redirect_downgrade); +} + +bool operator!=( + const CookieOptions::SameSiteCookieContext::ContextMetadata& lhs, + const CookieOptions::SameSiteCookieContext::ContextMetadata& rhs) { + return !(lhs == rhs); +} + +// Keep default values in sync with +// services/network/public/mojom/cookie_manager.mojom. CookieOptions::CookieOptions() : same_site_cookie_context_(SameSiteCookieContext( SameSiteCookieContext::ContextType::CROSS_SITE)) {}
diff --git a/net/cookies/cookie_options.h b/net/cookies/cookie_options.h index ae8bf371..6d78825 100644 --- a/net/cookies/cookie_options.h +++ b/net/cookies/cookie_options.h
@@ -45,10 +45,38 @@ // // When adding a field, also update CompleteEquivalenceForTesting. struct NET_EXPORT ContextMetadata { + // Possible "downgrades" for the SameSite context type, e.g. from a more + // trusted context to a less trusted context, as a result of some behavior + // change affecting the same-site calculation. + enum class ContextDowngradeType { + // Context not downgraded. + kNoDowngrade, + // Context was originally strictly same-site, was downgraded to laxly + // same-site. + kStrictToLax, + // Context was originally strictly same-site, was downgraded to + // cross-site. + kStrictToCross, + // Context was originally laxly same-site, was downgraded to cross-site. + kLaxToCross, + }; + // Whether the ContextType calculation was affected by the bugfix for // crbug.com/1166211. // TODO(crbug.com/1166211): Remove once no longer needed. bool affected_by_bugfix_1166211 = false; + + // Records the type of any context downgrade due to a cross-site redirect, + // i.e. whether the spec change in + // https://github.com/httpwg/http-extensions/pull/1348 changed the result + // of the context calculation. Note that a lax-to-cross downgrade can only + // happen for response cookies, because a laxly same-site context only + // happens for a top-level cross-site request, which cannot be downgraded + // due to a cross-site redirect to a non-top-level cross-site request. + // This only records whether the context was downgraded, not whether the + // cookie's inclusion result was changed. + ContextDowngradeType cross_site_redirect_downgrade = + ContextDowngradeType::kNoDowngrade; }; // The following three constructors apply default values for the metadata @@ -251,6 +279,13 @@ bool is_in_nontrivial_first_party_set_ = false; }; +NET_EXPORT bool operator==( + const CookieOptions::SameSiteCookieContext::ContextMetadata& lhs, + const CookieOptions::SameSiteCookieContext::ContextMetadata& rhs); +NET_EXPORT bool operator!=( + const CookieOptions::SameSiteCookieContext::ContextMetadata& lhs, + const CookieOptions::SameSiteCookieContext::ContextMetadata& rhs); + // Allows gtest to print more helpful error messages instead of printing hex. // (No need to null-check `os` because we can assume gtest will properly pass a // non-null pointer, and it is dereferenced immediately anyway.) @@ -259,12 +294,27 @@ *os << static_cast<int>(ct); } +inline void PrintTo( + const CookieOptions::SameSiteCookieContext::ContextMetadata& m, + std::ostream* os) { + *os << "{"; + if (m.affected_by_bugfix_1166211) + *os << " affected_by_bugfix_1166211,"; + *os << " cross_site_redirect_downgrade: " + << static_cast<int>(m.cross_site_redirect_downgrade); + *os << " }"; +} + inline void PrintTo(const CookieOptions::SameSiteCookieContext& sscc, std::ostream* os) { *os << "{ context: "; PrintTo(sscc.context(), os); *os << ", schemeful_context: "; PrintTo(sscc.schemeful_context(), os); + *os << ", metadata: "; + PrintTo(sscc.metadata(), os); + *os << ", schemeful_metadata: "; + PrintTo(sscc.schemeful_metadata(), os); *os << " }"; }
diff --git a/net/cookies/cookie_options_unittest.cc b/net/cookies/cookie_options_unittest.cc index 22a1720..96bf019 100644 --- a/net/cookies/cookie_options_unittest.cc +++ b/net/cookies/cookie_options_unittest.cc
@@ -35,18 +35,54 @@ SameSiteCookieContext::ContextType::SAME_SITE_LAX, SameSiteCookieContext::ContextType::CROSS_SITE); - EXPECT_EQ("{ context: 0, schemeful_context: 0 }", - ::testing::PrintToString(cross_cross)); - EXPECT_EQ("{ context: 2, schemeful_context: 2 }", - ::testing::PrintToString(lax_lax)); - EXPECT_EQ("{ context: 3, schemeful_context: 3 }", - ::testing::PrintToString(strict_strict)); - EXPECT_EQ("{ context: 3, schemeful_context: 0 }", - ::testing::PrintToString(strict_cross)); - EXPECT_EQ("{ context: 3, schemeful_context: 2 }", - ::testing::PrintToString(strict_lax)); - EXPECT_EQ("{ context: 2, schemeful_context: 0 }", - ::testing::PrintToString(lax_cross)); + SameSiteCookieContext::ContextMetadata metadata1; + metadata1.cross_site_redirect_downgrade = SameSiteCookieContext:: + ContextMetadata::ContextDowngradeType::kStrictToLax; + SameSiteCookieContext::ContextMetadata metadata2; + metadata2.affected_by_bugfix_1166211 = true; + metadata2.cross_site_redirect_downgrade = SameSiteCookieContext:: + ContextMetadata::ContextDowngradeType::kStrictToLax; + SameSiteCookieContext context_with_metadata( + SameSiteCookieContext::ContextType::SAME_SITE_STRICT, + SameSiteCookieContext::ContextType::SAME_SITE_STRICT, metadata1, + metadata2); + + EXPECT_EQ( + "{ context: 0, schemeful_context: 0, " + "metadata: { cross_site_redirect_downgrade: 0 }, " + "schemeful_metadata: { cross_site_redirect_downgrade: 0 } }", + ::testing::PrintToString(cross_cross)); + EXPECT_EQ( + "{ context: 2, schemeful_context: 2, " + "metadata: { cross_site_redirect_downgrade: 0 }, " + "schemeful_metadata: { cross_site_redirect_downgrade: 0 } }", + ::testing::PrintToString(lax_lax)); + EXPECT_EQ( + "{ context: 3, schemeful_context: 3, " + "metadata: { cross_site_redirect_downgrade: 0 }, " + "schemeful_metadata: { cross_site_redirect_downgrade: 0 } }", + ::testing::PrintToString(strict_strict)); + EXPECT_EQ( + "{ context: 3, schemeful_context: 0, " + "metadata: { cross_site_redirect_downgrade: 0 }, " + "schemeful_metadata: { cross_site_redirect_downgrade: 0 } }", + ::testing::PrintToString(strict_cross)); + EXPECT_EQ( + "{ context: 3, schemeful_context: 2, " + "metadata: { cross_site_redirect_downgrade: 0 }, " + "schemeful_metadata: { cross_site_redirect_downgrade: 0 } }", + ::testing::PrintToString(strict_lax)); + EXPECT_EQ( + "{ context: 2, schemeful_context: 0, " + "metadata: { cross_site_redirect_downgrade: 0 }, " + "schemeful_metadata: { cross_site_redirect_downgrade: 0 } }", + ::testing::PrintToString(lax_cross)); + EXPECT_EQ( + "{ context: 3, schemeful_context: 3, " + "metadata: { cross_site_redirect_downgrade: 1 }, " + "schemeful_metadata: { affected_by_bugfix_1166211, " + "cross_site_redirect_downgrade: 1 } }", + ::testing::PrintToString(context_with_metadata)); } } // namespace
diff --git a/net/cookies/cookie_util.cc b/net/cookies/cookie_util.cc index 358306a..054497b 100644 --- a/net/cookies/cookie_util.cc +++ b/net/cookies/cookie_util.cc
@@ -162,12 +162,26 @@ url_chain.size() == 1u || base::ranges::all_of(url_chain, is_same_site_with_site_for_cookies); - if (same_site_initiator && - (!base::FeatureList::IsEnabled( - features::kCookieSameSiteConsidersRedirectChain) || - same_site_redirect_chain)) { - result.context_type = ContextType::SAME_SITE_STRICT; - return result; + // Whether the context would be SAME_SITE_STRICT if not considering redirect + // chains, but is different after considering redirect chains. + bool cross_site_redirect_downgraded_from_strict = false; + // Allows the kCookieSameSiteConsidersRedirectChain feature to override the + // result and use SAME_SITE_STRICT. + bool use_strict = false; + + if (same_site_initiator) { + if (same_site_redirect_chain) { + result.context_type = ContextType::SAME_SITE_STRICT; + return result; + } + cross_site_redirect_downgraded_from_strict = true; + // If we are not supposed to consider redirect chains, record that the + // context result should ultimately be strictly same-site. We cannot + // just return early from here because we don't yet know what the context + // gets downgraded to, so we can't return with the correct metadata until we + // go through the rest of the logic below to determine that. + use_strict = !base::FeatureList::IsEnabled( + features::kCookieSameSiteConsidersRedirectChain); } if (is_http) { @@ -177,20 +191,56 @@ // Preserve old behavior if the bugfix is disabled. if (!base::FeatureList::IsEnabled(features::kSameSiteCookiesBugfix1166211)) { - result.context_type = ContextType::SAME_SITE_LAX; + if (cross_site_redirect_downgraded_from_strict) { + result.metadata.cross_site_redirect_downgrade = + ContextMetadata::ContextDowngradeType::kStrictToLax; + } + result.context_type = + use_strict ? ContextType::SAME_SITE_STRICT : ContextType::SAME_SITE_LAX; return result; } if (!is_http || is_main_frame_navigation) { - result.context_type = ContextType::SAME_SITE_LAX; + if (cross_site_redirect_downgraded_from_strict) { + result.metadata.cross_site_redirect_downgrade = + ContextMetadata::ContextDowngradeType::kStrictToLax; + } + result.context_type = + use_strict ? ContextType::SAME_SITE_STRICT : ContextType::SAME_SITE_LAX; return result; } - // Defaults to a cross-site context type. - result.metadata.affected_by_bugfix_1166211 = true; + if (cross_site_redirect_downgraded_from_strict) { + result.metadata.cross_site_redirect_downgrade = + ContextMetadata::ContextDowngradeType::kStrictToCross; + } + result.context_type = + use_strict ? ContextType::SAME_SITE_STRICT : ContextType::CROSS_SITE; + + result.metadata.affected_by_bugfix_1166211 = !use_strict; return result; } +// Setting any SameSite={Strict,Lax} cookie only requires a LAX context, so +// normalize any strictly same-site contexts to Lax for cookie writes. +void NormalizeStrictToLaxForSet(ComputeSameSiteContextResult& result) { + if (result.context_type == ContextType::SAME_SITE_STRICT) + result.context_type = ContextType::SAME_SITE_LAX; + + switch (result.metadata.cross_site_redirect_downgrade) { + case ContextMetadata::ContextDowngradeType::kStrictToLax: + result.metadata.cross_site_redirect_downgrade = + ContextMetadata::ContextDowngradeType::kNoDowngrade; + break; + case ContextMetadata::ContextDowngradeType::kStrictToCross: + result.metadata.cross_site_redirect_downgrade = + ContextMetadata::ContextDowngradeType::kLaxToCross; + break; + default: + break; + } +} + CookieOptions::SameSiteCookieContext ComputeSameSiteContextForSet( const std::vector<GURL>& url_chain, const SiteForCookies& site_for_cookies, @@ -206,12 +256,8 @@ url_chain, site_for_cookies, initiator, is_http, is_main_frame_navigation, true /* compute_schemefully */); - // Setting any SameSite={Strict,Lax} cookie only requires a LAX context, so - // normalize any strictly same-site contexts to Lax for cookie writes. - if (result.context_type == ContextType::SAME_SITE_STRICT) - result.context_type = ContextType::SAME_SITE_LAX; - if (schemeful_result.context_type == ContextType::SAME_SITE_STRICT) - schemeful_result.context_type = ContextType::SAME_SITE_LAX; + NormalizeStrictToLaxForSet(result); + NormalizeStrictToLaxForSet(schemeful_result); return MakeSameSiteCookieContext(result, schemeful_result); }
diff --git a/net/cookies/cookie_util_unittest.cc b/net/cookies/cookie_util_unittest.cc index 06b5a0d..3d9d2f38 100644 --- a/net/cookies/cookie_util_unittest.cc +++ b/net/cookies/cookie_util_unittest.cc
@@ -15,6 +15,7 @@ #include "base/time/time.h" #include "net/base/features.h" #include "net/cookies/cookie_constants.h" +#include "net/cookies/cookie_options.h" #include "net/cookies/cookie_util.h" #include "net/cookies/same_party_context.h" #include "testing/gmock/include/gmock/gmock.h" @@ -349,10 +350,44 @@ EXPECT_FALSE(cookie_util::IsDomainMatch(".example.de", "example.de.vu")); } +using ::testing::AllOf; +using SameSiteCookieContext = CookieOptions::SameSiteCookieContext; +using ContextType = CookieOptions::SameSiteCookieContext::ContextType; + MATCHER_P2(ContextTypeIsWithSchemefulMode, context_type, schemeful, "") { return context_type == (schemeful ? arg.schemeful_context() : arg.context()); } +// Checks for the expected metadata related to context downgrades from +// cross-site redirects. +MATCHER_P3(CrossSiteRedirectMetadataCorrectWithSchemefulMode, + context_type_without_chain, + context_type_with_chain, + schemeful, + "") { + using ContextDowngradeType = CookieOptions::SameSiteCookieContext:: + ContextMetadata::ContextDowngradeType; + + const auto& metadata = schemeful ? arg.schemeful_metadata() : arg.metadata(); + switch (metadata.cross_site_redirect_downgrade) { + case ContextDowngradeType::kNoDowngrade: + return context_type_without_chain == context_type_with_chain; + case ContextDowngradeType::kStrictToLax: + return context_type_without_chain == ContextType::SAME_SITE_STRICT && + (context_type_with_chain == ContextType::SAME_SITE_LAX || + context_type_with_chain == + ContextType::SAME_SITE_LAX_METHOD_UNSAFE); + case ContextDowngradeType::kStrictToCross: + return context_type_without_chain == ContextType::SAME_SITE_STRICT && + context_type_with_chain == ContextType::CROSS_SITE; + case ContextDowngradeType::kLaxToCross: + return (context_type_without_chain == ContextType::SAME_SITE_LAX || + context_type_without_chain == + ContextType::SAME_SITE_LAX_METHOD_UNSAFE) && + context_type_with_chain == ContextType::CROSS_SITE; + } +} + std::string UrlChainToString(const std::vector<GURL>& url_chain) { std::string s; for (const GURL& url : url_chain) { @@ -386,9 +421,6 @@ } ~CookieUtilComputeSameSiteContextTest() override = default; - using SameSiteCookieContext = CookieOptions::SameSiteCookieContext; - using ContextType = CookieOptions::SameSiteCookieContext::ContextType; - bool IsSchemeful() const { return std::get<0>(GetParam()); } bool IsBugfix1166211Enabled() const { return std::get<1>(GetParam()); } @@ -402,6 +434,13 @@ return ContextTypeIsWithSchemefulMode(context_type, IsSchemeful()); } + auto CrossSiteRedirectMetadataCorrect( + ContextType context_type_without_chain, + ContextType context_type_with_chain) const { + return CrossSiteRedirectMetadataCorrectWithSchemefulMode( + context_type_without_chain, context_type_with_chain, IsSchemeful()); + } + // The following methods return the sets of URLs/SiteForCookies/initiators/URL // chains that are same-site or cross-site with respect to kSiteUrl. @@ -1068,7 +1107,10 @@ test_case.method, url_chain, site_for_cookies, initiator, false /* is_main_frame_navigation */, false /* force_ignore_site_for_cookies */), - ContextTypeIs(expected_context_type)) + AllOf(ContextTypeIs(expected_context_type), + CrossSiteRedirectMetadataCorrect( + test_case.expected_context_type_without_chain, + test_case.expected_context_type))) << UrlChainToString(url_chain) << " " << site_for_cookies.ToDebugString() << " " << (initiator ? initiator->Serialize() : "nullopt"); @@ -1079,7 +1121,14 @@ test_case.method, url_chain, site_for_cookies, initiator, true /* is_main_frame_navigation */, false /* force_ignore_site_for_cookies */), - ContextTypeIs(expected_context_type_for_main_frame_navigation)) + AllOf( + ContextTypeIs( + expected_context_type_for_main_frame_navigation), + CrossSiteRedirectMetadataCorrect( + test_case + .expected_context_type_for_main_frame_navigation_without_chain, + test_case + .expected_context_type_for_main_frame_navigation))) << UrlChainToString(url_chain) << " " << site_for_cookies.ToDebugString() << " " << (initiator ? initiator->Serialize() : "nullopt"); @@ -1324,7 +1373,10 @@ url_chain, site_for_cookies, initiator, false /* is_main_frame_navigation */, false /* force_ignore_site_for_cookies */), - ContextTypeIs(expected_context_type)) + AllOf(ContextTypeIs(expected_context_type), + CrossSiteRedirectMetadataCorrect( + test_case.expected_context_type_without_chain, + test_case.expected_context_type))) << UrlChainToString(url_chain) << " " << site_for_cookies.ToDebugString() << " " << (initiator ? initiator->Serialize() : "nullopt"); @@ -1335,7 +1387,14 @@ url_chain, site_for_cookies, initiator, true /* is_main_frame_navigation */, false /* force_ignore_site_for_cookies */), - ContextTypeIs(expected_context_type_for_main_frame_navigation)) + AllOf( + ContextTypeIs( + expected_context_type_for_main_frame_navigation), + CrossSiteRedirectMetadataCorrect( + test_case + .expected_context_type_for_main_frame_navigation_without_chain, + test_case + .expected_context_type_for_main_frame_navigation))) << UrlChainToString(url_chain) << " " << site_for_cookies.ToDebugString() << " " << (initiator ? initiator->Serialize() : "nullopt");
diff --git a/net/data/ssl/chrome_root_store/BUILD.gn b/net/data/ssl/chrome_root_store/BUILD.gn index 794c67b..185d53e 100644 --- a/net/data/ssl/chrome_root_store/BUILD.gn +++ b/net/data/ssl/chrome_root_store/BUILD.gn
@@ -7,132 +7,132 @@ compiled_action("gen_root_store_inc") { tool = "//net/tools/root_store_tool:root_store_tool" - # It'd be really nice to list an input as "certs/*", but it doesn't seem to - # work. So we list them all out. + # It'd be really nice to list an input as "store/certs/*", but it doesn't seem + # to work. So we list them all out. inputs = [ - "root_store.textproto", - "certs/02ed0eb28c14da45165c566791700d6451d7fb56f0b2ab1d3b8eb070e56edff5.pem", - "certs/0376ab1d54c5f9803ce4b2e201a0ee7eef7b57b636e8a93c9b8d4860c96f5fa7.pem", - "certs/04048028bf1f2864d48f9ad4d83294366a828856553f3b14303f90147f5d40ef.pem", - "certs/0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739.pem", - "certs/0753e940378c1bd5e3836e395daea5cb839e5046f1bd0eae1951cf10fec7c965.pem", - "certs/0a81ec5a929777f145904af38d5d509f66b5e2c58fcdb531058b0e17f3f0b41b.pem", - "certs/0c2cd63df7806fa399ede809116b575bf87989f06518f9808c860503178baf66.pem", - "certs/125609aa301da0a249b97a8239cb6a34216f44dcac9f3954b14292f2e8c8608f.pem", - "certs/1465fa205397b876faa6f0a9958e5590e40fcc7faa4fb7c2c8677521fb5fb658.pem", - "certs/15d5b8774619ea7d54ce1ca6d0b0c403e037a917f131e8a04e1e6b7a71babce5.pem", - "certs/15f0ba00a3ac7af3ac884c072b1011a077bd77c097f40164b2f8598abd83860c.pem", - "certs/16af57a9f676b0ab126095aa5ebadef22ab31119d644ac95cd4b93dbf3f26aeb.pem", - "certs/1793927a0614549789adce2f8f34f7f0b66d0f3ae3a3b84d21ec15dbba4fadc7.pem", - "certs/179fbc148a3dd00fd24ea13458cc43bfa7f59c8182d783a513f6ebec100c8924.pem", - "certs/18ce6cfe7bf14e60b2e347b8dfe868cb31d02ebb3ada271569f50343b46db3a4.pem", - "certs/18f1fc7f205df8adddeb7fe007dd57e3af375a9c4d8d73546bf4f1fed1e18d35.pem", - "certs/1ba5b2aa8c65401a82960118f80bec4f62304d83cec4713a19c39c011ea46db4.pem", - "certs/22a2c1f7bded704cc1e701b5f408c310880fe956b5de2a4a44f99c873a25a7c8.pem", - "certs/2530cc8e98321502bad96f9b1fba1b099e2d299e0f4548bb914f363bc0d4531f.pem", - "certs/2a575471e31340bc21581cbd2cf13e158463203ece94bcf9d3cc196bf09a5472.pem", - "certs/2cabeafe37d06ca22aba7391c0033d25982952c453647349763a3ab5ad6ccf69.pem", - "certs/2ce1cb0bf9d2f9e102993fbe215152c3b2dd0cabde1c68e5319b839154dbb7f5.pem", - "certs/2e7bf16cc22485a7bbe2aa8696750761b0ae39be3b2fe9d0cc6d4ef73491425c.pem", - "certs/30d0895a9a448a262091635522d1f52010b5867acae12c78ef958fd4f4389f2f.pem", - "certs/31ad6648f8104138c738f39ea4320133393e3a18cc02296ef97c2ac9ef6731d0.pem", - "certs/3417bb06cc6007da1b961c920b8ab4ce3fad820e4aa30b9acbc4a74ebdcebc65.pem", - "certs/358df39d764af9e1b766e9c972df352ee15cfac227af6ad1d70e8e4a6edcba02.pem", - "certs/3c4fb0b95ab8b30032f432b86f535fe172c185d0fd39865837cf36187fa6f428.pem", - "certs/3c5f81fea5fab82c64bfa2eaecafcde8e077fc8620a7cae537163df36edbf378.pem", - "certs/3e9099b5015e8f486c00bcea9d111ee721faba355a89bcf1df69561e3dc6325c.pem", - "certs/40f6af0346a99aa1cd1d555a4e9cce62c7f9634603ee406615833dc8c8d00367.pem", - "certs/4200f5043ac8590ebb527d209ed1503029fbcbd41ca1b506ec27f15ade7dac69.pem", - "certs/4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161.pem", - "certs/43df5774b03e7fef5fe40d931a7bedf1bb2e6b42738c4e6d3841103d3aa7f339.pem", - "certs/44b545aa8a25e65a73ca15dc27fc36d24c1cb9953a066539b11582dc487b4833.pem", - "certs/45140b3247eb9cc8c5b4f0d7b53091f73292089e6e5a63e2749dd3aca9198eda.pem", - "certs/46edc3689046d53a453fb3104ab80dcaec658b2660ea1629dd7e867990648716.pem", - "certs/49e7a442acf0ea6287050054b52564b650e4f49e42e348d6aa38e039e957b1c1.pem", - "certs/4d2491414cfe956746ec4cefa6cf6f72e28a1329432f9d8a907ac4cb5dadc15a.pem", - "certs/4ff460d54b9c86dabfbcfc5712e0400d2bed3fbc4d4fbdaa86e06adcd2a9ad7a.pem", - "certs/513b2cecb810d4cde5dd85391adfc6c2dd60d87bb736d2b521484aa47a0ebef6.pem", - "certs/52f0e1c4e58ec629291b60317f074671b85d7ea80d5b07273463534b32b40234.pem", - "certs/552f7bdcf1a7af9e6ce672017f4f12abf77240c78e761ac203d1d9d20ac89988.pem", - "certs/55903859c8c0c3ebb8759ece4e2557225ff5758bbd38ebd48276601e1bd58097.pem", - "certs/55926084ec963a64b96e2abe01ce0ba86a64fbfebcc7aab5afc155b37fd76066.pem", - "certs/568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5.pem", - "certs/59769007f7685d0fcd50872f9f95d5755a5b2b457d81f3692b610a98672f0e1b.pem", - "certs/5a2fc03f0c83b090bbfa40604b0988446c7636183df9846e17101a447fb8efd6.pem", - "certs/5a885db19c01d912c5759388938cafbbdf031ab2d48e91ee15589b42971d039c.pem", - "certs/5c58468d55f58e497e743982d2b50010b6d165374acf83a7d4a32db768c4408e.pem", - "certs/5cc3d78e4e1d5e45547a04e6873e64f90cf9536d1ccc2ef800f355c4c5fd70fd.pem", - "certs/5d56499be4d2e08bcfcad08a3e38723d50503bde706948e42f55603019e528ae.pem", - "certs/62dd0be9b9f50a163ea0f8e75c053b1eca57ea55c8688f647c6881f2c8357b95.pem", - "certs/657cfe2fa73faa38462571f332a2363a46fce7020951710702cdfbb6eeda3305.pem", - "certs/6b9c08e86eb0f767cfad65cd98b62149e5494a67f5845e7bd1ed019f27b86bd6.pem", - "certs/6c61dac3a2def031506be036d2a6fe401994fbd13df9c8d466599274c446ec98.pem", - "certs/6dc47172e01cbcb0bf62580d895fe2b8ac9ad4f873801e0c10b9c837d21eb177.pem", - "certs/70a73f7f376b60074248904534b11482d5bf0e698ecc498df52577ebf2e93b9a.pem", - "certs/71cca5391f9e794b04802530b363e121da8a3043bb26662fea4dca7fc951a4bd.pem", - "certs/73c176434f1bc6d5adf45b0e76e727287c8de57616c1e6e6141a2b2cbc7d8e4c.pem", - "certs/7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf.pem", - "certs/7908b40314c138100b518d0735807ffbfcf8518a0095337105ba386b153dd927.pem", - "certs/7d05ebb682339f8c9451ee094eebfefa7953a114edb2f44949452fab7d2fc185.pem", - "certs/7e37cb8b4c47090cab36551ba6f45db840680fba166a952db100717f43053fc2.pem", - "certs/8560f91c3624daba9570b5fea0dbe36ff11a8323be9486854fb3f34a5571198d.pem", - "certs/85666a562ee0be5ce925c1d8890a6f76a87ec16d4d7d5f29ea7419cf20123b69.pem", - "certs/85a0dd7dd720adb7ff05f83d542b209dc7ff4528f7d677b18389fea5e5c49e86.pem", - "certs/86a1ecba089c4a8d3bbe2734c612ba341d813e043cf9e8a862cd5c57a36bbe6b.pem", - "certs/88ef81de202eb018452e43f864725cea5fbd1fc2d9d205730709c5d8b8690f46.pem", - "certs/8a866fd1b276b57e578e921c65828a2bed58e9f2f288054134b7f1f4bfc9cc74.pem", - "certs/8ecde6884f3d87b1125ba31ac3fcb13d7016de7f57cc904fe1cb97c6ae98196e.pem", - "certs/8fe4fb0af93a4d0d67db0bebb23e37c71bf325dcbcdd240ea04daf58b47e1840.pem", - "certs/91e2f5788d5810eba7ba58737de1548a8ecacd014598bc0b143e041b17052552.pem", - "certs/945bbc825ea554f489d1fd51a73ddf2ea624ac7019a05205225c22a78ccfa8b4.pem", - "certs/960adf0063e96356750c2965dd0a0867da0b9cbd6e77714aeafb2349ab393da3.pem", - "certs/96bcec06264976f37460779acf28c5a7cfe8a3c0aae11a8ffcee05c0bddf08c6.pem", - "certs/97552015f5ddfc3c8788c006944555408894450084f100867086bc1a2bb58dc8.pem", - "certs/9a114025197c5bb95d94e63d55cd43790847b646b23cdf11ada4a00eff15fb48.pem", - "certs/9a6ec012e1a7da9dbe34194d478ad7c0db1822fb071df12981496ed104384113.pem", - "certs/9bea11c976fe014764c1be56a6f914b5a560317abd9988393382e5161aa0493c.pem", - "certs/a040929a02ce53b4acf4f2ffc6981ce4496f755e6d45fe0b2a692bcd52523f36.pem", - "certs/a1339d33281a0b56e557d3d32b1ce7f9367eb094bd5fa72a7e5004c8ded7cafe.pem", - "certs/a45ede3bbbf09c8ae15c72efc07268d693a21c996fd51e67ca079460fd6d8873.pem", - "certs/b0bfd52bb0d7d9bd92bf5d4dc13da255c02c542f378365ea893911f55e55f23c.pem", - "certs/b676f2eddae8775cd36cb0f63cd1d4603961f49e6265ba013a2f0307b6d0b804.pem", - "certs/bc104f15a48be709dca542a7e1d4b9df6f054527e802eaa92d595444258afe71.pem", - "certs/bc4d809b15189d78db3e1d8cf4f9726a795da1643ca5f1358e1ddb0edc0d7eb3.pem", - "certs/bd71fdf6da97e4cf62d1647add2581b07d79adf8397eb4ecba9c5e8488821423.pem", - "certs/be6c4da2bbb9ba59b6f3939768374246c3c005993fa98f020d1dedbed48a81d5.pem", - "certs/beb00b30839b9bc32c32e4447905950641f26421b15ed089198b518ae2ea1b99.pem", - "certs/bec94911c2955676db6c0a550986d76e3ba005667c442c9762b4fbb773de228c.pem", - "certs/bf0feefb9e3a581ad5f9e9db7589985743d261085c4d314f6f5d7259aa421612.pem", - "certs/bfd88fe1101c41ae3e801bf8be56350ee9bad1a6b9bd515edc5c6d5b8711ac44.pem", - "certs/bfff8fd04433487d6a8aa60c1a29767a9fc2bbb05e420f713a13b992891d3893.pem", - "certs/c0a6f4dc63a24bfdcf54ef2a6a082a0a72de35803e2ff5ff527ae5d87206dfd5.pem", - "certs/c3846bf24b9e93ca64274c0ec67c1ecc5e024ffcacd2d74019350e81fe546ae4.pem", - "certs/c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60.pem", - "certs/c741f70f4b2a8d88bf2e71c14122ef53ef10eba0cfa5e64cfa20f418853073e0.pem", - "certs/ca42dd41745fd0b81eb902362cf9d8bf719da1bd1b1efc946f5b4c99f42c1b9e.pem", - "certs/cb3ccbb76031e5e0138f8dd39a23f9de47ffc35e43c1144cea27d46a5ab1cb5f.pem", - "certs/cbb522d7b7f127ad6a0113865bdf1cd4102e7d0759af635a7cf4720dc963c53b.pem", - "certs/cecddc905099d8dadfc5b1d209b737cbe2c18cfb2c10c0ff0bcf0d3286fc1aa2.pem", - "certs/d40e9c86cd8fe468c1776959f49ea774fa548684b6c406f3909261f4dce2575c.pem", - "certs/d43af9b35473755c9684fc06d7d8cb70ee5c28e773fb294eb41ee71722924d24.pem", - "certs/d48d3d23eedb50a459e55197601c27774b9d7b18c94d5a059511a10250b93168.pem", - "certs/d7a7a0fb5d7e2731d771e9484ebcdef71d5f0c3e0a2948782bc83ee0ea699ef4.pem", - "certs/db3517d1f6732a2d5ab97c533ec70779ee3270a62fb4ac4238372460e6f01e88.pem", - "certs/dd6936fe21f8f077c123a1a521c12224f72255b73e03a7260693e8a24b0fa389.pem", - "certs/e23d4a036d7b70e9f595b1422079d2b91edfbb1fb651a0633eaa8a9dc5f80703.pem", - "certs/e35d28419ed02025cfa69038cd623962458da5c695fbdea3c22b0bfb25897092.pem", - "certs/e3b6a2db2ed7ce48842f7ac53241c7b71d54144bfb40c11f3f1d0b42f5eea12d.pem", - "certs/e75e72ed9f560eec6eb4800073a43fc3ad19195a392282017895974a99026b6c.pem", - "certs/e793c9b02fd8aa13e21c31228accb08119643b749c898964b1746d46c3d4cbd2.pem", - "certs/eaa962c4fa4a6bafebe415196d351ccd888d4f53f3fa8ae6d7c466a94e6042bb.pem", - "certs/ebc5570c29018c4d67b1aa127baf12f703b4611ebc17b7dab5573894179b93fa.pem", - "certs/ebd41040e4bb3ec742c9e381d31ef2a41a48b6685c96e7cef3c1df6cd4331c99.pem", - "certs/edf7ebbca27a2a384d387b7d4010c666e2edb4843e4c29b4ae1d5b9332e6b24d.pem", - "certs/eec5496b988ce98625b934092eec2908bed0b0f316c2d4730c84eaf1f3d34881.pem", - "certs/f1c1b50ae5a20dd8030ec9f6bc24823dd367b5255759b4e71b61fce9f7375d73.pem", - "certs/f356bea244b7a91eb35d53ca9ad7864ace018e2d35d5f8f96ddf68a6f41aa474.pem", - "certs/f9e67d336c51002ac054c632022d66dda2e7e3fff10ad061ed31d8bbb410cfb2.pem", - "certs/fd73dad31c644ff1b43bef0ccdda96710b9cd9875eca7e31707af3e96d522bbd.pem", + "store/root_store.textproto", + "store/certs/02ed0eb28c14da45165c566791700d6451d7fb56f0b2ab1d3b8eb070e56edff5.pem", + "store/certs/0376ab1d54c5f9803ce4b2e201a0ee7eef7b57b636e8a93c9b8d4860c96f5fa7.pem", + "store/certs/04048028bf1f2864d48f9ad4d83294366a828856553f3b14303f90147f5d40ef.pem", + "store/certs/0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739.pem", + "store/certs/0753e940378c1bd5e3836e395daea5cb839e5046f1bd0eae1951cf10fec7c965.pem", + "store/certs/0a81ec5a929777f145904af38d5d509f66b5e2c58fcdb531058b0e17f3f0b41b.pem", + "store/certs/0c2cd63df7806fa399ede809116b575bf87989f06518f9808c860503178baf66.pem", + "store/certs/125609aa301da0a249b97a8239cb6a34216f44dcac9f3954b14292f2e8c8608f.pem", + "store/certs/1465fa205397b876faa6f0a9958e5590e40fcc7faa4fb7c2c8677521fb5fb658.pem", + "store/certs/15d5b8774619ea7d54ce1ca6d0b0c403e037a917f131e8a04e1e6b7a71babce5.pem", + "store/certs/15f0ba00a3ac7af3ac884c072b1011a077bd77c097f40164b2f8598abd83860c.pem", + "store/certs/16af57a9f676b0ab126095aa5ebadef22ab31119d644ac95cd4b93dbf3f26aeb.pem", + "store/certs/1793927a0614549789adce2f8f34f7f0b66d0f3ae3a3b84d21ec15dbba4fadc7.pem", + "store/certs/179fbc148a3dd00fd24ea13458cc43bfa7f59c8182d783a513f6ebec100c8924.pem", + "store/certs/18ce6cfe7bf14e60b2e347b8dfe868cb31d02ebb3ada271569f50343b46db3a4.pem", + "store/certs/18f1fc7f205df8adddeb7fe007dd57e3af375a9c4d8d73546bf4f1fed1e18d35.pem", + "store/certs/1ba5b2aa8c65401a82960118f80bec4f62304d83cec4713a19c39c011ea46db4.pem", + "store/certs/22a2c1f7bded704cc1e701b5f408c310880fe956b5de2a4a44f99c873a25a7c8.pem", + "store/certs/2530cc8e98321502bad96f9b1fba1b099e2d299e0f4548bb914f363bc0d4531f.pem", + "store/certs/2a575471e31340bc21581cbd2cf13e158463203ece94bcf9d3cc196bf09a5472.pem", + "store/certs/2cabeafe37d06ca22aba7391c0033d25982952c453647349763a3ab5ad6ccf69.pem", + "store/certs/2ce1cb0bf9d2f9e102993fbe215152c3b2dd0cabde1c68e5319b839154dbb7f5.pem", + "store/certs/2e7bf16cc22485a7bbe2aa8696750761b0ae39be3b2fe9d0cc6d4ef73491425c.pem", + "store/certs/30d0895a9a448a262091635522d1f52010b5867acae12c78ef958fd4f4389f2f.pem", + "store/certs/31ad6648f8104138c738f39ea4320133393e3a18cc02296ef97c2ac9ef6731d0.pem", + "store/certs/3417bb06cc6007da1b961c920b8ab4ce3fad820e4aa30b9acbc4a74ebdcebc65.pem", + "store/certs/358df39d764af9e1b766e9c972df352ee15cfac227af6ad1d70e8e4a6edcba02.pem", + "store/certs/3c4fb0b95ab8b30032f432b86f535fe172c185d0fd39865837cf36187fa6f428.pem", + "store/certs/3c5f81fea5fab82c64bfa2eaecafcde8e077fc8620a7cae537163df36edbf378.pem", + "store/certs/3e9099b5015e8f486c00bcea9d111ee721faba355a89bcf1df69561e3dc6325c.pem", + "store/certs/40f6af0346a99aa1cd1d555a4e9cce62c7f9634603ee406615833dc8c8d00367.pem", + "store/certs/4200f5043ac8590ebb527d209ed1503029fbcbd41ca1b506ec27f15ade7dac69.pem", + "store/certs/4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161.pem", + "store/certs/43df5774b03e7fef5fe40d931a7bedf1bb2e6b42738c4e6d3841103d3aa7f339.pem", + "store/certs/44b545aa8a25e65a73ca15dc27fc36d24c1cb9953a066539b11582dc487b4833.pem", + "store/certs/45140b3247eb9cc8c5b4f0d7b53091f73292089e6e5a63e2749dd3aca9198eda.pem", + "store/certs/46edc3689046d53a453fb3104ab80dcaec658b2660ea1629dd7e867990648716.pem", + "store/certs/49e7a442acf0ea6287050054b52564b650e4f49e42e348d6aa38e039e957b1c1.pem", + "store/certs/4d2491414cfe956746ec4cefa6cf6f72e28a1329432f9d8a907ac4cb5dadc15a.pem", + "store/certs/4ff460d54b9c86dabfbcfc5712e0400d2bed3fbc4d4fbdaa86e06adcd2a9ad7a.pem", + "store/certs/513b2cecb810d4cde5dd85391adfc6c2dd60d87bb736d2b521484aa47a0ebef6.pem", + "store/certs/52f0e1c4e58ec629291b60317f074671b85d7ea80d5b07273463534b32b40234.pem", + "store/certs/552f7bdcf1a7af9e6ce672017f4f12abf77240c78e761ac203d1d9d20ac89988.pem", + "store/certs/55903859c8c0c3ebb8759ece4e2557225ff5758bbd38ebd48276601e1bd58097.pem", + "store/certs/55926084ec963a64b96e2abe01ce0ba86a64fbfebcc7aab5afc155b37fd76066.pem", + "store/certs/568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5.pem", + "store/certs/59769007f7685d0fcd50872f9f95d5755a5b2b457d81f3692b610a98672f0e1b.pem", + "store/certs/5a2fc03f0c83b090bbfa40604b0988446c7636183df9846e17101a447fb8efd6.pem", + "store/certs/5a885db19c01d912c5759388938cafbbdf031ab2d48e91ee15589b42971d039c.pem", + "store/certs/5c58468d55f58e497e743982d2b50010b6d165374acf83a7d4a32db768c4408e.pem", + "store/certs/5cc3d78e4e1d5e45547a04e6873e64f90cf9536d1ccc2ef800f355c4c5fd70fd.pem", + "store/certs/5d56499be4d2e08bcfcad08a3e38723d50503bde706948e42f55603019e528ae.pem", + "store/certs/62dd0be9b9f50a163ea0f8e75c053b1eca57ea55c8688f647c6881f2c8357b95.pem", + "store/certs/657cfe2fa73faa38462571f332a2363a46fce7020951710702cdfbb6eeda3305.pem", + "store/certs/6b9c08e86eb0f767cfad65cd98b62149e5494a67f5845e7bd1ed019f27b86bd6.pem", + "store/certs/6c61dac3a2def031506be036d2a6fe401994fbd13df9c8d466599274c446ec98.pem", + "store/certs/6dc47172e01cbcb0bf62580d895fe2b8ac9ad4f873801e0c10b9c837d21eb177.pem", + "store/certs/70a73f7f376b60074248904534b11482d5bf0e698ecc498df52577ebf2e93b9a.pem", + "store/certs/71cca5391f9e794b04802530b363e121da8a3043bb26662fea4dca7fc951a4bd.pem", + "store/certs/73c176434f1bc6d5adf45b0e76e727287c8de57616c1e6e6141a2b2cbc7d8e4c.pem", + "store/certs/7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf.pem", + "store/certs/7908b40314c138100b518d0735807ffbfcf8518a0095337105ba386b153dd927.pem", + "store/certs/7d05ebb682339f8c9451ee094eebfefa7953a114edb2f44949452fab7d2fc185.pem", + "store/certs/7e37cb8b4c47090cab36551ba6f45db840680fba166a952db100717f43053fc2.pem", + "store/certs/8560f91c3624daba9570b5fea0dbe36ff11a8323be9486854fb3f34a5571198d.pem", + "store/certs/85666a562ee0be5ce925c1d8890a6f76a87ec16d4d7d5f29ea7419cf20123b69.pem", + "store/certs/85a0dd7dd720adb7ff05f83d542b209dc7ff4528f7d677b18389fea5e5c49e86.pem", + "store/certs/86a1ecba089c4a8d3bbe2734c612ba341d813e043cf9e8a862cd5c57a36bbe6b.pem", + "store/certs/88ef81de202eb018452e43f864725cea5fbd1fc2d9d205730709c5d8b8690f46.pem", + "store/certs/8a866fd1b276b57e578e921c65828a2bed58e9f2f288054134b7f1f4bfc9cc74.pem", + "store/certs/8ecde6884f3d87b1125ba31ac3fcb13d7016de7f57cc904fe1cb97c6ae98196e.pem", + "store/certs/8fe4fb0af93a4d0d67db0bebb23e37c71bf325dcbcdd240ea04daf58b47e1840.pem", + "store/certs/91e2f5788d5810eba7ba58737de1548a8ecacd014598bc0b143e041b17052552.pem", + "store/certs/945bbc825ea554f489d1fd51a73ddf2ea624ac7019a05205225c22a78ccfa8b4.pem", + "store/certs/960adf0063e96356750c2965dd0a0867da0b9cbd6e77714aeafb2349ab393da3.pem", + "store/certs/96bcec06264976f37460779acf28c5a7cfe8a3c0aae11a8ffcee05c0bddf08c6.pem", + "store/certs/97552015f5ddfc3c8788c006944555408894450084f100867086bc1a2bb58dc8.pem", + "store/certs/9a114025197c5bb95d94e63d55cd43790847b646b23cdf11ada4a00eff15fb48.pem", + "store/certs/9a6ec012e1a7da9dbe34194d478ad7c0db1822fb071df12981496ed104384113.pem", + "store/certs/9bea11c976fe014764c1be56a6f914b5a560317abd9988393382e5161aa0493c.pem", + "store/certs/a040929a02ce53b4acf4f2ffc6981ce4496f755e6d45fe0b2a692bcd52523f36.pem", + "store/certs/a1339d33281a0b56e557d3d32b1ce7f9367eb094bd5fa72a7e5004c8ded7cafe.pem", + "store/certs/a45ede3bbbf09c8ae15c72efc07268d693a21c996fd51e67ca079460fd6d8873.pem", + "store/certs/b0bfd52bb0d7d9bd92bf5d4dc13da255c02c542f378365ea893911f55e55f23c.pem", + "store/certs/b676f2eddae8775cd36cb0f63cd1d4603961f49e6265ba013a2f0307b6d0b804.pem", + "store/certs/bc104f15a48be709dca542a7e1d4b9df6f054527e802eaa92d595444258afe71.pem", + "store/certs/bc4d809b15189d78db3e1d8cf4f9726a795da1643ca5f1358e1ddb0edc0d7eb3.pem", + "store/certs/bd71fdf6da97e4cf62d1647add2581b07d79adf8397eb4ecba9c5e8488821423.pem", + "store/certs/be6c4da2bbb9ba59b6f3939768374246c3c005993fa98f020d1dedbed48a81d5.pem", + "store/certs/beb00b30839b9bc32c32e4447905950641f26421b15ed089198b518ae2ea1b99.pem", + "store/certs/bec94911c2955676db6c0a550986d76e3ba005667c442c9762b4fbb773de228c.pem", + "store/certs/bf0feefb9e3a581ad5f9e9db7589985743d261085c4d314f6f5d7259aa421612.pem", + "store/certs/bfd88fe1101c41ae3e801bf8be56350ee9bad1a6b9bd515edc5c6d5b8711ac44.pem", + "store/certs/bfff8fd04433487d6a8aa60c1a29767a9fc2bbb05e420f713a13b992891d3893.pem", + "store/certs/c0a6f4dc63a24bfdcf54ef2a6a082a0a72de35803e2ff5ff527ae5d87206dfd5.pem", + "store/certs/c3846bf24b9e93ca64274c0ec67c1ecc5e024ffcacd2d74019350e81fe546ae4.pem", + "store/certs/c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60.pem", + "store/certs/c741f70f4b2a8d88bf2e71c14122ef53ef10eba0cfa5e64cfa20f418853073e0.pem", + "store/certs/ca42dd41745fd0b81eb902362cf9d8bf719da1bd1b1efc946f5b4c99f42c1b9e.pem", + "store/certs/cb3ccbb76031e5e0138f8dd39a23f9de47ffc35e43c1144cea27d46a5ab1cb5f.pem", + "store/certs/cbb522d7b7f127ad6a0113865bdf1cd4102e7d0759af635a7cf4720dc963c53b.pem", + "store/certs/cecddc905099d8dadfc5b1d209b737cbe2c18cfb2c10c0ff0bcf0d3286fc1aa2.pem", + "store/certs/d40e9c86cd8fe468c1776959f49ea774fa548684b6c406f3909261f4dce2575c.pem", + "store/certs/d43af9b35473755c9684fc06d7d8cb70ee5c28e773fb294eb41ee71722924d24.pem", + "store/certs/d48d3d23eedb50a459e55197601c27774b9d7b18c94d5a059511a10250b93168.pem", + "store/certs/d7a7a0fb5d7e2731d771e9484ebcdef71d5f0c3e0a2948782bc83ee0ea699ef4.pem", + "store/certs/db3517d1f6732a2d5ab97c533ec70779ee3270a62fb4ac4238372460e6f01e88.pem", + "store/certs/dd6936fe21f8f077c123a1a521c12224f72255b73e03a7260693e8a24b0fa389.pem", + "store/certs/e23d4a036d7b70e9f595b1422079d2b91edfbb1fb651a0633eaa8a9dc5f80703.pem", + "store/certs/e35d28419ed02025cfa69038cd623962458da5c695fbdea3c22b0bfb25897092.pem", + "store/certs/e3b6a2db2ed7ce48842f7ac53241c7b71d54144bfb40c11f3f1d0b42f5eea12d.pem", + "store/certs/e75e72ed9f560eec6eb4800073a43fc3ad19195a392282017895974a99026b6c.pem", + "store/certs/e793c9b02fd8aa13e21c31228accb08119643b749c898964b1746d46c3d4cbd2.pem", + "store/certs/eaa962c4fa4a6bafebe415196d351ccd888d4f53f3fa8ae6d7c466a94e6042bb.pem", + "store/certs/ebc5570c29018c4d67b1aa127baf12f703b4611ebc17b7dab5573894179b93fa.pem", + "store/certs/ebd41040e4bb3ec742c9e381d31ef2a41a48b6685c96e7cef3c1df6cd4331c99.pem", + "store/certs/edf7ebbca27a2a384d387b7d4010c666e2edb4843e4c29b4ae1d5b9332e6b24d.pem", + "store/certs/eec5496b988ce98625b934092eec2908bed0b0f316c2d4730c84eaf1f3d34881.pem", + "store/certs/f1c1b50ae5a20dd8030ec9f6bc24823dd367b5255759b4e71b61fce9f7375d73.pem", + "store/certs/f356bea244b7a91eb35d53ca9ad7864ace018e2d35d5f8f96ddf68a6f41aa474.pem", + "store/certs/f9e67d336c51002ac054c632022d66dda2e7e3fff10ad061ed31d8bbb410cfb2.pem", + "store/certs/fd73dad31c644ff1b43bef0ccdda96710b9cd9875eca7e31707af3e96d522bbd.pem", ] outputs = [ "${target_gen_dir}/chrome-root-store-inc.cc" ] args = [ "--write-cpp=" + @@ -143,18 +143,17 @@ compiled_action("gen_root_store_test_inc") { tool = "//net/tools/root_store_tool:root_store_tool" - # It'd be really nice to list an input as "certs/*", but it doesn't seem to - # work. So we list them all out. + # It'd be really nice to list an input as "testdata/certs/*", but it doesn't + # seem to work. So we list them all out. inputs = [ - "root_store_testdata.textproto", - "testdata/568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5.pem", - "testdata/6b9c08e86eb0f767cfad65cd98b62149e5494a67f5845e7bd1ed019f27b86bd6.pem", - "testdata/c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60.pem", + "testdata/root_store.textproto", + "testdata/certs/568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5.pem", + "testdata/certs/6b9c08e86eb0f767cfad65cd98b62149e5494a67f5845e7bd1ed019f27b86bd6.pem", + "testdata/certs/c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60.pem", ] outputs = [ "${target_gen_dir}/chrome-root-store-test-data-inc.cc" ] args = [ - "--root-store-filename=root_store_testdata.textproto", - "--certs-sub-dir=testdata", + "--root-store-dir=net/data/ssl/chrome_root_store/testdata", "--write-cpp=" + rebase_path("${target_gen_dir}/chrome-root-store-test-data-inc.cc", root_build_dir),
diff --git a/net/data/ssl/chrome_root_store/README.md b/net/data/ssl/chrome_root_store/README.md index 7968167..040f80e 100644 --- a/net/data/ssl/chrome_root_store/README.md +++ b/net/data/ssl/chrome_root_store/README.md
@@ -4,14 +4,11 @@ [Chrome Root Store](https://www.chromium.org/Home/chromium-security/root-ca-policy). It is currently not used for trust decisions in Chrome. -The root store is defined by `root_store.textproto` file, which is a +The root store is defined by `store/root_store.textproto` file, which is a `RootStore` [protobuf](https://developers.google.com/protocol-buffers) message, defined in [`//net/tools/root_store_tool/root_store.proto`](/net/tools/root_store_tool/root_store.proto). -It references certificates in the `certs` directory. The +It references certificates in the `store/certs` directory. The [`root_store_tool`](/net/tools/root_store_tool/root_store_tool.cc) will files in this directory to eventually use this data for trust decisions in Chrome. - -TODO(https://crbug.com/1216547): update document when work on Chrome Root Store -is complete.
diff --git a/net/data/ssl/chrome_root_store/certs/02ed0eb28c14da45165c566791700d6451d7fb56f0b2ab1d3b8eb070e56edff5.pem b/net/data/ssl/chrome_root_store/store/certs/02ed0eb28c14da45165c566791700d6451d7fb56f0b2ab1d3b8eb070e56edff5.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/02ed0eb28c14da45165c566791700d6451d7fb56f0b2ab1d3b8eb070e56edff5.pem rename to net/data/ssl/chrome_root_store/store/certs/02ed0eb28c14da45165c566791700d6451d7fb56f0b2ab1d3b8eb070e56edff5.pem
diff --git a/net/data/ssl/chrome_root_store/certs/0376ab1d54c5f9803ce4b2e201a0ee7eef7b57b636e8a93c9b8d4860c96f5fa7.pem b/net/data/ssl/chrome_root_store/store/certs/0376ab1d54c5f9803ce4b2e201a0ee7eef7b57b636e8a93c9b8d4860c96f5fa7.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/0376ab1d54c5f9803ce4b2e201a0ee7eef7b57b636e8a93c9b8d4860c96f5fa7.pem rename to net/data/ssl/chrome_root_store/store/certs/0376ab1d54c5f9803ce4b2e201a0ee7eef7b57b636e8a93c9b8d4860c96f5fa7.pem
diff --git a/net/data/ssl/chrome_root_store/certs/04048028bf1f2864d48f9ad4d83294366a828856553f3b14303f90147f5d40ef.pem b/net/data/ssl/chrome_root_store/store/certs/04048028bf1f2864d48f9ad4d83294366a828856553f3b14303f90147f5d40ef.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/04048028bf1f2864d48f9ad4d83294366a828856553f3b14303f90147f5d40ef.pem rename to net/data/ssl/chrome_root_store/store/certs/04048028bf1f2864d48f9ad4d83294366a828856553f3b14303f90147f5d40ef.pem
diff --git a/net/data/ssl/chrome_root_store/certs/0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739.pem b/net/data/ssl/chrome_root_store/store/certs/0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739.pem rename to net/data/ssl/chrome_root_store/store/certs/0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739.pem
diff --git a/net/data/ssl/chrome_root_store/certs/0753e940378c1bd5e3836e395daea5cb839e5046f1bd0eae1951cf10fec7c965.pem b/net/data/ssl/chrome_root_store/store/certs/0753e940378c1bd5e3836e395daea5cb839e5046f1bd0eae1951cf10fec7c965.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/0753e940378c1bd5e3836e395daea5cb839e5046f1bd0eae1951cf10fec7c965.pem rename to net/data/ssl/chrome_root_store/store/certs/0753e940378c1bd5e3836e395daea5cb839e5046f1bd0eae1951cf10fec7c965.pem
diff --git a/net/data/ssl/chrome_root_store/certs/0a81ec5a929777f145904af38d5d509f66b5e2c58fcdb531058b0e17f3f0b41b.pem b/net/data/ssl/chrome_root_store/store/certs/0a81ec5a929777f145904af38d5d509f66b5e2c58fcdb531058b0e17f3f0b41b.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/0a81ec5a929777f145904af38d5d509f66b5e2c58fcdb531058b0e17f3f0b41b.pem rename to net/data/ssl/chrome_root_store/store/certs/0a81ec5a929777f145904af38d5d509f66b5e2c58fcdb531058b0e17f3f0b41b.pem
diff --git a/net/data/ssl/chrome_root_store/certs/0c2cd63df7806fa399ede809116b575bf87989f06518f9808c860503178baf66.pem b/net/data/ssl/chrome_root_store/store/certs/0c2cd63df7806fa399ede809116b575bf87989f06518f9808c860503178baf66.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/0c2cd63df7806fa399ede809116b575bf87989f06518f9808c860503178baf66.pem rename to net/data/ssl/chrome_root_store/store/certs/0c2cd63df7806fa399ede809116b575bf87989f06518f9808c860503178baf66.pem
diff --git a/net/data/ssl/chrome_root_store/certs/125609aa301da0a249b97a8239cb6a34216f44dcac9f3954b14292f2e8c8608f.pem b/net/data/ssl/chrome_root_store/store/certs/125609aa301da0a249b97a8239cb6a34216f44dcac9f3954b14292f2e8c8608f.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/125609aa301da0a249b97a8239cb6a34216f44dcac9f3954b14292f2e8c8608f.pem rename to net/data/ssl/chrome_root_store/store/certs/125609aa301da0a249b97a8239cb6a34216f44dcac9f3954b14292f2e8c8608f.pem
diff --git a/net/data/ssl/chrome_root_store/certs/1465fa205397b876faa6f0a9958e5590e40fcc7faa4fb7c2c8677521fb5fb658.pem b/net/data/ssl/chrome_root_store/store/certs/1465fa205397b876faa6f0a9958e5590e40fcc7faa4fb7c2c8677521fb5fb658.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/1465fa205397b876faa6f0a9958e5590e40fcc7faa4fb7c2c8677521fb5fb658.pem rename to net/data/ssl/chrome_root_store/store/certs/1465fa205397b876faa6f0a9958e5590e40fcc7faa4fb7c2c8677521fb5fb658.pem
diff --git a/net/data/ssl/chrome_root_store/certs/15d5b8774619ea7d54ce1ca6d0b0c403e037a917f131e8a04e1e6b7a71babce5.pem b/net/data/ssl/chrome_root_store/store/certs/15d5b8774619ea7d54ce1ca6d0b0c403e037a917f131e8a04e1e6b7a71babce5.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/15d5b8774619ea7d54ce1ca6d0b0c403e037a917f131e8a04e1e6b7a71babce5.pem rename to net/data/ssl/chrome_root_store/store/certs/15d5b8774619ea7d54ce1ca6d0b0c403e037a917f131e8a04e1e6b7a71babce5.pem
diff --git a/net/data/ssl/chrome_root_store/certs/15f0ba00a3ac7af3ac884c072b1011a077bd77c097f40164b2f8598abd83860c.pem b/net/data/ssl/chrome_root_store/store/certs/15f0ba00a3ac7af3ac884c072b1011a077bd77c097f40164b2f8598abd83860c.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/15f0ba00a3ac7af3ac884c072b1011a077bd77c097f40164b2f8598abd83860c.pem rename to net/data/ssl/chrome_root_store/store/certs/15f0ba00a3ac7af3ac884c072b1011a077bd77c097f40164b2f8598abd83860c.pem
diff --git a/net/data/ssl/chrome_root_store/certs/16af57a9f676b0ab126095aa5ebadef22ab31119d644ac95cd4b93dbf3f26aeb.pem b/net/data/ssl/chrome_root_store/store/certs/16af57a9f676b0ab126095aa5ebadef22ab31119d644ac95cd4b93dbf3f26aeb.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/16af57a9f676b0ab126095aa5ebadef22ab31119d644ac95cd4b93dbf3f26aeb.pem rename to net/data/ssl/chrome_root_store/store/certs/16af57a9f676b0ab126095aa5ebadef22ab31119d644ac95cd4b93dbf3f26aeb.pem
diff --git a/net/data/ssl/chrome_root_store/certs/1793927a0614549789adce2f8f34f7f0b66d0f3ae3a3b84d21ec15dbba4fadc7.pem b/net/data/ssl/chrome_root_store/store/certs/1793927a0614549789adce2f8f34f7f0b66d0f3ae3a3b84d21ec15dbba4fadc7.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/1793927a0614549789adce2f8f34f7f0b66d0f3ae3a3b84d21ec15dbba4fadc7.pem rename to net/data/ssl/chrome_root_store/store/certs/1793927a0614549789adce2f8f34f7f0b66d0f3ae3a3b84d21ec15dbba4fadc7.pem
diff --git a/net/data/ssl/chrome_root_store/certs/179fbc148a3dd00fd24ea13458cc43bfa7f59c8182d783a513f6ebec100c8924.pem b/net/data/ssl/chrome_root_store/store/certs/179fbc148a3dd00fd24ea13458cc43bfa7f59c8182d783a513f6ebec100c8924.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/179fbc148a3dd00fd24ea13458cc43bfa7f59c8182d783a513f6ebec100c8924.pem rename to net/data/ssl/chrome_root_store/store/certs/179fbc148a3dd00fd24ea13458cc43bfa7f59c8182d783a513f6ebec100c8924.pem
diff --git a/net/data/ssl/chrome_root_store/certs/18ce6cfe7bf14e60b2e347b8dfe868cb31d02ebb3ada271569f50343b46db3a4.pem b/net/data/ssl/chrome_root_store/store/certs/18ce6cfe7bf14e60b2e347b8dfe868cb31d02ebb3ada271569f50343b46db3a4.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/18ce6cfe7bf14e60b2e347b8dfe868cb31d02ebb3ada271569f50343b46db3a4.pem rename to net/data/ssl/chrome_root_store/store/certs/18ce6cfe7bf14e60b2e347b8dfe868cb31d02ebb3ada271569f50343b46db3a4.pem
diff --git a/net/data/ssl/chrome_root_store/certs/18f1fc7f205df8adddeb7fe007dd57e3af375a9c4d8d73546bf4f1fed1e18d35.pem b/net/data/ssl/chrome_root_store/store/certs/18f1fc7f205df8adddeb7fe007dd57e3af375a9c4d8d73546bf4f1fed1e18d35.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/18f1fc7f205df8adddeb7fe007dd57e3af375a9c4d8d73546bf4f1fed1e18d35.pem rename to net/data/ssl/chrome_root_store/store/certs/18f1fc7f205df8adddeb7fe007dd57e3af375a9c4d8d73546bf4f1fed1e18d35.pem
diff --git a/net/data/ssl/chrome_root_store/certs/1ba5b2aa8c65401a82960118f80bec4f62304d83cec4713a19c39c011ea46db4.pem b/net/data/ssl/chrome_root_store/store/certs/1ba5b2aa8c65401a82960118f80bec4f62304d83cec4713a19c39c011ea46db4.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/1ba5b2aa8c65401a82960118f80bec4f62304d83cec4713a19c39c011ea46db4.pem rename to net/data/ssl/chrome_root_store/store/certs/1ba5b2aa8c65401a82960118f80bec4f62304d83cec4713a19c39c011ea46db4.pem
diff --git a/net/data/ssl/chrome_root_store/certs/22a2c1f7bded704cc1e701b5f408c310880fe956b5de2a4a44f99c873a25a7c8.pem b/net/data/ssl/chrome_root_store/store/certs/22a2c1f7bded704cc1e701b5f408c310880fe956b5de2a4a44f99c873a25a7c8.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/22a2c1f7bded704cc1e701b5f408c310880fe956b5de2a4a44f99c873a25a7c8.pem rename to net/data/ssl/chrome_root_store/store/certs/22a2c1f7bded704cc1e701b5f408c310880fe956b5de2a4a44f99c873a25a7c8.pem
diff --git a/net/data/ssl/chrome_root_store/certs/2530cc8e98321502bad96f9b1fba1b099e2d299e0f4548bb914f363bc0d4531f.pem b/net/data/ssl/chrome_root_store/store/certs/2530cc8e98321502bad96f9b1fba1b099e2d299e0f4548bb914f363bc0d4531f.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/2530cc8e98321502bad96f9b1fba1b099e2d299e0f4548bb914f363bc0d4531f.pem rename to net/data/ssl/chrome_root_store/store/certs/2530cc8e98321502bad96f9b1fba1b099e2d299e0f4548bb914f363bc0d4531f.pem
diff --git a/net/data/ssl/chrome_root_store/certs/2a575471e31340bc21581cbd2cf13e158463203ece94bcf9d3cc196bf09a5472.pem b/net/data/ssl/chrome_root_store/store/certs/2a575471e31340bc21581cbd2cf13e158463203ece94bcf9d3cc196bf09a5472.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/2a575471e31340bc21581cbd2cf13e158463203ece94bcf9d3cc196bf09a5472.pem rename to net/data/ssl/chrome_root_store/store/certs/2a575471e31340bc21581cbd2cf13e158463203ece94bcf9d3cc196bf09a5472.pem
diff --git a/net/data/ssl/chrome_root_store/certs/2cabeafe37d06ca22aba7391c0033d25982952c453647349763a3ab5ad6ccf69.pem b/net/data/ssl/chrome_root_store/store/certs/2cabeafe37d06ca22aba7391c0033d25982952c453647349763a3ab5ad6ccf69.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/2cabeafe37d06ca22aba7391c0033d25982952c453647349763a3ab5ad6ccf69.pem rename to net/data/ssl/chrome_root_store/store/certs/2cabeafe37d06ca22aba7391c0033d25982952c453647349763a3ab5ad6ccf69.pem
diff --git a/net/data/ssl/chrome_root_store/certs/2ce1cb0bf9d2f9e102993fbe215152c3b2dd0cabde1c68e5319b839154dbb7f5.pem b/net/data/ssl/chrome_root_store/store/certs/2ce1cb0bf9d2f9e102993fbe215152c3b2dd0cabde1c68e5319b839154dbb7f5.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/2ce1cb0bf9d2f9e102993fbe215152c3b2dd0cabde1c68e5319b839154dbb7f5.pem rename to net/data/ssl/chrome_root_store/store/certs/2ce1cb0bf9d2f9e102993fbe215152c3b2dd0cabde1c68e5319b839154dbb7f5.pem
diff --git a/net/data/ssl/chrome_root_store/certs/2e7bf16cc22485a7bbe2aa8696750761b0ae39be3b2fe9d0cc6d4ef73491425c.pem b/net/data/ssl/chrome_root_store/store/certs/2e7bf16cc22485a7bbe2aa8696750761b0ae39be3b2fe9d0cc6d4ef73491425c.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/2e7bf16cc22485a7bbe2aa8696750761b0ae39be3b2fe9d0cc6d4ef73491425c.pem rename to net/data/ssl/chrome_root_store/store/certs/2e7bf16cc22485a7bbe2aa8696750761b0ae39be3b2fe9d0cc6d4ef73491425c.pem
diff --git a/net/data/ssl/chrome_root_store/certs/30d0895a9a448a262091635522d1f52010b5867acae12c78ef958fd4f4389f2f.pem b/net/data/ssl/chrome_root_store/store/certs/30d0895a9a448a262091635522d1f52010b5867acae12c78ef958fd4f4389f2f.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/30d0895a9a448a262091635522d1f52010b5867acae12c78ef958fd4f4389f2f.pem rename to net/data/ssl/chrome_root_store/store/certs/30d0895a9a448a262091635522d1f52010b5867acae12c78ef958fd4f4389f2f.pem
diff --git a/net/data/ssl/chrome_root_store/certs/31ad6648f8104138c738f39ea4320133393e3a18cc02296ef97c2ac9ef6731d0.pem b/net/data/ssl/chrome_root_store/store/certs/31ad6648f8104138c738f39ea4320133393e3a18cc02296ef97c2ac9ef6731d0.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/31ad6648f8104138c738f39ea4320133393e3a18cc02296ef97c2ac9ef6731d0.pem rename to net/data/ssl/chrome_root_store/store/certs/31ad6648f8104138c738f39ea4320133393e3a18cc02296ef97c2ac9ef6731d0.pem
diff --git a/net/data/ssl/chrome_root_store/certs/3417bb06cc6007da1b961c920b8ab4ce3fad820e4aa30b9acbc4a74ebdcebc65.pem b/net/data/ssl/chrome_root_store/store/certs/3417bb06cc6007da1b961c920b8ab4ce3fad820e4aa30b9acbc4a74ebdcebc65.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/3417bb06cc6007da1b961c920b8ab4ce3fad820e4aa30b9acbc4a74ebdcebc65.pem rename to net/data/ssl/chrome_root_store/store/certs/3417bb06cc6007da1b961c920b8ab4ce3fad820e4aa30b9acbc4a74ebdcebc65.pem
diff --git a/net/data/ssl/chrome_root_store/certs/358df39d764af9e1b766e9c972df352ee15cfac227af6ad1d70e8e4a6edcba02.pem b/net/data/ssl/chrome_root_store/store/certs/358df39d764af9e1b766e9c972df352ee15cfac227af6ad1d70e8e4a6edcba02.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/358df39d764af9e1b766e9c972df352ee15cfac227af6ad1d70e8e4a6edcba02.pem rename to net/data/ssl/chrome_root_store/store/certs/358df39d764af9e1b766e9c972df352ee15cfac227af6ad1d70e8e4a6edcba02.pem
diff --git a/net/data/ssl/chrome_root_store/certs/3c4fb0b95ab8b30032f432b86f535fe172c185d0fd39865837cf36187fa6f428.pem b/net/data/ssl/chrome_root_store/store/certs/3c4fb0b95ab8b30032f432b86f535fe172c185d0fd39865837cf36187fa6f428.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/3c4fb0b95ab8b30032f432b86f535fe172c185d0fd39865837cf36187fa6f428.pem rename to net/data/ssl/chrome_root_store/store/certs/3c4fb0b95ab8b30032f432b86f535fe172c185d0fd39865837cf36187fa6f428.pem
diff --git a/net/data/ssl/chrome_root_store/certs/3c5f81fea5fab82c64bfa2eaecafcde8e077fc8620a7cae537163df36edbf378.pem b/net/data/ssl/chrome_root_store/store/certs/3c5f81fea5fab82c64bfa2eaecafcde8e077fc8620a7cae537163df36edbf378.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/3c5f81fea5fab82c64bfa2eaecafcde8e077fc8620a7cae537163df36edbf378.pem rename to net/data/ssl/chrome_root_store/store/certs/3c5f81fea5fab82c64bfa2eaecafcde8e077fc8620a7cae537163df36edbf378.pem
diff --git a/net/data/ssl/chrome_root_store/certs/3e9099b5015e8f486c00bcea9d111ee721faba355a89bcf1df69561e3dc6325c.pem b/net/data/ssl/chrome_root_store/store/certs/3e9099b5015e8f486c00bcea9d111ee721faba355a89bcf1df69561e3dc6325c.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/3e9099b5015e8f486c00bcea9d111ee721faba355a89bcf1df69561e3dc6325c.pem rename to net/data/ssl/chrome_root_store/store/certs/3e9099b5015e8f486c00bcea9d111ee721faba355a89bcf1df69561e3dc6325c.pem
diff --git a/net/data/ssl/chrome_root_store/certs/40f6af0346a99aa1cd1d555a4e9cce62c7f9634603ee406615833dc8c8d00367.pem b/net/data/ssl/chrome_root_store/store/certs/40f6af0346a99aa1cd1d555a4e9cce62c7f9634603ee406615833dc8c8d00367.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/40f6af0346a99aa1cd1d555a4e9cce62c7f9634603ee406615833dc8c8d00367.pem rename to net/data/ssl/chrome_root_store/store/certs/40f6af0346a99aa1cd1d555a4e9cce62c7f9634603ee406615833dc8c8d00367.pem
diff --git a/net/data/ssl/chrome_root_store/certs/4200f5043ac8590ebb527d209ed1503029fbcbd41ca1b506ec27f15ade7dac69.pem b/net/data/ssl/chrome_root_store/store/certs/4200f5043ac8590ebb527d209ed1503029fbcbd41ca1b506ec27f15ade7dac69.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/4200f5043ac8590ebb527d209ed1503029fbcbd41ca1b506ec27f15ade7dac69.pem rename to net/data/ssl/chrome_root_store/store/certs/4200f5043ac8590ebb527d209ed1503029fbcbd41ca1b506ec27f15ade7dac69.pem
diff --git a/net/data/ssl/chrome_root_store/certs/4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161.pem b/net/data/ssl/chrome_root_store/store/certs/4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161.pem rename to net/data/ssl/chrome_root_store/store/certs/4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161.pem
diff --git a/net/data/ssl/chrome_root_store/certs/43df5774b03e7fef5fe40d931a7bedf1bb2e6b42738c4e6d3841103d3aa7f339.pem b/net/data/ssl/chrome_root_store/store/certs/43df5774b03e7fef5fe40d931a7bedf1bb2e6b42738c4e6d3841103d3aa7f339.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/43df5774b03e7fef5fe40d931a7bedf1bb2e6b42738c4e6d3841103d3aa7f339.pem rename to net/data/ssl/chrome_root_store/store/certs/43df5774b03e7fef5fe40d931a7bedf1bb2e6b42738c4e6d3841103d3aa7f339.pem
diff --git a/net/data/ssl/chrome_root_store/certs/44b545aa8a25e65a73ca15dc27fc36d24c1cb9953a066539b11582dc487b4833.pem b/net/data/ssl/chrome_root_store/store/certs/44b545aa8a25e65a73ca15dc27fc36d24c1cb9953a066539b11582dc487b4833.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/44b545aa8a25e65a73ca15dc27fc36d24c1cb9953a066539b11582dc487b4833.pem rename to net/data/ssl/chrome_root_store/store/certs/44b545aa8a25e65a73ca15dc27fc36d24c1cb9953a066539b11582dc487b4833.pem
diff --git a/net/data/ssl/chrome_root_store/certs/45140b3247eb9cc8c5b4f0d7b53091f73292089e6e5a63e2749dd3aca9198eda.pem b/net/data/ssl/chrome_root_store/store/certs/45140b3247eb9cc8c5b4f0d7b53091f73292089e6e5a63e2749dd3aca9198eda.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/45140b3247eb9cc8c5b4f0d7b53091f73292089e6e5a63e2749dd3aca9198eda.pem rename to net/data/ssl/chrome_root_store/store/certs/45140b3247eb9cc8c5b4f0d7b53091f73292089e6e5a63e2749dd3aca9198eda.pem
diff --git a/net/data/ssl/chrome_root_store/certs/46edc3689046d53a453fb3104ab80dcaec658b2660ea1629dd7e867990648716.pem b/net/data/ssl/chrome_root_store/store/certs/46edc3689046d53a453fb3104ab80dcaec658b2660ea1629dd7e867990648716.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/46edc3689046d53a453fb3104ab80dcaec658b2660ea1629dd7e867990648716.pem rename to net/data/ssl/chrome_root_store/store/certs/46edc3689046d53a453fb3104ab80dcaec658b2660ea1629dd7e867990648716.pem
diff --git a/net/data/ssl/chrome_root_store/certs/49e7a442acf0ea6287050054b52564b650e4f49e42e348d6aa38e039e957b1c1.pem b/net/data/ssl/chrome_root_store/store/certs/49e7a442acf0ea6287050054b52564b650e4f49e42e348d6aa38e039e957b1c1.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/49e7a442acf0ea6287050054b52564b650e4f49e42e348d6aa38e039e957b1c1.pem rename to net/data/ssl/chrome_root_store/store/certs/49e7a442acf0ea6287050054b52564b650e4f49e42e348d6aa38e039e957b1c1.pem
diff --git a/net/data/ssl/chrome_root_store/certs/4d2491414cfe956746ec4cefa6cf6f72e28a1329432f9d8a907ac4cb5dadc15a.pem b/net/data/ssl/chrome_root_store/store/certs/4d2491414cfe956746ec4cefa6cf6f72e28a1329432f9d8a907ac4cb5dadc15a.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/4d2491414cfe956746ec4cefa6cf6f72e28a1329432f9d8a907ac4cb5dadc15a.pem rename to net/data/ssl/chrome_root_store/store/certs/4d2491414cfe956746ec4cefa6cf6f72e28a1329432f9d8a907ac4cb5dadc15a.pem
diff --git a/net/data/ssl/chrome_root_store/certs/4ff460d54b9c86dabfbcfc5712e0400d2bed3fbc4d4fbdaa86e06adcd2a9ad7a.pem b/net/data/ssl/chrome_root_store/store/certs/4ff460d54b9c86dabfbcfc5712e0400d2bed3fbc4d4fbdaa86e06adcd2a9ad7a.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/4ff460d54b9c86dabfbcfc5712e0400d2bed3fbc4d4fbdaa86e06adcd2a9ad7a.pem rename to net/data/ssl/chrome_root_store/store/certs/4ff460d54b9c86dabfbcfc5712e0400d2bed3fbc4d4fbdaa86e06adcd2a9ad7a.pem
diff --git a/net/data/ssl/chrome_root_store/certs/513b2cecb810d4cde5dd85391adfc6c2dd60d87bb736d2b521484aa47a0ebef6.pem b/net/data/ssl/chrome_root_store/store/certs/513b2cecb810d4cde5dd85391adfc6c2dd60d87bb736d2b521484aa47a0ebef6.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/513b2cecb810d4cde5dd85391adfc6c2dd60d87bb736d2b521484aa47a0ebef6.pem rename to net/data/ssl/chrome_root_store/store/certs/513b2cecb810d4cde5dd85391adfc6c2dd60d87bb736d2b521484aa47a0ebef6.pem
diff --git a/net/data/ssl/chrome_root_store/certs/52f0e1c4e58ec629291b60317f074671b85d7ea80d5b07273463534b32b40234.pem b/net/data/ssl/chrome_root_store/store/certs/52f0e1c4e58ec629291b60317f074671b85d7ea80d5b07273463534b32b40234.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/52f0e1c4e58ec629291b60317f074671b85d7ea80d5b07273463534b32b40234.pem rename to net/data/ssl/chrome_root_store/store/certs/52f0e1c4e58ec629291b60317f074671b85d7ea80d5b07273463534b32b40234.pem
diff --git a/net/data/ssl/chrome_root_store/certs/552f7bdcf1a7af9e6ce672017f4f12abf77240c78e761ac203d1d9d20ac89988.pem b/net/data/ssl/chrome_root_store/store/certs/552f7bdcf1a7af9e6ce672017f4f12abf77240c78e761ac203d1d9d20ac89988.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/552f7bdcf1a7af9e6ce672017f4f12abf77240c78e761ac203d1d9d20ac89988.pem rename to net/data/ssl/chrome_root_store/store/certs/552f7bdcf1a7af9e6ce672017f4f12abf77240c78e761ac203d1d9d20ac89988.pem
diff --git a/net/data/ssl/chrome_root_store/certs/55903859c8c0c3ebb8759ece4e2557225ff5758bbd38ebd48276601e1bd58097.pem b/net/data/ssl/chrome_root_store/store/certs/55903859c8c0c3ebb8759ece4e2557225ff5758bbd38ebd48276601e1bd58097.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/55903859c8c0c3ebb8759ece4e2557225ff5758bbd38ebd48276601e1bd58097.pem rename to net/data/ssl/chrome_root_store/store/certs/55903859c8c0c3ebb8759ece4e2557225ff5758bbd38ebd48276601e1bd58097.pem
diff --git a/net/data/ssl/chrome_root_store/certs/55926084ec963a64b96e2abe01ce0ba86a64fbfebcc7aab5afc155b37fd76066.pem b/net/data/ssl/chrome_root_store/store/certs/55926084ec963a64b96e2abe01ce0ba86a64fbfebcc7aab5afc155b37fd76066.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/55926084ec963a64b96e2abe01ce0ba86a64fbfebcc7aab5afc155b37fd76066.pem rename to net/data/ssl/chrome_root_store/store/certs/55926084ec963a64b96e2abe01ce0ba86a64fbfebcc7aab5afc155b37fd76066.pem
diff --git a/net/data/ssl/chrome_root_store/certs/568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5.pem b/net/data/ssl/chrome_root_store/store/certs/568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5.pem rename to net/data/ssl/chrome_root_store/store/certs/568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5.pem
diff --git a/net/data/ssl/chrome_root_store/certs/59769007f7685d0fcd50872f9f95d5755a5b2b457d81f3692b610a98672f0e1b.pem b/net/data/ssl/chrome_root_store/store/certs/59769007f7685d0fcd50872f9f95d5755a5b2b457d81f3692b610a98672f0e1b.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/59769007f7685d0fcd50872f9f95d5755a5b2b457d81f3692b610a98672f0e1b.pem rename to net/data/ssl/chrome_root_store/store/certs/59769007f7685d0fcd50872f9f95d5755a5b2b457d81f3692b610a98672f0e1b.pem
diff --git a/net/data/ssl/chrome_root_store/certs/5a2fc03f0c83b090bbfa40604b0988446c7636183df9846e17101a447fb8efd6.pem b/net/data/ssl/chrome_root_store/store/certs/5a2fc03f0c83b090bbfa40604b0988446c7636183df9846e17101a447fb8efd6.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/5a2fc03f0c83b090bbfa40604b0988446c7636183df9846e17101a447fb8efd6.pem rename to net/data/ssl/chrome_root_store/store/certs/5a2fc03f0c83b090bbfa40604b0988446c7636183df9846e17101a447fb8efd6.pem
diff --git a/net/data/ssl/chrome_root_store/certs/5a885db19c01d912c5759388938cafbbdf031ab2d48e91ee15589b42971d039c.pem b/net/data/ssl/chrome_root_store/store/certs/5a885db19c01d912c5759388938cafbbdf031ab2d48e91ee15589b42971d039c.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/5a885db19c01d912c5759388938cafbbdf031ab2d48e91ee15589b42971d039c.pem rename to net/data/ssl/chrome_root_store/store/certs/5a885db19c01d912c5759388938cafbbdf031ab2d48e91ee15589b42971d039c.pem
diff --git a/net/data/ssl/chrome_root_store/certs/5c58468d55f58e497e743982d2b50010b6d165374acf83a7d4a32db768c4408e.pem b/net/data/ssl/chrome_root_store/store/certs/5c58468d55f58e497e743982d2b50010b6d165374acf83a7d4a32db768c4408e.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/5c58468d55f58e497e743982d2b50010b6d165374acf83a7d4a32db768c4408e.pem rename to net/data/ssl/chrome_root_store/store/certs/5c58468d55f58e497e743982d2b50010b6d165374acf83a7d4a32db768c4408e.pem
diff --git a/net/data/ssl/chrome_root_store/certs/5cc3d78e4e1d5e45547a04e6873e64f90cf9536d1ccc2ef800f355c4c5fd70fd.pem b/net/data/ssl/chrome_root_store/store/certs/5cc3d78e4e1d5e45547a04e6873e64f90cf9536d1ccc2ef800f355c4c5fd70fd.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/5cc3d78e4e1d5e45547a04e6873e64f90cf9536d1ccc2ef800f355c4c5fd70fd.pem rename to net/data/ssl/chrome_root_store/store/certs/5cc3d78e4e1d5e45547a04e6873e64f90cf9536d1ccc2ef800f355c4c5fd70fd.pem
diff --git a/net/data/ssl/chrome_root_store/certs/5d56499be4d2e08bcfcad08a3e38723d50503bde706948e42f55603019e528ae.pem b/net/data/ssl/chrome_root_store/store/certs/5d56499be4d2e08bcfcad08a3e38723d50503bde706948e42f55603019e528ae.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/5d56499be4d2e08bcfcad08a3e38723d50503bde706948e42f55603019e528ae.pem rename to net/data/ssl/chrome_root_store/store/certs/5d56499be4d2e08bcfcad08a3e38723d50503bde706948e42f55603019e528ae.pem
diff --git a/net/data/ssl/chrome_root_store/certs/62dd0be9b9f50a163ea0f8e75c053b1eca57ea55c8688f647c6881f2c8357b95.pem b/net/data/ssl/chrome_root_store/store/certs/62dd0be9b9f50a163ea0f8e75c053b1eca57ea55c8688f647c6881f2c8357b95.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/62dd0be9b9f50a163ea0f8e75c053b1eca57ea55c8688f647c6881f2c8357b95.pem rename to net/data/ssl/chrome_root_store/store/certs/62dd0be9b9f50a163ea0f8e75c053b1eca57ea55c8688f647c6881f2c8357b95.pem
diff --git a/net/data/ssl/chrome_root_store/certs/657cfe2fa73faa38462571f332a2363a46fce7020951710702cdfbb6eeda3305.pem b/net/data/ssl/chrome_root_store/store/certs/657cfe2fa73faa38462571f332a2363a46fce7020951710702cdfbb6eeda3305.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/657cfe2fa73faa38462571f332a2363a46fce7020951710702cdfbb6eeda3305.pem rename to net/data/ssl/chrome_root_store/store/certs/657cfe2fa73faa38462571f332a2363a46fce7020951710702cdfbb6eeda3305.pem
diff --git a/net/data/ssl/chrome_root_store/certs/6b9c08e86eb0f767cfad65cd98b62149e5494a67f5845e7bd1ed019f27b86bd6.pem b/net/data/ssl/chrome_root_store/store/certs/6b9c08e86eb0f767cfad65cd98b62149e5494a67f5845e7bd1ed019f27b86bd6.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/6b9c08e86eb0f767cfad65cd98b62149e5494a67f5845e7bd1ed019f27b86bd6.pem rename to net/data/ssl/chrome_root_store/store/certs/6b9c08e86eb0f767cfad65cd98b62149e5494a67f5845e7bd1ed019f27b86bd6.pem
diff --git a/net/data/ssl/chrome_root_store/certs/6c61dac3a2def031506be036d2a6fe401994fbd13df9c8d466599274c446ec98.pem b/net/data/ssl/chrome_root_store/store/certs/6c61dac3a2def031506be036d2a6fe401994fbd13df9c8d466599274c446ec98.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/6c61dac3a2def031506be036d2a6fe401994fbd13df9c8d466599274c446ec98.pem rename to net/data/ssl/chrome_root_store/store/certs/6c61dac3a2def031506be036d2a6fe401994fbd13df9c8d466599274c446ec98.pem
diff --git a/net/data/ssl/chrome_root_store/certs/6dc47172e01cbcb0bf62580d895fe2b8ac9ad4f873801e0c10b9c837d21eb177.pem b/net/data/ssl/chrome_root_store/store/certs/6dc47172e01cbcb0bf62580d895fe2b8ac9ad4f873801e0c10b9c837d21eb177.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/6dc47172e01cbcb0bf62580d895fe2b8ac9ad4f873801e0c10b9c837d21eb177.pem rename to net/data/ssl/chrome_root_store/store/certs/6dc47172e01cbcb0bf62580d895fe2b8ac9ad4f873801e0c10b9c837d21eb177.pem
diff --git a/net/data/ssl/chrome_root_store/certs/70a73f7f376b60074248904534b11482d5bf0e698ecc498df52577ebf2e93b9a.pem b/net/data/ssl/chrome_root_store/store/certs/70a73f7f376b60074248904534b11482d5bf0e698ecc498df52577ebf2e93b9a.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/70a73f7f376b60074248904534b11482d5bf0e698ecc498df52577ebf2e93b9a.pem rename to net/data/ssl/chrome_root_store/store/certs/70a73f7f376b60074248904534b11482d5bf0e698ecc498df52577ebf2e93b9a.pem
diff --git a/net/data/ssl/chrome_root_store/certs/71cca5391f9e794b04802530b363e121da8a3043bb26662fea4dca7fc951a4bd.pem b/net/data/ssl/chrome_root_store/store/certs/71cca5391f9e794b04802530b363e121da8a3043bb26662fea4dca7fc951a4bd.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/71cca5391f9e794b04802530b363e121da8a3043bb26662fea4dca7fc951a4bd.pem rename to net/data/ssl/chrome_root_store/store/certs/71cca5391f9e794b04802530b363e121da8a3043bb26662fea4dca7fc951a4bd.pem
diff --git a/net/data/ssl/chrome_root_store/certs/73c176434f1bc6d5adf45b0e76e727287c8de57616c1e6e6141a2b2cbc7d8e4c.pem b/net/data/ssl/chrome_root_store/store/certs/73c176434f1bc6d5adf45b0e76e727287c8de57616c1e6e6141a2b2cbc7d8e4c.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/73c176434f1bc6d5adf45b0e76e727287c8de57616c1e6e6141a2b2cbc7d8e4c.pem rename to net/data/ssl/chrome_root_store/store/certs/73c176434f1bc6d5adf45b0e76e727287c8de57616c1e6e6141a2b2cbc7d8e4c.pem
diff --git a/net/data/ssl/chrome_root_store/certs/7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf.pem b/net/data/ssl/chrome_root_store/store/certs/7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf.pem rename to net/data/ssl/chrome_root_store/store/certs/7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf.pem
diff --git a/net/data/ssl/chrome_root_store/certs/7908b40314c138100b518d0735807ffbfcf8518a0095337105ba386b153dd927.pem b/net/data/ssl/chrome_root_store/store/certs/7908b40314c138100b518d0735807ffbfcf8518a0095337105ba386b153dd927.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/7908b40314c138100b518d0735807ffbfcf8518a0095337105ba386b153dd927.pem rename to net/data/ssl/chrome_root_store/store/certs/7908b40314c138100b518d0735807ffbfcf8518a0095337105ba386b153dd927.pem
diff --git a/net/data/ssl/chrome_root_store/certs/7d05ebb682339f8c9451ee094eebfefa7953a114edb2f44949452fab7d2fc185.pem b/net/data/ssl/chrome_root_store/store/certs/7d05ebb682339f8c9451ee094eebfefa7953a114edb2f44949452fab7d2fc185.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/7d05ebb682339f8c9451ee094eebfefa7953a114edb2f44949452fab7d2fc185.pem rename to net/data/ssl/chrome_root_store/store/certs/7d05ebb682339f8c9451ee094eebfefa7953a114edb2f44949452fab7d2fc185.pem
diff --git a/net/data/ssl/chrome_root_store/certs/7e37cb8b4c47090cab36551ba6f45db840680fba166a952db100717f43053fc2.pem b/net/data/ssl/chrome_root_store/store/certs/7e37cb8b4c47090cab36551ba6f45db840680fba166a952db100717f43053fc2.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/7e37cb8b4c47090cab36551ba6f45db840680fba166a952db100717f43053fc2.pem rename to net/data/ssl/chrome_root_store/store/certs/7e37cb8b4c47090cab36551ba6f45db840680fba166a952db100717f43053fc2.pem
diff --git a/net/data/ssl/chrome_root_store/certs/8560f91c3624daba9570b5fea0dbe36ff11a8323be9486854fb3f34a5571198d.pem b/net/data/ssl/chrome_root_store/store/certs/8560f91c3624daba9570b5fea0dbe36ff11a8323be9486854fb3f34a5571198d.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/8560f91c3624daba9570b5fea0dbe36ff11a8323be9486854fb3f34a5571198d.pem rename to net/data/ssl/chrome_root_store/store/certs/8560f91c3624daba9570b5fea0dbe36ff11a8323be9486854fb3f34a5571198d.pem
diff --git a/net/data/ssl/chrome_root_store/certs/85666a562ee0be5ce925c1d8890a6f76a87ec16d4d7d5f29ea7419cf20123b69.pem b/net/data/ssl/chrome_root_store/store/certs/85666a562ee0be5ce925c1d8890a6f76a87ec16d4d7d5f29ea7419cf20123b69.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/85666a562ee0be5ce925c1d8890a6f76a87ec16d4d7d5f29ea7419cf20123b69.pem rename to net/data/ssl/chrome_root_store/store/certs/85666a562ee0be5ce925c1d8890a6f76a87ec16d4d7d5f29ea7419cf20123b69.pem
diff --git a/net/data/ssl/chrome_root_store/certs/85a0dd7dd720adb7ff05f83d542b209dc7ff4528f7d677b18389fea5e5c49e86.pem b/net/data/ssl/chrome_root_store/store/certs/85a0dd7dd720adb7ff05f83d542b209dc7ff4528f7d677b18389fea5e5c49e86.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/85a0dd7dd720adb7ff05f83d542b209dc7ff4528f7d677b18389fea5e5c49e86.pem rename to net/data/ssl/chrome_root_store/store/certs/85a0dd7dd720adb7ff05f83d542b209dc7ff4528f7d677b18389fea5e5c49e86.pem
diff --git a/net/data/ssl/chrome_root_store/certs/86a1ecba089c4a8d3bbe2734c612ba341d813e043cf9e8a862cd5c57a36bbe6b.pem b/net/data/ssl/chrome_root_store/store/certs/86a1ecba089c4a8d3bbe2734c612ba341d813e043cf9e8a862cd5c57a36bbe6b.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/86a1ecba089c4a8d3bbe2734c612ba341d813e043cf9e8a862cd5c57a36bbe6b.pem rename to net/data/ssl/chrome_root_store/store/certs/86a1ecba089c4a8d3bbe2734c612ba341d813e043cf9e8a862cd5c57a36bbe6b.pem
diff --git a/net/data/ssl/chrome_root_store/certs/88ef81de202eb018452e43f864725cea5fbd1fc2d9d205730709c5d8b8690f46.pem b/net/data/ssl/chrome_root_store/store/certs/88ef81de202eb018452e43f864725cea5fbd1fc2d9d205730709c5d8b8690f46.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/88ef81de202eb018452e43f864725cea5fbd1fc2d9d205730709c5d8b8690f46.pem rename to net/data/ssl/chrome_root_store/store/certs/88ef81de202eb018452e43f864725cea5fbd1fc2d9d205730709c5d8b8690f46.pem
diff --git a/net/data/ssl/chrome_root_store/certs/8a866fd1b276b57e578e921c65828a2bed58e9f2f288054134b7f1f4bfc9cc74.pem b/net/data/ssl/chrome_root_store/store/certs/8a866fd1b276b57e578e921c65828a2bed58e9f2f288054134b7f1f4bfc9cc74.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/8a866fd1b276b57e578e921c65828a2bed58e9f2f288054134b7f1f4bfc9cc74.pem rename to net/data/ssl/chrome_root_store/store/certs/8a866fd1b276b57e578e921c65828a2bed58e9f2f288054134b7f1f4bfc9cc74.pem
diff --git a/net/data/ssl/chrome_root_store/certs/8ecde6884f3d87b1125ba31ac3fcb13d7016de7f57cc904fe1cb97c6ae98196e.pem b/net/data/ssl/chrome_root_store/store/certs/8ecde6884f3d87b1125ba31ac3fcb13d7016de7f57cc904fe1cb97c6ae98196e.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/8ecde6884f3d87b1125ba31ac3fcb13d7016de7f57cc904fe1cb97c6ae98196e.pem rename to net/data/ssl/chrome_root_store/store/certs/8ecde6884f3d87b1125ba31ac3fcb13d7016de7f57cc904fe1cb97c6ae98196e.pem
diff --git a/net/data/ssl/chrome_root_store/certs/8fe4fb0af93a4d0d67db0bebb23e37c71bf325dcbcdd240ea04daf58b47e1840.pem b/net/data/ssl/chrome_root_store/store/certs/8fe4fb0af93a4d0d67db0bebb23e37c71bf325dcbcdd240ea04daf58b47e1840.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/8fe4fb0af93a4d0d67db0bebb23e37c71bf325dcbcdd240ea04daf58b47e1840.pem rename to net/data/ssl/chrome_root_store/store/certs/8fe4fb0af93a4d0d67db0bebb23e37c71bf325dcbcdd240ea04daf58b47e1840.pem
diff --git a/net/data/ssl/chrome_root_store/certs/91e2f5788d5810eba7ba58737de1548a8ecacd014598bc0b143e041b17052552.pem b/net/data/ssl/chrome_root_store/store/certs/91e2f5788d5810eba7ba58737de1548a8ecacd014598bc0b143e041b17052552.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/91e2f5788d5810eba7ba58737de1548a8ecacd014598bc0b143e041b17052552.pem rename to net/data/ssl/chrome_root_store/store/certs/91e2f5788d5810eba7ba58737de1548a8ecacd014598bc0b143e041b17052552.pem
diff --git a/net/data/ssl/chrome_root_store/certs/945bbc825ea554f489d1fd51a73ddf2ea624ac7019a05205225c22a78ccfa8b4.pem b/net/data/ssl/chrome_root_store/store/certs/945bbc825ea554f489d1fd51a73ddf2ea624ac7019a05205225c22a78ccfa8b4.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/945bbc825ea554f489d1fd51a73ddf2ea624ac7019a05205225c22a78ccfa8b4.pem rename to net/data/ssl/chrome_root_store/store/certs/945bbc825ea554f489d1fd51a73ddf2ea624ac7019a05205225c22a78ccfa8b4.pem
diff --git a/net/data/ssl/chrome_root_store/certs/960adf0063e96356750c2965dd0a0867da0b9cbd6e77714aeafb2349ab393da3.pem b/net/data/ssl/chrome_root_store/store/certs/960adf0063e96356750c2965dd0a0867da0b9cbd6e77714aeafb2349ab393da3.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/960adf0063e96356750c2965dd0a0867da0b9cbd6e77714aeafb2349ab393da3.pem rename to net/data/ssl/chrome_root_store/store/certs/960adf0063e96356750c2965dd0a0867da0b9cbd6e77714aeafb2349ab393da3.pem
diff --git a/net/data/ssl/chrome_root_store/certs/96bcec06264976f37460779acf28c5a7cfe8a3c0aae11a8ffcee05c0bddf08c6.pem b/net/data/ssl/chrome_root_store/store/certs/96bcec06264976f37460779acf28c5a7cfe8a3c0aae11a8ffcee05c0bddf08c6.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/96bcec06264976f37460779acf28c5a7cfe8a3c0aae11a8ffcee05c0bddf08c6.pem rename to net/data/ssl/chrome_root_store/store/certs/96bcec06264976f37460779acf28c5a7cfe8a3c0aae11a8ffcee05c0bddf08c6.pem
diff --git a/net/data/ssl/chrome_root_store/certs/97552015f5ddfc3c8788c006944555408894450084f100867086bc1a2bb58dc8.pem b/net/data/ssl/chrome_root_store/store/certs/97552015f5ddfc3c8788c006944555408894450084f100867086bc1a2bb58dc8.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/97552015f5ddfc3c8788c006944555408894450084f100867086bc1a2bb58dc8.pem rename to net/data/ssl/chrome_root_store/store/certs/97552015f5ddfc3c8788c006944555408894450084f100867086bc1a2bb58dc8.pem
diff --git a/net/data/ssl/chrome_root_store/certs/9a114025197c5bb95d94e63d55cd43790847b646b23cdf11ada4a00eff15fb48.pem b/net/data/ssl/chrome_root_store/store/certs/9a114025197c5bb95d94e63d55cd43790847b646b23cdf11ada4a00eff15fb48.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/9a114025197c5bb95d94e63d55cd43790847b646b23cdf11ada4a00eff15fb48.pem rename to net/data/ssl/chrome_root_store/store/certs/9a114025197c5bb95d94e63d55cd43790847b646b23cdf11ada4a00eff15fb48.pem
diff --git a/net/data/ssl/chrome_root_store/certs/9a6ec012e1a7da9dbe34194d478ad7c0db1822fb071df12981496ed104384113.pem b/net/data/ssl/chrome_root_store/store/certs/9a6ec012e1a7da9dbe34194d478ad7c0db1822fb071df12981496ed104384113.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/9a6ec012e1a7da9dbe34194d478ad7c0db1822fb071df12981496ed104384113.pem rename to net/data/ssl/chrome_root_store/store/certs/9a6ec012e1a7da9dbe34194d478ad7c0db1822fb071df12981496ed104384113.pem
diff --git a/net/data/ssl/chrome_root_store/certs/9bea11c976fe014764c1be56a6f914b5a560317abd9988393382e5161aa0493c.pem b/net/data/ssl/chrome_root_store/store/certs/9bea11c976fe014764c1be56a6f914b5a560317abd9988393382e5161aa0493c.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/9bea11c976fe014764c1be56a6f914b5a560317abd9988393382e5161aa0493c.pem rename to net/data/ssl/chrome_root_store/store/certs/9bea11c976fe014764c1be56a6f914b5a560317abd9988393382e5161aa0493c.pem
diff --git a/net/data/ssl/chrome_root_store/certs/a040929a02ce53b4acf4f2ffc6981ce4496f755e6d45fe0b2a692bcd52523f36.pem b/net/data/ssl/chrome_root_store/store/certs/a040929a02ce53b4acf4f2ffc6981ce4496f755e6d45fe0b2a692bcd52523f36.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/a040929a02ce53b4acf4f2ffc6981ce4496f755e6d45fe0b2a692bcd52523f36.pem rename to net/data/ssl/chrome_root_store/store/certs/a040929a02ce53b4acf4f2ffc6981ce4496f755e6d45fe0b2a692bcd52523f36.pem
diff --git a/net/data/ssl/chrome_root_store/certs/a1339d33281a0b56e557d3d32b1ce7f9367eb094bd5fa72a7e5004c8ded7cafe.pem b/net/data/ssl/chrome_root_store/store/certs/a1339d33281a0b56e557d3d32b1ce7f9367eb094bd5fa72a7e5004c8ded7cafe.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/a1339d33281a0b56e557d3d32b1ce7f9367eb094bd5fa72a7e5004c8ded7cafe.pem rename to net/data/ssl/chrome_root_store/store/certs/a1339d33281a0b56e557d3d32b1ce7f9367eb094bd5fa72a7e5004c8ded7cafe.pem
diff --git a/net/data/ssl/chrome_root_store/certs/a45ede3bbbf09c8ae15c72efc07268d693a21c996fd51e67ca079460fd6d8873.pem b/net/data/ssl/chrome_root_store/store/certs/a45ede3bbbf09c8ae15c72efc07268d693a21c996fd51e67ca079460fd6d8873.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/a45ede3bbbf09c8ae15c72efc07268d693a21c996fd51e67ca079460fd6d8873.pem rename to net/data/ssl/chrome_root_store/store/certs/a45ede3bbbf09c8ae15c72efc07268d693a21c996fd51e67ca079460fd6d8873.pem
diff --git a/net/data/ssl/chrome_root_store/certs/b0bfd52bb0d7d9bd92bf5d4dc13da255c02c542f378365ea893911f55e55f23c.pem b/net/data/ssl/chrome_root_store/store/certs/b0bfd52bb0d7d9bd92bf5d4dc13da255c02c542f378365ea893911f55e55f23c.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/b0bfd52bb0d7d9bd92bf5d4dc13da255c02c542f378365ea893911f55e55f23c.pem rename to net/data/ssl/chrome_root_store/store/certs/b0bfd52bb0d7d9bd92bf5d4dc13da255c02c542f378365ea893911f55e55f23c.pem
diff --git a/net/data/ssl/chrome_root_store/certs/b676f2eddae8775cd36cb0f63cd1d4603961f49e6265ba013a2f0307b6d0b804.pem b/net/data/ssl/chrome_root_store/store/certs/b676f2eddae8775cd36cb0f63cd1d4603961f49e6265ba013a2f0307b6d0b804.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/b676f2eddae8775cd36cb0f63cd1d4603961f49e6265ba013a2f0307b6d0b804.pem rename to net/data/ssl/chrome_root_store/store/certs/b676f2eddae8775cd36cb0f63cd1d4603961f49e6265ba013a2f0307b6d0b804.pem
diff --git a/net/data/ssl/chrome_root_store/certs/bc104f15a48be709dca542a7e1d4b9df6f054527e802eaa92d595444258afe71.pem b/net/data/ssl/chrome_root_store/store/certs/bc104f15a48be709dca542a7e1d4b9df6f054527e802eaa92d595444258afe71.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/bc104f15a48be709dca542a7e1d4b9df6f054527e802eaa92d595444258afe71.pem rename to net/data/ssl/chrome_root_store/store/certs/bc104f15a48be709dca542a7e1d4b9df6f054527e802eaa92d595444258afe71.pem
diff --git a/net/data/ssl/chrome_root_store/certs/bc4d809b15189d78db3e1d8cf4f9726a795da1643ca5f1358e1ddb0edc0d7eb3.pem b/net/data/ssl/chrome_root_store/store/certs/bc4d809b15189d78db3e1d8cf4f9726a795da1643ca5f1358e1ddb0edc0d7eb3.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/bc4d809b15189d78db3e1d8cf4f9726a795da1643ca5f1358e1ddb0edc0d7eb3.pem rename to net/data/ssl/chrome_root_store/store/certs/bc4d809b15189d78db3e1d8cf4f9726a795da1643ca5f1358e1ddb0edc0d7eb3.pem
diff --git a/net/data/ssl/chrome_root_store/certs/bd71fdf6da97e4cf62d1647add2581b07d79adf8397eb4ecba9c5e8488821423.pem b/net/data/ssl/chrome_root_store/store/certs/bd71fdf6da97e4cf62d1647add2581b07d79adf8397eb4ecba9c5e8488821423.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/bd71fdf6da97e4cf62d1647add2581b07d79adf8397eb4ecba9c5e8488821423.pem rename to net/data/ssl/chrome_root_store/store/certs/bd71fdf6da97e4cf62d1647add2581b07d79adf8397eb4ecba9c5e8488821423.pem
diff --git a/net/data/ssl/chrome_root_store/certs/be6c4da2bbb9ba59b6f3939768374246c3c005993fa98f020d1dedbed48a81d5.pem b/net/data/ssl/chrome_root_store/store/certs/be6c4da2bbb9ba59b6f3939768374246c3c005993fa98f020d1dedbed48a81d5.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/be6c4da2bbb9ba59b6f3939768374246c3c005993fa98f020d1dedbed48a81d5.pem rename to net/data/ssl/chrome_root_store/store/certs/be6c4da2bbb9ba59b6f3939768374246c3c005993fa98f020d1dedbed48a81d5.pem
diff --git a/net/data/ssl/chrome_root_store/certs/beb00b30839b9bc32c32e4447905950641f26421b15ed089198b518ae2ea1b99.pem b/net/data/ssl/chrome_root_store/store/certs/beb00b30839b9bc32c32e4447905950641f26421b15ed089198b518ae2ea1b99.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/beb00b30839b9bc32c32e4447905950641f26421b15ed089198b518ae2ea1b99.pem rename to net/data/ssl/chrome_root_store/store/certs/beb00b30839b9bc32c32e4447905950641f26421b15ed089198b518ae2ea1b99.pem
diff --git a/net/data/ssl/chrome_root_store/certs/bec94911c2955676db6c0a550986d76e3ba005667c442c9762b4fbb773de228c.pem b/net/data/ssl/chrome_root_store/store/certs/bec94911c2955676db6c0a550986d76e3ba005667c442c9762b4fbb773de228c.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/bec94911c2955676db6c0a550986d76e3ba005667c442c9762b4fbb773de228c.pem rename to net/data/ssl/chrome_root_store/store/certs/bec94911c2955676db6c0a550986d76e3ba005667c442c9762b4fbb773de228c.pem
diff --git a/net/data/ssl/chrome_root_store/certs/bf0feefb9e3a581ad5f9e9db7589985743d261085c4d314f6f5d7259aa421612.pem b/net/data/ssl/chrome_root_store/store/certs/bf0feefb9e3a581ad5f9e9db7589985743d261085c4d314f6f5d7259aa421612.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/bf0feefb9e3a581ad5f9e9db7589985743d261085c4d314f6f5d7259aa421612.pem rename to net/data/ssl/chrome_root_store/store/certs/bf0feefb9e3a581ad5f9e9db7589985743d261085c4d314f6f5d7259aa421612.pem
diff --git a/net/data/ssl/chrome_root_store/certs/bfd88fe1101c41ae3e801bf8be56350ee9bad1a6b9bd515edc5c6d5b8711ac44.pem b/net/data/ssl/chrome_root_store/store/certs/bfd88fe1101c41ae3e801bf8be56350ee9bad1a6b9bd515edc5c6d5b8711ac44.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/bfd88fe1101c41ae3e801bf8be56350ee9bad1a6b9bd515edc5c6d5b8711ac44.pem rename to net/data/ssl/chrome_root_store/store/certs/bfd88fe1101c41ae3e801bf8be56350ee9bad1a6b9bd515edc5c6d5b8711ac44.pem
diff --git a/net/data/ssl/chrome_root_store/certs/bfff8fd04433487d6a8aa60c1a29767a9fc2bbb05e420f713a13b992891d3893.pem b/net/data/ssl/chrome_root_store/store/certs/bfff8fd04433487d6a8aa60c1a29767a9fc2bbb05e420f713a13b992891d3893.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/bfff8fd04433487d6a8aa60c1a29767a9fc2bbb05e420f713a13b992891d3893.pem rename to net/data/ssl/chrome_root_store/store/certs/bfff8fd04433487d6a8aa60c1a29767a9fc2bbb05e420f713a13b992891d3893.pem
diff --git a/net/data/ssl/chrome_root_store/certs/c0a6f4dc63a24bfdcf54ef2a6a082a0a72de35803e2ff5ff527ae5d87206dfd5.pem b/net/data/ssl/chrome_root_store/store/certs/c0a6f4dc63a24bfdcf54ef2a6a082a0a72de35803e2ff5ff527ae5d87206dfd5.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/c0a6f4dc63a24bfdcf54ef2a6a082a0a72de35803e2ff5ff527ae5d87206dfd5.pem rename to net/data/ssl/chrome_root_store/store/certs/c0a6f4dc63a24bfdcf54ef2a6a082a0a72de35803e2ff5ff527ae5d87206dfd5.pem
diff --git a/net/data/ssl/chrome_root_store/certs/c3846bf24b9e93ca64274c0ec67c1ecc5e024ffcacd2d74019350e81fe546ae4.pem b/net/data/ssl/chrome_root_store/store/certs/c3846bf24b9e93ca64274c0ec67c1ecc5e024ffcacd2d74019350e81fe546ae4.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/c3846bf24b9e93ca64274c0ec67c1ecc5e024ffcacd2d74019350e81fe546ae4.pem rename to net/data/ssl/chrome_root_store/store/certs/c3846bf24b9e93ca64274c0ec67c1ecc5e024ffcacd2d74019350e81fe546ae4.pem
diff --git a/net/data/ssl/chrome_root_store/certs/c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60.pem b/net/data/ssl/chrome_root_store/store/certs/c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60.pem rename to net/data/ssl/chrome_root_store/store/certs/c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60.pem
diff --git a/net/data/ssl/chrome_root_store/certs/c741f70f4b2a8d88bf2e71c14122ef53ef10eba0cfa5e64cfa20f418853073e0.pem b/net/data/ssl/chrome_root_store/store/certs/c741f70f4b2a8d88bf2e71c14122ef53ef10eba0cfa5e64cfa20f418853073e0.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/c741f70f4b2a8d88bf2e71c14122ef53ef10eba0cfa5e64cfa20f418853073e0.pem rename to net/data/ssl/chrome_root_store/store/certs/c741f70f4b2a8d88bf2e71c14122ef53ef10eba0cfa5e64cfa20f418853073e0.pem
diff --git a/net/data/ssl/chrome_root_store/certs/ca42dd41745fd0b81eb902362cf9d8bf719da1bd1b1efc946f5b4c99f42c1b9e.pem b/net/data/ssl/chrome_root_store/store/certs/ca42dd41745fd0b81eb902362cf9d8bf719da1bd1b1efc946f5b4c99f42c1b9e.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/ca42dd41745fd0b81eb902362cf9d8bf719da1bd1b1efc946f5b4c99f42c1b9e.pem rename to net/data/ssl/chrome_root_store/store/certs/ca42dd41745fd0b81eb902362cf9d8bf719da1bd1b1efc946f5b4c99f42c1b9e.pem
diff --git a/net/data/ssl/chrome_root_store/certs/cb3ccbb76031e5e0138f8dd39a23f9de47ffc35e43c1144cea27d46a5ab1cb5f.pem b/net/data/ssl/chrome_root_store/store/certs/cb3ccbb76031e5e0138f8dd39a23f9de47ffc35e43c1144cea27d46a5ab1cb5f.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/cb3ccbb76031e5e0138f8dd39a23f9de47ffc35e43c1144cea27d46a5ab1cb5f.pem rename to net/data/ssl/chrome_root_store/store/certs/cb3ccbb76031e5e0138f8dd39a23f9de47ffc35e43c1144cea27d46a5ab1cb5f.pem
diff --git a/net/data/ssl/chrome_root_store/certs/cbb522d7b7f127ad6a0113865bdf1cd4102e7d0759af635a7cf4720dc963c53b.pem b/net/data/ssl/chrome_root_store/store/certs/cbb522d7b7f127ad6a0113865bdf1cd4102e7d0759af635a7cf4720dc963c53b.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/cbb522d7b7f127ad6a0113865bdf1cd4102e7d0759af635a7cf4720dc963c53b.pem rename to net/data/ssl/chrome_root_store/store/certs/cbb522d7b7f127ad6a0113865bdf1cd4102e7d0759af635a7cf4720dc963c53b.pem
diff --git a/net/data/ssl/chrome_root_store/certs/cecddc905099d8dadfc5b1d209b737cbe2c18cfb2c10c0ff0bcf0d3286fc1aa2.pem b/net/data/ssl/chrome_root_store/store/certs/cecddc905099d8dadfc5b1d209b737cbe2c18cfb2c10c0ff0bcf0d3286fc1aa2.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/cecddc905099d8dadfc5b1d209b737cbe2c18cfb2c10c0ff0bcf0d3286fc1aa2.pem rename to net/data/ssl/chrome_root_store/store/certs/cecddc905099d8dadfc5b1d209b737cbe2c18cfb2c10c0ff0bcf0d3286fc1aa2.pem
diff --git a/net/data/ssl/chrome_root_store/certs/d40e9c86cd8fe468c1776959f49ea774fa548684b6c406f3909261f4dce2575c.pem b/net/data/ssl/chrome_root_store/store/certs/d40e9c86cd8fe468c1776959f49ea774fa548684b6c406f3909261f4dce2575c.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/d40e9c86cd8fe468c1776959f49ea774fa548684b6c406f3909261f4dce2575c.pem rename to net/data/ssl/chrome_root_store/store/certs/d40e9c86cd8fe468c1776959f49ea774fa548684b6c406f3909261f4dce2575c.pem
diff --git a/net/data/ssl/chrome_root_store/certs/d43af9b35473755c9684fc06d7d8cb70ee5c28e773fb294eb41ee71722924d24.pem b/net/data/ssl/chrome_root_store/store/certs/d43af9b35473755c9684fc06d7d8cb70ee5c28e773fb294eb41ee71722924d24.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/d43af9b35473755c9684fc06d7d8cb70ee5c28e773fb294eb41ee71722924d24.pem rename to net/data/ssl/chrome_root_store/store/certs/d43af9b35473755c9684fc06d7d8cb70ee5c28e773fb294eb41ee71722924d24.pem
diff --git a/net/data/ssl/chrome_root_store/certs/d48d3d23eedb50a459e55197601c27774b9d7b18c94d5a059511a10250b93168.pem b/net/data/ssl/chrome_root_store/store/certs/d48d3d23eedb50a459e55197601c27774b9d7b18c94d5a059511a10250b93168.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/d48d3d23eedb50a459e55197601c27774b9d7b18c94d5a059511a10250b93168.pem rename to net/data/ssl/chrome_root_store/store/certs/d48d3d23eedb50a459e55197601c27774b9d7b18c94d5a059511a10250b93168.pem
diff --git a/net/data/ssl/chrome_root_store/certs/d7a7a0fb5d7e2731d771e9484ebcdef71d5f0c3e0a2948782bc83ee0ea699ef4.pem b/net/data/ssl/chrome_root_store/store/certs/d7a7a0fb5d7e2731d771e9484ebcdef71d5f0c3e0a2948782bc83ee0ea699ef4.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/d7a7a0fb5d7e2731d771e9484ebcdef71d5f0c3e0a2948782bc83ee0ea699ef4.pem rename to net/data/ssl/chrome_root_store/store/certs/d7a7a0fb5d7e2731d771e9484ebcdef71d5f0c3e0a2948782bc83ee0ea699ef4.pem
diff --git a/net/data/ssl/chrome_root_store/certs/db3517d1f6732a2d5ab97c533ec70779ee3270a62fb4ac4238372460e6f01e88.pem b/net/data/ssl/chrome_root_store/store/certs/db3517d1f6732a2d5ab97c533ec70779ee3270a62fb4ac4238372460e6f01e88.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/db3517d1f6732a2d5ab97c533ec70779ee3270a62fb4ac4238372460e6f01e88.pem rename to net/data/ssl/chrome_root_store/store/certs/db3517d1f6732a2d5ab97c533ec70779ee3270a62fb4ac4238372460e6f01e88.pem
diff --git a/net/data/ssl/chrome_root_store/certs/dd6936fe21f8f077c123a1a521c12224f72255b73e03a7260693e8a24b0fa389.pem b/net/data/ssl/chrome_root_store/store/certs/dd6936fe21f8f077c123a1a521c12224f72255b73e03a7260693e8a24b0fa389.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/dd6936fe21f8f077c123a1a521c12224f72255b73e03a7260693e8a24b0fa389.pem rename to net/data/ssl/chrome_root_store/store/certs/dd6936fe21f8f077c123a1a521c12224f72255b73e03a7260693e8a24b0fa389.pem
diff --git a/net/data/ssl/chrome_root_store/certs/e23d4a036d7b70e9f595b1422079d2b91edfbb1fb651a0633eaa8a9dc5f80703.pem b/net/data/ssl/chrome_root_store/store/certs/e23d4a036d7b70e9f595b1422079d2b91edfbb1fb651a0633eaa8a9dc5f80703.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/e23d4a036d7b70e9f595b1422079d2b91edfbb1fb651a0633eaa8a9dc5f80703.pem rename to net/data/ssl/chrome_root_store/store/certs/e23d4a036d7b70e9f595b1422079d2b91edfbb1fb651a0633eaa8a9dc5f80703.pem
diff --git a/net/data/ssl/chrome_root_store/certs/e35d28419ed02025cfa69038cd623962458da5c695fbdea3c22b0bfb25897092.pem b/net/data/ssl/chrome_root_store/store/certs/e35d28419ed02025cfa69038cd623962458da5c695fbdea3c22b0bfb25897092.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/e35d28419ed02025cfa69038cd623962458da5c695fbdea3c22b0bfb25897092.pem rename to net/data/ssl/chrome_root_store/store/certs/e35d28419ed02025cfa69038cd623962458da5c695fbdea3c22b0bfb25897092.pem
diff --git a/net/data/ssl/chrome_root_store/certs/e3b6a2db2ed7ce48842f7ac53241c7b71d54144bfb40c11f3f1d0b42f5eea12d.pem b/net/data/ssl/chrome_root_store/store/certs/e3b6a2db2ed7ce48842f7ac53241c7b71d54144bfb40c11f3f1d0b42f5eea12d.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/e3b6a2db2ed7ce48842f7ac53241c7b71d54144bfb40c11f3f1d0b42f5eea12d.pem rename to net/data/ssl/chrome_root_store/store/certs/e3b6a2db2ed7ce48842f7ac53241c7b71d54144bfb40c11f3f1d0b42f5eea12d.pem
diff --git a/net/data/ssl/chrome_root_store/certs/e75e72ed9f560eec6eb4800073a43fc3ad19195a392282017895974a99026b6c.pem b/net/data/ssl/chrome_root_store/store/certs/e75e72ed9f560eec6eb4800073a43fc3ad19195a392282017895974a99026b6c.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/e75e72ed9f560eec6eb4800073a43fc3ad19195a392282017895974a99026b6c.pem rename to net/data/ssl/chrome_root_store/store/certs/e75e72ed9f560eec6eb4800073a43fc3ad19195a392282017895974a99026b6c.pem
diff --git a/net/data/ssl/chrome_root_store/certs/e793c9b02fd8aa13e21c31228accb08119643b749c898964b1746d46c3d4cbd2.pem b/net/data/ssl/chrome_root_store/store/certs/e793c9b02fd8aa13e21c31228accb08119643b749c898964b1746d46c3d4cbd2.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/e793c9b02fd8aa13e21c31228accb08119643b749c898964b1746d46c3d4cbd2.pem rename to net/data/ssl/chrome_root_store/store/certs/e793c9b02fd8aa13e21c31228accb08119643b749c898964b1746d46c3d4cbd2.pem
diff --git a/net/data/ssl/chrome_root_store/certs/eaa962c4fa4a6bafebe415196d351ccd888d4f53f3fa8ae6d7c466a94e6042bb.pem b/net/data/ssl/chrome_root_store/store/certs/eaa962c4fa4a6bafebe415196d351ccd888d4f53f3fa8ae6d7c466a94e6042bb.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/eaa962c4fa4a6bafebe415196d351ccd888d4f53f3fa8ae6d7c466a94e6042bb.pem rename to net/data/ssl/chrome_root_store/store/certs/eaa962c4fa4a6bafebe415196d351ccd888d4f53f3fa8ae6d7c466a94e6042bb.pem
diff --git a/net/data/ssl/chrome_root_store/certs/ebc5570c29018c4d67b1aa127baf12f703b4611ebc17b7dab5573894179b93fa.pem b/net/data/ssl/chrome_root_store/store/certs/ebc5570c29018c4d67b1aa127baf12f703b4611ebc17b7dab5573894179b93fa.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/ebc5570c29018c4d67b1aa127baf12f703b4611ebc17b7dab5573894179b93fa.pem rename to net/data/ssl/chrome_root_store/store/certs/ebc5570c29018c4d67b1aa127baf12f703b4611ebc17b7dab5573894179b93fa.pem
diff --git a/net/data/ssl/chrome_root_store/certs/ebd41040e4bb3ec742c9e381d31ef2a41a48b6685c96e7cef3c1df6cd4331c99.pem b/net/data/ssl/chrome_root_store/store/certs/ebd41040e4bb3ec742c9e381d31ef2a41a48b6685c96e7cef3c1df6cd4331c99.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/ebd41040e4bb3ec742c9e381d31ef2a41a48b6685c96e7cef3c1df6cd4331c99.pem rename to net/data/ssl/chrome_root_store/store/certs/ebd41040e4bb3ec742c9e381d31ef2a41a48b6685c96e7cef3c1df6cd4331c99.pem
diff --git a/net/data/ssl/chrome_root_store/certs/edf7ebbca27a2a384d387b7d4010c666e2edb4843e4c29b4ae1d5b9332e6b24d.pem b/net/data/ssl/chrome_root_store/store/certs/edf7ebbca27a2a384d387b7d4010c666e2edb4843e4c29b4ae1d5b9332e6b24d.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/edf7ebbca27a2a384d387b7d4010c666e2edb4843e4c29b4ae1d5b9332e6b24d.pem rename to net/data/ssl/chrome_root_store/store/certs/edf7ebbca27a2a384d387b7d4010c666e2edb4843e4c29b4ae1d5b9332e6b24d.pem
diff --git a/net/data/ssl/chrome_root_store/certs/eec5496b988ce98625b934092eec2908bed0b0f316c2d4730c84eaf1f3d34881.pem b/net/data/ssl/chrome_root_store/store/certs/eec5496b988ce98625b934092eec2908bed0b0f316c2d4730c84eaf1f3d34881.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/eec5496b988ce98625b934092eec2908bed0b0f316c2d4730c84eaf1f3d34881.pem rename to net/data/ssl/chrome_root_store/store/certs/eec5496b988ce98625b934092eec2908bed0b0f316c2d4730c84eaf1f3d34881.pem
diff --git a/net/data/ssl/chrome_root_store/certs/f1c1b50ae5a20dd8030ec9f6bc24823dd367b5255759b4e71b61fce9f7375d73.pem b/net/data/ssl/chrome_root_store/store/certs/f1c1b50ae5a20dd8030ec9f6bc24823dd367b5255759b4e71b61fce9f7375d73.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/f1c1b50ae5a20dd8030ec9f6bc24823dd367b5255759b4e71b61fce9f7375d73.pem rename to net/data/ssl/chrome_root_store/store/certs/f1c1b50ae5a20dd8030ec9f6bc24823dd367b5255759b4e71b61fce9f7375d73.pem
diff --git a/net/data/ssl/chrome_root_store/certs/f356bea244b7a91eb35d53ca9ad7864ace018e2d35d5f8f96ddf68a6f41aa474.pem b/net/data/ssl/chrome_root_store/store/certs/f356bea244b7a91eb35d53ca9ad7864ace018e2d35d5f8f96ddf68a6f41aa474.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/f356bea244b7a91eb35d53ca9ad7864ace018e2d35d5f8f96ddf68a6f41aa474.pem rename to net/data/ssl/chrome_root_store/store/certs/f356bea244b7a91eb35d53ca9ad7864ace018e2d35d5f8f96ddf68a6f41aa474.pem
diff --git a/net/data/ssl/chrome_root_store/certs/f9e67d336c51002ac054c632022d66dda2e7e3fff10ad061ed31d8bbb410cfb2.pem b/net/data/ssl/chrome_root_store/store/certs/f9e67d336c51002ac054c632022d66dda2e7e3fff10ad061ed31d8bbb410cfb2.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/f9e67d336c51002ac054c632022d66dda2e7e3fff10ad061ed31d8bbb410cfb2.pem rename to net/data/ssl/chrome_root_store/store/certs/f9e67d336c51002ac054c632022d66dda2e7e3fff10ad061ed31d8bbb410cfb2.pem
diff --git a/net/data/ssl/chrome_root_store/certs/fd73dad31c644ff1b43bef0ccdda96710b9cd9875eca7e31707af3e96d522bbd.pem b/net/data/ssl/chrome_root_store/store/certs/fd73dad31c644ff1b43bef0ccdda96710b9cd9875eca7e31707af3e96d522bbd.pem similarity index 100% rename from net/data/ssl/chrome_root_store/certs/fd73dad31c644ff1b43bef0ccdda96710b9cd9875eca7e31707af3e96d522bbd.pem rename to net/data/ssl/chrome_root_store/store/certs/fd73dad31c644ff1b43bef0ccdda96710b9cd9875eca7e31707af3e96d522bbd.pem
diff --git a/net/data/ssl/chrome_root_store/root_store.textproto b/net/data/ssl/chrome_root_store/store/root_store.textproto similarity index 100% rename from net/data/ssl/chrome_root_store/root_store.textproto rename to net/data/ssl/chrome_root_store/store/root_store.textproto
diff --git a/net/data/ssl/chrome_root_store/testdata/568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5.pem b/net/data/ssl/chrome_root_store/testdata/certs/568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5.pem similarity index 100% rename from net/data/ssl/chrome_root_store/testdata/568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5.pem rename to net/data/ssl/chrome_root_store/testdata/certs/568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5.pem
diff --git a/net/data/ssl/chrome_root_store/testdata/6b9c08e86eb0f767cfad65cd98b62149e5494a67f5845e7bd1ed019f27b86bd6.pem b/net/data/ssl/chrome_root_store/testdata/certs/6b9c08e86eb0f767cfad65cd98b62149e5494a67f5845e7bd1ed019f27b86bd6.pem similarity index 100% rename from net/data/ssl/chrome_root_store/testdata/6b9c08e86eb0f767cfad65cd98b62149e5494a67f5845e7bd1ed019f27b86bd6.pem rename to net/data/ssl/chrome_root_store/testdata/certs/6b9c08e86eb0f767cfad65cd98b62149e5494a67f5845e7bd1ed019f27b86bd6.pem
diff --git a/net/data/ssl/chrome_root_store/testdata/c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60.pem b/net/data/ssl/chrome_root_store/testdata/certs/c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60.pem similarity index 100% rename from net/data/ssl/chrome_root_store/testdata/c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60.pem rename to net/data/ssl/chrome_root_store/testdata/certs/c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60.pem
diff --git a/net/data/ssl/chrome_root_store/root_store_testdata.textproto b/net/data/ssl/chrome_root_store/testdata/root_store.textproto similarity index 100% rename from net/data/ssl/chrome_root_store/root_store_testdata.textproto rename to net/data/ssl/chrome_root_store/testdata/root_store.textproto
diff --git a/net/tools/root_store_tool/root_store_tool.cc b/net/tools/root_store_tool/root_store_tool.cc index 5ef39cf..70bed92 100644 --- a/net/tools/root_store_tool/root_store_tool.cc +++ b/net/tools/root_store_tool/root_store_tool.cc
@@ -55,11 +55,9 @@ } absl::optional<RootStore> ReadTextRootStore( - const base::FilePath& root_store_dir, - const std::string certs_sub_dir, - const std::string root_store_filename) { + const base::FilePath& root_store_dir) { base::FilePath root_store_path = - root_store_dir.AppendASCII(root_store_filename); + root_store_dir.AppendASCII("root_store.textproto"); std::string root_store_text; if (!base::ReadFileToString(root_store_path, &root_store_text)) { LOG(ERROR) << "Could not read " << root_store_path; @@ -74,7 +72,7 @@ } // Replace the filenames with the actual certificate contents. - base::FilePath certs_dir = root_store_dir.AppendASCII(certs_sub_dir); + base::FilePath certs_dir = root_store_dir.AppendASCII("certs"); for (auto& anchor : *root_store.mutable_trust_anchors()) { base::FilePath pem_path = certs_dir.AppendASCII(anchor.filename()); @@ -127,38 +125,37 @@ base::FilePath cpp_path = command_line.GetSwitchValuePath("write-cpp"); if ((proto_path.empty() && cpp_path.empty()) || command_line.HasSwitch("help")) { - std::cerr << "Usage: root_store_tool [--write-proto=PROTO_FILE] " + std::cerr << "Usage: root_store_tool " + "[--root-store-dir=<relative-path>] + "[--write-proto=PROTO_FILE] " "[--write-cpp=CPP_FILE]" << std::endl; return 1; } - // TODO(hchao): simplify command line options to just specify a single - // directory which stores the textproto and certs (possibly in different - // subdirectories), and have tool assume a structure from there. + // Find root store directory. Assumptions: + // - Root store directory is relative to base::DIR_SOURCE_ROOT + // + // - $(ROOT_STORE_DIR)/root_store.textproto contains the textproto definition + // of the root store + // + // - Any certificate files referenced in + // $(ROOT_STORE_DIR)/root_store.textproto exist in the + // $(ROOT_STORE_DIR)/certs/ subdirectory. base::FilePath root_store_dir = command_line.GetSwitchValuePath("root-store-dir"); + base::FilePath source_root; + CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &source_root)); if (root_store_dir.empty()) { - base::FilePath source_root; - CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &source_root)); root_store_dir = source_root.AppendASCII("net") .AppendASCII("data") .AppendASCII("ssl") - .AppendASCII("chrome_root_store"); + .AppendASCII("chrome_root_store") + .AppendASCII("base"); + } else { + root_store_dir = source_root.Append(root_store_dir); } - std::string certs_sub_dir = command_line.GetSwitchValueASCII("certs-sub-dir"); - if (certs_sub_dir.empty()) { - certs_sub_dir = "certs"; - } - - std::string root_store_filename = - command_line.GetSwitchValueASCII("root-store-filename"); - if (root_store_filename.empty()) { - root_store_filename = "root_store.textproto"; - } - - absl::optional<RootStore> root_store = - ReadTextRootStore(root_store_dir, certs_sub_dir, root_store_filename); + absl::optional<RootStore> root_store = ReadTextRootStore(root_store_dir); if (!root_store) { return 1; }
diff --git a/printing/android/java/src/org/chromium/printing/PrintManagerDelegateImpl.java b/printing/android/java/src/org/chromium/printing/PrintManagerDelegateImpl.java index 2f03cee..150b4d75eb 100644 --- a/printing/android/java/src/org/chromium/printing/PrintManagerDelegateImpl.java +++ b/printing/android/java/src/org/chromium/printing/PrintManagerDelegateImpl.java
@@ -16,7 +16,6 @@ import android.text.TextUtils; import org.chromium.base.Log; -import org.chromium.base.annotations.RemovableInRelease; import java.util.List; @@ -39,8 +38,9 @@ mPrintManager.print(printJobName, documentAdapter, attributes); } - @RemovableInRelease private void dumpJobStatesForDebug() { + if (!Log.isLoggable(TAG, Log.VERBOSE)) return; + List<PrintJob> printJobs = mPrintManager.getPrintJobs(); String[] states = new String[printJobs.size()];
diff --git a/services/audio/public/cpp/audio_system_to_service_adapter.cc b/services/audio/public/cpp/audio_system_to_service_adapter.cc index 67c8586..2e6379d 100644 --- a/services/audio/public/cpp/audio_system_to_service_adapter.cc +++ b/services/audio/public/cpp/audio_system_to_service_adapter.cc
@@ -76,19 +76,21 @@ const Action action = (stream_type == kInput) ? kGetInputStreamParameters : kGetOutputStreamParameters; const base::TimeTicks start_time = base::TimeTicks::Now(); - TRACE_EVENT_ASYNC_BEGIN1("audio", GetTraceEvent(action), - ToTraceId(start_time), "device id", device_id); + const char* name = GetTraceEvent(action); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( + "audio", name, TRACE_ID_WITH_SCOPE(name, ToTraceId(start_time)), + "device id", device_id); return base::BindOnce( - [](Action action, base::TimeTicks start_time, + [](const char* name, base::TimeTicks start_time, OnAudioParamsCallback on_params_callback, const absl::optional<media::AudioParameters>& params) { - TRACE_EVENT_ASYNC_END1("audio", GetTraceEvent(action), - ToTraceId(start_time), "params", - ParamsToString(params)); + TRACE_EVENT_NESTABLE_ASYNC_END1( + "audio", name, TRACE_ID_WITH_SCOPE(name, ToTraceId(start_time)), + "params", ParamsToString(params)); std::move(on_params_callback).Run(params); }, - action, start_time, std::move(on_params_callback)); + name, start_time, std::move(on_params_callback)); } OnBoolCallback WrapHasDevicesReply(StreamType stream_type, @@ -96,17 +98,19 @@ const Action action = (stream_type == kInput) ? kHasInputDevices : kHasOutputDevices; const base::TimeTicks start_time = base::TimeTicks::Now(); - TRACE_EVENT_ASYNC_BEGIN0("audio", GetTraceEvent(action), - ToTraceId(start_time)); + const char* name = GetTraceEvent(action); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( + "audio", name, TRACE_ID_WITH_SCOPE(name, ToTraceId(start_time))); return base::BindOnce( - [](Action action, base::TimeTicks start_time, + [](const char* name, base::TimeTicks start_time, OnBoolCallback on_has_devices_callback, bool answer) { - TRACE_EVENT_ASYNC_END1("audio", GetTraceEvent(action), - ToTraceId(start_time), "answer", answer); + TRACE_EVENT_NESTABLE_ASYNC_END1( + "audio", name, TRACE_ID_WITH_SCOPE(name, ToTraceId(start_time)), + "answer", answer); std::move(on_has_devices_callback).Run(answer); }, - action, start_time, std::move(on_has_devices_callback)); + name, start_time, std::move(on_has_devices_callback)); } OnDeviceDescriptionsCallback WrapGetDeviceDescriptionsReply( @@ -115,61 +119,65 @@ const Action action = (stream_type == kInput) ? kGetInputDeviceDescriptions : kGetOutputDeviceDescriptions; const base::TimeTicks start_time = base::TimeTicks::Now(); - TRACE_EVENT_ASYNC_BEGIN0("audio", GetTraceEvent(action), - ToTraceId(start_time)); + const char* name = GetTraceEvent(action); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( + "audio", name, TRACE_ID_WITH_SCOPE(name, ToTraceId(start_time))); return base::BindOnce( - [](Action action, base::TimeTicks start_time, + [](const char* name, base::TimeTicks start_time, OnDeviceDescriptionsCallback on_descriptions_callback, media::AudioDeviceDescriptions descriptions) { - TRACE_EVENT_ASYNC_END1("audio", GetTraceEvent(action), - ToTraceId(start_time), "device count", - descriptions.size()); + TRACE_EVENT_NESTABLE_ASYNC_END1( + "audio", name, TRACE_ID_WITH_SCOPE(name, ToTraceId(start_time)), + "device count", descriptions.size()); std::move(on_descriptions_callback).Run(std::move(descriptions)); }, - action, start_time, std::move(on_descriptions_callback)); + name, start_time, std::move(on_descriptions_callback)); } OnDeviceIdCallback WrapGetAssociatedOutputDeviceIDReply( const std::string& input_device_id, OnDeviceIdCallback on_device_id_callback) { const base::TimeTicks start_time = base::TimeTicks::Now(); - TRACE_EVENT_ASYNC_BEGIN1("audio", GetTraceEvent(kGetAssociatedOutputDeviceID), - ToTraceId(start_time), "input_device_id", - input_device_id); + const char* name = GetTraceEvent(kGetAssociatedOutputDeviceID); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( + "audio", name, TRACE_ID_WITH_SCOPE(name, ToTraceId(start_time)), + "input_device_id", input_device_id); return base::BindOnce( - [](base::TimeTicks start_time, OnDeviceIdCallback on_device_id_callback, + [](const char* name, base::TimeTicks start_time, + OnDeviceIdCallback on_device_id_callback, const absl::optional<std::string>& answer) { - TRACE_EVENT_ASYNC_END1( - "audio", GetTraceEvent(kGetAssociatedOutputDeviceID), - ToTraceId(start_time), "answer", answer.value_or("nullopt")); + TRACE_EVENT_NESTABLE_ASYNC_END1( + "audio", name, TRACE_ID_WITH_SCOPE(name, ToTraceId(start_time)), + "answer", answer.value_or("nullopt")); std::move(on_device_id_callback).Run(answer); }, - start_time, std::move(on_device_id_callback)); + name, start_time, std::move(on_device_id_callback)); } OnInputDeviceInfoCallback WrapGetInputDeviceInfoReply( const std::string& input_device_id, OnInputDeviceInfoCallback on_input_device_info_callback) { const base::TimeTicks start_time = base::TimeTicks::Now(); - TRACE_EVENT_ASYNC_BEGIN1("audio", GetTraceEvent(kGetInputDeviceInfo), - ToTraceId(start_time), "input_device_id", - input_device_id); + const char* name = GetTraceEvent(kGetInputDeviceInfo); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( + "audio", name, TRACE_ID_WITH_SCOPE(name, ToTraceId(start_time)), + "input_device_id", input_device_id); return base::BindOnce( - [](base::TimeTicks start_time, + [](const char* name, base::TimeTicks start_time, OnInputDeviceInfoCallback on_input_device_info_callback, const absl::optional<AudioParameters>& params, const absl::optional<std::string>& associated_output_device_id) { - TRACE_EVENT_ASYNC_END2( - "audio", GetTraceEvent(kGetInputDeviceInfo), ToTraceId(start_time), + TRACE_EVENT_NESTABLE_ASYNC_END2( + "audio", name, TRACE_ID_WITH_SCOPE(name, ToTraceId(start_time)), "params", ParamsToString(params), "associated_output_device_id", associated_output_device_id.value_or("nullopt")); std::move(on_input_device_info_callback) .Run(params, associated_output_device_id); }, - start_time, std::move(on_input_device_info_callback)); + name, start_time, std::move(on_input_device_info_callback)); } } // namespace @@ -191,9 +199,9 @@ AudioSystemToServiceAdapter::~AudioSystemToServiceAdapter() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (system_info_.is_bound()) { - TRACE_EVENT_NESTABLE_ASYNC_END1("audio", - "AudioSystemToServiceAdapter bound", this, - "disconnect reason", "destroyed"); + TRACE_EVENT_NESTABLE_ASYNC_END1( + "audio", "AudioSystemToServiceAdapter bound", TRACE_ID_LOCAL(this), + "disconnect reason", "destroyed"); } } @@ -270,7 +278,7 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (!system_info_) { TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( - "audio", "AudioSystemToServiceAdapter bound", this); + "audio", "AudioSystemToServiceAdapter bound", TRACE_ID_LOCAL(this)); system_info_binder_.Run(system_info_.BindNewPipeAndPassReceiver()); system_info_.set_disconnect_handler( base::BindOnce(&AudioSystemToServiceAdapter::OnConnectionError, @@ -285,7 +293,7 @@ void AudioSystemToServiceAdapter::OnConnectionError() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); TRACE_EVENT_NESTABLE_ASYNC_END1("audio", "AudioSystemToServiceAdapter bound", - this, "disconnect reason", + TRACE_ID_LOCAL(this), "disconnect reason", "connection error"); system_info_.reset(); }
diff --git a/services/audio/service_metrics.cc b/services/audio/service_metrics.cc index c63b970..9fe802c 100644 --- a/services/audio/service_metrics.cc +++ b/services/audio/service_metrics.cc
@@ -17,13 +17,15 @@ } void ServiceMetrics::HasConnections() { - TRACE_EVENT_ASYNC_BEGIN0("audio", "Audio service has connections", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("audio", "Audio service has connections", + TRACE_ID_LOCAL(this)); has_connections_start_ = clock_->NowTicks(); LogHasNoConnectionsDuration(); } void ServiceMetrics::HasNoConnections() { - TRACE_EVENT_ASYNC_END0("audio", "Audio service has connections", this); + TRACE_EVENT_NESTABLE_ASYNC_END0("audio", "Audio service has connections", + TRACE_ID_LOCAL(this)); has_no_connections_start_ = clock_->NowTicks(); DCHECK_NE(base::TimeTicks(), has_connections_start_); UMA_HISTOGRAM_CUSTOM_TIMES("Media.AudioService.HasConnectionsDuration",
diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc index 6e4e8ac..8981336 100644 --- a/services/network/cors/cors_url_loader.cc +++ b/services/network/cors/cors_url_loader.cc
@@ -20,6 +20,7 @@ #include "services/network/public/cpp/header_util.h" #include "services/network/public/cpp/request_mode.h" #include "services/network/public/cpp/timing_allow_origin_parser.h" +#include "services/network/public/mojom/devtools_observer.mojom.h" #include "services/network/public/mojom/early_hints.mojom.h" #include "services/network/public/mojom/url_response_head.mojom.h" #include "services/network/trust_tokens/trust_token_operation_metrics_recorder.h"
diff --git a/services/network/cors/cors_url_loader_unittest.cc b/services/network/cors/cors_url_loader_unittest.cc index 9faf68c..8da94317 100644 --- a/services/network/cors/cors_url_loader_unittest.cc +++ b/services/network/cors/cors_url_loader_unittest.cc
@@ -34,6 +34,7 @@ #include "services/network/network_service.h" #include "services/network/public/cpp/parsed_headers.h" #include "services/network/public/mojom/cors.mojom.h" +#include "services/network/public/mojom/devtools_observer.mojom.h" #include "services/network/public/mojom/early_hints.mojom.h" #include "services/network/public/mojom/network_context.mojom.h" #include "services/network/public/mojom/url_loader.mojom.h"
diff --git a/services/network/cors/preflight_controller.cc b/services/network/cors/preflight_controller.cc index 83865d3..cc2338b9 100644 --- a/services/network/cors/preflight_controller.cc +++ b/services/network/cors/preflight_controller.cc
@@ -20,6 +20,7 @@ #include "services/network/public/cpp/cors/cors_error_status.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/simple_url_loader.h" +#include "services/network/public/mojom/devtools_observer.mojom.h" #include "services/network/public/mojom/http_raw_request_response_info.mojom.h" #include "services/network/public/mojom/network_service.mojom.h" #include "services/network/public/mojom/parsed_headers.mojom.h"
diff --git a/services/network/cors/preflight_controller_unittest.cc b/services/network/cors/preflight_controller_unittest.cc index f633a47..f6fabb4 100644 --- a/services/network/cors/preflight_controller_unittest.cc +++ b/services/network/cors/preflight_controller_unittest.cc
@@ -21,6 +21,7 @@ #include "services/network/cors/cors_url_loader_factory.h" #include "services/network/network_service.h" #include "services/network/public/cpp/cors/cors.h" +#include "services/network/public/mojom/devtools_observer.mojom.h" #include "services/network/public/mojom/network_context.mojom.h" #include "services/network/public/mojom/network_service.mojom.h" #include "services/network/public/mojom/url_loader_factory.mojom.h"
diff --git a/services/network/public/cpp/cookie_manager_mojom_traits.cc b/services/network/public/cpp/cookie_manager_mojom_traits.cc index 12951f1a..e9d9705 100644 --- a/services/network/public/cpp/cookie_manager_mojom_traits.cc +++ b/services/network/public/cpp/cookie_manager_mojom_traits.cc
@@ -5,6 +5,7 @@ #include "services/network/public/cpp/cookie_manager_mojom_traits.h" #include "mojo/public/cpp/base/time_mojom_traits.h" +#include "net/cookies/cookie_options.h" #include "net/cookies/same_party_context.h" namespace mojo { @@ -244,6 +245,63 @@ return false; } +network::mojom::CookieSameSiteContextMetadataDowngradeType +EnumTraits<network::mojom::CookieSameSiteContextMetadataDowngradeType, + net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType>:: + ToMojom(net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType input) { + switch (input) { + case net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType::kNoDowngrade: + return network::mojom::CookieSameSiteContextMetadataDowngradeType:: + kNoDowngrade; + case net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType::kStrictToLax: + return network::mojom::CookieSameSiteContextMetadataDowngradeType:: + kStrictToLax; + case net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType::kStrictToCross: + return network::mojom::CookieSameSiteContextMetadataDowngradeType:: + kStrictToCross; + case net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType::kLaxToCross: + return network::mojom::CookieSameSiteContextMetadataDowngradeType:: + kLaxToCross; + } +} + +bool EnumTraits<network::mojom::CookieSameSiteContextMetadataDowngradeType, + net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType>:: + FromMojom(network::mojom::CookieSameSiteContextMetadataDowngradeType input, + net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType* output) { + switch (input) { + case network::mojom::CookieSameSiteContextMetadataDowngradeType:: + kNoDowngrade: + *output = net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType::kNoDowngrade; + return true; + case network::mojom::CookieSameSiteContextMetadataDowngradeType:: + kStrictToLax: + *output = net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType::kStrictToLax; + return true; + case network::mojom::CookieSameSiteContextMetadataDowngradeType:: + kStrictToCross: + *output = net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType::kStrictToCross; + return true; + case network::mojom::CookieSameSiteContextMetadataDowngradeType:: + kLaxToCross: + *output = net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType::kLaxToCross; + return true; + } + return false; +} + network::mojom::CookieChangeCause EnumTraits<network::mojom::CookieChangeCause, net::CookieChangeCause>::ToMojom( net::CookieChangeCause input) { @@ -305,6 +363,8 @@ Read(network::mojom::CookieSameSiteContextMetadataDataView data, net::CookieOptions::SameSiteCookieContext::ContextMetadata* out) { out->affected_by_bugfix_1166211 = data.affected_by_bugfix_1166211(); + if (!data.ReadCrossSiteRedirectDowngrade(&out->cross_site_redirect_downgrade)) + return false; return true; }
diff --git a/services/network/public/cpp/cookie_manager_mojom_traits.h b/services/network/public/cpp/cookie_manager_mojom_traits.h index a63e3d1..bb81d1f2 100644 --- a/services/network/public/cpp/cookie_manager_mojom_traits.h +++ b/services/network/public/cpp/cookie_manager_mojom_traits.h
@@ -61,6 +61,19 @@ }; template <> +struct EnumTraits<network::mojom::CookieSameSiteContextMetadataDowngradeType, + net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType> { + static network::mojom::CookieSameSiteContextMetadataDowngradeType ToMojom( + net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType input); + static bool FromMojom( + network::mojom::CookieSameSiteContextMetadataDowngradeType input, + net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType* output); +}; + +template <> struct EnumTraits<network::mojom::CookieSourceScheme, net::CookieSourceScheme> { static network::mojom::CookieSourceScheme ToMojom( net::CookieSourceScheme input); @@ -86,6 +99,12 @@ const net::CookieOptions::SameSiteCookieContext::ContextMetadata& m) { return m.affected_by_bugfix_1166211; } + static net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType + cross_site_redirect_downgrade( + const net::CookieOptions::SameSiteCookieContext::ContextMetadata& m) { + return m.cross_site_redirect_downgrade; + } static bool Read(network::mojom::CookieSameSiteContextMetadataDataView, net::CookieOptions::SameSiteCookieContext::ContextMetadata*);
diff --git a/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc b/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc index f488c575..5e9ac5b 100644 --- a/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc +++ b/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc
@@ -284,33 +284,87 @@ } } +TEST(CookieManagerTraitsTest, + Roundtrips_CookieSameSiteContextMetadataDowngradeType) { + for (auto type : {net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType::kNoDowngrade, + net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType::kStrictToLax, + net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType::kStrictToCross, + net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType::kLaxToCross}) { + net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType roundtrip; + ASSERT_TRUE(mojo::test::SerializeAndDeserialize< + mojom::CookieSameSiteContextMetadataDowngradeType>(type, + roundtrip)); + EXPECT_EQ(type, roundtrip); + } +} + +TEST(CookieManagerTraitsTest, Roundtrips_CookieSameSiteContextMetadata) { + net::CookieOptions::SameSiteCookieContext::ContextMetadata metadata, + roundtrip; + + // Default values. + ASSERT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::CookieSameSiteContextMetadata>( + metadata, roundtrip)); + EXPECT_EQ(metadata, roundtrip); + + metadata.affected_by_bugfix_1166211 = true; + metadata.cross_site_redirect_downgrade = + net::CookieOptions::SameSiteCookieContext::ContextMetadata:: + ContextDowngradeType::kStrictToLax; + ASSERT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::CookieSameSiteContextMetadata>( + metadata, roundtrip)); + EXPECT_EQ(metadata, roundtrip); +} + TEST(CookieManagerTraitsTest, Roundtrips_CookieSameSiteContext) { using ContextType = net::CookieOptions::SameSiteCookieContext::ContextType; + using ContextMetadata = + net::CookieOptions::SameSiteCookieContext::ContextMetadata; const ContextType all_context_types[]{ ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX_METHOD_UNSAFE, ContextType::SAME_SITE_LAX, ContextType::SAME_SITE_STRICT}; - for (bool metadata_affected_by_bugfix_1166211 : {true, false}) { - net::CookieOptions::SameSiteCookieContext::ContextMetadata metadata; - metadata.affected_by_bugfix_1166211 = metadata_affected_by_bugfix_1166211; - for (ContextType context_type : all_context_types) { - for (ContextType schemeful_context_type : all_context_types) { - net::CookieOptions::SameSiteCookieContext copy; - net::CookieOptions::SameSiteCookieContext context_in( - context_type, context_type, metadata, metadata); - // We want to test malformed SameSiteCookieContexts. Since the - // constructor will DCHECK for these use this setter to bypass it. - context_in.SetContextTypesForTesting(context_type, - schemeful_context_type); + ContextMetadata metadata1; + metadata1.affected_by_bugfix_1166211 = true; + ContextMetadata metadata2; + metadata2.cross_site_redirect_downgrade = + ContextMetadata::ContextDowngradeType::kStrictToLax; + ContextMetadata metadata3; + metadata3.affected_by_bugfix_1166211 = true; + metadata3.cross_site_redirect_downgrade = + ContextMetadata::ContextDowngradeType::kLaxToCross; - EXPECT_EQ( - mojo::test::SerializeAndDeserialize<mojom::CookieSameSiteContext>( - context_in, copy), - schemeful_context_type <= context_type); + const ContextMetadata metadatas[]{ContextMetadata(), metadata1, metadata2, + metadata3}; - if (schemeful_context_type <= context_type) - EXPECT_TRUE(context_in.CompleteEquivalenceForTesting(copy)); + for (ContextType context_type : all_context_types) { + for (ContextType schemeful_context_type : all_context_types) { + for (const ContextMetadata& metadata : metadatas) { + for (const ContextMetadata& schemeful_metadata : metadatas) { + net::CookieOptions::SameSiteCookieContext copy; + net::CookieOptions::SameSiteCookieContext context_in( + context_type, context_type, metadata, schemeful_metadata); + // We want to test malformed SameSiteCookieContexts. Since the + // constructor will DCHECK for these use this setter to bypass it. + context_in.SetContextTypesForTesting(context_type, + schemeful_context_type); + + EXPECT_EQ( + mojo::test::SerializeAndDeserialize<mojom::CookieSameSiteContext>( + context_in, copy), + schemeful_context_type <= context_type); + + if (schemeful_context_type <= context_type) + EXPECT_TRUE(context_in.CompleteEquivalenceForTesting(copy)); + } } } }
diff --git a/services/network/public/cpp/resource_request.cc b/services/network/public/cpp/resource_request.cc index 13c90fe5..184b026 100644 --- a/services/network/public/cpp/resource_request.cc +++ b/services/network/public/cpp/resource_request.cc
@@ -9,6 +9,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/load_flags.h" #include "services/network/public/mojom/cookie_access_observer.mojom.h" +#include "services/network/public/mojom/devtools_observer.mojom.h" #include "services/network/public/mojom/url_request.mojom.h" #include "services/network/public/mojom/web_bundle_handle.mojom.h"
diff --git a/services/network/public/cpp/resource_request.h b/services/network/public/cpp/resource_request.h index 195ec32d0..a2ca6e2 100644 --- a/services/network/public/cpp/resource_request.h +++ b/services/network/public/cpp/resource_request.h
@@ -25,6 +25,7 @@ #include "services/network/public/mojom/client_security_state.mojom.h" #include "services/network/public/mojom/cookie_access_observer.mojom-forward.h" #include "services/network/public/mojom/cors.mojom-shared.h" +#include "services/network/public/mojom/devtools_observer.mojom-forward.h" #include "services/network/public/mojom/fetch_api.mojom-shared.h" #include "services/network/public/mojom/referrer_policy.mojom-shared.h" #include "services/network/public/mojom/trust_tokens.mojom.h"
diff --git a/services/network/public/cpp/url_request_mojom_traits.h b/services/network/public/cpp/url_request_mojom_traits.h index c07d741..233487a 100644 --- a/services/network/public/cpp/url_request_mojom_traits.h +++ b/services/network/public/cpp/url_request_mojom_traits.h
@@ -29,6 +29,7 @@ #include "services/network/public/mojom/client_security_state.mojom-forward.h" #include "services/network/public/mojom/cookie_access_observer.mojom.h" #include "services/network/public/mojom/data_pipe_getter.mojom.h" +#include "services/network/public/mojom/devtools_observer.mojom.h" #include "services/network/public/mojom/trust_tokens.mojom.h" #include "services/network/public/mojom/url_loader.mojom-shared.h" #include "services/network/public/mojom/url_loader_network_service_observer.mojom.h"
diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn index 0798c95..ec7c9c0 100644 --- a/services/network/public/mojom/BUILD.gn +++ b/services/network/public/mojom/BUILD.gn
@@ -167,6 +167,7 @@ "cross_origin_embedder_policy.mojom", "cross_origin_opener_policy.mojom", "data_pipe_getter.mojom", + "devtools_observer.mojom", "early_hints.mojom", "fetch_api.mojom", "http_raw_headers.mojom", @@ -186,10 +187,12 @@ "proxy_config.mojom", "proxy_config_with_annotation.mojom", "referrer_policy.mojom", + "request_priority.mojom", "source_location.mojom", "timing_allow_origin.mojom", "trust_tokens.mojom", "url_loader.mojom", + "url_loader_completion_status.mojom", "url_loader_network_service_observer.mojom", "url_request.mojom", "url_response_head.mojom", @@ -684,6 +687,10 @@ cpp = "::net::CookieEffectiveSameSite" }, { + mojom = "network.mojom.CookieSameSiteContextMetadataDowngradeType" + cpp = "::net::CookieOptions::SameSiteCookieContext::ContextMetadata::ContextDowngradeType" + }, + { mojom = "network.mojom.CookieSameSiteContextMetadata" cpp = "::net::CookieOptions::SameSiteCookieContext::ContextMetadata" },
diff --git a/services/network/public/mojom/cookie_manager.mojom b/services/network/public/mojom/cookie_manager.mojom index 162f841..0917e73 100644 --- a/services/network/public/mojom/cookie_manager.mojom +++ b/services/network/public/mojom/cookie_manager.mojom
@@ -96,9 +96,17 @@ SAME_SITE_STRICT }; +enum CookieSameSiteContextMetadataDowngradeType { + kNoDowngrade, + kStrictToLax, + kStrictToCross, + kLaxToCross, +}; + // Keep defaults here in sync with net/cookies/cookie_options.h. struct CookieSameSiteContextMetadata { bool affected_by_bugfix_1166211 = false; + CookieSameSiteContextMetadataDowngradeType cross_site_redirect_downgrade = kNoDowngrade; }; // Keep defaults here in sync with net/cookies/cookie_options.h.
diff --git a/services/network/public/mojom/devtools_observer.mojom b/services/network/public/mojom/devtools_observer.mojom new file mode 100644 index 0000000..109a0255 --- /dev/null +++ b/services/network/public/mojom/devtools_observer.mojom
@@ -0,0 +1,137 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module network.mojom; + +import "mojo/public/mojom/base/unguessable_token.mojom"; +import "services/network/public/mojom/client_security_state.mojom"; +import "services/network/public/mojom/cookie_manager.mojom"; +import "services/network/public/mojom/cors.mojom"; +import "services/network/public/mojom/http_raw_headers.mojom"; +import "services/network/public/mojom/http_request_headers.mojom"; +import "services/network/public/mojom/ip_address_space.mojom"; +import "services/network/public/mojom/referrer_policy.mojom"; +import "services/network/public/mojom/request_priority.mojom"; +import "services/network/public/mojom/trust_tokens.mojom"; +import "services/network/public/mojom/url_loader_completion_status.mojom"; +import "services/network/public/mojom/url_response_head.mojom"; +import "url/mojom/origin.mojom"; +import "url/mojom/url.mojom"; + +// A struct with information about a URLRequest that is reported to DevTools. +// See URLRequest definition for a description of the fields. +struct URLRequestDevToolsInfo { + string method; + url.mojom.Url url; + RequestPriority priority; + URLRequestReferrerPolicy referrer_policy; + TrustTokenParams? trust_token_params; + bool has_user_gesture; +}; + +// Interface for devtools receiving information about individual request +// state. +interface DevToolsObserver { + // Called to send raw header information and information about excluded + // cookies. Only called when |devtool_request_id| is available to the + // URLLoader. + OnRawRequest( + string devtool_request_id, + array<CookieWithAccessResult> cookies_with_access_result, + array<HttpRawHeaderPair> headers, + ClientSecurityState? client_security_state); + + // Called to send information about the cookies blocked from storage from a + // received response. Only called when |devtool_request_id| is available to + // the URLLoader. + OnRawResponse( + string devtool_request_id, + array<CookieAndLineWithAccessResult> cookies_with_access_result, + array<HttpRawHeaderPair> headers, + string? raw_response_headers, + IPAddressSpace resource_address_space); + + // Called to send information about a private network request that was blocked + // (then |is_warning| is false), or will be blocked in the future (then + // |is_warning| is true). It is possible to share sensitive information with + // DevTools as this is handled in the browser process. Called even when + // |devtool_request_id| is not available to the URLLoader to ensure the + // information can be recorded even when DevTools is closed. + OnPrivateNetworkRequest( + string? devtool_request_id, + url.mojom.Url url, + bool is_warning, + IPAddressSpace resource_address_space, + ClientSecurityState client_security_state); + + // Called to send the CORS preflight request information. Only called when + // |devtool_request_id| is available on the original request. + OnCorsPreflightRequest( + mojo_base.mojom.UnguessableToken devtool_request_id, + HttpRequestHeaders request_headers, + URLRequestDevToolsInfo request_info, + url.mojom.Url initiator_url, + string initiator_devtool_request_id); + + // Called to send the CORS preflight response information. Only called when + // |devtool_request_id| is available on the original request. + OnCorsPreflightResponse( + mojo_base.mojom.UnguessableToken devtool_request_id, + url.mojom.Url url, + URLResponseHead head); + + // Called to send the CORS preflight completion status. Only called when + // |devtool_request_id| is available on the original request. + OnCorsPreflightRequestCompleted( + mojo_base.mojom.UnguessableToken devtool_request_id, + URLLoaderCompletionStatus status); + + // Called to send the result of a successful or failed Trust Token + // operation. Only called when |devtools_request_id| is available on the + // original request. + OnTrustTokenOperationDone( + string devtool_request_id, + TrustTokenOperationResult result); + + // Called to send information about a CORS problem. This callback is intended + // to share sensitive information with DevTools, and is handled in the browser + // process. Called even when |devtool_request_id| is not available to the + // URLLoader to ensure CORS issues are recorded even if DevTools is closed. + OnCorsError( + string? devtool_request_id, + url.mojom.Origin? initiator_origin, + url.mojom.Url url, + CorsErrorStatus status); + + // Called when parsing the .wbn file has succeeded. The event + // contains the information about the web bundle contents. + OnSubresourceWebBundleMetadata( + string devtool_request_id, + array<url.mojom.Url> urls); + + // Called when parsing the .wbn file has failed. + OnSubresourceWebBundleMetadataError( + string devtool_request_id, + string error_message); + + // Called when handling requests for resources within a .wbn file. + // Note: this will only be fired for resources that are requested by the + // webpage. + OnSubresourceWebBundleInnerResponse( + string inner_request_devtools_id, + url.mojom.Url url, + string? bundle_request_devtools_id); + + // Called when an error occurs while handling a request within a .wbn file. + OnSubresourceWebBundleInnerResponseError( + string inner_request_devtools_id, + url.mojom.Url url, + string error_message, + string? bundle_request_devtools_id); + + // Used by the NetworkService to create a copy of this observer. + // (e.g. when creating an observer for URLLoader from URLLoaderFactory's + // observer). + Clone(pending_receiver<DevToolsObserver> listener); +};
diff --git a/services/network/public/mojom/host_resolver.mojom b/services/network/public/mojom/host_resolver.mojom index f5231d8..b1c22d7 100644 --- a/services/network/public/mojom/host_resolver.mojom +++ b/services/network/public/mojom/host_resolver.mojom
@@ -9,7 +9,7 @@ import "services/network/public/mojom/ip_endpoint.mojom"; import "services/network/public/mojom/network_isolation_key.mojom"; import "services/network/public/mojom/network_param.mojom"; -import "services/network/public/mojom/url_request.mojom"; +import "services/network/public/mojom/request_priority.mojom"; // An HTTPS server to send DNS queries to, per the DNS Queries over HTTPS spec. // spec: https://tools.ietf.org/html/draft-ietf-doh-dns-over-https-12
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index 25d6c99..a432702 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -19,6 +19,7 @@ import "services/network/public/mojom/cors_origin_pattern.mojom"; import "services/network/public/mojom/cross_origin_embedder_policy.mojom"; import "services/network/public/mojom/default_credentials.mojom"; +import "services/network/public/mojom/devtools_observer.mojom"; import "services/network/public/mojom/host_resolver.mojom"; import "services/network/public/mojom/http_request_headers.mojom"; import "services/network/public/mojom/ip_address.mojom";
diff --git a/services/network/public/mojom/referrer_policy.mojom b/services/network/public/mojom/referrer_policy.mojom index 237e8f2..8a15d2e 100644 --- a/services/network/public/mojom/referrer_policy.mojom +++ b/services/network/public/mojom/referrer_policy.mojom
@@ -6,13 +6,25 @@ [Stable] enum ReferrerPolicy { - kAlways, - kDefault, - kNoReferrerWhenDowngrade, - kNever, - kOrigin, - kOriginWhenCrossOrigin, - kStrictOriginWhenCrossOrigin, - kSameOrigin, - kStrictOrigin, + kAlways, + kDefault, + kNoReferrerWhenDowngrade, + kNever, + kOrigin, + kOriginWhenCrossOrigin, + kStrictOriginWhenCrossOrigin, + kSameOrigin, + kStrictOrigin, +}; + +// This enum corresponds to net::ReferrerPolicy. See its comments. +enum URLRequestReferrerPolicy { + kClearReferrerOnTransitionFromSecureToInsecure, + kReduceReferrerGranularityOnTransitionCrossOrigin, + kOriginOnlyOnTransitionCrossOrigin, + kNeverClearReferrer, + kOrigin, + kClearReferrerOnTransitionCrossOrigin, + kOriginClearOnTransitionFromSecureToInsecure, + kNoReferrer };
diff --git a/services/network/public/mojom/request_priority.mojom b/services/network/public/mojom/request_priority.mojom new file mode 100644 index 0000000..fbfeb29 --- /dev/null +++ b/services/network/public/mojom/request_priority.mojom
@@ -0,0 +1,15 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module network.mojom; + +// This enum corresponds to net::RequestPriority. See its comments for details. +enum RequestPriority { + kThrottled = 0, + kIdle, + kLowest, + kLow, + kMedium, + kHighest +};
diff --git a/services/network/public/mojom/url_loader.mojom b/services/network/public/mojom/url_loader.mojom index b258b82e..3118b41 100644 --- a/services/network/public/mojom/url_loader.mojom +++ b/services/network/public/mojom/url_loader.mojom
@@ -19,8 +19,10 @@ import "services/network/public/mojom/http_request_headers.mojom"; import "services/network/public/mojom/isolation_info.mojom"; import "services/network/public/mojom/network_param.mojom"; +import "services/network/public/mojom/request_priority.mojom"; import "services/network/public/mojom/site_for_cookies.mojom"; import "services/network/public/mojom/trust_tokens.mojom"; +import "services/network/public/mojom/url_loader_completion_status.mojom"; import "services/network/public/mojom/url_request.mojom"; import "services/network/public/mojom/url_response_head.mojom"; import "services/network/public/mojom/web_bundle_handle.mojom";
diff --git a/services/network/public/mojom/url_loader_completion_status.mojom b/services/network/public/mojom/url_loader_completion_status.mojom new file mode 100644 index 0000000..17be268 --- /dev/null +++ b/services/network/public/mojom/url_loader_completion_status.mojom
@@ -0,0 +1,8 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module network.mojom; + +[Native] +struct URLLoaderCompletionStatus;
diff --git a/services/network/public/mojom/url_request.mojom b/services/network/public/mojom/url_request.mojom index 72bab00..f336937 100644 --- a/services/network/public/mojom/url_request.mojom +++ b/services/network/public/mojom/url_request.mojom
@@ -15,12 +15,15 @@ import "services/network/public/mojom/cookie_manager.mojom"; import "services/network/public/mojom/chunked_data_pipe_getter.mojom"; import "services/network/public/mojom/data_pipe_getter.mojom"; +import "services/network/public/mojom/devtools_observer.mojom"; import "services/network/public/mojom/fetch_api.mojom"; import "services/network/public/mojom/http_raw_headers.mojom"; import "services/network/public/mojom/http_request_headers.mojom"; import "services/network/public/mojom/ip_address_space.mojom"; import "services/network/public/mojom/isolation_info.mojom"; import "services/network/public/mojom/network_param.mojom"; +import "services/network/public/mojom/referrer_policy.mojom"; +import "services/network/public/mojom/request_priority.mojom"; import "services/network/public/mojom/site_for_cookies.mojom"; import "services/network/public/mojom/trust_tokens.mojom"; import "services/network/public/mojom/url_response_head.mojom"; @@ -29,19 +32,6 @@ import "url/mojom/origin.mojom"; import "url/mojom/url.mojom"; -[Native] -struct URLLoaderCompletionStatus; - -// This enum corresponds to net::RequestPriority. See its comments for details. -enum RequestPriority { - kThrottled = 0, - kIdle, - kLowest, - kLow, - kMedium, - kHighest -}; - // This enums corresponds to net::SourceStream::SourceType. enum SourceType { kBrotli, @@ -51,18 +41,6 @@ kUnknown, }; -// This enum corresponds to net::ReferrerPolicy. See its comments. -enum URLRequestReferrerPolicy { - kClearReferrerOnTransitionFromSecureToInsecure, - kReduceReferrerGranularityOnTransitionCrossOrigin, - kOriginOnlyOnTransitionCrossOrigin, - kNeverClearReferrer, - kOrigin, - kClearReferrerOnTransitionCrossOrigin, - kOriginClearOnTransitionFromSecureToInsecure, - kNoReferrer -}; - // See documentation at `URLRequest.trusted_params`. struct TrustedUrlRequestParams { // If non-empty, this value will be used to set the SiteForCookies and @@ -505,120 +483,3 @@ DataElementDataPipe data_pipe; DataElementChunkedDataPipe chunked_data_pipe; }; - -// A struct with information about a URLRequest that is reported to DevTools. -// See URLRequest definition for a description of the fields. -struct URLRequestDevToolsInfo { - string method; - url.mojom.Url url; - RequestPriority priority; - URLRequestReferrerPolicy referrer_policy; - TrustTokenParams? trust_token_params; - bool has_user_gesture; -}; - -// Interface for devtools receiving information about individual request -// state. -interface DevToolsObserver { - // Called to send raw header information and information about excluded - // cookies. Only called when |devtool_request_id| is available to the - // URLLoader. - OnRawRequest( - string devtool_request_id, - array<CookieWithAccessResult> cookies_with_access_result, - array<HttpRawHeaderPair> headers, - ClientSecurityState? client_security_state); - - // Called to send information about the cookies blocked from storage from a - // received response. Only called when |devtool_request_id| is available to - // the URLLoader. - OnRawResponse( - string devtool_request_id, - array<CookieAndLineWithAccessResult> cookies_with_access_result, - array<HttpRawHeaderPair> headers, - string? raw_response_headers, - IPAddressSpace resource_address_space); - - // Called to send information about a private network request that was blocked - // (then |is_warning| is false), or will be blocked in the future (then - // |is_warning| is true). It is possible to share sensitive information with - // DevTools as this is handled in the browser process. Called even when - // |devtool_request_id| is not available to the URLLoader to ensure the - // information can be recorded even when DevTools is closed. - OnPrivateNetworkRequest( - string? devtool_request_id, - url.mojom.Url url, - bool is_warning, - IPAddressSpace resource_address_space, - ClientSecurityState client_security_state); - - // Called to send the CORS preflight request information. Only called when - // |devtool_request_id| is available on the original request. - OnCorsPreflightRequest( - mojo_base.mojom.UnguessableToken devtool_request_id, - HttpRequestHeaders request_headers, - URLRequestDevToolsInfo request_info, - url.mojom.Url initiator_url, - string initiator_devtool_request_id); - - // Called to send the CORS preflight response information. Only called when - // |devtool_request_id| is available on the original request. - OnCorsPreflightResponse( - mojo_base.mojom.UnguessableToken devtool_request_id, - url.mojom.Url url, - URLResponseHead head); - - // Called to send the CORS preflight completion status. Only called when - // |devtool_request_id| is available on the original request. - OnCorsPreflightRequestCompleted( - mojo_base.mojom.UnguessableToken devtool_request_id, - URLLoaderCompletionStatus status); - - // Called to send the result of a successful or failed Trust Token - // operation. Only called when |devtools_request_id| is available on the - // original request. - OnTrustTokenOperationDone( - string devtool_request_id, - TrustTokenOperationResult result); - - // Called to send information about a CORS problem. This callback is intended - // to share sensitive information with DevTools, and is handled in the browser - // process. Called even when |devtool_request_id| is not available to the - // URLLoader to ensure CORS issues are recorded even if DevTools is closed. - OnCorsError( - string? devtool_request_id, - url.mojom.Origin? initiator_origin, - url.mojom.Url url, - CorsErrorStatus status); - - // Called when parsing the .wbn file has succeeded. The event - // contains the information about the web bundle contents. - OnSubresourceWebBundleMetadata( - string devtool_request_id, - array<url.mojom.Url> urls); - - // Called when parsing the .wbn file has failed. - OnSubresourceWebBundleMetadataError( - string devtool_request_id, - string error_message); - - // Called when handling requests for resources within a .wbn file. - // Note: this will only be fired for resources that are requested by the - // webpage. - OnSubresourceWebBundleInnerResponse( - string inner_request_devtools_id, - url.mojom.Url url, - string? bundle_request_devtools_id); - - // Called when an error occurs while handling a request within a .wbn file. - OnSubresourceWebBundleInnerResponseError( - string inner_request_devtools_id, - url.mojom.Url url, - string error_message, - string? bundle_request_devtools_id); - - // Used by the NetworkService to create a copy of this observer. - // (e.g. when creating an observer for URLLoader from URLLoaderFactory's - // observer). - Clone(pending_receiver<DevToolsObserver> listener); -};
diff --git a/services/network/test/mock_devtools_observer.h b/services/network/test/mock_devtools_observer.h index 55857e9..2b016ae 100644 --- a/services/network/test/mock_devtools_observer.h +++ b/services/network/test/mock_devtools_observer.h
@@ -11,9 +11,9 @@ #include "mojo/public/cpp/bindings/receiver_set.h" #include "net/url_request/url_request.h" #include "services/network/public/mojom/client_security_state.mojom-forward.h" +#include "services/network/public/mojom/devtools_observer.mojom.h" #include "services/network/public/mojom/http_raw_headers.mojom-forward.h" #include "services/network/public/mojom/ip_address_space.mojom-forward.h" -#include "services/network/public/mojom/url_request.mojom.h" #include "testing/gmock/include/gmock/gmock.h" namespace network {
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index a5ba517..d2b4bd4 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -72,6 +72,7 @@ #include "services/network/public/mojom/cookie_access_observer.mojom-forward.h" #include "services/network/public/mojom/cookie_access_observer.mojom.h" #include "services/network/public/mojom/cookie_manager.mojom.h" +#include "services/network/public/mojom/devtools_observer.mojom.h" #include "services/network/public/mojom/early_hints.mojom.h" #include "services/network/public/mojom/fetch_api.mojom.h" #include "services/network/public/mojom/origin_policy_manager.mojom.h"
diff --git a/services/network/url_loader.h b/services/network/url_loader.h index 9a3f1d7..5c92771 100644 --- a/services/network/url_loader.h +++ b/services/network/url_loader.h
@@ -34,6 +34,7 @@ #include "services/network/public/mojom/accept_ch_frame_observer.mojom.h" #include "services/network/public/mojom/cookie_access_observer.mojom.h" #include "services/network/public/mojom/cross_origin_embedder_policy.mojom-forward.h" +#include "services/network/public/mojom/devtools_observer.mojom-forward.h" #include "services/network/public/mojom/fetch_api.mojom.h" #include "services/network/public/mojom/ip_address_space.mojom-forward.h" #include "services/network/public/mojom/ip_address_space.mojom-shared.h"
diff --git a/sql/README.md b/sql/README.md index d69ba9a..5610010 100644 --- a/sql/README.md +++ b/sql/README.md
@@ -448,6 +448,10 @@ Double-quoted string literals are non-standard SQL syntax. The SQLite authors [currently consider this be a misfeature](https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted). +SQLite support for double-quoted string literals is disabled for databases +opened with Chrome's `sql::Database` infrastructure. This is intended to steer +feature developers away from this discouraged feature. + After [WebSQL](https://www.w3.org/TR/webdatabase/) is removed from Chrome, we plan to disable SQLite's support for double-quoted string literals using
diff --git a/sql/database.cc b/sql/database.cc index fcad596..c45b4650 100644 --- a/sql/database.cc +++ b/sql/database.cc
@@ -1523,6 +1523,17 @@ return false; } + // The use of SQLite's non-standard string quoting is not allowed in Chrome. + // + // Allowing double-quoted string literals is now considered a misfeature by + // SQLite authors. See https://www.sqlite.org/quirks.html#dblquote + err = sqlite3_db_config(db_, SQLITE_DBCONFIG_DQS_DDL, 0, nullptr); + DCHECK_EQ(err, SQLITE_OK) + << "sqlite3_db_config(SQLITE_DBCONFIG_DQS_DDL) should not fail"; + err = sqlite3_db_config(db_, SQLITE_DBCONFIG_DQS_DML, 0, nullptr); + DCHECK_EQ(err, SQLITE_OK) + << "sqlite3_db_config(SQLITE_DBCONFIG_DQS_DML) should not fail"; + // The use of triggers is discouraged for Chrome code. Thanks to this // configuration change, triggers are not executed. CREATE TRIGGER and DROP // TRIGGER still succeed.
diff --git a/sql/database_unittest.cc b/sql/database_unittest.cc index 71f458b..9d58ac2 100644 --- a/sql/database_unittest.cc +++ b/sql/database_unittest.cc
@@ -1458,6 +1458,43 @@ << "Page cache usage should go down after calling TrimMemory()"; } +TEST_P(SQLDatabaseTest, DoubleQuotedStringLiteralsDisabledByDefault) { + ASSERT_TRUE(db_->Execute("CREATE TABLE data(item TEXT NOT NULL);")); + + struct TestCase { + const char* sql; + bool is_valid; + }; + std::vector<TestCase> test_cases = { + // DML tests. + {"SELECT item FROM data WHERE item >= 'string literal'", true}, + {"SELECT item FROM data WHERE item >= \"string literal\"", false}, + {"INSERT INTO data(item) VALUES('string literal')", true}, + {"INSERT INTO data(item) VALUES(\"string literal\")", false}, + {"UPDATE data SET item = 'string literal'", true}, + {"UPDATE data SET item = \"string literal\"", false}, + {"DELETE FROM data WHERE item >= 'string literal'", true}, + {"DELETE FROM data WHERE item >= \"string literal\"", false}, + + // DDL tests. + {"CREATE INDEX data_item ON data(item) WHERE item >= 'string literal'", + true}, + {"CREATE INDEX data_item ON data(item) WHERE item >= \"string literal\"", + false}, + {"CREATE TABLE data2(item TEXT DEFAULT 'string literal')", true}, + + // This should be an invalid DDL statement, due to the double-quoted + // string literal. However, SQLite currently parses it. + {"CREATE TABLE data2(item TEXT DEFAULT \"string literal\")", true}, + }; + + for (const TestCase& test_case : test_cases) { + SCOPED_TRACE(test_case.sql); + + EXPECT_EQ(test_case.is_valid, db_->IsSQLValid(test_case.sql)); + } +} + TEST_P(SQLDatabaseTest, TriggersDisabledByDefault) { ASSERT_TRUE(db_->Execute("CREATE TABLE data(id INTEGER)"));
diff --git a/storage/browser/blob/blob_reader.cc b/storage/browser/blob/blob_reader.cc index b004bf3..78a6fbd 100644 --- a/storage/browser/blob/blob_reader.cc +++ b/storage/browser/blob/blob_reader.cc
@@ -576,8 +576,9 @@ return Status::DONE; } if (result == net::ERR_IO_PENDING) { - TRACE_EVENT_ASYNC_BEGIN1("Blob", "BlobReader::ReadFileItem", this, "uuid", - blob_data_->uuid()); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("Blob", "BlobReader::ReadFileItem", + TRACE_ID_LOCAL(this), "uuid", + blob_data_->uuid()); io_pending_ = true; return Status::IO_PENDING; } @@ -586,8 +587,9 @@ void BlobReader::DidReadFile(int result) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - TRACE_EVENT_ASYNC_END1("Blob", "BlobReader::ReadFileItem", this, "uuid", - blob_data_->uuid()); + TRACE_EVENT_NESTABLE_ASYNC_END1("Blob", "BlobReader::ReadFileItem", + TRACE_ID_LOCAL(this), "uuid", + blob_data_->uuid()); DidReadItem(result); } @@ -636,8 +638,9 @@ return Status::DONE; } if (result == net::ERR_IO_PENDING) { - TRACE_EVENT_ASYNC_BEGIN1("Blob", "BlobReader::ReadReadableDataHandle", this, - "uuid", blob_data_->uuid()); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( + "Blob", "BlobReader::ReadReadableDataHandle", TRACE_ID_LOCAL(this), + "uuid", blob_data_->uuid()); io_pending_ = true; return Status::IO_PENDING; } @@ -646,8 +649,9 @@ void BlobReader::DidReadReadableDataHandle(int result) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - TRACE_EVENT_ASYNC_END1("Blob", "BlobReader::ReadReadableDataHandle", this, - "uuid", blob_data_->uuid()); + TRACE_EVENT_NESTABLE_ASYNC_END1("Blob", "BlobReader::ReadReadableDataHandle", + TRACE_ID_LOCAL(this), "uuid", + blob_data_->uuid()); RecordBytesReadFromDataHandle(current_item_index_, result); DidReadItem(result); }
diff --git a/storage/browser/blob/mojo_blob_reader.cc b/storage/browser/blob/mojo_blob_reader.cc index 2b20198..d5f4c9e9 100644 --- a/storage/browser/blob/mojo_blob_reader.cc +++ b/storage/browser/blob/mojo_blob_reader.cc
@@ -38,7 +38,8 @@ peer_closed_handle_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, base::SequencedTaskRunnerHandle::Get()) { - TRACE_EVENT_ASYNC_BEGIN1("Blob", "BlobReader", this, "uuid", handle->uuid()); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("Blob", "BlobReader", TRACE_ID_LOCAL(this), + "uuid", handle->uuid()); DCHECK(delegate_); base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, @@ -47,8 +48,8 @@ MojoBlobReader::~MojoBlobReader() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - TRACE_EVENT_ASYNC_END1("Blob", "BlobReader", this, "bytes_written", - total_written_bytes_); + TRACE_EVENT_NESTABLE_ASYNC_END1("Blob", "BlobReader", TRACE_ID_LOCAL(this), + "bytes_written", total_written_bytes_); } void MojoBlobReader::Start() { @@ -59,13 +60,14 @@ return; } - TRACE_EVENT_ASYNC_BEGIN0("Blob", "BlobReader::CountSize", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("Blob", "BlobReader::CountSize", + TRACE_ID_LOCAL(this)); BlobReader::Status size_status = blob_reader_->CalculateSize(base::BindOnce( &MojoBlobReader::DidCalculateSize, base::Unretained(this))); switch (size_status) { case BlobReader::Status::NET_ERROR: - TRACE_EVENT_ASYNC_END1("Blob", "BlobReader::CountSize", this, "result", - "error"); + TRACE_EVENT_NESTABLE_ASYNC_END1("Blob", "BlobReader::CountSize", + TRACE_ID_LOCAL(this), "result", "error"); NotifyCompletedAndDeleteIfNeeded(blob_reader_->net_error()); return; case BlobReader::Status::IO_PENDING: @@ -100,14 +102,15 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (result != net::OK) { - TRACE_EVENT_ASYNC_END1("Blob", "BlobReader::CountSize", this, "result", - "error"); + TRACE_EVENT_NESTABLE_ASYNC_END1("Blob", "BlobReader::CountSize", + TRACE_ID_LOCAL(this), "result", "error"); NotifyCompletedAndDeleteIfNeeded(result); return; } - TRACE_EVENT_ASYNC_END2("Blob", "BlobReader::CountSize", this, "result", - "success", "size", blob_reader_->total_size()); + TRACE_EVENT_NESTABLE_ASYNC_END2("Blob", "BlobReader::CountSize", + TRACE_ID_LOCAL(this), "result", "success", + "size", blob_reader_->total_size()); // Apply the range requirement. if (!byte_range_.ComputeBounds(blob_reader_->total_size())) { @@ -219,7 +222,8 @@ num_bytes = std::min(num_bytes, blink::BlobUtils::GetDataPipeChunkSize()); - TRACE_EVENT_ASYNC_BEGIN0("Blob", "BlobReader::ReadMore", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("Blob", "BlobReader::ReadMore", + TRACE_ID_LOCAL(this)); CHECK_GT(static_cast<uint32_t>(std::numeric_limits<int>::max()), num_bytes); DCHECK(pending_write_); auto buf = @@ -245,8 +249,9 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (num_bytes < 0) { - TRACE_EVENT_ASYNC_END2("Blob", "BlobReader::ReadMore", this, "result", - "error", "net_error", num_bytes); + TRACE_EVENT_NESTABLE_ASYNC_END2("Blob", "BlobReader::ReadMore", + TRACE_ID_LOCAL(this), "result", "error", + "net_error", num_bytes); writable_handle_watcher_.Cancel(); pending_write_->Complete(0); pending_write_ = nullptr; // This closes the data pipe. @@ -255,8 +260,9 @@ } if (num_bytes > 0) delegate_->DidRead(num_bytes); - TRACE_EVENT_ASYNC_END2("Blob", "BlobReader::ReadMore", this, "result", - "success", "num_bytes", num_bytes); + TRACE_EVENT_NESTABLE_ASYNC_END2("Blob", "BlobReader::ReadMore", + TRACE_ID_LOCAL(this), "result", "success", + "num_bytes", num_bytes); response_body_stream_ = pending_write_->Complete(num_bytes); total_written_bytes_ += num_bytes; pending_write_ = nullptr;
diff --git a/storage/browser/file_system/file_system_quota_client_unittest.cc b/storage/browser/file_system/file_system_quota_client_unittest.cc index 2b6ee18e..7f73e698 100644 --- a/storage/browser/file_system/file_system_quota_client_unittest.cc +++ b/storage/browser/file_system/file_system_quota_client_unittest.cc
@@ -344,7 +344,7 @@ kFileSystemTypeTemporary); const int64_t file_paths_cost_persistent = ComputeFilePathsCostForOriginAndType(kFiles, kDummyURL1, - kFileSystemTypeTemporary); + kFileSystemTypePersistent); for (int i = 0; i < 2; i++) { EXPECT_EQ(133 + 14 + file_paths_cost_temporary, @@ -439,18 +439,10 @@ {true, "", 0, kDummyURL3, kFileSystemTypePersistent}, }); - std::vector<StorageKey> storage_keys = - GetStorageKeysForType(quota_client, kTemporary); - EXPECT_EQ(2U, storage_keys.size()); - EXPECT_THAT( - storage_keys, - testing::Contains(StorageKey::CreateFromStringForTesting(kDummyURL1))); - EXPECT_THAT( - storage_keys, - testing::Contains(StorageKey::CreateFromStringForTesting(kDummyURL2))); - EXPECT_THAT(storage_keys, - testing::Not(testing::Contains( - StorageKey::CreateFromStringForTesting(kDummyURL3)))); + EXPECT_THAT(GetStorageKeysForType(quota_client, kTemporary), + testing::UnorderedElementsAre( + StorageKey::CreateFromStringForTesting(kDummyURL1), + StorageKey::CreateFromStringForTesting(kDummyURL2))); } TEST_F(FileSystemQuotaClientTest, GetStorageKeysForHost) { @@ -469,23 +461,11 @@ {true, "", 0, kURL5, kFileSystemTypePersistent}, }); - std::vector<StorageKey> storage_keys = - GetStorageKeysForHost(quota_client, kTemporary, "foo.com"); - EXPECT_EQ(3U, storage_keys.size()); - EXPECT_THAT(storage_keys, - testing::Contains(StorageKey::CreateFromStringForTesting(kURL1))); - EXPECT_THAT(storage_keys, - testing::Contains(StorageKey::CreateFromStringForTesting(kURL2))); - EXPECT_THAT(storage_keys, - testing::Contains(StorageKey::CreateFromStringForTesting(kURL3))); - EXPECT_THAT( - storage_keys, - testing::Not(testing::Contains( - StorageKey::CreateFromStringForTesting(kURL4)))); // Different host. - EXPECT_THAT( - storage_keys, - testing::Not(testing::Contains( - StorageKey::CreateFromStringForTesting(kURL5)))); // Different type. + EXPECT_THAT(GetStorageKeysForHost(quota_client, kTemporary, "foo.com"), + testing::UnorderedElementsAre( + StorageKey::CreateFromStringForTesting(kURL1), + StorageKey::CreateFromStringForTesting(kURL2), + StorageKey::CreateFromStringForTesting(kURL3))); } TEST_F(FileSystemQuotaClientTest, DeleteOriginTest) {
diff --git a/storage/browser/quota/quota_callbacks.h b/storage/browser/quota/quota_callbacks.h index fd68e8cd..d7002097 100644 --- a/storage/browser/quota/quota_callbacks.h +++ b/storage/browser/quota/quota_callbacks.h
@@ -15,6 +15,7 @@ #include "base/callback.h" #include "base/containers/contains.h" +#include "components/services/storage/public/cpp/buckets/bucket_info.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom-forward.h" @@ -45,8 +46,8 @@ base::OnceCallback<void(const std::set<blink::StorageKey>& storage_keys, blink::mojom::StorageType type)>; using GetUsageInfoCallback = base::OnceCallback<void(UsageInfoEntries)>; -using GetStorageKeyCallback = base::OnceCallback<void( - const absl::optional<blink::StorageKey>& storage_key)>; +using GetBucketCallback = + base::OnceCallback<void(const absl::optional<BucketInfo>& bucket_info)>; // Simple template wrapper for a callback queue. template <typename CallbackType, typename... Args>
diff --git a/storage/browser/quota/quota_database.cc b/storage/browser/quota/quota_database.cc index 5263663..2d2baeac 100644 --- a/storage/browser/quota/quota_database.cc +++ b/storage/browser/quota/quota_database.cc
@@ -56,9 +56,6 @@ } // anonymous namespace -// static -const char QuotaDatabase::kDefaultBucketName[] = "default"; - const QuotaDatabase::TableSchema QuotaDatabase::kTables[] = { {kHostQuotaTable, "(host TEXT NOT NULL," @@ -515,63 +512,20 @@ return true; } -bool QuotaDatabase::GetLRUStorageKey( +QuotaErrorOr<BucketInfo> QuotaDatabase::GetLRUBucket( StorageType type, - const std::set<StorageKey>& exceptions, - SpecialStoragePolicy* special_storage_policy, - absl::optional<StorageKey>* storage_key) { + const std::set<StorageKey>& storage_key_exceptions, + const std::set<BucketId>& bucket_exceptions, + SpecialStoragePolicy* special_storage_policy) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(storage_key); - if (LazyOpen(LazyOpenMode::kFailIfNotFound) != QuotaError::kNone) - return false; + QuotaError open_error = LazyOpen(LazyOpenMode::kFailIfNotFound); + if (open_error != QuotaError::kNone) + return open_error; + // clang-format off static constexpr char kSql[] = - // clang-format off - "SELECT origin FROM buckets " - "WHERE type = ? AND name = ? " - "ORDER BY last_accessed"; - // clang-format on - - sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); - statement.BindInt(0, static_cast<int>(type)); - statement.BindString(1, kDefaultBucketName); - - while (statement.Step()) { - absl::optional<StorageKey> read_storage_key = - StorageKey::Deserialize(statement.ColumnString(0)); - if (!read_storage_key.has_value()) - continue; - - if (base::Contains(exceptions, *read_storage_key)) - continue; - - GURL read_gurl = read_storage_key->origin().GetURL(); - if (special_storage_policy && - (special_storage_policy->IsStorageDurable(read_gurl) || - special_storage_policy->IsStorageUnlimited(read_gurl))) { - continue; - } - - *storage_key = std::move(read_storage_key).value(); - return true; - } - - storage_key->reset(); - return statement.Succeeded(); -} - -bool QuotaDatabase::GetLRUBucket(StorageType type, - const std::set<StorageKey>& exceptions, - SpecialStoragePolicy* special_storage_policy, - absl::optional<BucketId>* bucket_id) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(bucket_id); - if (LazyOpen(LazyOpenMode::kFailIfNotFound) != QuotaError::kNone) - return false; - - static constexpr char kSql[] = - // clang-format off - "SELECT id, origin FROM buckets " + "SELECT id, origin, name, expiration, quota " + "FROM buckets " "WHERE type = ? " "ORDER BY last_accessed"; // clang-format on @@ -580,13 +534,19 @@ statement.BindInt(0, static_cast<int>(type)); while (statement.Step()) { - int64_t read_bucket_id = statement.ColumnInt64(0); absl::optional<StorageKey> read_storage_key = StorageKey::Deserialize(statement.ColumnString(1)); if (!read_storage_key.has_value()) continue; - if (base::Contains(exceptions, *read_storage_key)) + std::string read_bucket_name = statement.ColumnString(2); + if (base::Contains(storage_key_exceptions, *read_storage_key) && + read_bucket_name == kDefaultBucketName) { + continue; + } + + BucketId read_bucket_id = BucketId(statement.ColumnInt64(0)); + if (base::Contains(bucket_exceptions, read_bucket_id)) continue; // TODO(crbug/1176774): Once BucketTable holds bucket durability info, @@ -597,13 +557,11 @@ special_storage_policy->IsStorageUnlimited(read_gurl))) { continue; } - - *bucket_id = BucketId(read_bucket_id); - return true; + return BucketInfo(read_bucket_id, std::move(read_storage_key).value(), type, + read_bucket_name, statement.ColumnTime(3), + statement.ColumnInt(4)); } - - bucket_id->reset(); - return statement.Succeeded(); + return QuotaError::kNotFound; } bool QuotaDatabase::GetStorageKeysModifiedBetween(
diff --git a/storage/browser/quota/quota_database.h b/storage/browser/quota/quota_database.h index fffdd4c..1bad41f5 100644 --- a/storage/browser/quota/quota_database.h +++ b/storage/browser/quota/quota_database.h
@@ -22,6 +22,7 @@ #include "base/types/id_type.h" #include "components/services/storage/public/cpp/buckets/bucket_id.h" #include "components/services/storage/public/cpp/buckets/bucket_info.h" +#include "components/services/storage/public/cpp/buckets/constants.h" #include "components/services/storage/public/cpp/quota_error_or.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/storage_key/storage_key.h" @@ -154,25 +155,17 @@ // Deletes the specified bucket. bool DeleteBucketInfo(BucketId bucket_id); - // TODO(crbug.com/1202167): Remove once all usages have been updated to use - // GetLRUBucket. Sets `storage_key` to the least recently used storage key of - // storage keys not included in `exceptions` and not granted the special - // unlimited storage right. Returns false when it fails in accessing the - // database. `storage_key` is set to nullopt when there is no matching storage - // key. This is limited to the storage key's default bucket. - bool GetLRUStorageKey(blink::mojom::StorageType type, - const std::set<blink::StorageKey>& exceptions, - SpecialStoragePolicy* special_storage_policy, - absl::optional<blink::StorageKey>* storage_key); - - // Sets `bucket_id` to the least recently used bucket from storage keys not - // included in `exceptions` and not granted special unlimited storage right. - // Returns false when it fails in accessing the database. `bucket_id` is - // set to nullopt when there is no matching bucket. - bool GetLRUBucket(blink::mojom::StorageType type, - const std::set<blink::StorageKey>& exceptions, - SpecialStoragePolicy* special_storage_policy, - absl::optional<BucketId>* bucket_id); + // Returns the BucketInfo for the least recently used bucket. Will exclude + // default buckets included in `storage_key_exceptions`, buckets with ids + // in `bucket_exceptions` and origins that have the special unlimited storage + // policy. Returns a QuotaError if the operation has failed. + // TODO(crbug.com/1199417): `storage_key_exceptions` should be removed once + // QuotaClient is migrated to operate per bucket. + QuotaErrorOr<BucketInfo> GetLRUBucket( + blink::mojom::StorageType type, + const std::set<blink::StorageKey>& storage_key_exceptions, + const std::set<BucketId>& bucket_exceptions, + SpecialStoragePolicy* special_storage_policy); // TODO(crbug.com/1202167): Remove once all usages have been updated to use // GetBucketsModifiedBetween. Populates `storage_keys` with the ones that have @@ -273,7 +266,6 @@ friend class QuotaDatabaseMigrationsTest; friend class QuotaManagerImpl; - static const char kDefaultBucketName[]; static const TableSchema kTables[]; static const size_t kTableCount; static const IndexSchema kIndexes[];
diff --git a/storage/browser/quota/quota_database_migrations.cc b/storage/browser/quota/quota_database_migrations.cc index 47f8b10..f4c7825 100644 --- a/storage/browser/quota/quota_database_migrations.cc +++ b/storage/browser/quota/quota_database_migrations.cc
@@ -79,7 +79,7 @@ // clang-format on sql::Statement import_origin_info_statement( db->GetCachedStatement(SQL_FROM_HERE, kImportOriginInfoSql)); - import_origin_info_statement.BindString(0, QuotaDatabase::kDefaultBucketName); + import_origin_info_statement.BindString(0, kDefaultBucketName); import_origin_info_statement.BindTime(1, base::Time::Max()); if (!import_origin_info_statement.Run()) return false;
diff --git a/storage/browser/quota/quota_database_unittest.cc b/storage/browser/quota/quota_database_unittest.cc index c9831689..b2d685c 100644 --- a/storage/browser/quota/quota_database_unittest.cc +++ b/storage/browser/quota/quota_database_unittest.cc
@@ -15,6 +15,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/test/task_environment.h" #include "build/build_config.h" +#include "components/services/storage/public/cpp/buckets/constants.h" #include "sql/database.h" #include "sql/meta_table.h" #include "sql/statement.h" @@ -38,8 +39,6 @@ static const blink::mojom::StorageType kPerm = blink::mojom::StorageType::kPersistent; -const char kDefaultBucketName[] = "default"; - } // namespace // Test parameter indicates if the database should be created for incognito @@ -299,101 +298,26 @@ } #endif // !defined(OS_FUCHSIA) -TEST_P(QuotaDatabaseTest, StorageKeyLastAccessTimeLRU) { - QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); - EXPECT_TRUE(LazyOpen(&db, LazyOpenMode::kCreateIfNotFound)); - - std::set<StorageKey> exceptions; - absl::optional<StorageKey> storage_key; - EXPECT_TRUE(db.GetLRUStorageKey(kTemp, exceptions, nullptr, &storage_key)); - EXPECT_FALSE(storage_key.has_value()); - - const StorageKey kStorageKey1 = - StorageKey::CreateFromStringForTesting("http://a/"); - const StorageKey kStorageKey2 = - StorageKey::CreateFromStringForTesting("http://b/"); - const StorageKey kStorageKey3 = - StorageKey::CreateFromStringForTesting("http://c/"); - const StorageKey kStorageKey4 = - StorageKey::CreateFromStringForTesting("http://p/"); - - // Adding three temporary storages, and - EXPECT_TRUE(db.SetStorageKeyLastAccessTime(kStorageKey1, kTemp, - base::Time::FromJavaTime(10))); - EXPECT_TRUE(db.SetStorageKeyLastAccessTime(kStorageKey2, kTemp, - base::Time::FromJavaTime(20))); - EXPECT_TRUE(db.SetStorageKeyLastAccessTime(kStorageKey3, kTemp, - base::Time::FromJavaTime(30))); - - // one persistent. - EXPECT_TRUE(db.SetStorageKeyLastAccessTime(kStorageKey4, kPerm, - base::Time::FromJavaTime(40))); - - EXPECT_TRUE(db.GetLRUStorageKey(kTemp, exceptions, nullptr, &storage_key)); - EXPECT_EQ(kStorageKey1, storage_key.value()); - - // Test that unlimited origins are excluded from eviction, but - // protected origins are not excluded. - scoped_refptr<MockSpecialStoragePolicy> policy(new MockSpecialStoragePolicy); - policy->AddUnlimited(kStorageKey1.origin().GetURL()); - policy->AddProtected(kStorageKey2.origin().GetURL()); - EXPECT_TRUE( - db.GetLRUStorageKey(kTemp, exceptions, policy.get(), &storage_key)); - EXPECT_EQ(kStorageKey2, storage_key.value()); - - // Test that durable origins are excluded from eviction. - policy->AddDurable(kStorageKey2.origin().GetURL()); - EXPECT_TRUE( - db.GetLRUStorageKey(kTemp, exceptions, policy.get(), &storage_key)); - EXPECT_EQ(kStorageKey3, storage_key.value()); - - exceptions.insert(kStorageKey1); - EXPECT_TRUE(db.GetLRUStorageKey(kTemp, exceptions, nullptr, &storage_key)); - EXPECT_EQ(kStorageKey2, storage_key.value()); - - exceptions.insert(kStorageKey2); - EXPECT_TRUE(db.GetLRUStorageKey(kTemp, exceptions, nullptr, &storage_key)); - EXPECT_EQ(kStorageKey3, storage_key.value()); - - exceptions.insert(kStorageKey3); - EXPECT_TRUE(db.GetLRUStorageKey(kTemp, exceptions, nullptr, &storage_key)); - EXPECT_FALSE(storage_key.has_value()); - - EXPECT_TRUE( - db.SetStorageKeyLastAccessTime(kStorageKey1, kTemp, base::Time::Now())); - - // Delete StorageKey/type last access time information. - EXPECT_TRUE(db.DeleteStorageKeyInfo(kStorageKey3, kTemp)); - - // Querying again to see if the deletion has worked. - exceptions.clear(); - EXPECT_TRUE(db.GetLRUStorageKey(kTemp, exceptions, nullptr, &storage_key)); - EXPECT_EQ(kStorageKey2, storage_key.value()); - - exceptions.insert(kStorageKey1); - exceptions.insert(kStorageKey2); - EXPECT_TRUE(db.GetLRUStorageKey(kTemp, exceptions, nullptr, &storage_key)); - EXPECT_FALSE(storage_key.has_value()); -} - TEST_P(QuotaDatabaseTest, BucketLastAccessTimeLRU) { QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); EXPECT_TRUE(LazyOpen(&db, LazyOpenMode::kCreateIfNotFound)); - std::set<StorageKey> exceptions; - absl::optional<BucketId> bucket_id; - EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, nullptr, &bucket_id)); - EXPECT_FALSE(bucket_id.has_value()); + std::set<StorageKey> storage_key_exceptions; + std::set<BucketId> bucket_exceptions; + QuotaErrorOr<BucketInfo> result = db.GetLRUBucket( + kTemp, storage_key_exceptions, bucket_exceptions, nullptr); + EXPECT_FALSE(result.ok()); + EXPECT_EQ(result.error(), QuotaError::kNotFound); // Insert bucket entries into BucketTable. base::Time now = base::Time::Now(); using Entry = QuotaDatabase::BucketTableEntry; Entry bucket1 = Entry( BucketId(1), StorageKey::CreateFromStringForTesting("http://example-a/"), - kTemp, "bucket_a", 99, now, now); + kTemp, kDefaultBucketName, 99, now, now); Entry bucket2 = Entry( BucketId(2), StorageKey::CreateFromStringForTesting("http://example-b/"), - kTemp, "bucket_b", 0, now, now); + kTemp, kDefaultBucketName, 0, now, now); Entry bucket3 = Entry( BucketId(3), StorageKey::CreateFromStringForTesting("http://example-c/"), kTemp, "bucket_c", 1, now, now); @@ -415,33 +339,54 @@ EXPECT_TRUE(db.SetBucketLastAccessTime(bucket4.bucket_id, base::Time::FromJavaTime(40))); - EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, nullptr, &bucket_id)); - EXPECT_EQ(bucket1.bucket_id, bucket_id); + result = db.GetLRUBucket(kTemp, storage_key_exceptions, bucket_exceptions, + nullptr); + EXPECT_TRUE(result.ok()); + EXPECT_EQ(bucket1.bucket_id, result.value().id); // Test that unlimited origins are excluded from eviction, but // protected origins are not excluded. scoped_refptr<MockSpecialStoragePolicy> policy(new MockSpecialStoragePolicy); policy->AddUnlimited(bucket1.storage_key.origin().GetURL()); policy->AddProtected(bucket2.storage_key.origin().GetURL()); - EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, policy.get(), &bucket_id)); - EXPECT_EQ(bucket2.bucket_id, bucket_id); + result = db.GetLRUBucket(kTemp, storage_key_exceptions, bucket_exceptions, + policy.get()); + EXPECT_TRUE(result.ok()); + EXPECT_EQ(bucket2.bucket_id, result.value().id); // Test that durable origins are excluded from eviction. policy->AddDurable(bucket2.storage_key.origin().GetURL()); - EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, policy.get(), &bucket_id)); - EXPECT_EQ(bucket3.bucket_id, bucket_id); + result = db.GetLRUBucket(kTemp, storage_key_exceptions, bucket_exceptions, + policy.get()); + EXPECT_TRUE(result.ok()); + EXPECT_EQ(bucket3.bucket_id, result.value().id); - exceptions.insert(bucket1.storage_key); - EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, nullptr, &bucket_id)); - EXPECT_EQ(bucket2.bucket_id, bucket_id); + // Test storage key exceptions exclude storage key default buckets. + storage_key_exceptions.insert(bucket1.storage_key); + result = db.GetLRUBucket(kTemp, storage_key_exceptions, bucket_exceptions, + nullptr); + EXPECT_TRUE(result.ok()); + EXPECT_EQ(bucket2.bucket_id, result.value().id); - exceptions.insert(bucket2.storage_key); - EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, nullptr, &bucket_id)); - EXPECT_EQ(bucket3.bucket_id, bucket_id); + storage_key_exceptions.insert(bucket2.storage_key); + result = db.GetLRUBucket(kTemp, storage_key_exceptions, bucket_exceptions, + nullptr); + EXPECT_TRUE(result.ok()); + EXPECT_EQ(bucket3.bucket_id, result.value().id); - exceptions.insert(bucket3.storage_key); - EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, nullptr, &bucket_id)); - EXPECT_FALSE(bucket_id.has_value()); + // Storage key exceptions does not exclude non-default buckets. + storage_key_exceptions.insert(bucket3.storage_key); + result = db.GetLRUBucket(kTemp, storage_key_exceptions, bucket_exceptions, + nullptr); + EXPECT_TRUE(result.ok()); + EXPECT_EQ(bucket3.bucket_id, result.value().id); + + // Bucket exceptions exclude specified buckets. + bucket_exceptions.insert(bucket3.bucket_id); + result = db.GetLRUBucket(kTemp, storage_key_exceptions, bucket_exceptions, + nullptr); + EXPECT_FALSE(result.ok()); + EXPECT_EQ(result.error(), QuotaError::kNotFound); EXPECT_TRUE(db.SetBucketLastAccessTime(bucket1.bucket_id, base::Time::Now())); @@ -449,14 +394,18 @@ EXPECT_TRUE(db.DeleteBucketInfo(bucket3.bucket_id)); // Querying again to see if the deletion has worked. - exceptions.clear(); - EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, nullptr, &bucket_id)); - EXPECT_EQ(bucket2.bucket_id, bucket_id); + storage_key_exceptions.clear(); + result = db.GetLRUBucket(kTemp, storage_key_exceptions, bucket_exceptions, + nullptr); + EXPECT_TRUE(result.ok()); + EXPECT_EQ(bucket2.bucket_id, result.value().id); - exceptions.insert(bucket1.storage_key); - exceptions.insert(bucket2.storage_key); - EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, nullptr, &bucket_id)); - EXPECT_FALSE(bucket_id.has_value()); + storage_key_exceptions.insert(bucket1.storage_key); + storage_key_exceptions.insert(bucket2.storage_key); + result = db.GetLRUBucket(kTemp, storage_key_exceptions, bucket_exceptions, + nullptr); + EXPECT_FALSE(result.ok()); + EXPECT_EQ(result.error(), QuotaError::kNotFound); } TEST_P(QuotaDatabaseTest, StorageKeyLastModifiedBetween) {
diff --git a/storage/browser/quota/quota_manager_impl.cc b/storage/browser/quota/quota_manager_impl.cc index 2ebe2c729..064c735 100644 --- a/storage/browser/quota/quota_manager_impl.cc +++ b/storage/browser/quota/quota_manager_impl.cc
@@ -6,6 +6,7 @@ #include <stddef.h> #include <stdint.h> +#include <sstream> #include <algorithm> #include <functional> @@ -20,6 +21,7 @@ #include "base/files/file_util.h" #include "base/macros.h" #include "base/memory/scoped_refptr.h" +#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/numerics/safe_conversions.h" #include "base/rand_util.h" @@ -136,36 +138,42 @@ return false; } -bool GetLRUStorageKeyOnDBThread(StorageType type, - const std::set<StorageKey>& exceptions, - SpecialStoragePolicy* policy, - absl::optional<StorageKey>* storage_key, - QuotaDatabase* database) { +QuotaErrorOr<BucketInfo> GetLRUBucketOnDBThread( + StorageType type, + const std::set<StorageKey>& storage_key_exceptions, + const std::set<BucketId>& bucket_exceptions, + SpecialStoragePolicy* policy, + QuotaDatabase* database) { DCHECK(database); - database->GetLRUStorageKey(type, exceptions, policy, storage_key); - return true; + return database->GetLRUBucket(type, storage_key_exceptions, bucket_exceptions, + policy); } bool DeleteStorageKeyInfoOnDBThread(const StorageKey& storage_key, StorageType type, - bool is_eviction, QuotaDatabase* database) { DCHECK(database); + return database->DeleteStorageKeyInfo(storage_key, type); +} - base::Time now = base::Time::Now(); +bool DeleteBucketInfoOnDBThread(const BucketId bucket_id, + bool is_eviction, + QuotaDatabase* database) { + DCHECK(database); if (is_eviction) { + base::Time now = base::Time::Now(); QuotaDatabase::BucketTableEntry entry; - database->GetStorageKeyInfo(storage_key, type, &entry); - UMA_HISTOGRAM_COUNTS_1M( - QuotaManagerImpl::kEvictedOriginAccessedCountHistogram, + database->GetBucketInfo(bucket_id, &entry); + base::UmaHistogramCounts1M( + QuotaManagerImpl::kEvictedBucketAccessedCountHistogram, entry.use_count); - UMA_HISTOGRAM_COUNTS_1000( - QuotaManagerImpl::kEvictedOriginDaysSinceAccessHistogram, + base::UmaHistogramCounts1000( + QuotaManagerImpl::kEvictedBucketDaysSinceAccessHistogram, (now - entry.last_accessed).InDays()); } - return database->DeleteStorageKeyInfo(storage_key, type); + return database->DeleteBucketInfo(bucket_id); } bool BootstrapDatabaseOnDBThread(std::set<StorageKey> storage_keys, @@ -229,8 +237,8 @@ constexpr int QuotaManagerImpl::kThresholdOfErrorsToBeDenylisted; constexpr int QuotaManagerImpl::kThresholdRandomizationPercent; constexpr char QuotaManagerImpl::kDatabaseName[]; -constexpr char QuotaManagerImpl::kEvictedOriginAccessedCountHistogram[]; -constexpr char QuotaManagerImpl::kEvictedOriginDaysSinceAccessHistogram[]; +constexpr char QuotaManagerImpl::kEvictedBucketAccessedCountHistogram[]; +constexpr char QuotaManagerImpl::kEvictedBucketDaysSinceAccessHistogram[]; QuotaManagerImpl::QuotaOverride::QuotaOverride() = default; QuotaManagerImpl::QuotaOverride::~QuotaOverride() = default; @@ -563,7 +571,6 @@ const StorageKey& storage_key, StorageType type, QuotaClientTypes quota_client_types, - bool is_eviction, StatusCallback callback) : QuotaTask(manager), storage_key_(storage_key), @@ -572,7 +579,6 @@ error_count_(0), remaining_clients_(0), skipped_clients_(0), - is_eviction_(is_eviction), callback_(std::move(callback)) {} protected: @@ -607,8 +613,7 @@ if (error_count_ == 0) { // Only remove the entire storage key if we didn't skip any client types. if (skipped_clients_ == 0) - manager()->DeleteStorageKeyFromDatabase(storage_key_, type_, - is_eviction_); + manager()->DeleteStorageKeyFromDatabase(storage_key_, type_); std::move(callback_).Run(blink::mojom::QuotaStatusCode::kOk); } else { std::move(callback_).Run( @@ -646,12 +651,120 @@ int error_count_; size_t remaining_clients_; int skipped_clients_; - const bool is_eviction_; StatusCallback callback_; base::WeakPtrFactory<StorageKeyDataDeleter> weak_factory_{this}; }; +// Calls all QuotaClients for the bucket StorageType to delete bucket data. +// Keeps track of operations that have failed, and will only complete the +// task if all operations have succeeded. This is currently only for the default +// bucket. If a non-default bucket is to be evicted, it will immediately +// complete the task since non-default bucket usage is not being tracked by +// QuotaClients yet. +// TODO(crbug.com/1199417): Update to call QuotaClients to clear data for +// non-default buckets when QuotaClient is migrated to operate on buckets. +class QuotaManagerImpl::BucketDataDeleter : public QuotaTask { + public: + BucketDataDeleter(QuotaManagerImpl* manager, + const BucketInfo& bucket, + QuotaClientTypes quota_client_types, + bool is_eviction, + StatusCallback callback) + : QuotaTask(manager), + bucket_(bucket), + quota_client_types_(std::move(quota_client_types)), + is_eviction_(is_eviction), + callback_(std::move(callback)) {} + + protected: + void Run() override { + DCHECK(manager()->client_types_.contains(bucket_.type)); + + // If bucket is not the default bucket, skip calls to the QuotaClient since + // they are not being tracked yet. + // TODO(crbug.com/1199417): Update to call for all buckets once QuotaClient + // is migrated to operate on buckets. + if (!bucket_.is_default()) { + CallCompleted(); + return; + } + + remaining_clients_ = manager()->client_types_[bucket_.type].size(); + + for (const auto& client_and_type : manager()->client_types_[bucket_.type]) { + mojom::QuotaClient* client = client_and_type.first; + QuotaClientType client_type = client_and_type.second; + if (quota_client_types_.contains(client_type)) { + static int tracing_id = 0; + std::ostringstream bucket_params; + bucket_params << "storage_key: " << bucket_.storage_key.Serialize() + << ", name: " << bucket_.name << ", id: " << bucket_.id; + TRACE_EVENT_NESTABLE_ASYNC_BEGIN2( + "browsing_data", "QuotaManagerImpl::BucketDataDeleter", + ++tracing_id, "client_type", client_type, "bucket", + bucket_params.str()); + client->DeleteStorageKeyData( + bucket_.storage_key, bucket_.type, + base::BindOnce(&BucketDataDeleter::DidDeleteBucketData, + weak_factory_.GetWeakPtr(), tracing_id)); + } else { + ++skipped_clients_; + --remaining_clients_; + } + } + + if (remaining_clients_ == 0) + CallCompleted(); + } + + void Completed() override { + if (error_count_ == 0) { + // Only remove the bucket if we didn't skip any client types. + if (skipped_clients_ == 0) + manager()->DeleteBucketFromDatabase(bucket_.id, is_eviction_); + std::move(callback_).Run(blink::mojom::QuotaStatusCode::kOk); + } else { + std::move(callback_).Run( + blink::mojom::QuotaStatusCode::kErrorInvalidModification); + } + DeleteSoon(); + } + + void Aborted() override { + std::move(callback_).Run(blink::mojom::QuotaStatusCode::kErrorAbort); + DeleteSoon(); + } + + private: + void DidDeleteBucketData(int tracing_id, + blink::mojom::QuotaStatusCode status) { + DCHECK_GT(remaining_clients_, 0U); + TRACE_EVENT_NESTABLE_ASYNC_END0( + "browsing_data", "QuotaManagerImpl::BucketDataDeleter", tracing_id); + + if (status != blink::mojom::QuotaStatusCode::kOk) + ++error_count_; + + if (--remaining_clients_ == 0) + CallCompleted(); + } + + QuotaManagerImpl* manager() const { + return static_cast<QuotaManagerImpl*>(observer()); + } + + const BucketInfo bucket_; + const QuotaClientTypes quota_client_types_; + int error_count_ = 0; + size_t remaining_clients_ = 0; + int skipped_clients_ = 0; + const bool is_eviction_; + StatusCallback callback_; + + base::WeakPtrFactory<BucketDataDeleter> weak_factory_{this}; +}; + class QuotaManagerImpl::HostDataDeleter : public QuotaTask { public: HostDataDeleter(QuotaManagerImpl* manager, @@ -714,7 +827,7 @@ remaining_deleters_ = storage_keys_.size(); for (const auto& storage_key : storage_keys_) { StorageKeyDataDeleter* deleter = new StorageKeyDataDeleter( - manager(), storage_key, type_, std::move(quota_client_types_), false, + manager(), storage_key, type_, std::move(quota_client_types_), base::BindOnce(&HostDataDeleter::DidDeleteStorageKeyData, weak_factory_.GetWeakPtr())); deleter->Start(); @@ -933,7 +1046,6 @@ base::TaskShutdownBehavior::BLOCK_SHUTDOWN})), get_settings_function_(get_settings_function), quota_change_callback_(std::move(quota_change_callback)), - is_getting_eviction_storage_key_(false), special_storage_policy_(std::move(special_storage_policy)), get_volume_info_fn_(&QuotaManagerImpl::GetVolumeInfo) { DCHECK_EQ(settings_.refresh_interval, base::TimeDelta::Max()); @@ -1143,7 +1255,7 @@ StatusCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DeleteStorageKeyDataInternal(storage_key, type, std::move(quota_client_types), - false, std::move(callback)); + std::move(callback)); } void QuotaManagerImpl::PerformStorageCleanup( @@ -1376,7 +1488,7 @@ } void QuotaManagerImpl::BootstrapDatabaseForEviction( - GetStorageKeyCallback did_get_storage_key_callback, + GetBucketCallback did_get_bucket_callback, int64_t usage, int64_t unlimited_usage) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -1389,17 +1501,16 @@ base::BindOnce(&BootstrapDatabaseOnDBThread, std::move(storage_keys)), base::BindOnce(&QuotaManagerImpl::DidBootstrapDatabase, weak_factory_.GetWeakPtr(), - std::move(did_get_storage_key_callback))); + std::move(did_get_bucket_callback))); } void QuotaManagerImpl::DidBootstrapDatabase( - GetStorageKeyCallback did_get_storage_key_callback, + GetBucketCallback did_get_bucket_callback, bool success) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); is_database_bootstrapped_ = success; DidDatabaseWork(success); - GetLRUStorageKey(StorageType::kTemporary, - std::move(did_get_storage_key_callback)); + GetLRUBucket(StorageType::kTemporary, std::move(did_get_bucket_callback)); } void QuotaManagerImpl::RegisterClient( @@ -1446,8 +1557,8 @@ base::Time access_time) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); LazyInitialize(); - if (type == StorageType::kTemporary && is_getting_eviction_storage_key_) { - // Record the accessed storage keys while GetLRUStorageKey task is running + if (type == StorageType::kTemporary && is_getting_eviction_bucket_) { + // Record the accessed storage keys while GetLRUBucket task is running // to filter out them from eviction. access_notified_storage_keys_.insert(storage_key); } @@ -1523,8 +1634,7 @@ void QuotaManagerImpl::DeleteStorageKeyFromDatabase( const StorageKey& storage_key, - StorageType type, - bool is_eviction) { + StorageType type) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); LazyInitialize(); if (db_disabled_) @@ -1532,38 +1642,64 @@ PostTaskAndReplyWithResultForDBThread( FROM_HERE, - base::BindOnce(&DeleteStorageKeyInfoOnDBThread, storage_key, type, - is_eviction), + base::BindOnce(&DeleteStorageKeyInfoOnDBThread, storage_key, type), base::BindOnce(&QuotaManagerImpl::DidDatabaseWork, weak_factory_.GetWeakPtr())); } -void QuotaManagerImpl::DidStorageKeyDataEvicted( +void QuotaManagerImpl::DeleteBucketFromDatabase(BucketId bucket_id, + bool is_eviction) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + LazyInitialize(); + if (db_disabled_) + return; + + PostTaskAndReplyWithResultForDBThread( + FROM_HERE, + base::BindOnce(&DeleteBucketInfoOnDBThread, bucket_id, is_eviction), + base::BindOnce(&QuotaManagerImpl::DidDatabaseWork, + weak_factory_.GetWeakPtr())); +} + +void QuotaManagerImpl::DidBucketDataEvicted( blink::mojom::QuotaStatusCode status) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(io_thread_->BelongsToCurrentThread()); - // We only try evict storage keys that are not in use, so basically - // deletion attempt for eviction should not fail. Let's record - // the storage key if we get error and exclude it from future eviction - // if the error happens consistently (> kThresholdOfErrorsToBeDenylisted). + // We only try to evict buckets that are not in use, so basically deletion + // attempt for eviction should not fail. Let's record the bucket if we get + // an error and exclude it from future eviction if the error happens + // consistently (> kThresholdOfErrorsToBeDenylisted). if (status != blink::mojom::QuotaStatusCode::kOk) - storage_keys_in_error_[eviction_context_.evicted_storage_key]++; + buckets_in_error_[eviction_context_.evicted_bucket.id]++; - std::move(eviction_context_.evict_storage_key_data_callback).Run(status); + std::move(eviction_context_.evict_bucket_data_callback).Run(status); } -void QuotaManagerImpl::DeleteStorageKeyDataInternal( - const StorageKey& storage_key, - StorageType type, +void QuotaManagerImpl::DeleteBucketDataInternal( + const BucketInfo& bucket, QuotaClientTypes quota_client_types, bool is_eviction, StatusCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); LazyInitialize(); + BucketDataDeleter* deleter = + new BucketDataDeleter(this, bucket, std::move(quota_client_types), + is_eviction, std::move(callback)); + deleter->Start(); +} + +void QuotaManagerImpl::DeleteStorageKeyDataInternal( + const StorageKey& storage_key, + StorageType type, + QuotaClientTypes quota_client_types, + StatusCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + LazyInitialize(); + StorageKeyDataDeleter* deleter = new StorageKeyDataDeleter( - this, storage_key, type, std::move(quota_client_types), is_eviction, + this, storage_key, type, std::move(quota_client_types), std::move(callback)); deleter->Start(); } @@ -1761,78 +1897,81 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); std::set<StorageKey> exceptions; for (const auto& p : storage_keys_in_use_) { - if (p.second > 0) - exceptions.insert(p.first); + DCHECK_GE(p.second, 0); + exceptions.insert(p.first); } - - for (const auto& p : storage_keys_in_error_) { - if (p.second > QuotaManagerImpl::kThresholdOfErrorsToBeDenylisted) - exceptions.insert(p.first); - } - return exceptions; } -void QuotaManagerImpl::DidGetEvictionStorageKey( - GetStorageKeyCallback callback, - const absl::optional<StorageKey>& storage_key) { +std::set<BucketId> QuotaManagerImpl::GetEvictionBucketExceptions() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // Make sure the returned storage key is (still) not in the - // storage_key_in_use_ set and has not been accessed since we posted the task. - DCHECK(!storage_key.has_value() || - !storage_key->origin().GetURL().is_empty()); - if (storage_key.has_value() && - (base::Contains(storage_keys_in_use_, *storage_key) || - base::Contains(access_notified_storage_keys_, *storage_key))) { + std::set<BucketId> exceptions; + for (const auto& p : buckets_in_error_) { + if (p.second > QuotaManagerImpl::kThresholdOfErrorsToBeDenylisted) + exceptions.insert(p.first); + } + return exceptions; +} + +void QuotaManagerImpl::DidGetEvictionBucket( + GetBucketCallback callback, + const absl::optional<BucketInfo>& bucket) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Make sure the returned bucket's storage key is (still) not in the + // `storage_keys_in_use_` set if it is the default bucket and has not been + // accessed since we posted the task. + DCHECK(!bucket.has_value() || + !bucket->storage_key.origin().GetURL().is_empty()); + if (bucket.has_value() && bucket->is_default() && + (base::Contains(storage_keys_in_use_, bucket->storage_key) || + base::Contains(access_notified_storage_keys_, bucket->storage_key))) { std::move(callback).Run(absl::nullopt); } else { - std::move(callback).Run(storage_key); + std::move(callback).Run(bucket); } access_notified_storage_keys_.clear(); - is_getting_eviction_storage_key_ = false; + is_getting_eviction_bucket_ = false; } -void QuotaManagerImpl::GetEvictionStorageKey(StorageType type, - int64_t global_quota, - GetStorageKeyCallback callback) { +void QuotaManagerImpl::GetEvictionBucket(StorageType type, + int64_t global_quota, + GetBucketCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); LazyInitialize(); // This must not be called while there's an in-flight task. - DCHECK(!is_getting_eviction_storage_key_); - is_getting_eviction_storage_key_ = true; + DCHECK(!is_getting_eviction_bucket_); + is_getting_eviction_bucket_ = true; - auto did_get_storage_key_callback = - base::BindOnce(&QuotaManagerImpl::DidGetEvictionStorageKey, + auto did_get_bucket_callback = + base::BindOnce(&QuotaManagerImpl::DidGetEvictionBucket, weak_factory_.GetWeakPtr(), std::move(callback)); if (!is_database_bootstrapped_ && !eviction_disabled_) { - // Once bootstrapped, GetLRUStorageKey will be called. + // Once bootstrapped, GetLRUBucket will be called. GetGlobalUsage( StorageType::kTemporary, base::BindOnce(&QuotaManagerImpl::BootstrapDatabaseForEviction, weak_factory_.GetWeakPtr(), - std::move(did_get_storage_key_callback))); + std::move(did_get_bucket_callback))); return; } - GetLRUStorageKey(type, std::move(did_get_storage_key_callback)); + GetLRUBucket(type, std::move(did_get_bucket_callback)); } -void QuotaManagerImpl::EvictStorageKeyData(const StorageKey& storage_key, - StorageType type, - StatusCallback callback) { +void QuotaManagerImpl::EvictBucketData(const BucketInfo& bucket, + StatusCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(io_thread_->BelongsToCurrentThread()); - DCHECK_EQ(type, StorageType::kTemporary); + DCHECK_EQ(bucket.type, StorageType::kTemporary); - eviction_context_.evicted_storage_key = storage_key; - eviction_context_.evicted_type = type; - eviction_context_.evict_storage_key_data_callback = std::move(callback); + eviction_context_.evicted_bucket = bucket; + eviction_context_.evict_bucket_data_callback = std::move(callback); - DeleteStorageKeyDataInternal( - storage_key, type, AllQuotaClientTypes(), true, - base::BindOnce(&QuotaManagerImpl::DidStorageKeyDataEvicted, + DeleteBucketDataInternal( + bucket, AllQuotaClientTypes(), true, + base::BindOnce(&QuotaManagerImpl::DidBucketDataEvicted, weak_factory_.GetWeakPtr())); } @@ -1846,28 +1985,25 @@ helper->Start(); } -void QuotaManagerImpl::GetLRUStorageKey(StorageType type, - GetStorageKeyCallback callback) { +void QuotaManagerImpl::GetLRUBucket(StorageType type, + GetBucketCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); LazyInitialize(); // This must not be called while there's an in-flight task. - DCHECK(lru_storage_key_callback_.is_null()); - lru_storage_key_callback_ = std::move(callback); + DCHECK(lru_bucket_callback_.is_null()); + lru_bucket_callback_ = std::move(callback); if (db_disabled_) { - std::move(lru_storage_key_callback_).Run(absl::nullopt); + std::move(lru_bucket_callback_).Run(absl::nullopt); return; } - auto storage_key = std::make_unique<absl::optional<StorageKey>>(); - auto* storage_key_ptr = storage_key.get(); PostTaskAndReplyWithResultForDBThread( - FROM_HERE, - base::BindOnce(&GetLRUStorageKeyOnDBThread, type, + base::BindOnce(&GetLRUBucketOnDBThread, type, GetEvictionStorageKeyExceptions(), - base::RetainedRef(special_storage_policy_), - base::Unretained(storage_key_ptr)), - base::BindOnce(&QuotaManagerImpl::DidGetLRUStorageKey, - weak_factory_.GetWeakPtr(), std::move(storage_key))); + GetEvictionBucketExceptions(), + base::RetainedRef(special_storage_policy_)), + base::BindOnce(&QuotaManagerImpl::DidGetLRUBucket, + weak_factory_.GetWeakPtr())); } void QuotaManagerImpl::DidGetPersistentHostQuota(const std::string& host, @@ -1892,13 +2028,16 @@ *new_quota); } -void QuotaManagerImpl::DidGetLRUStorageKey( - std::unique_ptr<absl::optional<StorageKey>> storage_key, - bool success) { +void QuotaManagerImpl::DidGetLRUBucket(QuotaErrorOr<BucketInfo> result) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DidDatabaseWork(success); + DidDatabaseWork(result.ok() || result.error() != QuotaError::kDatabaseError); - std::move(lru_storage_key_callback_).Run(*storage_key); + if (result.ok()) { + std::move(lru_bucket_callback_) + .Run(absl::make_optional(std::move(result.value()))); + } else { + std::move(lru_bucket_callback_).Run(absl::nullopt); + } } namespace {
diff --git a/storage/browser/quota/quota_manager_impl.h b/storage/browser/quota/quota_manager_impl.h index 9408e4296..c44fa64 100644 --- a/storage/browser/quota/quota_manager_impl.h +++ b/storage/browser/quota/quota_manager_impl.h
@@ -77,16 +77,15 @@ // the current settings, capacity, and usage. virtual void GetEvictionRoundInfo(EvictionRoundInfoCallback callback) = 0; - // Returns the next storage key to evict, or nullopt if there are no evictable - // storage keys. - virtual void GetEvictionStorageKey(blink::mojom::StorageType type, - int64_t global_quota, - GetStorageKeyCallback callback) = 0; + // Returns the next bucket to evict, or nullopt if there are no evictable + // buckets. + virtual void GetEvictionBucket(blink::mojom::StorageType type, + int64_t global_quota, + GetBucketCallback callback) = 0; - // Called to evict a storage key. - virtual void EvictStorageKeyData(const blink::StorageKey& storage_key, - blink::mojom::StorageType type, - StatusCallback callback) = 0; + // Called to evict a bucket. + virtual void EvictBucketData(const BucketInfo& bucket, + StatusCallback callback) = 0; protected: virtual ~QuotaEvictionHandler() = default; @@ -338,11 +337,10 @@ static constexpr char kDatabaseName[] = "QuotaManager"; - // TODO(crbug.com/1215208): Change counters to have StorageKey in their names. - static constexpr char kEvictedOriginAccessedCountHistogram[] = - "Quota.EvictedOriginAccessCount"; - static constexpr char kEvictedOriginDaysSinceAccessHistogram[] = - "Quota.EvictedOriginDaysSinceAccess"; + static constexpr char kEvictedBucketAccessedCountHistogram[] = + "Quota.EvictedBucketAccessCount"; + static constexpr char kEvictedBucketDaysSinceAccessHistogram[] = + "Quota.EvictedBucketDaysSinceAccess"; // Kept non-const so that test code can change the value. // TODO(kinuko): Make this a real const value and add a proper way to set @@ -373,6 +371,7 @@ class EvictionRoundInfoHelper; class UsageAndQuotaInfoGatherer; class GetUsageInfoTask; + class BucketDataDeleter; class StorageKeyDataDeleter; class HostDataDeleter; class GetModifiedSinceHelper; @@ -411,10 +410,8 @@ struct EvictionContext { EvictionContext(); ~EvictionContext(); - blink::StorageKey evicted_storage_key; - blink::mojom::StorageType evicted_type = - blink::mojom::StorageType::kUnknown; - StatusCallback evict_storage_key_data_callback; + BucketInfo evicted_bucket; + StatusCallback evict_bucket_data_callback; }; // Lazily called on the IO thread when the first quota manager API is called. @@ -423,11 +420,10 @@ // manager by RegisterClient(). void LazyInitialize(); void FinishLazyInitialize(bool is_database_bootstraped); - void BootstrapDatabaseForEviction( - GetStorageKeyCallback did_get_storage_key_callback, - int64_t unused_usage, - int64_t unused_unlimited_usage); - void DidBootstrapDatabase(GetStorageKeyCallback did_get_storage_key_callback, + void BootstrapDatabaseForEviction(GetBucketCallback did_get_bucket_callback, + int64_t unused_usage, + int64_t unused_unlimited_usage); + void DidBootstrapDatabase(GetBucketCallback did_get_bucket_callback, bool success); // Called by clients via proxy. @@ -447,19 +443,26 @@ void DumpQuotaTable(DumpQuotaTableCallback callback); void DumpBucketTable(DumpBucketTableCallback callback); + // Runs BucketDataDeleter which calls QuotaClients to clear data for the + // bucket. Once the task is complete, calls the QuotaDatabase to delete the + // bucket from the bucket table. + void DeleteBucketDataInternal(const BucketInfo& bucket, + QuotaClientTypes quota_client_types, + bool is_eviction, + StatusCallback callback); + void DeleteStorageKeyDataInternal(const blink::StorageKey& storage_key, blink::mojom::StorageType type, QuotaClientTypes quota_client_types, - bool is_eviction, StatusCallback callback); // Methods for eviction logic. void StartEviction(); void DeleteStorageKeyFromDatabase(const blink::StorageKey& storage_key, - blink::mojom::StorageType type, - bool is_eviction); + blink::mojom::StorageType type); + void DeleteBucketFromDatabase(BucketId bucket_id, bool is_eviction); - void DidStorageKeyDataEvicted(blink::mojom::QuotaStatusCode status); + void DidBucketDataEvicted(blink::mojom::QuotaStatusCode status); void ReportHistogram(); void DidGetTemporaryGlobalUsageForHistogram(int64_t usage, @@ -471,22 +474,24 @@ int64_t unlimited_usage); void DidDumpBucketTableForHistogram(const BucketTableEntries& entries); + // Returns the list of storage keys that are currently in use and should be + // excluded from eviction. std::set<blink::StorageKey> GetEvictionStorageKeyExceptions(); - void DidGetEvictionStorageKey( - GetStorageKeyCallback callback, - const absl::optional<blink::StorageKey>& storage_key); + // Returns the list of bucket ids that should be excluded from eviction due to + // consistent errors after multiple attempts. + std::set<BucketId> GetEvictionBucketExceptions(); + void DidGetEvictionBucket(GetBucketCallback callback, + const absl::optional<BucketInfo>& bucket); // QuotaEvictionHandler. - void GetEvictionStorageKey(blink::mojom::StorageType type, - int64_t global_quota, - GetStorageKeyCallback callback) override; - void EvictStorageKeyData(const blink::StorageKey& storage_key, - blink::mojom::StorageType type, - StatusCallback callback) override; + void GetEvictionBucket(blink::mojom::StorageType type, + int64_t global_quota, + GetBucketCallback callback) override; + void EvictBucketData(const BucketInfo& bucket, + StatusCallback callback) override; void GetEvictionRoundInfo(EvictionRoundInfoCallback callback) override; - void GetLRUStorageKey(blink::mojom::StorageType type, - GetStorageKeyCallback callback); + void GetLRUBucket(blink::mojom::StorageType type, GetBucketCallback callback); void DidGetPersistentHostQuota(const std::string& host, const int64_t* quota, @@ -495,9 +500,7 @@ QuotaCallback callback, const int64_t* new_quota, bool success); - void DidGetLRUStorageKey( - std::unique_ptr<absl::optional<blink::StorageKey>> storage_key, - bool success); + void DidGetLRUBucket(QuotaErrorOr<BucketInfo> result); void GetQuotaSettings(QuotaSettingsCallback callback); void DidGetSettings(absl::optional<QuotaSettings> settings); void GetStorageCapacity(StorageCapacityCallback callback); @@ -576,7 +579,10 @@ CallbackQueue<StorageCapacityCallback, int64_t, int64_t> storage_capacity_callbacks_; - GetStorageKeyCallback lru_storage_key_callback_; + GetBucketCallback lru_bucket_callback_; + + // Keeps track of storage keys that have been accessed during an eviction task + // so they can be filtered out from eviction. std::set<blink::StorageKey> access_notified_storage_keys_; std::map<blink::StorageKey, QuotaOverride> devtools_overrides_; @@ -607,7 +613,8 @@ std::unique_ptr<QuotaTemporaryStorageEvictor> temporary_storage_evictor_; EvictionContext eviction_context_; - bool is_getting_eviction_storage_key_; + // Set when there is an eviction task in-flight. + bool is_getting_eviction_bucket_ = false; CallbackQueueMap<QuotaCallback, std::string, @@ -615,10 +622,14 @@ int64_t> persistent_host_quota_callbacks_; - // Map from storage key to count. + // Map from storage key to count. This is only for the default bucket. + // TODO(crbug.com/1199417): Update to be `buckets_in_use_` when QuotaClient + // is migrated to operate on buckets and keep track for all buckets in use, + // not just default. std::map<blink::StorageKey, int> storage_keys_in_use_; - // Map from storage key to error count. - std::map<blink::StorageKey, int> storage_keys_in_error_; + + // Map from bucket id to eviction error count. + std::map<BucketId, int> buckets_in_error_; scoped_refptr<SpecialStoragePolicy> special_storage_policy_;
diff --git a/storage/browser/quota/quota_manager_unittest.cc b/storage/browser/quota/quota_manager_unittest.cc index 1844183..dc01200 100644 --- a/storage/browser/quota/quota_manager_unittest.cc +++ b/storage/browser/quota/quota_manager_unittest.cc
@@ -141,28 +141,34 @@ void GetOrCreateBucket(const StorageKey& storage_key, const std::string& bucket_name) { + base::RunLoop run_loop; quota_manager_impl_->GetOrCreateBucket( storage_key, bucket_name, base::BindOnce(&QuotaManagerImplTest::DidGetBucket, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr(), run_loop.QuitClosure())); + run_loop.Run(); } void CreateBucketForTesting(const StorageKey& storage_key, const std::string& bucket_name, blink::mojom::StorageType storage_type) { + base::RunLoop run_loop; quota_manager_impl_->CreateBucketForTesting( storage_key, bucket_name, storage_type, base::BindOnce(&QuotaManagerImplTest::DidGetBucket, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr(), run_loop.QuitClosure())); + run_loop.Run(); } void GetBucket(const StorageKey& storage_key, const std::string& bucket_name, blink::mojom::StorageType storage_type) { + base::RunLoop run_loop; quota_manager_impl_->GetBucket( storage_key, bucket_name, storage_type, base::BindOnce(&QuotaManagerImplTest::DidGetBucket, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr(), run_loop.QuitClosure())); + run_loop.Run(); } void GetUsageInfo() { @@ -277,12 +283,11 @@ weak_factory_.GetWeakPtr())); } - void EvictStorageKeyData(const StorageKey& storage_key, StorageType type) { + void EvictBucketData(const BucketInfo& bucket) { quota_status_ = QuotaStatusCode::kUnknown; - quota_manager_impl_->EvictStorageKeyData( - storage_key, type, - base::BindOnce(&QuotaManagerImplTest::StatusCallback, - weak_factory_.GetWeakPtr())); + quota_manager_impl_->EvictBucketData( + bucket, base::BindOnce(&QuotaManagerImplTest::StatusCallback, + weak_factory_.GetWeakPtr())); } void DeleteStorageKeyData(const StorageKey& storage_key, @@ -333,18 +338,17 @@ IncrementMockTime()); } - void DeleteStorageKeyFromDatabase(const StorageKey& storage_key, - StorageType type) { - quota_manager_impl_->DeleteStorageKeyFromDatabase(storage_key, type, false); + void DeleteBucketFromDatabase(BucketId bucket_id) { + quota_manager_impl_->DeleteBucketFromDatabase(bucket_id, false); } - void GetEvictionStorageKey(StorageType type) { - eviction_storage_key_.reset(); + void GetEvictionBucket(StorageType type) { + eviction_bucket_.reset(); // The quota manager's default eviction policy is to use an LRU eviction // policy. - quota_manager_impl_->GetEvictionStorageKey( + quota_manager_impl_->GetEvictionBucket( type, 0, - base::BindOnce(&QuotaManagerImplTest::DidGetEvictionStorageKey, + base::BindOnce(&QuotaManagerImplTest::DidGetEvictionBucket, weak_factory_.GetWeakPtr())); } @@ -379,8 +383,10 @@ &QuotaManagerImplTest::DidDumpBucketTable, weak_factory_.GetWeakPtr())); } - void DidGetBucket(QuotaErrorOr<BucketInfo> result) { + void DidGetBucket(base::OnceClosure quit_closure, + QuotaErrorOr<BucketInfo> result) { bucket_ = std::move(result); + std::move(quit_closure).Run(); } void DidGetUsageInfo(UsageInfoEntries entries) { @@ -453,10 +459,10 @@ usage_ = global_usage; } - void DidGetEvictionStorageKey(const absl::optional<StorageKey>& storage_key) { - eviction_storage_key_ = storage_key; - DCHECK(!storage_key.has_value() || - !storage_key->origin().GetURL().is_empty()); + void DidGetEvictionBucket(const absl::optional<BucketInfo>& bucket) { + eviction_bucket_ = bucket; + DCHECK(!bucket.has_value() || + !bucket->storage_key.origin().GetURL().is_empty()); } void DidGetModifiedStorageKeys(const std::set<StorageKey>& storage_keys, @@ -524,8 +530,8 @@ int64_t quota() const { return quota_; } int64_t total_space() const { return total_space_; } int64_t available_space() const { return available_space_; } - const absl::optional<StorageKey>& eviction_storage_key() const { - return eviction_storage_key_; + const absl::optional<BucketInfo>& eviction_bucket() const { + return eviction_bucket_; } const std::set<StorageKey>& modified_storage_keys() const { return modified_storage_keys_; @@ -568,7 +574,7 @@ int64_t quota_; int64_t total_space_; int64_t available_space_; - absl::optional<StorageKey> eviction_storage_key_; + absl::optional<BucketInfo> eviction_bucket_; std::set<StorageKey> modified_storage_keys_; StorageType modified_storage_keys_type_; QuotaTableEntries quota_entries_; @@ -630,13 +636,11 @@ std::string bucket_name = "bucket_a"; GetOrCreateBucket(storage_key, bucket_name); - task_environment_.RunUntilIdle(); ASSERT_TRUE(bucket_.ok()); BucketId created_bucket_id = bucket_.value().id; GetOrCreateBucket(storage_key, bucket_name); - task_environment_.RunUntilIdle(); EXPECT_TRUE(bucket_.ok()); EXPECT_EQ(bucket_.value().id, created_bucket_id); } @@ -646,18 +650,15 @@ std::string bucket_name = "bucket_a"; CreateBucketForTesting(storage_key, bucket_name, kTemp); - task_environment_.RunUntilIdle(); ASSERT_TRUE(bucket_.ok()); BucketInfo created_bucket = bucket_.value(); GetBucket(storage_key, bucket_name, kTemp); - task_environment_.RunUntilIdle(); ASSERT_TRUE(bucket_.ok()); BucketInfo retrieved_bucket = bucket_.value(); EXPECT_EQ(created_bucket.id, retrieved_bucket.id); GetBucket(storage_key, "bucket_b", kTemp); - task_environment_.RunUntilIdle(); ASSERT_FALSE(bucket_.ok()); EXPECT_EQ(bucket_.error(), QuotaError::kNotFound); } @@ -1599,7 +1600,7 @@ EXPECT_LE(0, available_space()); } -TEST_F(QuotaManagerImplTest, EvictStorageKeyData) { +TEST_F(QuotaManagerImplTest, EvictBucketData) { static const MockStorageKeyData kData1[] = { {"http://foo.com/", kTemp, 1}, {"http://foo.com:1/", kTemp, 20}, @@ -1640,16 +1641,20 @@ } task_environment_.RunUntilIdle(); - EvictStorageKeyData(ToStorageKey("http://foo.com/"), kTemp); + GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName, kTemp); + ASSERT_TRUE(bucket_.ok()); + + EvictBucketData(bucket_.value()); task_environment_.RunUntilIdle(); DumpBucketTable(); task_environment_.RunUntilIdle(); for (const auto& entry : bucket_entries()) { - if (entry.type == kTemp) + if (entry.type == kTemp) { EXPECT_NE(std::string("http://foo.com/"), entry.storage_key.origin().GetURL().spec()); + } } GetGlobalUsage(kTemp); @@ -1665,7 +1670,69 @@ EXPECT_EQ(predelete_host_pers, usage()); } -TEST_F(QuotaManagerImplTest, EvictStorageKeyDataHistogram) { +TEST_F(QuotaManagerImplTest, EvictNonDefaultBucketData) { + static const MockStorageKeyData kData[] = {{"http://foo.com/", kTemp, 100}}; + CreateAndRegisterClient(kData, QuotaClientType::kFileSystem, {kTemp}); + + GetGlobalUsage(kTemp); + task_environment_.RunUntilIdle(); + int64_t predelete_global_tmp = usage(); + + GetHostUsageWithBreakdown("foo.com", kTemp); + task_environment_.RunUntilIdle(); + int64_t predelete_host_tmp = usage(); + + StorageKey storage_key = ToStorageKey("http://foo.com/"); + quota_manager_impl()->NotifyStorageAccessed(storage_key, kTemp, + base::Time::Now()); + task_environment_.RunUntilIdle(); + + CreateBucketForTesting(storage_key, "foo_bucket", kTemp); + ASSERT_TRUE(bucket_.ok()); + BucketInfo created_bucket = bucket_.value(); + + EvictBucketData(created_bucket); + task_environment_.RunUntilIdle(); + + EXPECT_EQ(QuotaStatusCode::kOk, status()); + + DumpBucketTable(); + task_environment_.RunUntilIdle(); + + for (const auto& entry : bucket_entries()) { + if (entry.type == kTemp) + EXPECT_NE(created_bucket.id, entry.bucket_id); + } + + // Evicting non-default bucket should not change usage. + GetGlobalUsage(kTemp); + task_environment_.RunUntilIdle(); + EXPECT_EQ(predelete_global_tmp, usage()); + + GetHostUsageWithBreakdown("foo.com", kTemp); + task_environment_.RunUntilIdle(); + EXPECT_EQ(predelete_host_tmp, usage()); + + GetBucket(storage_key, kDefaultBucketName, kTemp); + ASSERT_TRUE(bucket_.ok()); + BucketInfo default_bucket = bucket_.value(); + + EvictBucketData(default_bucket); + task_environment_.RunUntilIdle(); + + EXPECT_EQ(QuotaStatusCode::kOk, status()); + + // Evicting default bucket should remove usage. + GetGlobalUsage(kTemp); + task_environment_.RunUntilIdle(); + EXPECT_EQ(usage(), 0); + + GetHostUsageWithBreakdown("foo.com", kTemp); + task_environment_.RunUntilIdle(); + EXPECT_EQ(usage(), 0); +} + +TEST_F(QuotaManagerImplTest, EvictBucketDataHistogram) { const StorageKey kStorageKey = ToStorageKey("http://foo.com/"); static const MockStorageKeyData kData[] = { {"http://foo.com/", kTemp, 1}, @@ -1679,16 +1746,19 @@ GetGlobalUsage(kTemp); task_environment_.RunUntilIdle(); - EvictStorageKeyData(kStorageKey, kTemp); + CreateBucketForTesting(kStorageKey, kDefaultBucketName, kTemp); + ASSERT_TRUE(bucket_.ok()); + + EvictBucketData(bucket_.value()); task_environment_.RunUntilIdle(); // Ensure use count and time since access are recorded. histograms.ExpectTotalCount( - QuotaManagerImpl::kEvictedOriginAccessedCountHistogram, 1); + QuotaManagerImpl::kEvictedBucketAccessedCountHistogram, 1); histograms.ExpectBucketCount( - QuotaManagerImpl::kEvictedOriginAccessedCountHistogram, 0, 1); + QuotaManagerImpl::kEvictedBucketAccessedCountHistogram, 0, 1); histograms.ExpectTotalCount( - QuotaManagerImpl::kEvictedOriginDaysSinceAccessHistogram, 1); + QuotaManagerImpl::kEvictedBucketDaysSinceAccessHistogram, 1); client->AddStorageKeyAndNotify(kStorageKey, kTemp, 100); @@ -1700,26 +1770,26 @@ GetGlobalUsage(kTemp); task_environment_.RunUntilIdle(); - EvictStorageKeyData(kStorageKey, kTemp); + EvictBucketData(bucket_.value()); task_environment_.RunUntilIdle(); // The new use count should be logged. histograms.ExpectTotalCount( - QuotaManagerImpl::kEvictedOriginAccessedCountHistogram, 2); + QuotaManagerImpl::kEvictedBucketAccessedCountHistogram, 2); histograms.ExpectBucketCount( - QuotaManagerImpl::kEvictedOriginAccessedCountHistogram, 1, 1); + QuotaManagerImpl::kEvictedBucketAccessedCountHistogram, 1, 1); histograms.ExpectTotalCount( - QuotaManagerImpl::kEvictedOriginDaysSinceAccessHistogram, 2); + QuotaManagerImpl::kEvictedBucketDaysSinceAccessHistogram, 2); } -TEST_F(QuotaManagerImplTest, EvictStorageKeyDataWithDeletionError) { +TEST_F(QuotaManagerImplTest, EvictBucketDataWithDeletionError) { static const MockStorageKeyData kData[] = { {"http://foo.com/", kTemp, 1}, {"http://foo.com:1/", kTemp, 20}, {"http://foo.com/", kPerm, 300}, {"http://bar.com/", kTemp, 4000}, }; - static const int kNumberOfTemporaryStorageKeys = 3; + static const int kNumberOfTemporaryBuckets = 3; MockQuotaClient* client = CreateAndRegisterClient(kData, QuotaClientType::kFileSystem, {blink::mojom::StorageType::kTemporary, @@ -1743,9 +1813,12 @@ client->AddStorageKeyToErrorSet(ToStorageKey("http://foo.com/"), kTemp); + GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName, kTemp); + ASSERT_TRUE(bucket_.ok()); + for (int i = 0; i < QuotaManagerImpl::kThresholdOfErrorsToBeDenylisted + 1; ++i) { - EvictStorageKeyData(ToStorageKey("http://foo.com/"), kTemp); + EvictBucketData(bucket_.value()); task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kErrorInvalidModification, status()); } @@ -1755,33 +1828,33 @@ bool found_storage_key_in_database = false; for (const auto& entry : bucket_entries()) { - if (entry.type == kTemp && + if (entry.type == kTemp && entry.name == kDefaultBucketName && entry.storage_key == ToStorageKey("http://foo.com/")) { found_storage_key_in_database = true; break; } } - // The storage key for "http://foo.com/" should be in the database. + // The default bucket for "http://foo.com/" should be in the database. EXPECT_TRUE(found_storage_key_in_database); - for (size_t i = 0; i < kNumberOfTemporaryStorageKeys - 1; ++i) { - GetEvictionStorageKey(kTemp); + for (size_t i = 0; i < kNumberOfTemporaryBuckets - 1; ++i) { + GetEvictionBucket(kTemp); task_environment_.RunUntilIdle(); - EXPECT_TRUE(eviction_storage_key().has_value()); + EXPECT_TRUE(eviction_bucket().has_value()); // "http://foo.com/" should not be in the LRU list. EXPECT_NE(std::string("http://foo.com/"), - eviction_storage_key()->origin().GetURL().spec()); - DeleteStorageKeyFromDatabase(*eviction_storage_key(), kTemp); + eviction_bucket()->storage_key.origin().GetURL().spec()); + DeleteBucketFromDatabase(eviction_bucket()->id); task_environment_.RunUntilIdle(); } // Now the LRU list must be empty. - GetEvictionStorageKey(kTemp); + GetEvictionBucket(kTemp); task_environment_.RunUntilIdle(); - EXPECT_FALSE(eviction_storage_key().has_value()); + EXPECT_FALSE(eviction_bucket().has_value()); - // Deleting storage keys from the database should not affect the results of - // the following checks. + // Deleting buckets from the database should not affect the results of the + // following checks. GetGlobalUsage(kTemp); task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_global_tmp, usage()); @@ -2064,8 +2137,6 @@ EXPECT_EQ(QuotaStatusCode::kOk, status()); } -// Single-run DeleteStorageKeyData cases must be well covered by -// EvictStorageKeyData tests. TEST_F(QuotaManagerImplTest, DeleteStorageKeyDataMultiple) { static const MockStorageKeyData kData1[] = { {"http://foo.com/", kTemp, 1}, @@ -2306,7 +2377,7 @@ } } -TEST_F(QuotaManagerImplTest, NotifyAndLRUStorageKey) { +TEST_F(QuotaManagerImplTest, NotifyAndLRUBucket) { static const MockStorageKeyData kData[] = { {"http://a.com/", kTemp, 0}, {"http://a.com:1/", kTemp, 0}, {"https://a.com/", kTemp, 0}, {"http://b.com/", kPerm, 0}, // persistent @@ -2316,34 +2387,38 @@ {blink::mojom::StorageType::kTemporary, blink::mojom::StorageType::kPersistent}); - GetEvictionStorageKey(kTemp); + GetEvictionBucket(kTemp); task_environment_.RunUntilIdle(); - EXPECT_FALSE(eviction_storage_key().has_value()); + EXPECT_FALSE(eviction_bucket().has_value()); NotifyStorageAccessed(ToStorageKey("http://a.com/"), kTemp); - GetEvictionStorageKey(kTemp); + GetEvictionBucket(kTemp); task_environment_.RunUntilIdle(); - EXPECT_EQ("http://a.com/", eviction_storage_key()->origin().GetURL().spec()); + EXPECT_EQ("http://a.com/", + eviction_bucket()->storage_key.origin().GetURL().spec()); NotifyStorageAccessed(ToStorageKey("http://b.com/"), kPerm); NotifyStorageAccessed(ToStorageKey("https://a.com/"), kTemp); NotifyStorageAccessed(ToStorageKey("http://c.com/"), kTemp); - GetEvictionStorageKey(kTemp); + GetEvictionBucket(kTemp); task_environment_.RunUntilIdle(); - EXPECT_EQ("http://a.com/", eviction_storage_key()->origin().GetURL().spec()); + EXPECT_EQ("http://a.com/", + eviction_bucket()->storage_key.origin().GetURL().spec()); - DeleteStorageKeyFromDatabase(*eviction_storage_key(), kTemp); - GetEvictionStorageKey(kTemp); + DeleteBucketFromDatabase(eviction_bucket()->id); + GetEvictionBucket(kTemp); task_environment_.RunUntilIdle(); - EXPECT_EQ("https://a.com/", eviction_storage_key()->origin().GetURL().spec()); + EXPECT_EQ("https://a.com/", + eviction_bucket()->storage_key.origin().GetURL().spec()); - DeleteStorageKeyFromDatabase(*eviction_storage_key(), kTemp); - GetEvictionStorageKey(kTemp); + DeleteBucketFromDatabase(eviction_bucket()->id); + GetEvictionBucket(kTemp); task_environment_.RunUntilIdle(); - EXPECT_EQ("http://c.com/", eviction_storage_key()->origin().GetURL().spec()); + EXPECT_EQ("http://c.com/", + eviction_bucket()->storage_key.origin().GetURL().spec()); } -TEST_F(QuotaManagerImplTest, GetLRUStorageKeyWithStorageKeyInUse) { +TEST_F(QuotaManagerImplTest, GetLRUBucketWithStorageKeyInUse) { static const MockStorageKeyData kData[] = { {"http://a.com/", kTemp, 0}, {"http://a.com:1/", kTemp, 0}, {"https://a.com/", kTemp, 0}, {"http://b.com/", kPerm, 0}, // persistent @@ -2353,47 +2428,47 @@ {blink::mojom::StorageType::kTemporary, blink::mojom::StorageType::kPersistent}); - GetEvictionStorageKey(kTemp); + GetEvictionBucket(kTemp); task_environment_.RunUntilIdle(); - EXPECT_FALSE(eviction_storage_key().has_value()); + EXPECT_FALSE(eviction_bucket().has_value()); NotifyStorageAccessed(ToStorageKey("http://a.com/"), kTemp); NotifyStorageAccessed(ToStorageKey("http://b.com/"), kPerm); NotifyStorageAccessed(ToStorageKey("https://a.com/"), kTemp); NotifyStorageAccessed(ToStorageKey("http://c.com/"), kTemp); - GetEvictionStorageKey(kTemp); + GetEvictionBucket(kTemp); task_environment_.RunUntilIdle(); - EXPECT_EQ(ToStorageKey("http://a.com/"), *eviction_storage_key()); + EXPECT_EQ(ToStorageKey("http://a.com/"), eviction_bucket()->storage_key); // Notify that the storage key for http://a.com is in use. NotifyStorageKeyInUse(ToStorageKey("http://a.com/")); - GetEvictionStorageKey(kTemp); + GetEvictionBucket(kTemp); task_environment_.RunUntilIdle(); - EXPECT_EQ(ToStorageKey("https://a.com/"), *eviction_storage_key()); + EXPECT_EQ(ToStorageKey("https://a.com/"), eviction_bucket()->storage_key); // Notify that the storage key for https://a.com is in use while - // GetEvictionStorageKey is running. - GetEvictionStorageKey(kTemp); + // GetEvictionBucket is running. + GetEvictionBucket(kTemp); NotifyStorageKeyInUse(ToStorageKey("https://a.com/")); task_environment_.RunUntilIdle(); // Post-filtering must have excluded the returned storage key, so we will // see empty result here. - EXPECT_FALSE(eviction_storage_key().has_value()); + EXPECT_FALSE(eviction_bucket().has_value()); - // Notify access for http://c.com while GetEvictionStorageKey is running. - GetEvictionStorageKey(kTemp); + // Notify access for http://c.com while GetEvictionBucket is running. + GetEvictionBucket(kTemp); NotifyStorageAccessed(ToStorageKey("http://c.com/"), kTemp); task_environment_.RunUntilIdle(); // Post-filtering must have excluded the returned storage key, so we will // see empty result here. - EXPECT_FALSE(eviction_storage_key().has_value()); + EXPECT_FALSE(eviction_bucket().has_value()); NotifyStorageKeyNoLongerInUse(ToStorageKey("http://a.com/")); NotifyStorageKeyNoLongerInUse(ToStorageKey("https://a.com/")); - GetEvictionStorageKey(kTemp); + GetEvictionBucket(kTemp); task_environment_.RunUntilIdle(); - EXPECT_EQ(ToStorageKey("http://a.com/"), *eviction_storage_key()); + EXPECT_EQ(ToStorageKey("http://a.com/"), eviction_bucket()->storage_key); } TEST_F(QuotaManagerImplTest, GetStorageKeysModifiedBetween) {
diff --git a/storage/browser/quota/quota_temporary_storage_evictor.cc b/storage/browser/quota/quota_temporary_storage_evictor.cc index 56723b2a..9aa65c0 100644 --- a/storage/browser/quota/quota_temporary_storage_evictor.cc +++ b/storage/browser/quota/quota_temporary_storage_evictor.cc
@@ -10,24 +10,23 @@ #include "base/auto_reset.h" #include "base/bind.h" -#include "storage/browser/quota/quota_macros.h" +#include "base/metrics/histogram_functions.h" #include "storage/browser/quota/quota_manager_impl.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" #include "url/gurl.h" -#define UMA_HISTOGRAM_MINUTES(name, sample) \ - UMA_HISTOGRAM_CUSTOM_TIMES( \ - (name), (sample), \ - base::TimeDelta::FromMinutes(1), \ - base::TimeDelta::FromDays(1), 50) - namespace { constexpr int64_t kMBytes = 1024 * 1024; constexpr double kUsageRatioToStartEviction = 0.7; constexpr int kThresholdOfErrorsToStopEviction = 5; constexpr int kHistogramReportIntervalMinutes = 60; constexpr double kDiskSpaceShortageAllowanceRatio = 0.5; + +void UmaHistogramMbytes(const std::string& name, int sample) { + base::UmaHistogramCustomCounts(name, sample / kMBytes, 1, + 10 * 1024 * 1024 /* 10 TB */, 100); +} } namespace storage { @@ -52,7 +51,7 @@ (*statistics)["errors-on-getting-usage-and-quota"] = statistics_.num_errors_on_getting_usage_and_quota; - (*statistics)["evicted-storage-keys"] = statistics_.num_evicted_storage_keys; + (*statistics)["evicted-buckets"] = statistics_.num_evicted_buckets; (*statistics)["eviction-rounds"] = statistics_.num_eviction_rounds; (*statistics)["skipped-eviction-rounds"] = @@ -65,25 +64,22 @@ DCHECK(round_statistics_.is_initialized); base::Time now = base::Time::Now(); - UMA_HISTOGRAM_TIMES("Quota.TimeSpentToAEvictionRound", - now - round_statistics_.start_time); + base::UmaHistogramTimes("Quota.TimeSpentToAEvictionRound", + now - round_statistics_.start_time); if (!time_of_end_of_last_round_.is_null()) { - UMA_HISTOGRAM_MINUTES("Quota.TimeDeltaOfEvictionRounds", - now - time_of_end_of_last_round_); + base::UmaHistogramCustomTimes( + "Quota.TimeDeltaOfEvictionRounds", now - time_of_end_of_last_round_, + base::TimeDelta::FromMinutes(1), base::TimeDelta::FromDays(1), 50); } time_of_end_of_last_round_ = now; - UMA_HISTOGRAM_MBYTES("Quota.DiskspaceShortage", - round_statistics_.diskspace_shortage_at_round); - UMA_HISTOGRAM_MBYTES("Quota.EvictedBytesPerRound", - round_statistics_.usage_on_beginning_of_round - - round_statistics_.usage_on_end_of_round); - - // Even though the metric now captures the number of evicted storage keys - // (instead of origins), we keep the metric identifier - // NumberOfEvictedOriginsPerRound so we don't lose historical data. - UMA_HISTOGRAM_COUNTS_1M("Quota.NumberOfEvictedOriginsPerRound", - round_statistics_.num_evicted_storage_keys_in_round); + UmaHistogramMbytes("Quota.DiskspaceShortage", + round_statistics_.diskspace_shortage_at_round); + UmaHistogramMbytes("Quota.EvictedBytesPerRound", + round_statistics_.usage_on_beginning_of_round - + round_statistics_.usage_on_end_of_round); + base::UmaHistogramCounts1M("Quota.NumberOfEvictedBucketsPerRound", + round_statistics_.num_evicted_buckets_in_round); } void QuotaTemporaryStorageEvictor::ReportPerHourHistogram() { @@ -92,15 +88,12 @@ stats_in_hour.subtract_assign(previous_statistics_); previous_statistics_ = statistics_; - // Even though the metric now captures the number of evicted storage keys - // (instead of origins), we keep the metric identifier EvictedOriginsPerHour - // so we don't lose historical data. - UMA_HISTOGRAM_COUNTS_1M("Quota.EvictedOriginsPerHour", - stats_in_hour.num_evicted_storage_keys); - UMA_HISTOGRAM_COUNTS_1M("Quota.EvictionRoundsPerHour", - stats_in_hour.num_eviction_rounds); - UMA_HISTOGRAM_COUNTS_1M("Quota.SkippedEvictionRoundsPerHour", - stats_in_hour.num_skipped_eviction_rounds); + base::UmaHistogramCounts1M("Quota.EvictedBucketsPerHour", + stats_in_hour.num_evicted_buckets); + base::UmaHistogramCounts1M("Quota.EvictionRoundsPerHour", + stats_in_hour.num_eviction_rounds); + base::UmaHistogramCounts1M("Quota.SkippedEvictionRoundsPerHour", + stats_in_hour.num_skipped_eviction_rounds); } void QuotaTemporaryStorageEvictor::OnEvictionRoundStarted() { @@ -116,7 +109,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Check if skipped round - if (round_statistics_.num_evicted_storage_keys_in_round) { + if (round_statistics_.num_evicted_buckets_in_round) { ReportPerRoundHistogram(); time_of_end_of_last_nonskipped_round_ = base::Time::Now(); } else { @@ -202,9 +195,9 @@ // continue. // TODO(michaeln): if the reason for eviction is low physical disk space, // make 'unlimited' storage keys subject to eviction too. - quota_eviction_handler_->GetEvictionStorageKey( + quota_eviction_handler_->GetEvictionBucket( blink::mojom::StorageType::kTemporary, settings.pool_size, - base::BindOnce(&QuotaTemporaryStorageEvictor::OnGotEvictionStorageKey, + base::BindOnce(&QuotaTemporaryStorageEvictor::OnGotEvictionBucket, weak_factory_.GetWeakPtr())); return; } @@ -222,20 +215,20 @@ OnEvictionRoundFinished(); } -void QuotaTemporaryStorageEvictor::OnGotEvictionStorageKey( - const absl::optional<blink::StorageKey>& storage_key) { +void QuotaTemporaryStorageEvictor::OnGotEvictionBucket( + const absl::optional<BucketInfo>& bucket) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!storage_key.has_value()) { + if (!bucket.has_value()) { StartEvictionTimerWithDelay(interval_ms_); OnEvictionRoundFinished(); return; } - DCHECK(!storage_key->origin().GetURL().is_empty()); + DCHECK(!bucket->storage_key.origin().GetURL().is_empty()); - quota_eviction_handler_->EvictStorageKeyData( - *storage_key, blink::mojom::StorageType::kTemporary, + quota_eviction_handler_->EvictBucketData( + bucket.value(), base::BindOnce(&QuotaTemporaryStorageEvictor::OnEvictionComplete, weak_factory_.GetWeakPtr())); } @@ -245,14 +238,14 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Just calling ConsiderEviction() or StartEvictionTimerWithDelay() here is - // ok. No need to deal with the case that all of the Delete operations fail - // for a certain storage key. It doesn't result in trying to evict the same - // storage key permanently. The evictor skips storage keys which had deletion - // errors a few times. + // ok. No need to deal with the case that all of the Delete operations fail + // for a certain bucket. It doesn't result in trying to evict the same bucket + // permanently. The evictor skips buckets which had deletion errors a few + // times. if (status == blink::mojom::QuotaStatusCode::kOk) { - ++statistics_.num_evicted_storage_keys; - ++round_statistics_.num_evicted_storage_keys_in_round; + ++statistics_.num_evicted_buckets; + ++round_statistics_.num_evicted_buckets_in_round; // We many need to get rid of more space so reconsider immediately. ConsiderEviction(); } else {
diff --git a/storage/browser/quota/quota_temporary_storage_evictor.h b/storage/browser/quota/quota_temporary_storage_evictor.h index 05de164..7eecc08f 100644 --- a/storage/browser/quota/quota_temporary_storage_evictor.h +++ b/storage/browser/quota/quota_temporary_storage_evictor.h
@@ -16,13 +16,10 @@ #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" #include "base/timer/timer.h" +#include "components/services/storage/public/cpp/buckets/bucket_info.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" -namespace blink { -class StorageKey; -} - namespace storage { class QuotaEvictionHandler; @@ -32,14 +29,14 @@ public: struct Statistics { int64_t num_errors_on_getting_usage_and_quota = 0; - int64_t num_evicted_storage_keys = 0; + int64_t num_evicted_buckets = 0; int64_t num_eviction_rounds = 0; int64_t num_skipped_eviction_rounds = 0; void subtract_assign(const Statistics& rhs) { num_errors_on_getting_usage_and_quota -= rhs.num_errors_on_getting_usage_and_quota; - num_evicted_storage_keys -= rhs.num_evicted_storage_keys; + num_evicted_buckets -= rhs.num_evicted_buckets; num_eviction_rounds -= rhs.num_eviction_rounds; num_skipped_eviction_rounds -= rhs.num_skipped_eviction_rounds; } @@ -54,7 +51,7 @@ int64_t usage_on_beginning_of_round = -1; int64_t usage_on_end_of_round = -1; - int64_t num_evicted_storage_keys_in_round = 0; + int64_t num_evicted_buckets_in_round = 0; }; QuotaTemporaryStorageEvictor(QuotaEvictionHandler* quota_eviction_handler, @@ -77,8 +74,7 @@ int64_t total_space, int64_t current_usage, bool current_usage_is_complete); - void OnGotEvictionStorageKey( - const absl::optional<blink::StorageKey>& storage_key); + void OnGotEvictionBucket(const absl::optional<BucketInfo>& bucket); void OnEvictionComplete(blink::mojom::QuotaStatusCode status); void OnEvictionRoundStarted();
diff --git a/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc b/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc index 63f751f8..89ffbc6 100644 --- a/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc +++ b/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc
@@ -16,12 +16,12 @@ #include "base/memory/weak_ptr.h" #include "base/run_loop.h" #include "base/test/task_environment.h" +#include "components/services/storage/public/cpp/buckets/bucket_id.h" +#include "components/services/storage/public/cpp/buckets/bucket_info.h" #include "storage/browser/quota/quota_manager_impl.h" #include "storage/browser/quota/quota_temporary_storage_evictor.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/storage_key/storage_key.h" -using ::blink::StorageKey; using ::blink::mojom::StorageType; namespace storage { @@ -30,28 +30,23 @@ namespace { -StorageKey ToStorageKey(const std::string& url) { - return StorageKey::CreateFromStringForTesting(url); -} - class MockQuotaEvictionHandler : public QuotaEvictionHandler { public: explicit MockQuotaEvictionHandler(QuotaTemporaryStorageEvictorTest* test) : available_space_(0), - error_on_evict_storage_key_data_(false), + error_on_evict_buckets_data_(false), error_on_get_usage_and_quota_(false) {} - void EvictStorageKeyData(const StorageKey& storage_key, - StorageType type, - StatusCallback callback) override { - if (error_on_evict_storage_key_data_) { + void EvictBucketData(const BucketInfo& bucket, + StatusCallback callback) override { + if (error_on_evict_buckets_data_) { std::move(callback).Run( blink::mojom::QuotaStatusCode::kErrorInvalidModification); return; } - int64_t storage_key_usage = EnsureStorageKeyRemoved(storage_key); - if (storage_key_usage >= 0) - available_space_ += storage_key_usage; + int64_t bucket_usage = EnsureBucketRemoved(bucket); + if (bucket_usage >= 0) + available_space_ += bucket_usage; std::move(callback).Run(blink::mojom::QuotaStatusCode::kOk); } @@ -68,19 +63,20 @@ true); } - void GetEvictionStorageKey(StorageType type, - int64_t global_quota, - GetStorageKeyCallback callback) override { - if (storage_key_order_.empty()) + void GetEvictionBucket(StorageType type, + int64_t global_quota, + GetBucketCallback callback) override { + if (bucket_order_.empty()) { std::move(callback).Run(absl::nullopt); - else - std::move(callback).Run(storage_key_order_.front()); + } else { + std::move(callback).Run(bucket_order_.front()); + } } int64_t GetUsage() const { int64_t total_usage = 0; - for (const auto& storage_key_usage_pair : storage_keys_) - total_usage += storage_key_usage_pair.second; + for (const auto& bucket_usage_pair : buckets_) + total_usage += bucket_usage_pair.second; return total_usage; } @@ -98,49 +94,48 @@ void set_task_for_get_usage_and_quota(base::RepeatingClosure task) { task_for_get_usage_and_quota_ = std::move(task); } - void set_error_on_evict_storage_key_data( - bool error_on_evict_storage_key_data) { - error_on_evict_storage_key_data_ = error_on_evict_storage_key_data; + void set_error_on_evict_buckets_data(bool error_on_evict_buckets_data) { + error_on_evict_buckets_data_ = error_on_evict_buckets_data; } void set_error_on_get_usage_and_quota(bool error_on_get_usage_and_quota) { error_on_get_usage_and_quota_ = error_on_get_usage_and_quota; } - // Simulates an access to `storage_key`. It reorders the internal LRU list. - // It internally uses AddStorageKey(). - void AccessStorageKey(const StorageKey& storage_key) { - const auto& it = storage_keys_.find(storage_key); - EXPECT_TRUE(storage_keys_.end() != it); - AddStorageKey(storage_key, it->second); + // Simulates an access to `bucket`. It reorders the internal LRU list. + // It internally uses AddBucket(). + void AccessBucket(const BucketInfo& bucket) { + const auto& it = buckets_.find(bucket.id); + EXPECT_TRUE(buckets_.end() != it); + AddBucket(bucket, it->second); } - // Simulates adding or overwriting the `storage_key` to the internal storage - // key set with the `usage`. It also adds or moves the `storage_key` to the + // Simulates adding or overwriting the `bucket` to the internal bucket set + // with the `usage`. It also adds or moves the `bucket` to the // end of the LRU list. - void AddStorageKey(const StorageKey& storage_key, int64_t usage) { - EnsureStorageKeyRemoved(storage_key); - storage_key_order_.push_back(storage_key); - storage_keys_[storage_key] = usage; + void AddBucket(const BucketInfo& bucket, int64_t usage) { + EnsureBucketRemoved(bucket); + bucket_order_.push_back(bucket); + buckets_[bucket.id] = usage; } private: - int64_t EnsureStorageKeyRemoved(const StorageKey& storage_key) { - int64_t storage_key_usage; - if (!base::Contains(storage_keys_, storage_key)) + int64_t EnsureBucketRemoved(const BucketInfo& bucket) { + int64_t bucket_usage; + if (!base::Contains(buckets_, bucket.id)) return -1; else - storage_key_usage = storage_keys_[storage_key]; + bucket_usage = buckets_[bucket.id]; - storage_keys_.erase(storage_key); - storage_key_order_.remove(storage_key); - return storage_key_usage; + buckets_.erase(bucket.id); + bucket_order_.remove(bucket); + return bucket_usage; } QuotaSettings settings_; int64_t available_space_; - std::list<StorageKey> storage_key_order_; - std::map<StorageKey, int64_t> storage_keys_; - bool error_on_evict_storage_key_data_; + std::list<BucketInfo> bucket_order_; + std::map<BucketId, int64_t> buckets_; + bool error_on_evict_buckets_data_; bool error_on_get_usage_and_quota_; base::RepeatingClosure task_for_get_usage_and_quota_; @@ -168,9 +163,8 @@ } void TaskForRepeatedEvictionTest( - const std::pair<absl::optional<StorageKey>, int64_t>& - storage_key_to_be_added, - const absl::optional<StorageKey>& storage_key_to_be_accessed, + const std::pair<absl::optional<BucketInfo>, int64_t>& bucket_to_be_added, + const absl::optional<BucketInfo> bucket_to_be_accessed, int expected_usage_after_first, int expected_usage_after_second) { EXPECT_GE(4, num_get_usage_and_quota_for_eviction_); @@ -178,12 +172,11 @@ case 2: EXPECT_EQ(expected_usage_after_first, quota_eviction_handler()->GetUsage()); - if (storage_key_to_be_added.first.has_value()) - quota_eviction_handler()->AddStorageKey( - *storage_key_to_be_added.first, storage_key_to_be_added.second); - if (storage_key_to_be_accessed.has_value()) - quota_eviction_handler()->AccessStorageKey( - *storage_key_to_be_accessed); + if (bucket_to_be_added.first.has_value()) + quota_eviction_handler()->AddBucket(*bucket_to_be_added.first, + bucket_to_be_added.second); + if (bucket_to_be_accessed.has_value()) + quota_eviction_handler()->AccessBucket(*bucket_to_be_accessed); break; case 3: EXPECT_EQ(expected_usage_after_second, @@ -194,6 +187,13 @@ ++num_get_usage_and_quota_for_eviction_; } + BucketInfo CreateBucket(const std::string& url, const std::string& name) { + return BucketInfo(bucket_id_generator_.GenerateNextId(), + blink::StorageKey::CreateFromStringForTesting(url), + blink::mojom::StorageType::kTemporary, name, + /*expiration=*/base::Time::Max(), /*quota=*/0); + } + protected: MockQuotaEvictionHandler* quota_eviction_handler() const { return static_cast<MockQuotaEvictionHandler*>( @@ -216,6 +216,7 @@ return num_get_usage_and_quota_for_eviction_; } + BucketId::Generator bucket_id_generator_; base::test::TaskEnvironment task_environment_; std::unique_ptr<MockQuotaEvictionHandler> quota_eviction_handler_; std::unique_ptr<QuotaTemporaryStorageEvictor> temporary_storage_evictor_; @@ -225,12 +226,12 @@ }; TEST_F(QuotaTemporaryStorageEvictorTest, SimpleEvictionTest) { - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.z.com"), - 3000); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.y.com"), - 200); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.x.com"), - 500); + quota_eviction_handler()->AddBucket(CreateBucket("http://www.z.com", "test"), + 3000); + quota_eviction_handler()->AddBucket(CreateBucket("http://www.y.com", "test"), + 200); + quota_eviction_handler()->AddBucket(CreateBucket("http://www.x.com", "test"), + 500); quota_eviction_handler()->SetPoolSize(4000); quota_eviction_handler()->set_available_space(1000000000); EXPECT_EQ(3000 + 200 + 500, quota_eviction_handler()->GetUsage()); @@ -240,19 +241,20 @@ EXPECT_EQ(200 + 500, quota_eviction_handler()->GetUsage()); EXPECT_EQ(0, statistics().num_errors_on_getting_usage_and_quota); - EXPECT_EQ(1, statistics().num_evicted_storage_keys); + EXPECT_EQ(1, statistics().num_evicted_buckets); EXPECT_EQ(1, statistics().num_eviction_rounds); EXPECT_EQ(0, statistics().num_skipped_eviction_rounds); } TEST_F(QuotaTemporaryStorageEvictorTest, MultipleEvictionTest) { - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.z.com"), 20); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.y.com"), - 2900); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.x.com"), - 450); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.w.com"), - 400); + quota_eviction_handler()->AddBucket( + CreateBucket("http://www.z.com", kDefaultBucketName), 20); + quota_eviction_handler()->AddBucket( + CreateBucket("http://www.y.com", kDefaultBucketName), 2900); + quota_eviction_handler()->AddBucket( + CreateBucket("http://www.x.com", kDefaultBucketName), 450); + quota_eviction_handler()->AddBucket( + CreateBucket("http://www.w.com", kDefaultBucketName), 400); quota_eviction_handler()->SetPoolSize(4000); quota_eviction_handler()->set_available_space(1000000000); EXPECT_EQ(20 + 2900 + 450 + 400, quota_eviction_handler()->GetUsage()); @@ -262,7 +264,7 @@ EXPECT_EQ(450 + 400, quota_eviction_handler()->GetUsage()); EXPECT_EQ(0, statistics().num_errors_on_getting_usage_and_quota); - EXPECT_EQ(2, statistics().num_evicted_storage_keys); + EXPECT_EQ(2, statistics().num_evicted_buckets); EXPECT_EQ(1, statistics().num_eviction_rounds); EXPECT_EQ(0, statistics().num_skipped_eviction_rounds); } @@ -275,21 +277,21 @@ const int64_t initial_total_size = a_size + b_size + c_size + d_size; const int64_t e_size = 275; - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.d.com"), - d_size); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.c.com"), - c_size); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.b.com"), - b_size); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.a.com"), - a_size); + quota_eviction_handler()->AddBucket(CreateBucket("http://www.d.com", "test"), + d_size); + quota_eviction_handler()->AddBucket(CreateBucket("http://www.c.com", "test"), + c_size); + quota_eviction_handler()->AddBucket(CreateBucket("http://www.b.com", "test"), + b_size); + quota_eviction_handler()->AddBucket(CreateBucket("http://www.a.com", "test"), + a_size); quota_eviction_handler()->SetPoolSize(1000); quota_eviction_handler()->set_available_space(1000000000); quota_eviction_handler()->set_task_for_get_usage_and_quota( base::BindRepeating( &QuotaTemporaryStorageEvictorTest::TaskForRepeatedEvictionTest, weak_factory_.GetWeakPtr(), - std::make_pair(ToStorageKey("http://www.e.com"), e_size), + std::make_pair(CreateBucket("http://www.e.com", "test"), e_size), absl::nullopt, initial_total_size - d_size, initial_total_size - d_size + e_size - c_size)); EXPECT_EQ(initial_total_size, quota_eviction_handler()->GetUsage()); @@ -300,7 +302,7 @@ EXPECT_EQ(5, num_get_usage_and_quota_for_eviction()); EXPECT_EQ(0, statistics().num_errors_on_getting_usage_and_quota); - EXPECT_EQ(3, statistics().num_evicted_storage_keys); + EXPECT_EQ(3, statistics().num_evicted_buckets); EXPECT_EQ(2, statistics().num_eviction_rounds); EXPECT_EQ(0, statistics().num_skipped_eviction_rounds); } @@ -312,14 +314,14 @@ const int64_t d_size = 292; const int64_t initial_total_size = a_size + b_size + c_size + d_size; - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.d.com"), - d_size); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.c.com"), - c_size); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.b.com"), - b_size); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.a.com"), - a_size); + quota_eviction_handler()->AddBucket( + CreateBucket("http://www.d.com", kDefaultBucketName), d_size); + quota_eviction_handler()->AddBucket( + CreateBucket("http://www.c.com", kDefaultBucketName), c_size); + quota_eviction_handler()->AddBucket( + CreateBucket("http://www.b.com", kDefaultBucketName), b_size); + quota_eviction_handler()->AddBucket( + CreateBucket("http://www.a.com", kDefaultBucketName), a_size); quota_eviction_handler()->SetPoolSize(1000); quota_eviction_handler()->set_available_space(1000000000); quota_eviction_handler()->set_task_for_get_usage_and_quota( @@ -336,13 +338,12 @@ EXPECT_EQ(4, num_get_usage_and_quota_for_eviction()); EXPECT_EQ(0, statistics().num_errors_on_getting_usage_and_quota); - EXPECT_EQ(1, statistics().num_evicted_storage_keys); + EXPECT_EQ(1, statistics().num_evicted_buckets); EXPECT_EQ(3, statistics().num_eviction_rounds); EXPECT_EQ(2, statistics().num_skipped_eviction_rounds); } -TEST_F(QuotaTemporaryStorageEvictorTest, - RepeatedEvictionWithAccessStorageKeyTest) { +TEST_F(QuotaTemporaryStorageEvictorTest, RepeatedEvictionWithAccessBucketTest) { const int64_t a_size = 400; const int64_t b_size = 150; const int64_t c_size = 120; @@ -350,22 +351,23 @@ const int64_t initial_total_size = a_size + b_size + c_size + d_size; const int64_t e_size = 275; - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.d.com"), - d_size); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.c.com"), - c_size); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.b.com"), - b_size); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.a.com"), - a_size); + BucketInfo a_bucket = CreateBucket("http://www.a.com", kDefaultBucketName); + BucketInfo b_bucket = CreateBucket("http://www.b.com", kDefaultBucketName); + BucketInfo c_bucket = CreateBucket("http://www.c.com", kDefaultBucketName); + BucketInfo d_bucket = CreateBucket("http://www.d.com", kDefaultBucketName); + BucketInfo e_bucket = CreateBucket("http://www.e.com", kDefaultBucketName); + + quota_eviction_handler()->AddBucket(d_bucket, d_size); + quota_eviction_handler()->AddBucket(c_bucket, c_size); + quota_eviction_handler()->AddBucket(b_bucket, b_size); + quota_eviction_handler()->AddBucket(a_bucket, a_size); quota_eviction_handler()->SetPoolSize(1000); quota_eviction_handler()->set_available_space(1000000000); quota_eviction_handler()->set_task_for_get_usage_and_quota( base::BindRepeating( &QuotaTemporaryStorageEvictorTest::TaskForRepeatedEvictionTest, - weak_factory_.GetWeakPtr(), - std::make_pair(ToStorageKey("http://www.e.com"), e_size), - ToStorageKey("http://www.c.com"), initial_total_size - d_size, + weak_factory_.GetWeakPtr(), std::make_pair(e_bucket, e_size), + c_bucket, initial_total_size - d_size, initial_total_size - d_size + e_size - b_size)); EXPECT_EQ(initial_total_size, quota_eviction_handler()->GetUsage()); temporary_storage_evictor()->Start(); @@ -375,7 +377,7 @@ EXPECT_EQ(5, num_get_usage_and_quota_for_eviction()); EXPECT_EQ(0, statistics().num_errors_on_getting_usage_and_quota); - EXPECT_EQ(3, statistics().num_evicted_storage_keys); + EXPECT_EQ(3, statistics().num_evicted_buckets); EXPECT_EQ(2, statistics().num_eviction_rounds); EXPECT_EQ(0, statistics().num_skipped_eviction_rounds); } @@ -383,8 +385,10 @@ TEST_F(QuotaTemporaryStorageEvictorTest, DiskSpaceNonEvictionTest) { // If we're using so little that evicting all of it wouldn't // do enough to alleviate a diskspace shortage, we don't evict. - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.z.com"), 10); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.x.com"), 20); + quota_eviction_handler()->AddBucket( + CreateBucket("http://www.z.com", kDefaultBucketName), 10); + quota_eviction_handler()->AddBucket( + CreateBucket("http://www.x.com", kDefaultBucketName), 20); quota_eviction_handler()->SetPoolSize(10000); quota_eviction_handler()->set_available_space( quota_eviction_handler()->settings().should_remain_available - 350); @@ -395,20 +399,20 @@ EXPECT_EQ(10 + 20, quota_eviction_handler()->GetUsage()); EXPECT_EQ(0, statistics().num_errors_on_getting_usage_and_quota); - EXPECT_EQ(0, statistics().num_evicted_storage_keys); + EXPECT_EQ(0, statistics().num_evicted_buckets); EXPECT_EQ(1, statistics().num_eviction_rounds); EXPECT_EQ(1, statistics().num_skipped_eviction_rounds); } TEST_F(QuotaTemporaryStorageEvictorTest, DiskSpaceEvictionTest) { - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.z.com"), - 294); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.y.com"), - 120); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.x.com"), - 150); - quota_eviction_handler()->AddStorageKey(ToStorageKey("http://www.w.com"), - 300); + quota_eviction_handler()->AddBucket( + CreateBucket("http://www.z.com", kDefaultBucketName), 294); + quota_eviction_handler()->AddBucket( + CreateBucket("http://www.y.com", kDefaultBucketName), 120); + quota_eviction_handler()->AddBucket( + CreateBucket("http://www.x.com", kDefaultBucketName), 150); + quota_eviction_handler()->AddBucket( + CreateBucket("http://www.w.com", kDefaultBucketName), 300); quota_eviction_handler()->SetPoolSize(10000); quota_eviction_handler()->set_available_space( quota_eviction_handler()->settings().should_remain_available - 350); @@ -419,7 +423,7 @@ EXPECT_EQ(150 + 300, quota_eviction_handler()->GetUsage()); EXPECT_EQ(0, statistics().num_errors_on_getting_usage_and_quota); - EXPECT_EQ(2, statistics().num_evicted_storage_keys); + EXPECT_EQ(2, statistics().num_evicted_buckets); EXPECT_EQ(1, statistics().num_eviction_rounds); EXPECT_EQ(0, statistics().num_skipped_eviction_rounds); // FIXME? }
diff --git a/styleguide/c++/c++.md b/styleguide/c++/c++.md index 6c75bba..3e6346cb 100644 --- a/styleguide/c++/c++.md +++ b/styleguide/c++/c++.md
@@ -35,7 +35,7 @@ * "Chromium" is the name of the project, not the product, and should never appear in code, variable names, API names etc. Use "Chrome" instead. -## Test-only Code +## Tests and Test-only Code * Functions used only for testing should be restricted to test-only usages with the testing suffixes supported by @@ -46,9 +46,17 @@ * Classes used only for testing should be in a GN build target that is marked `testonly=true`. Tests can depend on such targets, but production code can not. - * The code for `testonly` targets should be placed in a `test/` subdirectory. - For test classes used across multiple directories, it might make sense to - move them into a nested `test` namespace for clarity. + * While test files generally appear alongside the production code they test, + support code for `testonly` targets should be placed in a `test/` subdirectory. + For example, see `//mojo/core/core_unittest.cc` and + `//mojo/core/test/mojo_test_base.cc`. For test classes used across multiple + directories, it might make sense to move them into a nested `test` namespace for + clarity. + * Despite the Google C++ style guide + [deprecating](https://google.github.io/styleguide/cppguide.html#File_Names) + the `_unittest.cc` suffix for unit test files, in Chromium we still use this + suffix to distinguish unit tests from browser tests, which are written in + files with the `_browsertest.cc` suffix. ## Code formatting
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index f6aec05..f6b734d 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -4795,7 +4795,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -4830,18 +4830,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -4864,7 +4864,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -4899,18 +4899,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -4934,7 +4934,7 @@ "--test-launcher-batch-limit=1", "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -4969,18 +4969,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -5003,7 +5003,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -5038,18 +5038,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -5072,7 +5072,7 @@ "args": [ "angle_unittests", "-v", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [], @@ -5102,18 +5102,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -5127,7 +5127,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -5162,18 +5162,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -5196,7 +5196,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -5231,18 +5231,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -5265,7 +5265,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -5300,18 +5300,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -5334,7 +5334,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -5369,18 +5369,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -5403,7 +5403,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -5438,18 +5438,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -5472,7 +5472,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -5508,18 +5508,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -5543,7 +5543,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -5578,18 +5578,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -5612,7 +5612,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -5647,18 +5647,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -5681,7 +5681,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -5716,18 +5716,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -5751,7 +5751,7 @@ "--gtest_filter=-*UsingRealWebcam*", "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -5786,18 +5786,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -5820,7 +5820,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -5855,18 +5855,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -5889,7 +5889,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -5924,18 +5924,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -5958,7 +5958,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -5993,18 +5993,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -6027,7 +6027,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb", + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb", "--git-revision=${got_revision}" ], "merge": { @@ -6068,18 +6068,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -6103,7 +6103,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -6138,18 +6138,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -6172,7 +6172,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -6207,18 +6207,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -6242,7 +6242,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -6277,18 +6277,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -6312,7 +6312,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -6347,18 +6347,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -6382,7 +6382,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -6417,18 +6417,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -6452,7 +6452,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -6487,18 +6487,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -6521,7 +6521,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -6556,18 +6556,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -6590,7 +6590,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -6625,18 +6625,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -6659,7 +6659,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -6694,18 +6694,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -6728,7 +6728,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -6763,18 +6763,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -6797,7 +6797,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -6832,18 +6832,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -6866,7 +6866,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -6901,18 +6901,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -6935,7 +6935,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -6970,18 +6970,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -7005,7 +7005,7 @@ "--use-cmd-decoder=validating", "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -7041,18 +7041,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -7075,7 +7075,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -7110,18 +7110,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -7144,7 +7144,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -7179,18 +7179,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -7213,7 +7213,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -7248,18 +7248,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -7282,7 +7282,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -7317,18 +7317,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -7351,7 +7351,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -7386,18 +7386,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -7420,7 +7420,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -7455,18 +7455,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -7489,7 +7489,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -7524,18 +7524,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -7558,7 +7558,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -7593,18 +7593,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -7627,7 +7627,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -7662,18 +7662,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -7696,7 +7696,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -7731,18 +7731,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -7765,7 +7765,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -7800,18 +7800,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -7834,7 +7834,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -7869,18 +7869,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -7903,7 +7903,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -7938,18 +7938,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -7972,7 +7972,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -8007,18 +8007,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -8041,7 +8041,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -8076,18 +8076,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -8110,7 +8110,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -8145,18 +8145,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -8179,7 +8179,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -8214,18 +8214,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -8249,7 +8249,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -8284,18 +8284,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -8318,7 +8318,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -8353,18 +8353,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -8387,7 +8387,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -8422,18 +8422,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -8456,7 +8456,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -8491,18 +8491,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -8525,7 +8525,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -8560,18 +8560,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -8594,7 +8594,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -8629,18 +8629,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -8663,7 +8663,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -8698,18 +8698,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -8732,7 +8732,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -8767,18 +8767,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -8801,7 +8801,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -8836,18 +8836,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -8870,7 +8870,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -8905,18 +8905,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -8939,7 +8939,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -8974,18 +8974,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -9008,7 +9008,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -9043,18 +9043,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -9078,7 +9078,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -9113,18 +9113,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -9147,7 +9147,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -9182,18 +9182,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -9216,7 +9216,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -9251,18 +9251,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -9285,7 +9285,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -9320,18 +9320,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -9354,7 +9354,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -9389,18 +9389,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -9423,7 +9423,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -9458,18 +9458,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -9492,7 +9492,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -9527,18 +9527,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -9561,7 +9561,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -9601,18 +9601,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -9636,7 +9636,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -9671,18 +9671,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -9706,7 +9706,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -9741,18 +9741,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -9775,7 +9775,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -9810,18 +9810,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] }, @@ -9844,7 +9844,7 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], "merge": { "args": [ @@ -9879,18 +9879,18 @@ ], "named_caches": [ { - "name": "avd_generic_android_s", + "name": "avd_generic_android31", "path": ".android" }, { - "name": "system_images_android_s_google_apis_x64", + "name": "system_images_android_31_google_apis_x64", "path": ".emulator_sdk" } ], "optional_dimensions": { "60": [ { - "caches": "avd_generic_android_s" + "caches": "avd_generic_android31" } ] },
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 2f06cac..b90a9ca 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -29276,32 +29276,6 @@ }, { "args": [ - "angle_gles1_conformance_tests", - "--test-timeout=40", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "containment_type": "AUTO", - "dimension_sets": [ - { - "gpu": "8086:5912-26.20.100.8141|8086:3e92-26.20.100.8141", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_gles1_conformance_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_gles1_conformance_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ "angle_white_box_tests", "--bot-mode", "--max-processes=1" @@ -29852,32 +29826,6 @@ }, { "args": [ - "angle_gles1_conformance_tests", - "--test-timeout=40", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "containment_type": "AUTO", - "dimension_sets": [ - { - "gpu": "10de:1cb3-27.21.14.5148", - "os": "Windows-10-18363", - "pool": "chromium.tests.gpu" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_gles1_conformance_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_gles1_conformance_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ "angle_white_box_tests", "--bot-mode" ],
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index a0c8060..5c54172 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -180,13 +180,10 @@ ] }, }, - # TODO(crbug.com/1225851): Update "S" and "_s" to the right value once S is - # released. Using "_s" in stead of "S" in swarming as it does not accept - # uppercase character. '12-x64-emulator': { '$mixin_append': { 'args': [ - '--avd-config=../../tools/android/avd/proto/generic_androidS.textpb', + '--avd-config=../../tools/android/avd/proto/generic_android31.textpb', ], }, 'swarming': { @@ -194,17 +191,17 @@ 'optional_dimensions': { '60': [ { - 'caches': 'avd_generic_android_s', + 'caches': 'avd_generic_android31', } ], }, 'named_caches': [ { - 'name': 'avd_generic_android_s', + 'name': 'avd_generic_android31', 'path': '.android', }, { - 'name': 'system_images_android_s_google_apis_x64', + 'name': 'system_images_android_31_google_apis_x64', 'path': '.emulator_sdk', }, ]
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index bb565bc1..ed95887 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -6567,7 +6567,6 @@ 'gpu_fyi_win_optional_gtests': [ 'gpu_angle_end2end_gtests', - 'gpu_angle_gles1_conformance_gtests', 'gpu_angle_white_box_gtests', 'gpu_default_and_optional_win_specific_gtests', 'gpu_fyi_and_optional_non_linux_gtests',
diff --git a/testing/trigger_scripts/base_test_triggerer.py b/testing/trigger_scripts/base_test_triggerer.py index 0d6a53e..eb9acec 100755 --- a/testing/trigger_scripts/base_test_triggerer.py +++ b/testing/trigger_scripts/base_test_triggerer.py
@@ -149,7 +149,6 @@ def list_bots(self, dimensions, - verbose, server='chromium-swarm.appspot.com'): """List bots having specified bot dimensions. @@ -162,8 +161,7 @@ for key in sorted(dimensions): args.extend(['-dimension', '%s=%s' % (key, dimensions[key])]) - if verbose: - logging.info('Running Go `swarming` with args: %s', args) + logging.info('Running Go `swarming` with args: %s', args) with tempfile.NamedTemporaryFile(delete=False) as result_json: result_json.close() @@ -177,7 +175,6 @@ def query_swarming(self, api, query_args, - verbose, limit='0', server='chromium-swarm.appspot.com'): try: @@ -189,7 +186,7 @@ ] # Append the query at the end args.append(('%s?%s' % (api, encoded_args))) - ret = self.run_swarming(args, verbose) + ret = self.run_swarming(args) if ret: raise Exception('Error running swarming.py') return self.read_encoded_json_from_temp_file(temp_file) @@ -223,20 +220,18 @@ with open(output_file, 'w') as f: json.dump(merged_json, f) - def run_swarming(self, args, verbose): - if verbose: - logging.info('Running Swarming with args: %s', args) + def run_swarming(self, args): + logging.info('Running Swarming with args: %s', args) return subprocess.call([sys.executable, SWARMING_PY] + args) def run_swarming_go(self, args, - verbose, json_path, shard_index, shards, merged_json=None): - if verbose: - logging.info('Running Go `swarming` with args: %s', args) + + logging.info('Running Go `swarming` with args: %s', args) if merged_json is None: merged_json = {} @@ -263,12 +258,12 @@ self.write_json_to_file(merged_json, json_path) return ret - def prune_test_specific_configs(self, args, verbose): + def prune_test_specific_configs(self, args): # Ability for base class to further prune configs to # run tests on. pass - def select_config_indices(self, args, verbose): + def select_config_indices(self, args): # Main implementation for base class to determine which bot config to # trigger for each shard. # @@ -284,7 +279,7 @@ else: return [args.shard_index] - def generate_shard_map(self, args, buildername, selected_config, verbose): + def generate_shard_map(self, args, buildername, selected_config): """Returns shard map generated on runtime if needed.""" pass @@ -299,14 +294,17 @@ Returns: Exit code for the script. """ + if args.multiple_dimension_script_verbose: + logging.basicConfig(level=logging.DEBUG) + # crbug/1140389: debug print outs logging.info('DEBUG: init: %s', remaining) - verbose = args.multiple_dimension_script_verbose + self.parse_bot_configs(args) # Prunes config list to the exact set of configurations to trigger jobs # on. This logic is specific to the base class if they want to prune # list further. - self.prune_test_specific_configs(args, verbose) + self.prune_test_specific_configs(args) # In the remaining arguments, find the Swarming dimensions that are # specified by the bot configs and remove them, because for each shard, @@ -321,10 +319,10 @@ logging.info('DEBUG: After filtered: %s', filtered_remaining_args) merged_json = {} - selected_config = self.select_config_indices(args, verbose) + selected_config = self.select_config_indices(args) shard_map = self.generate_shard_map( args, self._findBuilderName(filtered_remaining_args), - selected_config, verbose) + selected_config) # Choose selected configs for this run of the test suite. for shard_index, bot_index in selected_config: # For each shard that we're going to distribute, do the following: @@ -345,7 +343,7 @@ # crbug/1140389: debug print outs logging.info('DEBUG: Before calling swarming: %s', args_to_pass) - ret = self.run_swarming_go(args_to_pass, verbose, json_temp, + ret = self.run_swarming_go(args_to_pass, json_temp, shard_index, args.shards, merged_json) if ret:
diff --git a/testing/trigger_scripts/chromeos_device_trigger.py b/testing/trigger_scripts/chromeos_device_trigger.py index fb1fc4cf..7a8e686 100755 --- a/testing/trigger_scripts/chromeos_device_trigger.py +++ b/testing/trigger_scripts/chromeos_device_trigger.py
@@ -127,7 +127,7 @@ ]) new_args += additional_args[1:] - return triggerer.run_swarming_go(new_args, True, args.dump_json, + return triggerer.run_swarming_go(new_args, args.dump_json, args.shard_index or 0, args.shards)
diff --git a/testing/trigger_scripts/perf_device_trigger.py b/testing/trigger_scripts/perf_device_trigger.py index bd96eec..e9a8efbd 100755 --- a/testing/trigger_scripts/perf_device_trigger.py +++ b/testing/trigger_scripts/perf_device_trigger.py
@@ -106,15 +106,17 @@ self._query_swarming_for_eligible_bot_configs( self._dimensions)) - def generate_shard_map(self, args, buildername, selected_config, verbose): + if args.multiple_dimension_script_verbose: + logging.basicConfig(level=logging.DEBUG) + + def generate_shard_map(self, args, buildername, selected_config): shard_map = None num_of_shards = len(selected_config) builder = bot_platforms.find_bot_platform(buildername) if args.use_dynamic_shards and builder and num_of_shards: - if verbose: - print( - 'Generating dynamic shardmap for builder: %s with %d shards' - % (buildername, num_of_shards)) + logging.info( + 'Generating dynamic shardmap for builder: %s with %d shards', + buildername, num_of_shards) shard_map = generate_perf_sharding.GenerateShardMap( builder=builder, num_of_shards=num_of_shards) for shard_index, bot_index in selected_config: @@ -145,7 +147,7 @@ for _, bot in self._eligible_bots_by_ids.iteritems(): self._bot_configs.append(bot.as_json_config()) - def select_config_indices(self, args, verbose): + def select_config_indices(self, args): if args.multiple_trigger_configs: configs = [] # If specific bot ids were passed in, we want to trigger a job for @@ -154,10 +156,10 @@ for index in range(len(self.indices_to_trigger(args))): configs.append((index, index)) if args.use_dynamic_shards: - return self._select_config_indices_with_dynamic_sharding(verbose) - return self._select_config_indices_with_soft_affinity(args, verbose) + return self._select_config_indices_with_dynamic_sharding() + return self._select_config_indices_with_soft_affinity(args) - def _select_config_indices_with_dynamic_sharding(self, verbose): + def _select_config_indices_with_dynamic_sharding(self): alive_bot_ids = [ bot_id for bot_id, b in self._eligible_bots_by_ids.iteritems() if b.is_alive() @@ -171,22 +173,20 @@ for i in range(trigger_count)] selected_config.sort() - if verbose: - for shard_index, bot_index in selected_config: - print('Shard %d\n\tBot: %s' % - (shard_index, self._bot_configs[bot_index]['id'])) + for shard_index, bot_index in selected_config: + logging.info('Shard %d\n\tBot: %s', shard_index, + self._bot_configs[bot_index]['id']) return selected_config - def _select_config_indices_with_soft_affinity(self, args, verbose): + def _select_config_indices_with_soft_affinity(self, args): trigger_count = len(self.indices_to_trigger(args)) # First make sure the number of shards doesn't exceed the # number of eligible bots. This means there is a config error somewhere. if trigger_count > len(self._eligible_bots_by_ids): - if verbose: - self._print_device_affinity_info({}, {}, - self._eligible_bots_by_ids, - trigger_count) + self._print_device_affinity_info({}, {}, + self._eligible_bots_by_ids, + trigger_count) raise ValueError( 'Not enough available machines exist in swarming ' 'pool. Shards requested (%d) exceeds available bots ' @@ -222,9 +222,8 @@ if not bot and unallocated_healthy_bots: shard_to_bot_assignment_map[shard_index] = \ unallocated_healthy_bots.pop() - if verbose: - print('First time shard %d has been triggered' % - shard_index) + logging.info('First time shard %d has been triggered', + shard_index) elif not bot: shard_to_bot_assignment_map[ shard_index] = unallocated_bad_bots.pop() @@ -236,11 +235,10 @@ dead_bot = bot healthy_bot = unallocated_healthy_bots.pop() shard_to_bot_assignment_map[shard_index] = healthy_bot - if verbose: - print( - 'Device affinity broken for shard #%d. bot %s is dead,' - ' new mapping to bot %s' % - (shard_index, dead_bot.id(), healthy_bot.id())) + logging.info( + 'Device affinity broken for shard #%d. bot %s is dead,' + ' new mapping to bot %s', shard_index, dead_bot.id(), + healthy_bot.id()) # Now populate the indices into the bot_configs array selected_configs = [] @@ -249,16 +247,15 @@ (shard_index, self._find_bot_config_index( shard_to_bot_assignment_map[shard_index].id()))) - if verbose: - self._print_device_affinity_info(shard_to_bot_assignment_map, - existing_shard_bot_to_shard_map, - self._eligible_bots_by_ids, - trigger_count) + self._print_device_affinity_info(shard_to_bot_assignment_map, + existing_shard_bot_to_shard_map, + self._eligible_bots_by_ids, + trigger_count) return selected_configs def _print_device_affinity_info(self, new_map, existing_map, health_map, num_shards): - print() + logging.info('') for shard_index in xrange(num_shards): existing = existing_map.get(shard_index, None) new = new_map.get(shard_index, None) @@ -268,8 +265,8 @@ new_id = '' if new: new_id = new.id() - print('Shard %d\n\tprevious: %s\n\tnew: %s' % - (shard_index, existing_id, new_id)) + logging.info('Shard %d\n\tprevious: %s\n\tnew: %s', shard_index, + existing_id, new_id) healthy_bots = [] dead_bots = [] @@ -278,12 +275,12 @@ healthy_bots.append(b.id()) else: dead_bots.append(b.id()) - print('Shards needed: %d' % num_shards) - print('Total bots (dead + healthy): %d' % - (len(dead_bots) + len(healthy_bots))) - print('Healthy bots, %d: %s' % (len(healthy_bots), healthy_bots)) - print('Dead Bots, %d: %s' % (len(dead_bots), dead_bots)) - print() + logging.info('Shards needed: %d', num_shards) + logging.info('Total bots (dead + healthy): %d', + len(dead_bots) + len(healthy_bots)) + logging.info('Healthy bots, %d: %s', len(healthy_bots), healthy_bots) + logging.info('Dead Bots, %d: %s', len(dead_bots), dead_bots) + logging.info('') def _query_swarming_for_eligible_bot_configs(self, dimensions): """Query Swarming to figure out which bots are available. @@ -294,7 +291,6 @@ """ query_result = self.list_bots(dimensions, - True, server=self._swarming_server) perf_bots = {} for bot in query_result: @@ -346,7 +342,6 @@ query_result = self.query_swarming( 'tasks/list', values_with_shard, - True, limit='1', server=self._swarming_server) except Exception: @@ -354,7 +349,6 @@ if self._sharded_query_failed: query_result = self.query_swarming('tasks/list', values, - True, limit='1', server=self._swarming_server)
diff --git a/testing/trigger_scripts/perf_device_trigger_unittest.py b/testing/trigger_scripts/perf_device_trigger_unittest.py index 115e0e2..87718b5 100755 --- a/testing/trigger_scripts/perf_device_trigger_unittest.py +++ b/testing/trigger_scripts/perf_device_trigger_unittest.py
@@ -51,23 +51,20 @@ def list_bots(self, dimensions, - verbose, server='chromium-swarm.appspot.com'): return self._list_bots_result - def run_swarming(self, args, verbose): - del verbose #unused + def run_swarming(self, args): self._swarming_runs.append(args) def run_swarming_go(self, args, - verbose, _json_path, _shard_index, _shard, _merged_json=None): self._triggered_with_swarming_go += 1 - self.run_swarming(args, verbose) + self.run_swarming(args) class UnitTest(unittest.TestCase):
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index dcdde15f..f953fa47 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -954,7 +954,7 @@ ] } ], - "AutofillAssistantInCCTTriggeringLaunch": [ + "AutofillAssistantInCCTTriggering": [ { "platforms": [ "android" @@ -962,6 +962,9 @@ "experiments": [ { "name": "Enabled_20210611", + "params": { + "json_parameters": "\n{\n \"denylistedDomains\": [\"google.com\", \"facebook.com\", \"ampproject.org\",\n \"amazon.com\", \"pornhub.com\", \"xnxx.com\",\n \"xvideos.com\", \"twitter.com\", \"instagram.com\",\n \"craigslist.org\", \"yahoo.com\",\n \"googleadservices.com\", \"youtube.com\",\n \"zillow.com\", \"wikipedia.org\", \"xhamster.com\",\n \"pinterest.com\", \"reddit.com\", \"indeed.com\",\n \"dailymail.co.uk\", \"weather.com\", \"mlb.com\",\n \"live.com\", \"realtor.com\", \"trulia.com\",\n \"ca.gov\", \"pch.com\", \"paypal.com\", \"office.com\",\n \"espn.com\"],\n \"heuristics\":[\n {\n \"intent\":\"SHOPPING_ASSISTED_CHECKOUT\",\n \"conditionSet\":{\n \"schemes\":[\"https\"],\n \"urlMatches\":\"(?i)cart|trolley|basket|checkout|fulfil+ment|bag|shipping|pay|buy\"\n }\n },\n {\n \"intent\":\"SHOPPING_ASSISTED_CHECKOUT\",\n \"conditionSet\":{\n \"urlPrefix\":\"https://www.jegs.com/webapp/wcs/stores/servlet/OrderItemDisplay\"\n }\n }\n ]\n}" + }, "enable_features": [ "AutofillAssistantInCctTriggering", "AutofillAssistantUrlHeuristics"
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index 99d90b8f..94a8381f 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -40,7 +40,6 @@ "choosers/file_chooser.mojom", "choosers/popup_menu.mojom", "clipboard/clipboard.mojom", - "clipboard/raw_clipboard.mojom", "commit_result/commit_result.mojom", "compute_pressure/compute_pressure.mojom", "content_index/content_index.mojom",
diff --git a/third_party/blink/public/mojom/clipboard/raw_clipboard.mojom b/third_party/blink/public/mojom/clipboard/raw_clipboard.mojom deleted file mode 100644 index 90958fff..0000000 --- a/third_party/blink/public/mojom/clipboard/raw_clipboard.mojom +++ /dev/null
@@ -1,41 +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. - -module blink.mojom; - -import "mojo/public/mojom/base/string16.mojom"; -import "mojo/public/mojom/base/big_buffer.mojom"; - -// RawClipboardHost allows "raw", unmodified, and unsanitized communication with -// the system clipboard, and can pass platform-specific clipboard payloads. -// -// Individual operations are atomic, but successive operations are not. -// Therefore, it's possible that one may see a format available from -// ReadAvailableFormatNames(), but that a subsequent Read() may then fail. -// -// The RawClipboardHost mojo connection enforces that interactions aren't done -// without permission by only binding if permission is granted, and -// automatically unbinding if permission is revoked. -// (It won't automatically re-bind if permission is re-granted afterwards). -// -// Please be careful about endpoints that use this interface, as unsanitized -// content reaching the platform clipboard may lead to remote code execution. -interface RawClipboardHost { - // Conservative limits to maximum format name and data sizes, to avoid - // potential attacks with long strings. - const int32 kMaxFormatSize = 1024; - const int32 kMaxDataSize = 1073741824; // 1 GB, or 1 << 30 - - // Reads unsanitized/raw platform-specific types. - ReadAvailableFormatNames() => (array<mojo_base.mojom.String16> raw_types); - - // Reads unsanitized/raw data from the platform. - Read(mojo_base.mojom.String16 format) => (mojo_base.mojom.BigBuffer data); - - // Writes unsanitized/raw data from renderer. - Write(mojo_base.mojom.String16 format, mojo_base.mojom.BigBuffer data); - - // Writes must call CommitWrite for changes to reach the underlying platform. - CommitWrite(); -};
diff --git a/third_party/blink/public/mojom/fetch/fetch_api_request.mojom b/third_party/blink/public/mojom/fetch/fetch_api_request.mojom index 57287aebc..8e30381e 100644 --- a/third_party/blink/public/mojom/fetch/fetch_api_request.mojom +++ b/third_party/blink/public/mojom/fetch/fetch_api_request.mojom
@@ -9,6 +9,7 @@ import "mojo/public/mojom/base/unguessable_token.mojom"; import "services/network/public/mojom/chunked_data_pipe_getter.mojom"; import "services/network/public/mojom/fetch_api.mojom"; +import "services/network/public/mojom/request_priority.mojom"; import "services/network/public/mojom/url_request.mojom"; import "third_party/blink/public/mojom/blob/serialized_blob.mojom"; import "third_party/blink/public/mojom/loader/request_context_frame_type.mojom";
diff --git a/third_party/blink/public/mojom/loader/resource_load_info.mojom b/third_party/blink/public/mojom/loader/resource_load_info.mojom index edb1cdcf..565e3ad 100644 --- a/third_party/blink/public/mojom/loader/resource_load_info.mojom +++ b/third_party/blink/public/mojom/loader/resource_load_info.mojom
@@ -4,12 +4,12 @@ module blink.mojom; +import "services/network/public/mojom/fetch_api.mojom"; import "services/network/public/mojom/ip_address.mojom"; import "services/network/public/mojom/ip_endpoint.mojom"; import "services/network/public/mojom/load_timing_info.mojom"; import "services/network/public/mojom/network_param.mojom"; -import "services/network/public/mojom/url_request.mojom"; -import "services/network/public/mojom/fetch_api.mojom"; +import "services/network/public/mojom/request_priority.mojom"; import "url/mojom/origin.mojom"; import "url/mojom/url.mojom";
diff --git a/third_party/blink/public/mojom/loader/resource_load_info_notifier.mojom b/third_party/blink/public/mojom/loader/resource_load_info_notifier.mojom index 667649e..76d7a92f 100644 --- a/third_party/blink/public/mojom/loader/resource_load_info_notifier.mojom +++ b/third_party/blink/public/mojom/loader/resource_load_info_notifier.mojom
@@ -6,6 +6,7 @@ import "services/network/public/mojom/fetch_api.mojom"; import "services/network/public/mojom/url_loader.mojom"; +import "services/network/public/mojom/url_loader_completion_status.mojom"; import "services/network/public/mojom/url_request.mojom"; import "services/network/public/mojom/url_response_head.mojom"; import "third_party/blink/public/mojom/loader/resource_load_info.mojom";
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index bf1047f0..378e4878 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -3274,6 +3274,7 @@ kV8URLPattern_Constructor = 3959, kV8URLPattern_Test_Method = 3960, kV8URLPattern_Exec_Method = 3961, + kSameSiteCookieInclusionChangedByCrossSiteRedirect = 3962, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/renderer/core/clipboard/build.gni b/third_party/blink/renderer/core/clipboard/build.gni index 65a04dc..fe60db8 100644 --- a/third_party/blink/renderer/core/clipboard/build.gni +++ b/third_party/blink/renderer/core/clipboard/build.gni
@@ -21,8 +21,6 @@ "dragged_isolated_file_system.cc", "dragged_isolated_file_system.h", "paste_mode.h", - "raw_system_clipboard.cc", - "raw_system_clipboard.h", "system_clipboard.cc", "system_clipboard.h", ]
diff --git a/third_party/blink/renderer/core/clipboard/raw_system_clipboard.cc b/third_party/blink/renderer/core/clipboard/raw_system_clipboard.cc deleted file mode 100644 index 73e8a75..0000000 --- a/third_party/blink/renderer/core/clipboard/raw_system_clipboard.cc +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/core/clipboard/raw_system_clipboard.h" - -#include "mojo/public/cpp/base/big_buffer.h" -#include "third_party/blink/public/common/browser_interface_broker_proxy.h" -#include "third_party/blink/renderer/core/frame/local_dom_window.h" -#include "third_party/blink/renderer/core/frame/local_frame.h" - -#include "third_party/blink/public/mojom/clipboard/raw_clipboard.mojom-blink.h" -namespace blink { - -RawSystemClipboard::RawSystemClipboard(LocalFrame* frame) - : clipboard_(frame->DomWindow()) { - frame->GetBrowserInterfaceBroker().GetInterface( - clipboard_.BindNewPipeAndPassReceiver( - frame->GetTaskRunner(TaskType::kUserInteraction))); -} - -void RawSystemClipboard::ReadAvailableFormatNames( - mojom::blink::RawClipboardHost::ReadAvailableFormatNamesCallback callback) { - clipboard_->ReadAvailableFormatNames(std::move(callback)); -} - -void RawSystemClipboard::Read( - const String& type, - mojom::blink::RawClipboardHost::ReadCallback callback) { - clipboard_->Read(type, std::move(callback)); -} - -void RawSystemClipboard::Write(const String& type, mojo_base::BigBuffer data) { - clipboard_->Write(type, std::move(data)); -} - -void RawSystemClipboard::CommitWrite() { - clipboard_->CommitWrite(); -} - -void RawSystemClipboard::Trace(Visitor* visitor) const { - visitor->Trace(clipboard_); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/clipboard/raw_system_clipboard.h b/third_party/blink/renderer/core/clipboard/raw_system_clipboard.h deleted file mode 100644 index e78f93e1..0000000 --- a/third_party/blink/renderer/core/clipboard/raw_system_clipboard.h +++ /dev/null
@@ -1,50 +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 THIRD_PARTY_BLINK_RENDERER_CORE_CLIPBOARD_RAW_SYSTEM_CLIPBOARD_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_CLIPBOARD_RAW_SYSTEM_CLIPBOARD_H_ - -#include "third_party/blink/public/mojom/clipboard/raw_clipboard.mojom-blink.h" -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/platform/heap/heap.h" -#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" -#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" - -// RawSystemClipboard: -// - is a singleton. -// - provides read/write access of unsanitized, platform-specific data. -// - mediates between async clipboard and mojom::RawClipboardHost. -// -// All calls to Write() must be followed by a call to CommitWrite(). -namespace blink { - -class LocalFrame; - -class CORE_EXPORT RawSystemClipboard final - : public GarbageCollected<RawSystemClipboard> { - public: - explicit RawSystemClipboard(LocalFrame* frame); - - RawSystemClipboard(const RawSystemClipboard&) = delete; - RawSystemClipboard& operator=(const RawSystemClipboard&) = delete; - - void ReadAvailableFormatNames( - mojom::blink::RawClipboardHost::ReadAvailableFormatNamesCallback - callback); - - void Read(const String& type, - mojom::blink::RawClipboardHost::ReadCallback callback); - - void Write(const String& type, mojo_base::BigBuffer data); - - void CommitWrite(); - void Trace(Visitor*) const; - - private: - HeapMojoRemote<mojom::blink::RawClipboardHost> clipboard_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CLIPBOARD_RAW_SYSTEM_CLIPBOARD_H_
diff --git a/third_party/blink/renderer/core/css/counter_style.cc b/third_party/blink/renderer/core/css/counter_style.cc index f8c9b9cc..356f0fa3 100644 --- a/third_party/blink/renderer/core/css/counter_style.cc +++ b/third_party/blink/renderer/core/css/counter_style.cc
@@ -422,7 +422,7 @@ String HebrewAlgorithmUnder1000(unsigned number) { // FIXME: CSS3 mentions various refinements not implemented here. // FIXME: Should take a look at Mozilla's HebrewToText function (in - // nsBulletFrame). + // CounterStyleManager.cpp). DCHECK_LT(number, 1000u); StringBuilder letters; unsigned four_hundreds = number / 400;
diff --git a/third_party/blink/renderer/core/editing/finder/find_task_controller.cc b/third_party/blink/renderer/core/editing/finder/find_task_controller.cc index 872cb300..fde9373 100644 --- a/third_party/blink/renderer/core/editing/finder/find_task_controller.cc +++ b/third_party/blink/renderer/core/editing/finder/find_task_controller.cc
@@ -167,7 +167,9 @@ int identifier, const WebString& search_text, const mojom::blink::FindOptions& options) { - TRACE_EVENT_ASYNC_BEGIN0("blink", "FindInPageRequest", identifier); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( + "blink", "FindInPageRequest", + TRACE_ID_WITH_SCOPE("FindInPageRequest", identifier)); current_request_start_time_ = base::TimeTicks::Now(); total_task_duration_for_current_request_ = base::TimeDelta(); task_count_for_current_request_ = 0; @@ -252,8 +254,10 @@ void FindTaskController::RecordRequestMetrics( RequestEndState request_end_state) { bool aborted = (request_end_state == RequestEndState::ABORTED); - TRACE_EVENT_ASYNC_END1("blink", "FindInPageRequest", current_find_identifier_, - "aborted", aborted); + TRACE_EVENT_NESTABLE_ASYNC_END1( + "blink", "FindInPageRequest", + TRACE_ID_WITH_SCOPE("FindInPageRequest", current_find_identifier_), + "aborted", aborted); if (aborted) { UMA_HISTOGRAM_MEDIUM_TIMES("WebCore.FindInPage.TotalTaskDuration.Aborted", total_task_duration_for_current_request_);
diff --git a/third_party/blink/renderer/core/frame/dom_window.cc b/third_party/blink/renderer/core/frame/dom_window.cc index c9d144c..9fec4d76 100644 --- a/third_party/blink/renderer/core/frame/dom_window.cc +++ b/third_party/blink/renderer/core/frame/dom_window.cc
@@ -712,12 +712,44 @@ delegate_payment_request = capability_list.Contains("paymentrequest"); } - MessageEvent* event = - MessageEvent::Create(std::move(channels), std::move(message), - source->GetSecurityOrigin()->ToString(), String(), - source, user_activation, delegate_payment_request); + PostedMessage* posted_message = MakeGarbageCollected<PostedMessage>(); + posted_message->source_origin = source->GetSecurityOrigin(); + posted_message->target_origin = std::move(target); + posted_message->data = std::move(message); + posted_message->channels = std::move(channels); + posted_message->source = source; + posted_message->user_activation = user_activation; + posted_message->delegate_payment_request = delegate_payment_request; + SchedulePostMessage(posted_message); +} - SchedulePostMessage(event, std::move(target), source); +void DOMWindow::PostedMessage::Trace(Visitor* visitor) const { + visitor->Trace(source); + visitor->Trace(user_activation); +} + +BlinkTransferableMessage +DOMWindow::PostedMessage::ToBlinkTransferableMessage() && { + BlinkTransferableMessage result; + + // Message data and cluster ID (optional). + result.message = std::move(data); + if (result.message->IsLockedToAgentCluster()) + result.locked_agent_cluster_id = source->GetAgentClusterID(); + + // Ports + result.ports = std::move(channels); + + // User activation + if (user_activation) { + result.user_activation = mojom::blink::UserActivationSnapshot::New( + user_activation->hasBeenActive(), user_activation->isActive()); + } + + // Capability delegation + result.delegate_payment_request = delegate_payment_request; + + return result; } void DOMWindow::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/core/frame/dom_window.h b/third_party/blink/renderer/core/frame/dom_window.h index 9c935c8d..1f382084 100644 --- a/third_party/blink/renderer/core/frame/dom_window.h +++ b/third_party/blink/renderer/core/frame/dom_window.h
@@ -13,6 +13,7 @@ #include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/core/frame/frame.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -22,13 +23,15 @@ class InputDeviceCapabilitiesConstants; class LocalDOMWindow; class Location; -class MessageEvent; class ScriptValue; class SecurityOrigin; class SerializedScriptValue; +class UserActivation; class WindowPostMessageOptions; class WindowProxyManager; +struct BlinkTransferableMessage; + // DOMWindow is an abstract class of Window interface implementations. // We have two derived implementation classes; LocalDOMWindow and // RemoteDOMWindow. @@ -154,9 +157,19 @@ protected: explicit DOMWindow(Frame&); - virtual void SchedulePostMessage(MessageEvent*, - scoped_refptr<const SecurityOrigin> target, - LocalDOMWindow* source) = 0; + struct PostedMessage final : GarbageCollected<PostedMessage> { + void Trace(Visitor* visitor) const; + BlinkTransferableMessage ToBlinkTransferableMessage() &&; + + scoped_refptr<const SecurityOrigin> source_origin; + scoped_refptr<const SecurityOrigin> target_origin; + scoped_refptr<SerializedScriptValue> data; + Vector<MessagePortChannel> channels; + Member<LocalDOMWindow> source; + Member<UserActivation> user_activation; + bool delegate_payment_request = false; + }; + virtual void SchedulePostMessage(PostedMessage* message) = 0; void DisconnectFromFrame() { frame_ = nullptr; }
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc index 45756c1..071399c 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -973,10 +973,9 @@ return navigator_.Get(); } -void LocalDOMWindow::SchedulePostMessage( - MessageEvent* event, - scoped_refptr<const SecurityOrigin> target, - LocalDOMWindow* source) { +void LocalDOMWindow::SchedulePostMessage(PostedMessage* posted_message) { + LocalDOMWindow* source = posted_message->source; + // Record UKM metrics for postMessage event. ukm::SourceId source_frame_ukm_source_id = source->UkmSourceID(); if (ShouldRecordPostMessageIncomingFrameUkmEvent( @@ -986,6 +985,14 @@ .Record(UkmRecorder()); } + // Convert the posted message to a MessageEvent so it can be unpacked for + // local dispatch. + MessageEvent* event = MessageEvent::Create( + std::move(posted_message->channels), std::move(posted_message->data), + posted_message->source_origin->ToString(), String(), + posted_message->source, posted_message->user_activation, + posted_message->delegate_payment_request); + // Allowing unbounded amounts of messages to build up for a suspended context // is problematic; consider imposing a limit or other restriction if this // surfaces often as a problem (see crbug.com/587012). @@ -994,7 +1001,8 @@ ->PostTask( FROM_HERE, WTF::Bind(&LocalDOMWindow::DispatchPostMessage, WrapPersistent(this), - WrapPersistent(event), std::move(target), + WrapPersistent(event), + std::move(posted_message->target_origin), std::move(location), source->GetAgent()->cluster_id())); probe::AsyncTaskScheduled(this, "postMessage", event->async_task_id()); }
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h index b37537b..a7c0ead9 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.h +++ b/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -443,9 +443,7 @@ const RegisteredEventListener&) override; // Protected DOMWindow overrides. - void SchedulePostMessage(MessageEvent*, - scoped_refptr<const SecurityOrigin> target, - LocalDOMWindow* source) override; + void SchedulePostMessage(PostedMessage*) override; private: // Intentionally private to prevent redundant checks when the type is
diff --git a/third_party/blink/renderer/core/frame/local_dom_window_test.cc b/third_party/blink/renderer/core/frame/local_dom_window_test.cc index f598a010..6c36273 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window_test.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window_test.cc
@@ -44,6 +44,7 @@ #include "third_party/blink/renderer/platform/scheduler/public/event_loop.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" +#include "third_party/blink/renderer/platform/wtf/threading.h" namespace blink { @@ -192,6 +193,9 @@ { url::ScopedSchemeRegistryForTests scoped_registry; url::AddStandardScheme("very-special-scheme", url::SCHEME_WITH_HOST); +#if DCHECK_IS_ON() + WTF::SetIsBeforeThreadCreatedForTest(); // Required for next operation: +#endif SchemeRegistry::RegisterURLSchemeBypassingSecureContextCheck( "very-special-scheme"); NavigateWithSandbox(KURL("very-special-scheme://example.test"));
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 0c296b4..1ea4cd1 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -75,7 +75,6 @@ #include "third_party/blink/renderer/bindings/core/v8/script_controller.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" -#include "third_party/blink/renderer/core/clipboard/raw_system_clipboard.h" #include "third_party/blink/renderer/core/clipboard/system_clipboard.h" #include "third_party/blink/renderer/core/content_capture/content_capture_manager.h" #include "third_party/blink/renderer/core/core_initializer.h" @@ -420,7 +419,6 @@ visitor->Trace(smooth_scroll_sequencer_); visitor->Trace(content_capture_manager_); visitor->Trace(system_clipboard_); - visitor->Trace(raw_system_clipboard_); visitor->Trace(virtual_keyboard_overlay_changed_observers_); visitor->Trace(pause_handle_receivers_); #if defined(OS_MAC) @@ -818,7 +816,6 @@ // LocalDOMWindow was set, we need to create new SystemClipboard and // RawSystemClipboard. system_clipboard_ = nullptr; - raw_system_clipboard_ = nullptr; } GetWindowProxyManager()->ClearForNavigation(); dom_window_ = dom_window; @@ -2660,13 +2657,6 @@ return system_clipboard_.Get(); } -RawSystemClipboard* LocalFrame::GetRawSystemClipboard() { - if (!raw_system_clipboard_) - raw_system_clipboard_ = MakeGarbageCollected<RawSystemClipboard>(this); - - return raw_system_clipboard_.Get(); -} - void LocalFrame::WasAttachedAsLocalMainFrame() { mojo_handler_->WasAttachedAsLocalMainFrame(); }
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index b8e666d8..fe3cde3 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -128,7 +128,6 @@ class PerformanceMonitor; class PolicyContainer; class PluginData; -class RawSystemClipboard; class SystemClipboard; class SmoothScrollSequencer; class SpellChecker; @@ -653,7 +652,6 @@ void UpdateWindowControlsOverlay(const gfx::Rect& bounding_rect_in_dips); SystemClipboard* GetSystemClipboard(); - RawSystemClipboard* GetRawSystemClipboard(); // Indicate that this frame was attached as a MainFrame. void WasAttachedAsLocalMainFrame(); @@ -915,8 +913,6 @@ // Access to the global sanitized system clipboard. Member<SystemClipboard> system_clipboard_; - // Access to the global raw/unsanitized system clipboard - Member<RawSystemClipboard> raw_system_clipboard_; // Access to background-color paint image generator. Initialized per local // root and reused among sub frames.
diff --git a/third_party/blink/renderer/core/frame/remote_dom_window.cc b/third_party/blink/renderer/core/frame/remote_dom_window.cc index 12f154f..12fe8012 100644 --- a/third_party/blink/renderer/core/frame/remote_dom_window.cc +++ b/third_party/blink/renderer/core/frame/remote_dom_window.cc
@@ -31,10 +31,7 @@ DisconnectFromFrame(); } -void RemoteDOMWindow::SchedulePostMessage( - MessageEvent* event, - scoped_refptr<const SecurityOrigin> target, - LocalDOMWindow* source) { +void RemoteDOMWindow::SchedulePostMessage(PostedMessage* posted_message) { // To match same-process behavior, the IPC to forward postMessage // cross-process should only be sent after the current script finishes // running, to preserve relative ordering of IPCs. See @@ -45,27 +42,26 @@ // should also be observable by the target frame prior to receiving the // postMessage. We might consider forcing layout in ForwardPostMessage or // further delaying postMessage forwarding until after the next BeginFrame. - source->GetTaskRunner(TaskType::kPostedMessage) - ->PostTask(FROM_HERE, - WTF::Bind(&RemoteDOMWindow::ForwardPostMessage, - WrapPersistent(this), WrapPersistent(event), - std::move(target), WrapPersistent(source))); + posted_message->source->GetTaskRunner(TaskType::kPostedMessage) + ->PostTask(FROM_HERE, WTF::Bind(&RemoteDOMWindow::ForwardPostMessage, + WrapPersistent(this), + WrapPersistent(posted_message))); } -void RemoteDOMWindow::ForwardPostMessage( - MessageEvent* event, - scoped_refptr<const SecurityOrigin> target, - LocalDOMWindow* source) { +void RemoteDOMWindow::ForwardPostMessage(PostedMessage* posted_message) { // If the target frame was detached after the message was scheduled, // don't deliver the message. if (!GetFrame()) return; - absl::optional<base::UnguessableToken> agent_cluster; - if (event->IsLockedToAgentCluster()) - agent_cluster = source->GetAgentClusterID(); - GetFrame()->ForwardPostMessage(event, agent_cluster, std::move(target), - source->GetFrame()); + LocalFrame* source_frame = posted_message->source->GetFrame(); + scoped_refptr<const SecurityOrigin> source_origin = + posted_message->source_origin; + scoped_refptr<const SecurityOrigin> target_origin = + posted_message->target_origin; + GetFrame()->ForwardPostMessage( + std::move(*posted_message).ToBlinkTransferableMessage(), source_frame, + std::move(source_origin), std::move(target_origin)); } } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/remote_dom_window.h b/third_party/blink/renderer/core/frame/remote_dom_window.h index 109548b3..4787e12 100644 --- a/third_party/blink/renderer/core/frame/remote_dom_window.h +++ b/third_party/blink/renderer/core/frame/remote_dom_window.h
@@ -30,9 +30,7 @@ protected: // Protected DOMWindow overrides: - void SchedulePostMessage(MessageEvent*, - scoped_refptr<const SecurityOrigin> target, - LocalDOMWindow* source) override; + void SchedulePostMessage(PostedMessage*) override; private: // Intentionally private to prevent redundant checks when the type is @@ -40,9 +38,7 @@ bool IsLocalDOMWindow() const override { return false; } bool IsRemoteDOMWindow() const override { return true; } - void ForwardPostMessage(MessageEvent*, - scoped_refptr<const SecurityOrigin> target, - LocalDOMWindow* source); + void ForwardPostMessage(PostedMessage*); }; template <>
diff --git a/third_party/blink/renderer/core/frame/remote_frame.cc b/third_party/blink/renderer/core/frame/remote_frame.cc index f15f35b..24d0997 100644 --- a/third_party/blink/renderer/core/frame/remote_frame.cc +++ b/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -486,22 +486,24 @@ } void RemoteFrame::ForwardPostMessage( - MessageEvent* message_event, - absl::optional<base::UnguessableToken> cluster_id, - scoped_refptr<const SecurityOrigin> target_security_origin, - LocalFrame* source_frame) { + BlinkTransferableMessage transferable_message, + LocalFrame* source_frame, + scoped_refptr<const SecurityOrigin> source_security_origin, + scoped_refptr<const SecurityOrigin> target_security_origin) { absl::optional<blink::LocalFrameToken> source_token; if (source_frame) source_token = source_frame->GetLocalFrameToken(); - String source_origin = message_event->origin(); - String target_origin = g_empty_string; - if (target_security_origin) - target_origin = target_security_origin->ToString(); + String source_origin = source_security_origin + ? source_security_origin->ToString() + : g_empty_string; + String target_origin = target_security_origin + ? target_security_origin->ToString() + : g_empty_string; - GetRemoteFrameHostRemote().RouteMessageEvent( - source_token, source_origin, target_origin, - BlinkTransferableMessage::FromMessageEvent(message_event, cluster_id)); + GetRemoteFrameHostRemote().RouteMessageEvent(source_token, source_origin, + target_origin, + std::move(transferable_message)); } mojom::blink::RemoteFrameHost& RemoteFrame::GetRemoteFrameHostRemote() {
diff --git a/third_party/blink/renderer/core/frame/remote_frame.h b/third_party/blink/renderer/core/frame/remote_frame.h index 1e8574e..47c9672 100644 --- a/third_party/blink/renderer/core/frame/remote_frame.h +++ b/third_party/blink/renderer/core/frame/remote_frame.h
@@ -33,14 +33,15 @@ namespace blink { class AssociatedInterfaceProvider; +class ChildFrameCompositingHelper; class InterfaceRegistry; class LocalFrame; -class MessageEvent; class RemoteFrameClient; -struct FrameLoadRequest; -class ChildFrameCompositingHelper; class WebFrameWidget; +struct BlinkTransferableMessage; +struct FrameLoadRequest; + // A RemoteFrame is a frame that is possibly hosted outside this process. class CORE_EXPORT RemoteFrame final : public Frame, public ChildFrameCompositor, @@ -96,10 +97,10 @@ void CreateView(); void ForwardPostMessage( - MessageEvent* message_event, - absl::optional<base::UnguessableToken> cluster_id, - scoped_refptr<const SecurityOrigin> target_security_origin, - LocalFrame* source_frame); + BlinkTransferableMessage, + LocalFrame* source_frame, + scoped_refptr<const SecurityOrigin> source_security_origin, + scoped_refptr<const SecurityOrigin> target_security_origin); mojom::blink::RemoteFrameHost& GetRemoteFrameHostRemote();
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc index f1bf945..7946d7a 100644 --- a/third_party/blink/renderer/core/frame/web_frame_test.cc +++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -161,6 +161,7 @@ #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/core/loader/frame_load_request.h" +#include "third_party/blink/renderer/core/messaging/blink_cloneable_message.h" #include "third_party/blink/renderer/core/messaging/blink_transferable_message.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/drag_image.h" @@ -1249,23 +1250,25 @@ auto* frame = To<LocalFrame>(web_view_helper.GetWebView()->GetPage()->MainFrame()); - scoped_refptr<SerializedScriptValue> data = SerializedScriptValue::Create(); - MessageEvent* message_event = MessageEvent::Create( - /*ports=*/nullptr, std::move(data), "http://origin.com"); + auto make_message = []() { + BlinkTransferableMessage message; + message.message = SerializedScriptValue::NullValue(); + message.sender_origin = + SecurityOrigin::CreateFromString("https://origin.com"); + return message; + }; // Send a message with the correct origin. scoped_refptr<SecurityOrigin> correct_origin = SecurityOrigin::Create(ToKURL(base_url_)); - frame->PostMessageEvent( - absl::nullopt, g_empty_string, correct_origin->ToString(), - BlinkTransferableMessage::FromMessageEvent(message_event)); + frame->PostMessageEvent(absl::nullopt, g_empty_string, + correct_origin->ToString(), make_message()); // Send another message with incorrect origin. scoped_refptr<SecurityOrigin> incorrect_origin = SecurityOrigin::Create(ToKURL(chrome_url_)); - frame->PostMessageEvent( - absl::nullopt, g_empty_string, incorrect_origin->ToString(), - BlinkTransferableMessage::FromMessageEvent(message_event)); + frame->PostMessageEvent(absl::nullopt, g_empty_string, + incorrect_origin->ToString(), make_message()); // Verify that only the first addition is in the body of the page. std::string content = TestWebFrameContentDumper::DumpWebViewAsText(
diff --git a/third_party/blink/renderer/core/loader/interactive_detector.cc b/third_party/blink/renderer/core/loader/interactive_detector.cc index d39006d..c065c4f 100644 --- a/third_party/blink/renderer/core/loader/interactive_detector.cc +++ b/third_party/blink/renderer/core/loader/interactive_detector.cc
@@ -277,22 +277,28 @@ if (delay > kFirstInputDelayTraceEventThreshold) { // Emit a trace event to highlight long first input delays. - TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0( + TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0( "latency", "Long First Input Delay", - TRACE_ID_LOCAL(g_num_long_input_events), event_timestamp); - TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0( + TRACE_ID_WITH_SCOPE("Long First Input Delay", + g_num_long_input_events), + event_timestamp); + TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0( "latency", "Long First Input Delay", - TRACE_ID_LOCAL(g_num_long_input_events), event_timestamp + delay); + TRACE_ID_WITH_SCOPE("Long First Input Delay", + g_num_long_input_events), + event_timestamp + delay); g_num_long_input_events++; } } else if (delay > kInputDelayTraceEventThreshold) { // Emit a trace event to highlight long input delays from second input and // onwards. - TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0( - "latency", "Long Input Delay", TRACE_ID_LOCAL(g_num_long_input_events), + TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0( + "latency", "Long Input Delay", + TRACE_ID_WITH_SCOPE("Long Input Delay", g_num_long_input_events), event_timestamp); - TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0( - "latency", "Long Input Delay", TRACE_ID_LOCAL(g_num_long_input_events), + TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0( + "latency", "Long Input Delay", + TRACE_ID_WITH_SCOPE("Long Input Delay", g_num_long_input_events), event_timestamp + delay); // Apply metadata on stack samples. base::ApplyMetadataToPastSamples(
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc index a0d7076..bfbf961 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
@@ -9,8 +9,6 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/mojom/blob/blob.mojom-blink.h" #include "third_party/blink/public/platform/cross_variant_mojo_util.h" -#include "third_party/blink/public/web/web_dom_message_event.h" -#include "third_party/blink/renderer/core/events/message_event.h" #include "third_party/blink/renderer/core/frame/user_activation.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" #include "third_party/blink/renderer/platform/blob/blob_data.h" @@ -19,107 +17,6 @@ namespace blink { // static -BlinkTransferableMessage BlinkTransferableMessage::FromMessageEvent( - MessageEvent* message_event, - absl::optional<base::UnguessableToken> cluster_id) { - BlinkTransferableMessage result; - SerializedScriptValue* serialized_script_value = - message_event->DataAsSerializedScriptValue(); - - // Message data and cluster ID (optional). - base::span<const uint8_t> message_wire_data = - serialized_script_value->GetWireData(); - result.message = SerializedScriptValue::Create( - reinterpret_cast<const char*>(message_wire_data.data()), - message_wire_data.size()); - result.locked_agent_cluster_id = cluster_id; - - // Ports - Vector<MessagePortChannel> ports = message_event->ReleaseChannels(); - result.ports.AppendRange(ports.begin(), ports.end()); - - // User activation - UserActivation* user_activation = message_event->userActivation(); - if (user_activation) { - result.user_activation = mojom::blink::UserActivationSnapshot::New( - user_activation->hasBeenActive(), user_activation->isActive()); - } - - // Capability delegation - result.delegate_payment_request = message_event->delegatePaymentRequest(); - - // Blobs. - for (const auto& blob : serialized_script_value->BlobDataHandles()) { - result.message->BlobDataHandles().Set( - blob.value->Uuid(), - BlobDataHandle::Create(blob.value->Uuid(), blob.value->GetType(), - blob.value->size(), - blob.value->CloneBlobRemote())); - } - - // Stream channels. - for (auto& stream : serialized_script_value->GetStreams()) { - result.message->GetStreams().push_back(std::move(stream)); - } - // Array buffer contents array. - auto& source_array_buffer_contents_array = - serialized_script_value->GetArrayBufferContentsArray(); - if (!source_array_buffer_contents_array.IsEmpty()) { - SerializedScriptValue::ArrayBufferContentsArray array_buffer_contents_array; - array_buffer_contents_array.ReserveInitialCapacity( - base::checked_cast<wtf_size_t>( - source_array_buffer_contents_array.size())); - - for (auto& source_contents : source_array_buffer_contents_array) { - uint8_t* allocation_start = static_cast<uint8_t*>(source_contents.Data()); - mojo_base::BigBuffer buffer( - base::make_span(allocation_start, source_contents.DataLength())); - ArrayBufferContents contents(buffer.size(), 1, - ArrayBufferContents::kNotShared, - ArrayBufferContents::kDontInitialize); - // Check if we allocated the backing store of the ArrayBufferContents - // correctly. - CHECK_EQ(contents.DataLength(), buffer.size()); - memcpy(contents.Data(), buffer.data(), buffer.size()); - array_buffer_contents_array.push_back(std::move(contents)); - } - result.message->SetArrayBufferContentsArray( - std::move(array_buffer_contents_array)); - } - - // Image bitmap contents array. - auto& source_image_bitmap_contents_array = - serialized_script_value->GetImageBitmapContentsArray(); - if (!source_image_bitmap_contents_array.IsEmpty()) { - SerializedScriptValue::ImageBitmapContentsArray image_bitmap_contents_array; - image_bitmap_contents_array.ReserveInitialCapacity( - base::checked_cast<wtf_size_t>( - source_image_bitmap_contents_array.size())); - - for (auto& contents : image_bitmap_contents_array) { - absl::optional<SkBitmap> sk_bitmap = ToSkBitmap(contents); - if (!sk_bitmap) - continue; - - const scoped_refptr<StaticBitmapImage> bitmap_contents = - ToStaticBitmapImage(sk_bitmap.value()); - if (!bitmap_contents) - continue; - image_bitmap_contents_array.push_back(bitmap_contents); - } - result.message->SetImageBitmapContentsArray( - std::move(image_bitmap_contents_array)); - } - - // File System Access transfer tokens. - for (auto& token : serialized_script_value->FileSystemAccessTokens()) { - result.message->FileSystemAccessTokens().push_back(std::move(token)); - } - - return result; -} - -// static BlinkTransferableMessage BlinkTransferableMessage::FromTransferableMessage( TransferableMessage message) { BlinkTransferableMessage result;
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message.h b/third_party/blink/renderer/core/messaging/blink_transferable_message.h index 9b455afa..c1140c07a 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message.h +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message.h
@@ -17,16 +17,11 @@ namespace blink { -class MessageEvent; - // This struct represents messages as they are posted over a message port. This // type can be serialized as a blink::mojom::TransferableMessage struct. // This is the renderer-side equivalent of blink::TransferableMessage, where // this struct uses blink types, while the other struct uses std:: types. struct CORE_EXPORT BlinkTransferableMessage : BlinkCloneableMessage { - static BlinkTransferableMessage FromMessageEvent( - MessageEvent*, - absl::optional<base::UnguessableToken> cluster_id = absl::nullopt); static BlinkTransferableMessage FromTransferableMessage(TransferableMessage); BlinkTransferableMessage();
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc index 682d837..3f926ee 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc +++ b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
@@ -6,7 +6,6 @@ #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/clipboard/clipboard.mojom-blink.h" -#include "third_party/blink/public/mojom/clipboard/raw_clipboard.mojom-blink.h" #include "third_party/blink/renderer/core/clipboard/clipboard_mime_types.h" #include "third_party/blink/renderer/core/clipboard/system_clipboard.h" #include "third_party/blink/renderer/core/dom/document_fragment.h" @@ -261,9 +260,6 @@ // static bool ClipboardWriter::IsValidType(const String& type, bool is_custom_format_type) { - if (is_custom_format_type) - return type.length() < mojom::blink::RawClipboardHost::kMaxFormatSize; - if (type == kMimeTypeImageSvg) return RuntimeEnabledFeatures::ClipboardSvgEnabled();
diff --git a/third_party/blink/renderer/modules/file_system_access/BUILD.gn b/third_party/blink/renderer/modules/file_system_access/BUILD.gn index d416279..7c77f5cc 100644 --- a/third_party/blink/renderer/modules/file_system_access/BUILD.gn +++ b/third_party/blink/renderer/modules/file_system_access/BUILD.gn
@@ -8,6 +8,7 @@ sources = [ "data_transfer_item_file_system_access.cc", "data_transfer_item_file_system_access.h", + "file_error_or.h", "file_system_access_error.cc", "file_system_access_error.h", "file_system_access_file_delegate.h",
diff --git a/third_party/blink/renderer/modules/file_system_access/file_error_or.h b/third_party/blink/renderer/modules/file_system_access/file_error_or.h new file mode 100644 index 0000000..50376ee --- /dev/null +++ b/third_party/blink/renderer/modules/file_system_access/file_error_or.h
@@ -0,0 +1,50 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FILE_SYSTEM_ACCESS_FILE_ERROR_OR_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILE_SYSTEM_ACCESS_FILE_ERROR_OR_H_ + +#include <utility> + +#include "base/files/file.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace blink { + +// TODO(crbug.com/1228745): This is a copy of base::FileErrorOr. Delete this +// class once FileErrorOr is moved to //base. + +// Helper for methods which perform file system operations and which may fail. +// Objects of this type can take on EITHER a base::File::Error value OR a result +// value of arbitrary type. +template <typename ValueType> +class FileErrorOr { + public: + explicit FileErrorOr() = default; + FileErrorOr(base::File::Error error) : error_(error) {} + FileErrorOr(ValueType&& value) + : maybe_value_(absl::in_place, std::move(value)) {} + FileErrorOr(const FileErrorOr&) = delete; + FileErrorOr(FileErrorOr&&) = default; + FileErrorOr& operator=(const FileErrorOr&) = delete; + FileErrorOr& operator=(FileErrorOr&&) = default; + ~FileErrorOr() = default; + + bool is_error() const { return !maybe_value_.has_value(); } + base::File::Error error() const { return error_; } + + ValueType& value() { return maybe_value_.value(); } + const ValueType& value() const { return maybe_value_.value(); } + + ValueType* operator->() { return &maybe_value_.value(); } + const ValueType* operator->() const { return &maybe_value_.value(); } + + private: + base::File::Error error_ = base::File::FILE_ERROR_FAILED; + absl::optional<ValueType> maybe_value_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FILE_SYSTEM_ACCESS_FILE_ERROR_OR_H_
diff --git a/third_party/blink/renderer/modules/file_system_access/file_system_access_file_delegate.h b/third_party/blink/renderer/modules/file_system_access/file_system_access_file_delegate.h index 9ae8bc4..e09f284 100644 --- a/third_party/blink/renderer/modules/file_system_access/file_system_access_file_delegate.h +++ b/third_party/blink/renderer/modules/file_system_access/file_system_access_file_delegate.h
@@ -9,7 +9,9 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/mojom/file_system_access/file_system_access_file_handle.mojom-blink.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/modules/file_system_access/file_error_or.h" #include "third_party/blink/renderer/platform/heap/handle.h" + namespace blink { // File object providing a common interface for file operations for an @@ -28,17 +30,18 @@ incognito_file_remote); // Reads the given number of bytes (or until EOF is reached) into the span - // starting with the given offset. Returns the number of bytes read, or -1 on - // error. - virtual int Read(int64_t offset, base::span<uint8_t> data) = 0; + // starting with the given offset. Returns the number of bytes read, or a file + // error on failure. + virtual FileErrorOr<int> Read(int64_t offset, base::span<uint8_t> data) = 0; // Writes the span into the file at the given offset, overwriting any data - // that was previously there. Returns the number of bytes written, or -1 on - // error. - virtual int Write(int64_t offset, const base::span<uint8_t> data) = 0; + // that was previously there. Returns the number of bytes written, or a file + // error on failure. + virtual FileErrorOr<int> Write(int64_t offset, + const base::span<uint8_t> data) = 0; - // Returns the current size of this file, or a negative number on failure. - virtual int64_t GetLength() = 0; + // Returns the current size of this file, or a file error on failure. + virtual FileErrorOr<int64_t> GetLength() = 0; // Truncates the file to the given length. If |length| is greater than the // current size of the file, the file is extended with zeros. If the file @@ -54,15 +57,6 @@ // Returns |true| if the file handle wrapped by this object is valid. virtual bool IsValid() const = 0; - // TODO(crbug.com/1228745): Move FileErrorOr to //base and use as a return - // type for the methods above. Then remove this method. - // - // Returns the error for the last operation on this file and converts it to - // the closest base::File::Error equivalent. Unlike the base::File equivalent, - // this method returns a cached error value which is guaranteed to be from the - // last operation on this file. - virtual base::File::Error GetLastFileError() = 0; - // GarbageCollected virtual void Trace(Visitor* visitor) const {} };
diff --git a/third_party/blink/renderer/modules/file_system_access/file_system_access_incognito_file_delegate.cc b/third_party/blink/renderer/modules/file_system_access/file_system_access_incognito_file_delegate.cc index f73dcae..7761ea5 100644 --- a/third_party/blink/renderer/modules/file_system_access/file_system_access_incognito_file_delegate.cc +++ b/third_party/blink/renderer/modules/file_system_access/file_system_access_incognito_file_delegate.cc
@@ -38,14 +38,15 @@ FileSystemAccessFileDelegate::Trace(visitor); } -int FileSystemAccessIncognitoFileDelegate::Read(int64_t offset, - base::span<uint8_t> data) { +FileErrorOr<int> FileSystemAccessIncognitoFileDelegate::Read( + int64_t offset, + base::span<uint8_t> data) { // TODO(crbug.com/1225653): Implement this method. NOTIMPLEMENTED(); return 0; } -int FileSystemAccessIncognitoFileDelegate::Write( +FileErrorOr<int> FileSystemAccessIncognitoFileDelegate::Write( int64_t offset, const base::span<uint8_t> data) { // TODO(crbug.com/1225653): Implement this method. @@ -53,7 +54,7 @@ return 0; } -int64_t FileSystemAccessIncognitoFileDelegate::GetLength() { +FileErrorOr<int64_t> FileSystemAccessIncognitoFileDelegate::GetLength() { // TODO(crbug.com/1225653): Implement this method. NOTIMPLEMENTED(); return 0; @@ -76,10 +77,4 @@ NOTIMPLEMENTED(); } -base::File::Error FileSystemAccessIncognitoFileDelegate::GetLastFileError() { - // TODO(crbug.com/1225653): Implement this method. - NOTIMPLEMENTED(); - return base::File::Error::FILE_OK; -} - } // namespace blink
diff --git a/third_party/blink/renderer/modules/file_system_access/file_system_access_incognito_file_delegate.h b/third_party/blink/renderer/modules/file_system_access/file_system_access_incognito_file_delegate.h index e2bf801a..704f383 100644 --- a/third_party/blink/renderer/modules/file_system_access/file_system_access_incognito_file_delegate.h +++ b/third_party/blink/renderer/modules/file_system_access/file_system_access_incognito_file_delegate.h
@@ -33,10 +33,11 @@ FileSystemAccessIncognitoFileDelegate& operator=( const FileSystemAccessIncognitoFileDelegate&) = delete; - int Read(int64_t offset, base::span<uint8_t> data) override; - int Write(int64_t offset, const base::span<uint8_t> data) override; + FileErrorOr<int> Read(int64_t offset, base::span<uint8_t> data) override; + FileErrorOr<int> Write(int64_t offset, + const base::span<uint8_t> data) override; - int64_t GetLength() override; + FileErrorOr<int64_t> GetLength() override; bool SetLength(int64_t length) override; bool Flush() override; @@ -44,8 +45,6 @@ bool IsValid() const override { return mojo_ptr_.is_bound(); } - base::File::Error GetLastFileError() override; - void Trace(Visitor*) const override; private:
diff --git a/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.cc b/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.cc index 37e41b04..82d0a73 100644 --- a/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.cc +++ b/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.cc
@@ -21,21 +21,23 @@ base::PassKey<FileSystemAccessFileDelegate>) : backing_file_(std::move(backing_file)) {} -int FileSystemAccessRegularFileDelegate::Read(int64_t offset, - base::span<uint8_t> data) { +FileErrorOr<int> FileSystemAccessRegularFileDelegate::Read( + int64_t offset, + base::span<uint8_t> data) { // TODO(crbug.com/1218431): Implement this method. NOTIMPLEMENTED(); return 0; } -int FileSystemAccessRegularFileDelegate::Write(int64_t offset, - const base::span<uint8_t> data) { +FileErrorOr<int> FileSystemAccessRegularFileDelegate::Write( + int64_t offset, + const base::span<uint8_t> data) { // TODO(crbug.com/1218431): Implement this method. NOTIMPLEMENTED(); return 0; } -int64_t FileSystemAccessRegularFileDelegate::GetLength() { +FileErrorOr<int64_t> FileSystemAccessRegularFileDelegate::GetLength() { // TODO(crbug.com/1218431): Implement this method. NOTIMPLEMENTED(); return 0; @@ -58,10 +60,4 @@ NOTIMPLEMENTED(); } -base::File::Error FileSystemAccessRegularFileDelegate::GetLastFileError() { - // TODO(crbug.com/1218431): Implement this method. - NOTIMPLEMENTED(); - return base::File::Error::FILE_OK; -} - } // namespace blink
diff --git a/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.h b/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.h index 991f813..3c1f88d9 100644 --- a/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.h +++ b/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.h
@@ -30,10 +30,11 @@ FileSystemAccessRegularFileDelegate& operator=( const FileSystemAccessRegularFileDelegate&) = delete; - int Read(int64_t offset, base::span<uint8_t> data) override; - int Write(int64_t offset, const base::span<uint8_t> data) override; + FileErrorOr<int> Read(int64_t offset, base::span<uint8_t> data) override; + FileErrorOr<int> Write(int64_t offset, + const base::span<uint8_t> data) override; - int64_t GetLength() override; + FileErrorOr<int64_t> GetLength() override; bool SetLength(int64_t length) override; bool Flush() override; @@ -41,8 +42,6 @@ bool IsValid() const override { return backing_file_.IsValid(); } - base::File::Error GetLastFileError() override; - private: // The file on disk backing the parent FileSystemFileHandle. base::File backing_file_;
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc index c5c25cb..773bdb18 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc +++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc
@@ -133,7 +133,12 @@ if (baseline_drop_elements_.Contains(local_name.LowerASCII())) return nullptr; LocalDOMWindow* window = LocalDOMWindow::From(script_state); - Element* element = window->document()->CreateElementForBinding( + Document* inert_document = DocumentInit::Create() + .WithURL(window->Url()) + .WithTypeFrom("text/html") + .WithExecutionContext(window) + .CreateDocument(); + Element* element = inert_document->CreateElementForBinding( AtomicString(local_name), exception_state); if (exception_state.HadException()) { exception_state.ClearException();
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc b/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc index 9543bf7..cb00f2a 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc +++ b/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc
@@ -297,146 +297,91 @@ // Test all constructors. scoped_refptr<media::VideoFrame> media_frame1 = CreateDefaultBlackMediaVideoFrame(); - auto handle_1_1 = base::MakeRefCounted<VideoFrameHandle>( - media_frame1, scope.GetExecutionContext(), source1); - EXPECT_EQ(monitor.NumFrames(source1), 1u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 1); - scoped_refptr<media::VideoFrame> media_frame2 = CreateDefaultBlackMediaVideoFrame(); + + auto verify_expectations = + [&](wtf_size_t num_frames_source1, int num_refs_frame1_source1, + int num_refs_frame2_source1, wtf_size_t num_frames_source2, + int num_refs_frame1_source2, int num_refs_frame2_source2) { + EXPECT_EQ(monitor.NumFrames(source1), num_frames_source1); + EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), + num_refs_frame1_source1); + EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), + num_refs_frame2_source1); + EXPECT_EQ(monitor.NumFrames(source2), num_frames_source2); + EXPECT_EQ(monitor.NumRefs(source2, media_frame1->unique_id()), + num_refs_frame1_source2); + EXPECT_EQ(monitor.NumRefs(source2, media_frame2->unique_id()), + num_refs_frame2_source2); + }; + + auto handle_1_1 = base::MakeRefCounted<VideoFrameHandle>( + media_frame1, scope.GetExecutionContext(), source1); + verify_expectations(/* source1 */ 1, 1, 0, /* source2 */ 0, 0, 0); + sk_sp<SkSurface> surface(SkSurface::MakeRaster( SkImageInfo::MakeN32Premul(5, 5, SkColorSpace::MakeSRGB()))); sk_sp<SkImage> sk_image = surface->makeImageSnapshot(); auto handle_2_1 = base::MakeRefCounted<VideoFrameHandle>( media_frame2, sk_image, scope.GetExecutionContext(), source1); - EXPECT_EQ(monitor.NumFrames(source1), 2u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 1); - - auto non_monitored1 = base::MakeRefCounted<VideoFrameHandle>( - media_frame2, sk_image, scope.GetExecutionContext()); - EXPECT_EQ(monitor.NumFrames(source1), 2u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 1); + verify_expectations(/* source1 */ 2, 1, 1, /* source2 */ 0, 0, 0); auto& logger = WebCodecsLogger::From(*scope.GetExecutionContext()); auto handle_1_1b = base::MakeRefCounted<VideoFrameHandle>( media_frame1, sk_image, logger.GetCloseAuditor(), source1); - EXPECT_EQ(monitor.NumFrames(source1), 2u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 2); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 1); + verify_expectations(/* source1 */ 2, 2, 1, /* source2 */ 0, 0, 0); auto handle_1_2 = base::MakeRefCounted<VideoFrameHandle>(media_frame1, sk_image, source2); - EXPECT_EQ(monitor.NumFrames(source1), 2u); - EXPECT_EQ(monitor.NumFrames(source2), 1u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 2); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame2->unique_id()), 0); + verify_expectations(/* source1 */ 2, 2, 1, /* source2 */ 1, 1, 0); + + auto non_monitored1 = base::MakeRefCounted<VideoFrameHandle>( + media_frame2, sk_image, scope.GetExecutionContext()); + verify_expectations(/* source1 */ 2, 2, 1, /* source2 */ 1, 1, 0); auto non_monitored2 = base::MakeRefCounted<VideoFrameHandle>(media_frame1, sk_image); - EXPECT_EQ(monitor.NumFrames(source1), 2u); - EXPECT_EQ(monitor.NumFrames(source2), 1u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 2); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame2->unique_id()), 0); + verify_expectations(/* source1 */ 2, 2, 1, /* source2 */ 1, 1, 0); // Move constructor auto handle_1_1c = std::move(handle_1_1b); - EXPECT_EQ(monitor.NumFrames(source1), 2u); - EXPECT_EQ(monitor.NumFrames(source2), 1u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 2); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame2->unique_id()), 0); + verify_expectations(/* source1 */ 2, 2, 1, /* source2 */ 1, 1, 0); // Test all clone methods. auto clone_1_1a = handle_1_1->Clone(); - EXPECT_EQ(monitor.NumFrames(source1), 2u); - EXPECT_EQ(monitor.NumFrames(source2), 1u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 3); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame2->unique_id()), 0); + verify_expectations(/* source1 */ 2, 3, 1, /* source2 */ 1, 1, 0); auto clone_1_1b = handle_1_1->CloneForInternalUse(); - EXPECT_EQ(monitor.NumFrames(source1), 2u); - EXPECT_EQ(monitor.NumFrames(source2), 1u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 4); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame2->unique_id()), 0); + verify_expectations(/* source1 */ 2, 4, 1, /* source2 */ 1, 1, 0); // Clone non-monitored frame auto non_monitored_clone = non_monitored2->CloneForInternalUse(); - EXPECT_EQ(monitor.NumFrames(source1), 2u); - EXPECT_EQ(monitor.NumFrames(source2), 1u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 4); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame2->unique_id()), 0); + verify_expectations(/* source1 */ 2, 4, 1, /* source2 */ 1, 1, 0); // Test invalidate handle_1_1->Invalidate(); - EXPECT_EQ(monitor.NumFrames(source1), 2u); - EXPECT_EQ(monitor.NumFrames(source2), 1u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 3); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame2->unique_id()), 0); + verify_expectations(/* source1 */ 2, 3, 1, /* source2 */ 1, 1, 0); // handle_1_1b was moved to handle_1_1c handle_1_1c->Invalidate(); - EXPECT_EQ(monitor.NumFrames(source1), 2u); - EXPECT_EQ(monitor.NumFrames(source2), 1u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 2); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame2->unique_id()), 0); + verify_expectations(/* source1 */ 2, 2, 1, /* source2 */ 1, 1, 0); handle_2_1->Invalidate(); - EXPECT_EQ(monitor.NumFrames(source1), 1u); - EXPECT_EQ(monitor.NumFrames(source2), 1u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 2); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 0); - EXPECT_EQ(monitor.NumRefs(source2, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame2->unique_id()), 0); + verify_expectations(/* source1 */ 1, 2, 0, /* source2 */ 1, 1, 0); non_monitored1->Invalidate(); - EXPECT_EQ(monitor.NumFrames(source1), 1u); - EXPECT_EQ(monitor.NumFrames(source2), 1u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 2); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 0); - EXPECT_EQ(monitor.NumRefs(source2, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame2->unique_id()), 0); + verify_expectations(/* source1 */ 1, 2, 0, /* source2 */ 1, 1, 0); non_monitored2->Invalidate(); - EXPECT_EQ(monitor.NumFrames(source1), 1u); - EXPECT_EQ(monitor.NumFrames(source2), 1u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 2); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 0); - EXPECT_EQ(monitor.NumRefs(source2, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame2->unique_id()), 0); + verify_expectations(/* source1 */ 1, 2, 0, /* source2 */ 1, 1, 0); clone_1_1a->Invalidate(); - EXPECT_EQ(monitor.NumFrames(source1), 1u); - EXPECT_EQ(monitor.NumFrames(source2), 1u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 0); - EXPECT_EQ(monitor.NumRefs(source2, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source2, media_frame2->unique_id()), 0); + verify_expectations(/* source1 */ 1, 1, 0, /* source2 */ 1, 1, 0); // Resetting handles instead of invalidating. handle_1_2.reset(); - EXPECT_EQ(monitor.NumFrames(source1), 1u); - EXPECT_EQ(monitor.NumFrames(source2), 0u); - EXPECT_EQ(monitor.NumRefs(source1, media_frame1->unique_id()), 1); - EXPECT_EQ(monitor.NumRefs(source1, media_frame2->unique_id()), 0); - EXPECT_EQ(monitor.NumRefs(source2, media_frame1->unique_id()), 0); - EXPECT_EQ(monitor.NumRefs(source2, media_frame2->unique_id()), 0); + verify_expectations(/* source1 */ 1, 1, 0, /* source2 */ 0, 0, 0); clone_1_1b.reset(); EXPECT_TRUE(monitor.IsEmpty()); @@ -450,55 +395,50 @@ V8TestingScope scope; VideoFrameMonitor& monitor = VideoFrameMonitor::Instance(); const std::string source = "source"; - EXPECT_TRUE(monitor.IsEmpty()); - scoped_refptr<media::VideoFrame> media_frame = CreateDefaultBlackMediaVideoFrame(); + auto verify_expectations = [&](wtf_size_t num_frames, int num_refs) { + EXPECT_EQ(monitor.NumFrames(source), num_frames); + EXPECT_EQ(monitor.NumRefs(source, media_frame->unique_id()), num_refs); + }; + EXPECT_TRUE(monitor.IsEmpty()); + // Test all constructors auto* frame1 = MakeGarbageCollected<VideoFrame>( media_frame, scope.GetExecutionContext(), source); - EXPECT_EQ(monitor.NumFrames(source), 1u); - EXPECT_EQ(monitor.NumRefs(source, media_frame->unique_id()), 1); + verify_expectations(1u, 1); auto* non_monitored1 = MakeGarbageCollected<VideoFrame>( media_frame, scope.GetExecutionContext()); - EXPECT_EQ(monitor.NumFrames(source), 1u); - EXPECT_EQ(monitor.NumRefs(source, media_frame->unique_id()), 1); + verify_expectations(1u, 1); auto monitored_handle = base::MakeRefCounted<VideoFrameHandle>( media_frame, scope.GetExecutionContext(), source); auto* frame2 = MakeGarbageCollected<VideoFrame>(std::move(monitored_handle)); - EXPECT_EQ(monitor.NumFrames(source), 1u); - EXPECT_EQ(monitor.NumRefs(source, media_frame->unique_id()), 2); + verify_expectations(1u, 2); auto non_monitored_handle = base::MakeRefCounted<VideoFrameHandle>( media_frame, scope.GetExecutionContext()); auto* non_monitored2 = MakeGarbageCollected<VideoFrame>(std::move(non_monitored_handle)); - EXPECT_EQ(monitor.NumFrames(source), 1u); - EXPECT_EQ(monitor.NumRefs(source, media_frame->unique_id()), 2); + verify_expectations(1u, 2); auto* clone = frame1->clone(scope.GetExceptionState()); - EXPECT_EQ(monitor.NumFrames(source), 1u); - EXPECT_EQ(monitor.NumRefs(source, media_frame->unique_id()), 3); + verify_expectations(1u, 3); auto* non_monitored_clone = non_monitored1->clone(scope.GetExceptionState()); - EXPECT_EQ(monitor.NumFrames(source), 1u); - EXPECT_EQ(monitor.NumRefs(source, media_frame->unique_id()), 3); + verify_expectations(1u, 3); frame1->close(); - EXPECT_EQ(monitor.NumFrames(source), 1u); - EXPECT_EQ(monitor.NumRefs(source, media_frame->unique_id()), 2); + verify_expectations(1u, 2); frame2->close(); - EXPECT_EQ(monitor.NumFrames(source), 1u); - EXPECT_EQ(monitor.NumRefs(source, media_frame->unique_id()), 1); + verify_expectations(1u, 1); non_monitored1->close(); non_monitored2->close(); non_monitored_clone->close(); - EXPECT_EQ(monitor.NumFrames(source), 1u); - EXPECT_EQ(monitor.NumRefs(source, media_frame->unique_id()), 1); + verify_expectations(1u, 1); // Garbage-collecting a non-closed monitored frame should reclaim it and // update the monitor.
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc index 493a1e4..a38d76b 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -1420,9 +1420,9 @@ gfx::Vector2dF post_scale(1.f, 1.f); ri->BeginRasterCHROMIUM( - background_color, needs_clear, /*msaa_sample_count=*/0, - ColorParams().CanUseLcdText(), ColorParams().GetStorageGfxColorSpace(), - mailbox.name); + background_color, needs_clear, /*msaa_sample_count=*/1, + gpu::raster::MsaaMode::kDMSAA, ColorParams().CanUseLcdText(), + ColorParams().GetStorageGfxColorSpace(), mailbox.name); ri->RasterCHROMIUM(list.get(), GetOrCreateCanvasImageProvider(), size, full_raster_rect, playback_rect, post_translate,
diff --git a/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_hash_table_backing.h b/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_hash_table_backing.h index 2d81ed8..c4d69e8 100644 --- a/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_hash_table_backing.h +++ b/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_hash_table_backing.h
@@ -14,6 +14,7 @@ #include "third_party/blink/renderer/platform/wtf/conditional_destructor.h" #include "third_party/blink/renderer/platform/wtf/hash_table.h" #include "third_party/blink/renderer/platform/wtf/hash_traits.h" +#include "third_party/blink/renderer/platform/wtf/sanitizers.h" #include "v8/include/cppgc/custom-space.h" #include "v8/include/cppgc/explicit-management.h" #include "v8/include/cppgc/object-size-trait.h" @@ -30,6 +31,11 @@ using ValueType = typename Table::ValueType; public: + // Although the HeapHashTableBacking is fully constructed, the array resulting + // from ToArray may not be fully constructed as the elements of the array are + // not initialized and may have null vtable pointers. Null vtable pointer + // violates CFI for polymorphic types. + NO_SANITIZE_UNRELATED_CAST static ValueType* ToArray(ClassType* backing) { return reinterpret_cast<ValueType*>(backing); }
diff --git a/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_vector_backing.h b/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_vector_backing.h index 6859009..b9e1307 100644 --- a/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_vector_backing.h +++ b/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_vector_backing.h
@@ -12,6 +12,7 @@ #include "third_party/blink/renderer/platform/heap/trace_traits.h" #include "third_party/blink/renderer/platform/wtf/conditional_destructor.h" #include "third_party/blink/renderer/platform/wtf/container_annotations.h" +#include "third_party/blink/renderer/platform/wtf/sanitizers.h" #include "third_party/blink/renderer/platform/wtf/type_traits.h" #include "third_party/blink/renderer/platform/wtf/vector_traits.h" #include "v8/include/cppgc/allocation.h" @@ -38,6 +39,11 @@ using ClassType = HeapVectorBacking<T, Traits>; public: + // Although the HeapVectorBacking is fully constructed, the array resulting + // from ToArray may not be fully constructed as the elements of the array are + // not initialized and may have null vtable pointers. Null vtable pointer + // violates CFI for polymorphic types. + NO_SANITIZE_UNRELATED_CAST static T* ToArray(ClassType* backing) { return reinterpret_cast<T*>(backing); }
diff --git a/third_party/blink/renderer/platform/weborigin/scheme_registry_test.cc b/third_party/blink/renderer/platform/weborigin/scheme_registry_test.cc index 3f763bab..51b6575e 100644 --- a/third_party/blink/renderer/platform/weborigin/scheme_registry_test.cc +++ b/third_party/blink/renderer/platform/weborigin/scheme_registry_test.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/platform/weborigin/scheme_registry.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/wtf/threading.h" namespace blink { namespace { @@ -61,6 +62,9 @@ EXPECT_FALSE(SchemeRegistry::SchemeShouldBypassSecureContextCheck(scheme2)); EXPECT_FALSE(SchemeRegistry::SchemeShouldBypassSecureContextCheck(scheme3)); +#if DCHECK_IS_ON() + WTF::SetIsBeforeThreadCreatedForTest(); // Required for next operation: +#endif SchemeRegistry::RegisterURLSchemeBypassingSecureContextCheck("random-scheme"); EXPECT_FALSE(SchemeRegistry::SchemeShouldBypassSecureContextCheck(scheme1));
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests index e751967..ed6b928 100644 --- a/third_party/blink/web_tests/SlowTests +++ b/third_party/blink/web_tests/SlowTests
@@ -169,6 +169,7 @@ crbug.com/726075 [ Mac ] virtual/gpu/fast/canvas/canvas-composite-shadow.html [ Slow ] # Slow oopr canvas tests +crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-composite.html [ Slow ] crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-composite-alpha.html [ Slow ] crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-composite-shadow.html [ Slow ] crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow.html [ Slow ] @@ -178,11 +179,13 @@ crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-blending-gradient-over-color.html [ Slow ] crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-blending-clipping.html [ Slow ] crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-blending-image-over-color.html [ Slow ] +crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-blending-image-over-gradient.html [ Slow ] crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-blending-pattern-over-color.html [ Slow ] crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-blending-pattern-over-pattern.html [ Slow ] crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-blending-text.html [ Slow ] crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-blending-gradient-over-pattern.html [ Slow ] crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-blending-transforms.html [ Slow ] +crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-incremental-repaint.html [ Slow ] crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/color-space/canvas-createImageBitmap-rec2020.html [ Slow ] crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/fillrect_gradient.html [ Slow ] crbug.com/1081534 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-blend-solid.html [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 5cf1133..bb6d437 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1964,6 +1964,10 @@ # Temporarily disabled until document marker serialization is enabled for AXInlineTextBox crbug.com/1227485 accessibility/spelling-markers.html [ Failure ] +# Bugs caused by enabling DMSAA on OOPR-Canvas +crbug.com/1229463 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-largedraws.html [ Crash ] +crbug.com/1229486 virtual/oopr-canvas2d/fast/canvas/canvas-incremental-repaint.html [ Failure ] + # Temporarily disabled after chromium change crbug.com/492511 [ Mac ] virtual/text-antialias/atsui-negative-spacing-features.html [ Failure ] crbug.com/492511 [ Mac ] virtual/text-antialias/international/arabic-justify.html [ Failure ] @@ -7292,9 +7296,6 @@ crbug.com/1226445 [ Mac ] virtual/storage-access-api/external/wpt/storage-access-api/storageAccess.testdriver.sub.html [ Failure Pass ] # DevTools roll -crbug.com/1223391 http/tests/devtools/security/interstitial-sidebar.js [ Skip ] -crbug.com/1223391 http/tests/devtools/security/mixed-content-sidebar.js [ Skip ] -crbug.com/1223391 http/tests/devtools/security/origin-view-then-interstitial.js [ Skip ] crbug.com/1215068 http/tests/devtools/tracing/tracing-timeline-load.js [ Skip ] # Sheriff 2021-07-07 @@ -7376,11 +7377,4 @@ # Sheriff 2021-07-19 crbug.com/1230534 [ Linux ] external/wpt/webrtc/simulcast/vp8.https.html [ Pass Timeout ] -# Temporary: Oilpan library launch -crbug.com/1230599 [ Linux ] fast/workers/chromium/worker-document-leak.html [ Crash Pass ] -crbug.com/1230599 [ Linux ] fast/workers/worker-close-more.html [ Crash Pass ] -crbug.com/1230599 [ Linux ] fast/workers/worker-lifecycle.html [ Crash Pass ] -crbug.com/1230599 [ Linux ] virtual/plz-dedicated-worker/fast/workers/chromium/worker-document-leak.html [ Crash ] -crbug.com/1230599 [ Linux ] virtual/shared_array_buffer_on_desktop/fast/workers/dedicated-worker-lifecycle.html [ Crash Pass ] - crbug.com/1230836 [ Mac ] fast/forms/calendar-picker/date-picker-appearance-zoom150.html [ Pass Failure Crash ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 0c11e9f..36e55bc 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -57,7 +57,8 @@ "--enable-blink-features=OffMainThreadCSSPaint", "--enable-gpu-rasterization", "--enable-oop-rasterization", - "--enable-accelerated-2d-canvas"] + "--enable-accelerated-2d-canvas", + "--disable-features=CanvasOopRasterization"] }, { "prefix": "prefer_compositing_to_lcd_text",
diff --git a/third_party/blink/web_tests/WebGPUExpectations b/third_party/blink/web_tests/WebGPUExpectations index 388d301..cf72d20 100644 --- a/third_party/blink/web_tests/WebGPUExpectations +++ b/third_party/blink/web_tests/WebGPUExpectations
@@ -193,6 +193,9 @@ crbug.com/dawn/773 wpt_internal/webgpu/cts.html?q=webgpu:api,operation,buffers,map:remapped_for_write:* [ Failure Crash ] crbug.com/dawn/773 wpt_internal/webgpu/cts.html?worker=1&q=webgpu:api,operation,buffers,map:remapped_for_write:* [ Failure Crash ] +crbug.com/1231108 wpt_internal/webgpu/cts.html?q=webgpu:api,operation,buffers,map:mapAsync,read:* [ Failure ] +crbug.com/1231108 wpt_internal/webgpu/cts.html?worker=1&q=webgpu:api,operation,buffers,map:mapAsync,read:* [ Failure ] + crbug.com/dawn/746 wpt_internal/webgpu/cts.html?q=webgpu:api,operation,shader_module,compilation_info:offset_and_length:valid=false;unicode=true [ Failure ] crbug.com/dawn/129 wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createBindGroup:texture_must_have_correct_dimension:viewDimension="1d";* [ Failure ]
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-sticky-crash.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-sticky-crash.html new file mode 100644 index 0000000..71debf7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-sticky-crash.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<link rel="help" href="http://crbug.com/1197946"> +<style> +legend { + position: sticky; + left: -1em; +} +fieldset { + position: sticky; + left: -1em; + overflow-y: auto; +} +</style> +<fieldset> +<legend>Legend</legend> +</fieldset>
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-insertable-streams/MediaStreamTrackGenerator-video.https.html b/third_party/blink/web_tests/external/wpt/mediacapture-insertable-streams/MediaStreamTrackGenerator-video.https.html index 3042f038..1185630b 100644 --- a/third_party/blink/web_tests/external/wpt/mediacapture-insertable-streams/MediaStreamTrackGenerator-video.https.html +++ b/third_party/blink/web_tests/external/wpt/mediacapture-insertable-streams/MediaStreamTrackGenerator-video.https.html
@@ -4,6 +4,7 @@ <title>MediaStream Insertable Streams - Video</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/webrtc/RTCPeerConnection-helper.js"></script> </head> <body> <p class="instructions">When prompted, use the accept button to give permission to use your audio and video devices.</p> @@ -12,16 +13,16 @@ <script> const pixelColour = [50, 100, 150, 255]; + const height = 240; + const width = 320; function makeVideoFrame(timestamp) { - const height = 240; - const width = 320; const canvas = new OffscreenCanvas(width, height); const ctx = canvas.getContext('2d', { alpha: false }); ctx.fillStyle = `rgba(${pixelColour[0]}, ${pixelColour[1]}, ${pixelColour[2]}, ${pixelColour[3]})`; ctx.fillRect(0, 0, width, height); - return new VideoFrame(canvas.transferToImageBitmap(), { timestamp }); + return new VideoFrame(canvas.transferToImageBitmap(), { timestamp, alpha: 'discard' }); } async function getVideoFrame() { @@ -35,14 +36,40 @@ } function assertPixel(t, bytes, expected) { + const epsilon = 5; for (let i = 0; i < bytes.length; i++) { t.step(() => { - assert_less_than(bytes[i], expected[i] + 2, "Mismatched pixel"); - assert_greater_than(bytes[i], expected[i] - 2, "Mismatched pixel"); + assert_less_than(Math.abs(bytes[i] - expected[i]), epsilon, "Mismatched pixel"); }); } } + async function initiateSingleTrackCall(t, track, output) { + const caller = new RTCPeerConnection(); + t.add_cleanup(() => caller.close()); + const callee = new RTCPeerConnection(); + t.add_cleanup(() => callee.close()); + + caller.addTrack(track); + t.add_cleanup(() => track.stop()); + + callee.ontrack = e => output.srcObject = new MediaStream([e.track]); + let ontrack_promise = addEventListenerPromise(t, callee, 'track'); + + exchangeIceCandidates(caller, callee); + await exchangeOffer(caller, callee); + + // Wait for the first track. + await ontrack_promise; + + // Exchange answer. + let answer = await callee.createAnswer(); + await callee.setLocalDescription(answer); + await caller.setRemoteDescription(answer); + + await waitForConnectionStateChange(callee, ['connected']); + } + promise_test(async t => { const videoFrame = await getVideoFrame(); const originalWidth = videoFrame.displayWidth; @@ -73,8 +100,7 @@ const videoFrame = makeVideoFrame(1); const originalWidth = videoFrame.displayWidth; const originalHeight = videoFrame.displayHeight; - const originalTimestamp = videoFrame.timestamp; - const generator = new MediaStreamTrackGenerator({kind: 'video'}); + const generator = new MediaStreamTrackGenerator({ kind: 'video' }); t.add_cleanup(() => generator.stop()); const video = document.createElement("video"); @@ -104,6 +130,51 @@ }, 'Tests that frames are actually rendered correctly in a stream used for a video element.'); promise_test(async t => { + const generator = new MediaStreamTrackGenerator({ kind: 'video' }); + t.add_cleanup(() => generator.stop()); + + const video = document.createElement("video"); + video.autoplay = true; + video.width = width; + video.height = height; + video.muted = true; + + let connectedResolver; + const connectedPromise = new Promise((resolve) => connectedResolver = resolve); + + // Wait for the video element to be connected to the generator and + // generate some frames. + video.onloadstart = async () => { + // Ensure the peer connection has connected before injecting frames. + await connectedPromise; + let writer = generator.writable.getWriter(); + for (let i = 0; i < 5; i++) { + await writer.write(makeVideoFrame(i)); + } + }; + + let videoPlayPromise = new Promise((resolve)=> { + video.ontimeupdate = t.step_func(() => { + const canvas = document.createElement("canvas"); + canvas.width = width; + canvas.height = height; + const context = canvas.getContext('2d'); + context.drawImage(video, 0, 0); + // Pick a pixel in the centre of the video and check that it has the colour of the frame provided. + const pixel = context.getImageData(width / 2, height / 2, 1, 1); + assertPixel(t, pixel.data, pixelColour); + resolve(); + }); + }); + + await initiateSingleTrackCall(t, generator, video); + connectedResolver(); + + return videoPlayPromise; + }, 'Tests that frames are actually rendered correctly in a stream sent over a peer connection.'); + + + promise_test(async t => { const generator = new MediaStreamTrackGenerator("video"); t.add_cleanup(() => generator.stop());
diff --git a/third_party/blink/web_tests/external/wpt/sanitizer-api/sanitizer-sanitize.https.tentative.html b/third_party/blink/web_tests/external/wpt/sanitizer-api/sanitizer-sanitize.https.tentative.html index b146290..66d8db9 100644 --- a/third_party/blink/web_tests/external/wpt/sanitizer-api/sanitizer-sanitize.https.tentative.html +++ b/third_party/blink/web_tests/external/wpt/sanitizer-api/sanitizer-sanitize.https.tentative.html
@@ -53,17 +53,6 @@ assert_node_equals(expected, sanitized); }, "Sanitizer.sanitze(Document)"); - - async_test(t => { - let s = new Sanitizer(); - fragment = s.sanitize(getFragment("<img src='http://bla/'>")); - t.step_timeout(_ => { - assert_equals(performance.getEntriesByName("http://bla/").length, 0); - t.done(); - }, 1000); - }, "SanitizerAPI sanitize function shouldn't load the image."); - - testcases.forEach(c => test(t => { let s = new Sanitizer(c.config_input); var dom = new DOMParser().parseFromString("<!DOCTYPE html><body>" + c.value, "text/html");
diff --git a/third_party/blink/web_tests/external/wpt/sanitizer-api/sanitizer-sanitizeFor.https.tentative.html b/third_party/blink/web_tests/external/wpt/sanitizer-api/sanitizer-sanitizeFor.https.tentative.html index 85dd353..b24ea65 100644 --- a/third_party/blink/web_tests/external/wpt/sanitizer-api/sanitizer-sanitizeFor.https.tentative.html +++ b/third_party/blink/web_tests/external/wpt/sanitizer-api/sanitizer-sanitizeFor.https.tentative.html
@@ -42,6 +42,15 @@ }, `Sanitizer.sanitizeFor("${context}", ...) should ${should_fail ? "fail" : "pass"}.`); } + async_test(t => { + let s = new Sanitizer(); + s.sanitizeFor("div", "<img src='https://bla/'>"); + t.step_timeout(_ => { + assert_equals(performance.getEntriesByName("https://bla/").length, 0); + t.done(); + }, 1000); + }, "Sanitizer.sanitizeFor function shouldn't load the image."); + test(t => { const probe = `<a href="about:blank">hello</a><script>con` + `sole.log("world!");<` + `/script>`;
diff --git a/third_party/blink/web_tests/external/wpt/webmessaging/postMessage_crosssite.sub.htm b/third_party/blink/web_tests/external/wpt/webmessaging/postMessage_crosssite.sub.htm new file mode 100644 index 0000000..25bccd9d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webmessaging/postMessage_crosssite.sub.htm
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<script> +async function addIframeAndReceiveMessage(path) { + let url = new URL('resources/transfer-arraybuffer-to-parent.html', location); + url.hostname = '{{hosts[alt][]}}'; + + let frame = document.createElement('iframe'); + try { + frame.src = url; + document.body.appendChild(frame); + return await new Promise((resolve, reject) => { + window.addEventListener('message', e => resolve(e)); + window.addEventListener('messageerror', e => reject(new Error('received messageerror'))); + }); + } finally { + frame.remove(); + } +} + +promise_test(async () => { + let messageEvent = await addIframeAndReceiveMessage('resources/transfer-arraybuffer-to-parent.html'); + assert_class_string(messageEvent.data, 'ArrayBuffer'); + assert_array_equals(new Uint8Array(messageEvent.data), [42, 222]); +}, "cross-site windows can send transferred ArrayBuffer"); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/webmessaging/resources/transfer-arraybuffer-to-parent.html b/third_party/blink/web_tests/external/wpt/webmessaging/resources/transfer-arraybuffer-to-parent.html new file mode 100644 index 0000000..97cff4d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webmessaging/resources/transfer-arraybuffer-to-parent.html
@@ -0,0 +1,5 @@ +<!DOCTYPE html> +<script> +let ab = new Uint8Array([42, 222]).buffer; +window.parent.postMessage(ab, '*', [ab]); +</script>
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/interstitial-sidebar-expected.txt b/third_party/blink/web_tests/http/tests/devtools/security/interstitial-sidebar-expected.txt index 83e9dac8..b99254f 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/interstitial-sidebar-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/security/interstitial-sidebar-expected.txt
@@ -17,7 +17,7 @@ </STYLE> <DIV class=tree-outline-disclosure > <OL class=tree-outline role=tree tabindex=-1 > - <LI role=treeitem class=security-main-view-sidebar-tree-item selected force-white-icons tabindex=0 aria-selected=true > + <LI role=treeitem class=security-main-view-sidebar-tree-item selected force-white-icons title=Overview tabindex=0 aria-selected=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -30,7 +30,7 @@ </LI> <OL class=children role=group > </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > + <LI title=Main origin role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -38,7 +38,7 @@ </SPAN> </LI> <OL class=children expanded role=group aria-label=Main origin > - <LI role=treeitem class=security-main-view-reload-message > + <LI title=Reload to view details role=treeitem class=security-main-view-reload-message > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -48,7 +48,7 @@ <OL class=children role=group > </OL> </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > + <LI title=Non-secure origins role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -57,7 +57,7 @@ </LI> <OL class=children expanded hidden role=group aria-label=Non-secure origins > </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > + <LI title=Secure origins role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -65,7 +65,7 @@ </SPAN> </LI> <OL class=children expanded role=group aria-label=Secure origins > - <LI role=treeitem class=security-sidebar-tree-item > + <LI role=treeitem class=security-sidebar-tree-item title=https://foo.test > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -86,7 +86,7 @@ </LI> <OL class=children role=group > </OL> - <LI role=treeitem class=security-sidebar-tree-item > + <LI role=treeitem class=security-sidebar-tree-item title=https://bar.test > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -108,7 +108,7 @@ <OL class=children role=group > </OL> </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > + <LI title=Unknown / canceled role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -142,7 +142,7 @@ </STYLE> <DIV class=tree-outline-disclosure > <OL class=tree-outline role=tree tabindex=-1 > - <LI role=treeitem class=security-main-view-sidebar-tree-item selected force-white-icons tabindex=0 aria-selected=true > + <LI role=treeitem class=security-main-view-sidebar-tree-item selected force-white-icons title=Overview tabindex=0 aria-selected=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -155,7 +155,7 @@ </LI> <OL class=children role=group > </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > + <LI title=Main origin role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -163,7 +163,7 @@ </SPAN> </LI> <OL class=children expanded hidden role=group aria-label=Main origin > - <LI role=treeitem class=security-main-view-reload-message > + <LI title=Reload to view details role=treeitem class=security-main-view-reload-message > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -173,7 +173,7 @@ <OL class=children role=group > </OL> </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > + <LI title=Non-secure origins role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -182,7 +182,7 @@ </LI> <OL class=children expanded hidden role=group aria-label=Non-secure origins > </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > + <LI title=Secure origins role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -190,7 +190,7 @@ </SPAN> </LI> <OL class=children expanded hidden role=group aria-label=Secure origins > - <LI role=treeitem class=security-sidebar-tree-item > + <LI role=treeitem class=security-sidebar-tree-item title=https://foo.test > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -211,7 +211,7 @@ </LI> <OL class=children role=group > </OL> - <LI role=treeitem class=security-sidebar-tree-item > + <LI role=treeitem class=security-sidebar-tree-item title=https://bar.test > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -233,7 +233,7 @@ <OL class=children role=group > </OL> </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > + <LI title=Unknown / canceled role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -267,7 +267,7 @@ </STYLE> <DIV class=tree-outline-disclosure > <OL class=tree-outline role=tree tabindex=-1 > - <LI role=treeitem class=security-main-view-sidebar-tree-item selected force-white-icons tabindex=0 aria-selected=true > + <LI role=treeitem class=security-main-view-sidebar-tree-item selected force-white-icons title=Overview tabindex=0 aria-selected=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -280,7 +280,7 @@ </LI> <OL class=children role=group > </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > + <LI title=Main origin role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -288,7 +288,7 @@ </SPAN> </LI> <OL class=children expanded role=group aria-label=Main origin > - <LI role=treeitem class=security-main-view-reload-message > + <LI title=Reload to view details role=treeitem class=security-main-view-reload-message > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -298,7 +298,7 @@ <OL class=children role=group > </OL> </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > + <LI title=Non-secure origins role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -307,7 +307,7 @@ </LI> <OL class=children expanded role=group aria-label=Non-secure origins > </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > + <LI title=Secure origins role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -315,7 +315,7 @@ </SPAN> </LI> <OL class=children expanded role=group aria-label=Secure origins > - <LI role=treeitem class=security-sidebar-tree-item > + <LI role=treeitem class=security-sidebar-tree-item title=https://foo.test > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -336,7 +336,7 @@ </LI> <OL class=children role=group > </OL> - <LI role=treeitem class=security-sidebar-tree-item > + <LI role=treeitem class=security-sidebar-tree-item title=https://bar.test > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -358,7 +358,7 @@ <OL class=children role=group > </OL> </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > + <LI title=Unknown / canceled role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title >
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-sidebar-expected.txt b/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-sidebar-expected.txt index 251de2a..3e21b01 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-sidebar-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-sidebar-expected.txt
@@ -17,7 +17,7 @@ </STYLE> <DIV class=tree-outline-disclosure > <OL class=tree-outline role=tree tabindex=-1 > - <LI role=treeitem class=security-main-view-sidebar-tree-item selected force-white-icons tabindex=0 aria-selected=true > + <LI role=treeitem class=security-main-view-sidebar-tree-item selected force-white-icons title=Overview tabindex=0 aria-selected=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -30,7 +30,7 @@ </LI> <OL class=children role=group > </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > + <LI title=Main origin role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -38,7 +38,7 @@ </SPAN> </LI> <OL class=children expanded role=group aria-label=Main origin > - <LI role=treeitem class=security-main-view-reload-message > + <LI title=Reload to view details role=treeitem class=security-main-view-reload-message > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -48,7 +48,7 @@ <OL class=children role=group > </OL> </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > + <LI title=Non-secure origins role=treeitem class=parent always-parent expanded security-sidebar-origins aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -56,7 +56,7 @@ </SPAN> </LI> <OL class=children expanded role=group aria-label=Non-secure origins > - <LI role=treeitem class=security-sidebar-tree-item > + <LI role=treeitem class=security-sidebar-tree-item title=http://foo.test > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -77,7 +77,7 @@ </LI> <OL class=children role=group > </OL> - <LI role=treeitem class=security-sidebar-tree-item > + <LI role=treeitem class=security-sidebar-tree-item title=http://bar.test > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -99,7 +99,7 @@ <OL class=children role=group > </OL> </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > + <LI title=Secure origins role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title > @@ -108,7 +108,7 @@ </LI> <OL class=children expanded hidden role=group aria-label=Secure origins > </OL> - <LI role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > + <LI title=Unknown / canceled role=treeitem class=parent always-parent expanded security-sidebar-origins hidden aria-expanded=true > <DIV class=selection fill > </DIV> <SPAN class=tree-element-title >
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/origin-view-then-interstitial-expected.txt b/third_party/blink/web_tests/http/tests/devtools/security/origin-view-then-interstitial-expected.txt index da746f93..48a4a45 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/origin-view-then-interstitial-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/security/origin-view-then-interstitial-expected.txt
@@ -7,11 +7,11 @@ Security overview </DIV> <DIV class=lock-spectrum > - <DIV class=lock-icon lock-icon-secure > + <DIV class=lock-icon lock-icon-secure title=Secure > </DIV> - <DIV class=lock-icon lock-icon-neutral > + <DIV class=lock-icon lock-icon-neutral title=Info > </DIV> - <DIV class=lock-icon lock-icon-insecure > + <DIV class=lock-icon lock-icon-insecure title=Not secure > </DIV> </DIV> <DIV class=triangle-pointer-container > @@ -75,11 +75,11 @@ Security overview </DIV> <DIV class=lock-spectrum > - <DIV class=lock-icon lock-icon-secure > + <DIV class=lock-icon lock-icon-secure title=Secure > </DIV> - <DIV class=lock-icon lock-icon-neutral > + <DIV class=lock-icon lock-icon-neutral title=Info > </DIV> - <DIV class=lock-icon lock-icon-insecure > + <DIV class=lock-icon lock-icon-insecure title=Not secure > </DIV> </DIV> <DIV class=triangle-pointer-container >
diff --git a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-composite-expected.png b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-composite-expected.png index 270dc39..a13e4230 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-composite-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-composite-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-expected.png b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-expected.png index 335f2e59..0b430d58 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow-expected.png b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow-expected.png index eff4d3d..fe22291a 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-incremental-repaint-expected.png b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-incremental-repaint-expected.png index be4bcf26..d29ea06 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-incremental-repaint-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-incremental-repaint-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-shadow-source-in-expected.png b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-shadow-source-in-expected.png index ddebd76..7608142 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-shadow-source-in-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-shadow-source-in-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-text-baseline-expected.png b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-text-baseline-expected.png index d03b89a..04e0c67 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-text-baseline-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/canvas-text-baseline-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/image-object-in-canvas-expected.png b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/image-object-in-canvas-expected.png index 5e7f875..4c9a3d9 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/image-object-in-canvas-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/image-object-in-canvas-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/quadraticCurveTo-expected.png b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/quadraticCurveTo-expected.png index 4c5892c..5d67f3f 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/quadraticCurveTo-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/oopr-canvas2d/fast/canvas/quadraticCurveTo-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-composite-transformclip-expected.png b/third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/oopr-canvas2d/fast/canvas/canvas-composite-transformclip-expected.png similarity index 100% rename from third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-composite-transformclip-expected.png rename to third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/oopr-canvas2d/fast/canvas/canvas-composite-transformclip-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-expected.png new file mode 100644 index 0000000..dbf2396 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-fill-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-fill-expected.png new file mode 100644 index 0000000..f617ebb7 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-fill-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-composite-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-composite-expected.png index 47b0fb2..2b701f0 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-composite-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-composite-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-composite-transformclip-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-composite-transformclip-expected.png new file mode 100644 index 0000000..158a3c5 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-composite-transformclip-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-expected.png index b03258f..a16ba98 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow-expected.png index 81e5ecf..f3fccb8 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-expected.png new file mode 100644 index 0000000..07466c2 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-fill-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-fill-expected.png index aa2913ba..951754e 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-fill-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-fill-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-connecting-line-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-connecting-line-expected.png new file mode 100644 index 0000000..5166bb7 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-connecting-line-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png index 0a5b340..265b08d6 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-incremental-repaint-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-incremental-repaint-expected.png index 2806748..56d5482 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-incremental-repaint-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-incremental-repaint-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png index bc1f13bb..809e71b 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-text-baseline-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-text-baseline-expected.png index d487eae..6774bff 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-text-baseline-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-text-baseline-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-zero-length-lineCap-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-zero-length-lineCap-expected.png similarity index 72% rename from third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-zero-length-lineCap-expected.png rename to third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-zero-length-lineCap-expected.png index b84e40c640..acccb15 100644 --- a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-zero-length-lineCap-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/canvas-zero-length-lineCap-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/image-object-in-canvas-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/image-object-in-canvas-expected.png index 9f680a3..bb57243 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/image-object-in-canvas-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/image-object-in-canvas-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/quadraticCurveTo-expected.png b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/quadraticCurveTo-expected.png index e6c26c6..33b9999 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/quadraticCurveTo-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/oopr-canvas2d/fast/canvas/quadraticCurveTo-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-expected.png new file mode 100644 index 0000000..2887729 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-fill-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-fill-expected.png new file mode 100644 index 0000000..ed717978 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-fill-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-composite-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-composite-expected.png index 2a511e4..646c7114 100644 --- a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-composite-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-composite-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-composite-transformclip-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-composite-transformclip-expected.png new file mode 100644 index 0000000..3abfa8b0 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-composite-transformclip-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-expected.png index e68ec73e..7d2cdbc 100644 --- a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow-expected.png index 3fcb4484..c94ec19 100644 --- a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-expected.png new file mode 100644 index 0000000..b9230f3 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-fill-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-fill-expected.png new file mode 100644 index 0000000..16770eb --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-fill-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-connecting-line-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-connecting-line-expected.png new file mode 100644 index 0000000..6c7e6a6 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-connecting-line-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png index f01b876..84951e3 100644 --- a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-incremental-repaint-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-incremental-repaint-expected.png index a67f5de..6ae50423 100644 --- a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-incremental-repaint-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-incremental-repaint-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png new file mode 100644 index 0000000..8409a99 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-shadow-source-in-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-shadow-source-in-expected.png index 4ed3d43e..5c7fbd06 100644 --- a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-shadow-source-in-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-shadow-source-in-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-text-baseline-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-text-baseline-expected.png index 2c21971..5a45f3ad 100644 --- a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-text-baseline-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-text-baseline-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-zero-length-lineCap-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-zero-length-lineCap-expected.png similarity index 69% copy from third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-zero-length-lineCap-expected.png copy to third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-zero-length-lineCap-expected.png index b84e40c640..1d9f07c3 100644 --- a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-zero-length-lineCap-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/canvas-zero-length-lineCap-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/image-object-in-canvas-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/image-object-in-canvas-expected.png index 95b8657..5489791 100644 --- a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/image-object-in-canvas-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/image-object-in-canvas-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/quadraticCurveTo-expected.png b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/quadraticCurveTo-expected.png index c1f645d..6e56be9 100644 --- a/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/quadraticCurveTo-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/oopr-canvas2d/fast/canvas/quadraticCurveTo-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-expected.png b/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-expected.png deleted file mode 100644 index 8bc6a29..0000000 --- a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-fill-expected.png b/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-fill-expected.png deleted file mode 100644 index 5b5c255..0000000 --- a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-arc-circumference-fill-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-drawImage-antiAlias-expected.png b/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-drawImage-antiAlias-expected.png index ef8933d..7c511f5 100644 --- a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-drawImage-antiAlias-expected.png +++ b/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-drawImage-antiAlias-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-expected.png b/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-expected.png deleted file mode 100644 index 2b5c0b0..0000000 --- a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-fill-expected.png b/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-fill-expected.png deleted file mode 100644 index 0e9fc25..0000000 --- a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-circumference-fill-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-connecting-line-expected.png b/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-connecting-line-expected.png deleted file mode 100644 index 814152a..0000000 --- a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-ellipse-connecting-line-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png b/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png deleted file mode 100644 index 2ac683c..0000000 --- a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/inspector_protocol/lib/base_string_adapter_cc.template b/third_party/inspector_protocol/lib/base_string_adapter_cc.template index 96a0c8e..7df6e64 100644 --- a/third_party/inspector_protocol/lib/base_string_adapter_cc.template +++ b/third_party/inspector_protocol/lib/base_string_adapter_cc.template
@@ -54,7 +54,7 @@ if (value->is_dict()) { std::unique_ptr<protocol::DictionaryValue> result = protocol::DictionaryValue::create(); - for (const auto& it : value->DictItems()) { + for (const auto it : value->DictItems()) { std::unique_ptr<protocol::Value> converted = toProtocolValue(&it.second, depth - 1); if (converted)
diff --git a/third_party/nearby/BUILD.gn b/third_party/nearby/BUILD.gn index ebd6042..ae0404a 100644 --- a/third_party/nearby/BUILD.gn +++ b/third_party/nearby/BUILD.gn
@@ -122,6 +122,7 @@ sources = [ "src/cpp/platform/base/base64_utils.cc", "src/cpp/platform/base/bluetooth_utils.cc", + "src/cpp/platform/base/input_stream.cc", "src/cpp/platform/base/prng.cc", ] public = [
diff --git a/third_party/nearby/README.chromium b/third_party/nearby/README.chromium index 3090f94..bacce12 100644 --- a/third_party/nearby/README.chromium +++ b/third_party/nearby/README.chromium
@@ -1,7 +1,7 @@ Name: Nearby Connections Library Short Name: Nearby URL: https://github.com/google/nearby-connections -Version: 258403118d3bd98ec6c52eeb6db0d626af05249d +Version: 7c1f423014003e2bf4ed2feb7520b3355c834fed License: Apache 2.0 License File: LICENSE Security Critical: yes
diff --git a/third_party/tflite/BUILD.gn b/third_party/tflite/BUILD.gn index da455ca..a0378b7 100644 --- a/third_party/tflite/BUILD.gn +++ b/third_party/tflite/BUILD.gn
@@ -24,6 +24,7 @@ # TODO(crbug.com/1147556): Try to clean/remove no-sign-compare if possible. "-Wno-sign-compare", "-Wno-gnu-inline-cpp-without-extern", + "-Wno-loop-analysis", ] defines = [ @@ -471,9 +472,9 @@ configs -= [ "//build/config/compiler:chromium_code" ] configs += [ - ":tflite_flags", "//build/config/compiler:no_chromium_code", "//third_party/eigen3:eigen_includes", + ":tflite_flags", ] public_configs = [ ":tflite_config" ]
diff --git a/tools/android/avd/proto/generic_android31.textpb b/tools/android/avd/proto/generic_android31.textpb new file mode 100644 index 0000000..0c36551 --- /dev/null +++ b/tools/android/avd/proto/generic_android31.textpb
@@ -0,0 +1,25 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Configuration for a generic x86_64 android-12 AVD (userdebug build). + +emulator_package { + package_name: "chromium/third_party/android_sdk/public/emulator" + version: "gMHhUuoQRKfxr-MBn3fNNXZtkAVXtOwMwT7kfx8jkIgC" # 30.7.5 + dest_path: ".emulator_sdk" +} + +system_image_package { + package_name: "chromium/third_party/android_sdk/public/system-images/android-31/google_apis/x86_64" + version: "R6Jh5_P21Euu-kdb11zcNjdJKN4vV1mdQTb8t4gph4IC" # 6 + dest_path: ".emulator_sdk" +} +system_image_name: "system-images;android-31;google_apis;x86_64" + +avd_package { + package_name: "chromium/third_party/android_sdk/public/avds/android-31/google_apis/x86_64" + version: "Ur_zl6_BRKRkf_9X3SMZ3eH2auoOyJ2kLslpTZZwi3gC" # created in bb_id 8841388797862621664 + dest_path: ".android" +} +avd_name: "android_31_google_apis_x86_64"
diff --git a/tools/android/avd/proto/generic_androidS.textpb b/tools/android/avd/proto/generic_androidS.textpb deleted file mode 100644 index 135ae84a..0000000 --- a/tools/android/avd/proto/generic_androidS.textpb +++ /dev/null
@@ -1,25 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# Configuration for a generic x86_64 android-S AVD (userdebug build). - -emulator_package { - package_name: "chromium/third_party/android_sdk/public/emulator" - version: "iyhul4Fb1wyCHoMUUxoRoy_8gaCnX2qhZ90-6c2bzd0C" # 30.7.4 - dest_path: ".emulator_sdk" -} - -system_image_package { - package_name: "chromium/third_party/android_sdk/public/system-images/android-s/google_apis/x86_64" - version: "iHc5D9PmBYiiKKdkrmPcR0eybw5oRdsMrAEmmENmNT8C" # 5 - dest_path: ".emulator_sdk" -} -system_image_name: "system-images;android-S;google_apis;x86_64" - -avd_package { - package_name: "chromium/third_party/android_sdk/public/avds/android-s/google_apis/x86_64" - version: "fqHFqlWl64uAEJtYmeaeb_U1Dvl-lcRyvmwFfPymkeIC" # created in bb_id 8843601341032598960 - dest_path: ".android" -} -avd_name: "android_S_google_apis_x86_64"
diff --git a/tools/android/avd/proto/generic_playstore_android31.textpb b/tools/android/avd/proto/generic_playstore_android31.textpb new file mode 100644 index 0000000..edf2bc1 --- /dev/null +++ b/tools/android/avd/proto/generic_playstore_android31.textpb
@@ -0,0 +1,25 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Configuration for a generic x86_64 android-12 AVD with playstore (user build). + +emulator_package { + package_name: "chromium/third_party/android_sdk/public/emulator" + version: "gMHhUuoQRKfxr-MBn3fNNXZtkAVXtOwMwT7kfx8jkIgC" # 30.7.5 + dest_path: ".emulator_sdk" +} + +system_image_package { + package_name: "chromium/third_party/android_sdk/public/system-images/android-31/google_apis_playstore/x86_64" + version: "HIBuigElsaW8mOKuSQwACbEhg-h6iqsLf9sgzCgqSTQC" # 6 + dest_path: ".emulator_sdk" +} +system_image_name: "system-images;android-31;google_apis_playstore;x86_64" + +avd_package { + package_name: "chromium/third_party/android_sdk/public/avds/android-31/google_apis_playstore/x86_64" + version: "5Mg381-L9zrRlO5Wok8dfSvGAJ0bGGza_enNhxUkhqcC" # created in bb_id 8841388797862621664 + dest_path: ".android" +} +avd_name: "android_31_google_apis_playstore_x86_64"
diff --git a/tools/android/avd/proto/generic_playstore_androidS.textpb b/tools/android/avd/proto/generic_playstore_androidS.textpb deleted file mode 100644 index 83ff459..0000000 --- a/tools/android/avd/proto/generic_playstore_androidS.textpb +++ /dev/null
@@ -1,25 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# Configuration for a generic x86_64 android-S AVD with playstore (user build). - -emulator_package { - package_name: "chromium/third_party/android_sdk/public/emulator" - version: "iyhul4Fb1wyCHoMUUxoRoy_8gaCnX2qhZ90-6c2bzd0C" # 30.7.4 - dest_path: ".emulator_sdk" -} - -system_image_package { - package_name: "chromium/third_party/android_sdk/public/system-images/android-s/google_apis_playstore/x86_64" - version: "fQ951BAPMUtbk54s1QaF9Vm99Z0GbRukZdUFxm_hUG0C" # 5 - dest_path: ".emulator_sdk" -} -system_image_name: "system-images;android-S;google_apis_playstore;x86_64" - -avd_package { - package_name: "chromium/third_party/android_sdk/public/avds/android-s/google_apis_playstore/x86_64" - version: "ZMZo_LHAbZpqYrVC9F0o5iSulL5wp4zXWUqVWX0v4rIC" # created in bb_id 8843601341032598960 - dest_path: ".android" -} -avd_name: "android_S_google_apis_playstore_x86_64"
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index c15b676..320085d 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -999,6 +999,12 @@ <enum name="AccountCapabilitiesGetFromSystemLibraryResult"> <int value="0" label="Success"/> <int value="1" label="Error (Generic)"/> + <int value="10" label="Error (Api Request Failed)"/> + <int value="11" label="Error (Api Error)"/> + <int value="12" label="Error (Api Not Permitted)"/> + <int value="13" label="Error (Api Unknown Capability)"/> + <int value="14" label="Error (Api Failed To Sync)"/> + <int value="15" label="Error (Api Not Available)"/> <int value="20" label="Error (Missing Capability)"/> <int value="21" label="Error (Unexpected Value)"/> </enum> @@ -14809,6 +14815,13 @@ <int value="4" label="Securely Set Cookie Nonsecure Request"/> </enum> +<enum name="CookieSameSite"> + <int value="-1" label="No SameSite attribute is specified."/> + <int value="0" label="SameSite=None"/> + <int value="1" label="SameSite=Lax"/> + <int value="2" label="SameSite=Strict"/> +</enum> + <enum name="CookieSameSiteString"> <int value="0" label="No SameSite attribute is present."/> <int value="1" label="SameSite attribute is specified but has no value."/> @@ -34035,6 +34048,7 @@ <int value="3959" label="V8URLPattern_Constructor"/> <int value="3960" label="V8URLPattern_Test_Method"/> <int value="3961" label="V8URLPattern_Exec_Method"/> + <int value="3962" label="SameSiteCookieInclusionChangedByCrossSiteRedirect"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -48456,6 +48470,7 @@ <int value="-338978205" label="NavigationMojoResponse:enabled"/> <int value="-338606027" label="TrimOnMemoryPressure:disabled"/> <int value="-338277966" label="DecoupleSyncFromAndroidMasterSync:enabled"/> + <int value="-336768659" label="NtpPhotosModule:enabled"/> <int value="-334873793" label="MediaSessionNotification:enabled"/> <int value="-333216449" label="MouseSubframeNoImplicitCapture:enabled"/> <int value="-329727402" label="disable-files-quick-view"/> @@ -49832,6 +49847,7 @@ <int value="787080596" label="DynamicTcmallocTuning:enabled"/> <int value="787385958" label="RegionalLocalesAsDisplayUI:enabled"/> <int value="788130042" label="PrivacySandboxSettings2:enabled"/> + <int value="791541863" label="NtpPhotosModule:disabled"/> <int value="792307132" label="KeyboardBasedDisplayArrangementInSettings:enabled"/> <int value="792884862" label="EnableSharedImageForWebview:enabled"/> @@ -74944,6 +74960,9 @@ </enum> <enum name="SigninInterceptSessionStartupResult"> + <obsolete> + Removed 2021-07. + </obsolete> <int value="0" label="Nothing to do (Reconcilor)"/> <int value="1" label="Nothing to do (Multilogin)"/> <int value="2" label="Success (reconcilor)"/>
diff --git a/tools/metrics/histograms/histograms_xml/android/histograms.xml b/tools/metrics/histograms/histograms_xml/android/histograms.xml index 0887d75a..b73b83b 100644 --- a/tools/metrics/histograms/histograms_xml/android/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/android/histograms.xml
@@ -493,6 +493,9 @@ <histogram name="Android.ChromeStartupDelegate.{Result}.Time" units="ms" expires_after="2021-07-01"> + <obsolete> + Deprecated as of 07/2021 + </obsolete> <owner>gangwu@chromium.org</owner> <owner>twellington@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/histograms_xml/bluetooth/histograms.xml b/tools/metrics/histograms/histograms_xml/bluetooth/histograms.xml index ac283620..377ed32 100644 --- a/tools/metrics/histograms/histograms_xml/bluetooth/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/bluetooth/histograms.xml
@@ -32,7 +32,12 @@ <variant name=".Dual"/> </variants> -<variants name="BluetoothUISurfaces"> +<variants name="DeviceSelectionUISurfaces"> + <variant name=".Settings"/> + <variant name=".SystemTray"/> +</variants> + +<variants name="UserInitiatedReconnectionUISurfaces"> <variant name=".Settings"/> <variant name=".SystemTray"/> </variants> @@ -87,45 +92,45 @@ </histogram> <histogram - name="Bluetooth.ChromeOS.DeviceSelectionDuration{BluetoothUISurfaces}" + name="Bluetooth.ChromeOS.DeviceSelectionDuration{DeviceSelectionUISurfaces}" units="ms" expires_after="2022-07-01"> <owner>khorimoto@chromium.org</owner> <owner>cros-connectivity@google.com</owner> <summary> Records how long it takes for the user to select a device either after they open the UI and Bluetooth is on, or after Bluetooth turns on while the UI is - open. {BluetoothUISurfaces} + open. {DeviceSelectionUISurfaces} </summary> - <token key="BluetoothUISurfaces" variants="BluetoothUISurfaces"> + <token key="DeviceSelectionUISurfaces" variants="DeviceSelectionUISurfaces"> <variant name=""/> </token> </histogram> <histogram - name="Bluetooth.ChromeOS.DeviceSelectionDuration{BluetoothUISurfaces}.NotPaired{BluetoothTransportTypes}" + name="Bluetooth.ChromeOS.DeviceSelectionDuration{DeviceSelectionUISurfaces}.NotPaired{BluetoothTransportTypes}" units="ms" expires_after="2022-07-01"> <owner>khorimoto@chromium.org</owner> <owner>cros-connectivity@google.com</owner> <summary> Records how long it takes for the user to select a device either after they open the UI and Bluetooth is on, or after Bluetooth turns on while the UI is - open. {BluetoothUISurfaces}{BluetoothTransportTypes} + open. {DeviceSelectionUISurfaces}{BluetoothTransportTypes} </summary> - <token key="BluetoothUISurfaces" variants="BluetoothUISurfaces"/> + <token key="DeviceSelectionUISurfaces" variants="DeviceSelectionUISurfaces"/> <token key="BluetoothTransportTypes" variants="BluetoothTransportTypes"/> </histogram> <histogram - name="Bluetooth.ChromeOS.DeviceSelectionDuration{BluetoothUISurfaces}{BluetoothPairedStates}" + name="Bluetooth.ChromeOS.DeviceSelectionDuration{DeviceSelectionUISurfaces}{BluetoothPairedStates}" units="ms" expires_after="2022-07-01"> <owner>khorimoto@chromium.org</owner> <owner>cros-connectivity@google.com</owner> <summary> Records how long it takes for the user to select a device either after they open the UI and Bluetooth is on, or after Bluetooth turns on while the UI is - open. {BluetoothUISurfaces}{BluetoothPairedStates} + open. {DeviceSelectionUISurfaces}{BluetoothPairedStates} </summary> - <token key="BluetoothUISurfaces" variants="BluetoothUISurfaces"/> + <token key="DeviceSelectionUISurfaces" variants="DeviceSelectionUISurfaces"/> <token key="BluetoothPairedStates" variants="BluetoothPairedStates"/> </histogram> @@ -220,7 +225,7 @@ </histogram> <histogram - name="Bluetooth.ChromeOS.UserInitiatedReconnectionAttempt.Result.FailureReason{BluetoothUISurfaces}" + name="Bluetooth.ChromeOS.UserInitiatedReconnectionAttempt.Result.FailureReason{UserInitiatedReconnectionUISurfaces}" enum="BluetoothConnectionFailureReason" expires_after="2022-03-05"> <owner>khorimoto@chromium.org</owner> <owner>cros-connectivity@google.com</owner> @@ -230,15 +235,16 @@ Suffixed by Bluetooth UI surface. View the base histogram to see results for all UI surfaces aggregated together, and suffixed histograms for the results - of just that particular UI surfaces. {BluetoothUISurfaces} + of just that particular UI surfaces. {UserInitiatedReconnectionUISurfaces} </summary> - <token key="BluetoothUISurfaces" variants="BluetoothUISurfaces"> + <token key="UserInitiatedReconnectionUISurfaces" + variants="UserInitiatedReconnectionUISurfaces"> <variant name=""/> </token> </histogram> <histogram - name="Bluetooth.ChromeOS.UserInitiatedReconnectionAttempt.Result{BluetoothUISurfaces}" + name="Bluetooth.ChromeOS.UserInitiatedReconnectionAttempt.Result{UserInitiatedReconnectionUISurfaces}" enum="BooleanSuccess" expires_after="2021-11-14"> <owner>khorimoto@chromium.org</owner> <owner>cros-connectivity@google.com</owner> @@ -250,9 +256,10 @@ Suffixed by Bluetooth UI surface. View the base histogram to see results for all UI surfaces aggregated together, and suffixed histograms for the results - of just that particular UI surfaces. {BluetoothUISurfaces} + of just that particular UI surfaces. {UserInitiatedReconnectionUISurfaces} </summary> - <token key="BluetoothUISurfaces" variants="BluetoothUISurfaces"> + <token key="UserInitiatedReconnectionUISurfaces" + variants="UserInitiatedReconnectionUISurfaces"> <variant name=""/> </token> </histogram>
diff --git a/tools/metrics/histograms/histograms_xml/cookie/histograms.xml b/tools/metrics/histograms/histograms_xml/cookie/histograms.xml index cd0eed4..fb793a9 100644 --- a/tools/metrics/histograms/histograms_xml/cookie/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/cookie/histograms.xml
@@ -169,6 +169,28 @@ </summary> </histogram> +<histogram + name="Cookie.CrossSiteRedirectDowngradeChangesInclusion.{AccessType}" + enum="CookieSameSite" expires_after="2022-07-15"> + <owner>chlily@chromium.org</owner> + <owner>bingler@chromium.org</owner> + <summary> + The SameSite attribute of a cookie whose inclusion is changed by considering + redirects as part of the same-site context calculation. I.e., this is logged + for cookies which are included if not considering redirects when calculating + the same-site context, but are excluded (solely due to the SameSite + attribute) if cross-site redirects can cause a request to be considered + cross-site. This is only recorded for cookies accessed over HTTP, since + redirects are not relevant for JS cookie accesses. This is logged for each + cookie (whose inclusion is changed) when it is {AccessType}, regardless of + whether the cookie was ultimately included. + </summary> + <token key="AccessType"> + <variant name="Read" summary="read for a request"/> + <variant name="Write" summary="set by a response"/> + </token> +</histogram> + <histogram name="Cookie.DomainSet" enum="Boolean" expires_after="2021-11-18"> <owner>bingler@chromium.org</owner> <owner>chlily@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml b/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml index fd10251..41c7284 100644 --- a/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml
@@ -238,7 +238,7 @@ <histogram name="Enterprise.AutoEnrollmentPsmHashDanceDifferentResultsComparison" - enum="PsmHashDanceDifferentResultsComparison" expires_after="2021-09-01"> + enum="PsmHashDanceDifferentResultsComparison" expires_after="2022-03-01"> <owner>amraboelkher@google.com</owner> <owner>mpolzer@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/histograms_xml/omnibox/histograms.xml b/tools/metrics/histograms/histograms_xml/omnibox/histograms.xml index f17623dd..9a936910 100644 --- a/tools/metrics/histograms/histograms_xml/omnibox/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/omnibox/histograms.xml
@@ -537,7 +537,7 @@ </histogram> <histogram name="Omnibox.MatchStability.AsyncMatchChange2" units="position" - expires_after="2021-08-29"> + expires_after="2022-07-29"> <owner>tommycli@chromium.org</owner> <owner>jdonnelly@chromium.org</owner> <summary> @@ -567,7 +567,7 @@ </histogram> <histogram name="Omnibox.MatchStability.AsyncMatchChangedInAnyPosition" - enum="BooleanChanged" expires_after="2022-01-02"> + enum="BooleanChanged" expires_after="2022-07-29"> <owner>tommycli@chromium.org</owner> <owner>jdonnelly@chromium.org</owner> <summary> @@ -811,7 +811,7 @@ </histogram> <histogram name="Omnibox.Start.WantAsyncMatches" enum="Boolean" - expires_after="2021-10-31"> + expires_after="2022-07-29"> <owner>tommycli@chromium.org</owner> <owner>jdonnelly@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml index d882f4a..28fc065 100644 --- a/tools/metrics/histograms/histograms_xml/others/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -11811,6 +11811,13 @@ multiplied by 100. The histogram is capped at 20000 (equivalent to 2 cores fully loaded). I.e. 4 cores busy at 25% each will read as 25 * 4 * 100 = 10000. + + NOTE: This metric has one signigicant limitation, it doesn't report the CPU + usage of processes that terminate before the end of the interval. This means + that short lived processes will rarely be included in the data. Furthermore, + we know that short-lived processes are very common (see + Renderer.ProcessLifetime). A future version of this metric will address this + limitation. </summary> <token key="ProcessName" variants="ProcessName"/> <!-- Usage scenario variant defined in tools/metrics/histograms/histograms_xml/power/histograms.xml --> @@ -11829,6 +11836,13 @@ Average disk utilization of a process, recorded at every two-minute interval. The amount of data transferred (Total I/O bytes per second) for a given process. + + NOTE: This metric has one signigicant limitation, it doesn't report the CPU + usage of processes that terminate before the end of the interval. This means + that short lived processes will rarely be included in the data. Furthermore, + we know that short-lived processes are very common (see + Renderer.ProcessLifetime). A future version of this metric will address this + limitation. </summary> </histogram> @@ -11842,6 +11856,13 @@ Monitor and the battery menu. This incorporates CPU utilization, idle wakeups, IO, and task QoS level using per-machine-model weights. Divide by 100 to match Activity Monitor's scale. Recorded every two minutes. + + NOTE: This metric has one signigicant limitation, it doesn't report the CPU + usage of processes that terminate before the end of the interval. This means + that short lived processes will rarely be included in the data. Furthermore, + we know that short-lived processes are very common (see + Renderer.ProcessLifetime). A future version of this metric will address this + limitation. </summary> <token key="ProcessName" variants="ProcessName"/> <!-- Usage scenario variant defined in tools/metrics/histograms/histograms_xml/power/histograms.xml --> @@ -11869,6 +11890,13 @@ <owner>markchang@chromium.org</owner> <summary> The average CPU idle wakeups per second, sampled every two minutes. + + NOTE: This metric has one signigicant limitation, it doesn't report the CPU + usage of processes that terminate before the end of the interval. This means + that short lived processes will rarely be included in the data. Furthermore, + we know that short-lived processes are very common (see + Renderer.ProcessLifetime). A future version of this metric will address this + limitation. </summary> <token key="ProcessName" variants="ProcessName"/> <!-- Usage scenario variant defined in tools/metrics/histograms/histograms_xml/power/histograms.xml --> @@ -11886,6 +11914,13 @@ two minutes. This is a subset of wakeups that indicate that the processor complex was taken out of low-power state. For more info, see the powermetrics man page on macOS. + + NOTE: This metric has one signigicant limitation, it doesn't report the CPU + usage of processes that terminate before the end of the interval. This means + that short lived processes will rarely be included in the data. Furthermore, + we know that short-lived processes are very common (see + Renderer.ProcessLifetime). A future version of this metric will address this + limitation. </summary> <token key="ProcessName" variants="ProcessName"/> <!-- Usage scenario variant defined in tools/metrics/histograms/histograms_xml/power/histograms.xml -->
diff --git a/tools/metrics/histograms/histograms_xml/page/histograms.xml b/tools/metrics/histograms/histograms_xml/page/histograms.xml index c132d0f9..c964c62 100644 --- a/tools/metrics/histograms/histograms_xml/page/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/page/histograms.xml
@@ -2233,7 +2233,7 @@ Measures the maximum cumulative layout shift (bit.ly/cls-explainer) that has occurred in a {Window}. The gap between two consecutive shifts in a window is not bigger than {Gap} and the maximum window size is {MaxWindowSize}. - This metric's integral value is 100x the fractional cumulative layout shift + This metric's integral value is 10x the fractional cumulative layout shift score described in the explainer. If {Bfcache} is triggered, we record the metric when the user navigates away or closes the page after the page was restored from back-forward cache. Otherwise, we record it at the end of the
diff --git a/tools/metrics/histograms/histograms_xml/quota/histograms.xml b/tools/metrics/histograms/histograms_xml/quota/histograms.xml index 4d96884..62e34c9 100644 --- a/tools/metrics/histograms/histograms_xml/quota/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/quota/histograms.xml
@@ -84,17 +84,53 @@ </summary> </histogram> +<histogram name="Quota.EvictedBucketAccessCount" units="units" + expires_after="2022-01-19"> + <owner>ayui@chromium.org</owner> + <owner>chrome-owp-storage@google.com</owner> + <summary> + The number of times the evicted bucket was accessed. Logged when the bucket + is evicted. Replaces Quota.EvictedOriginAccessCount when eviction was per + origin. + </summary> +</histogram> + +<histogram name="Quota.EvictedBucketDaysSinceAccess" units="units" + expires_after="2022-01-19"> + <owner>ayui@chromium.org</owner> + <owner>chrome-owp-storage@google.com</owner> + <summary> + The number of days since the evicted bucket was last accessed. Logged when + the bucket is evicted. Replaces Quota.EvictedOriginDaysSinceAccess when + eviction was per origin. + </summary> +</histogram> + +<histogram name="Quota.EvictedBucketPerHour" units="units" + expires_after="2022-01-19"> + <owner>ayui@chromium.org</owner> + <owner>chrome-owp-storage@google.com</owner> + <summary> + Number of evicted buckets in an hour. Replaces Quota.EvictedOriginPerHour + when eviction was per origin. + </summary> +</histogram> + <histogram name="Quota.EvictedBytesPerRound" units="MB" expires_after="2021-12-14"> <owner>jarrydg@chromium.org</owner> <owner>chrome-owp-storage@google.com</owner> <summary> - Amount of usage used by evicted origins in an eviction round. + Amount of usage used by evicted buckets in an eviction round. Prior to M94, + evictions were based on per origin instead of per bucket. </summary> </histogram> <histogram name="Quota.EvictedOriginAccessCount" units="units" expires_after="2021-09-19"> + <obsolete> + Removed as of 2021/07. Replaced by Quota.EvictedBucketAccessCount. + </obsolete> <owner>jarrydg@chromium.org</owner> <owner>chrome-owp-storage@google.com</owner> <summary> @@ -107,6 +143,9 @@ <histogram name="Quota.EvictedOriginDaysSinceAccess" units="units" expires_after="2021-09-19"> + <obsolete> + Removed as of 2021/07. Replaced by Quota.EvictedBucketDaysSinceAccess. + </obsolete> <owner>jarrydg@chromium.org</owner> <owner>chrome-owp-storage@google.com</owner> <summary> @@ -119,6 +158,9 @@ <histogram name="Quota.EvictedOriginsPerHour" units="units" expires_after="2021-09-05"> + <obsolete> + Removed as of 2021/07. Replaced by Quota.EvictedBucketPerHour. + </obsolete> <owner>jarrydg@chromium.org</owner> <owner>chrome-owp-storage@google.com</owner> <summary> @@ -156,8 +198,18 @@ <summary>Global usage of temporary storage.</summary> </histogram> +<histogram name="Quota.NumberOfEvictedBucketsPerRound" units="units" + expires_after="2022-05-18"> + <owner>ayui@chromium.org</owner> + <owner>chrome-owp-storage@google.com</owner> + <summary>Number of evicted buckets per round.</summary> +</histogram> + <histogram name="Quota.NumberOfEvictedOriginsPerRound" units="units" expires_after="2022-05-18"> + <obsolete> + Removed as of 2021/07. Replaced by Quota.NumberOfEvictedBucketsPerRound. + </obsolete> <owner>jarrydg@chromium.org</owner> <owner>chrome-owp-storage@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/histograms_xml/signin/histograms.xml b/tools/metrics/histograms/histograms_xml/signin/histograms.xml index 59235f1..419815e4 100644 --- a/tools/metrics/histograms/histograms_xml/signin/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/signin/histograms.xml
@@ -597,6 +597,9 @@ <histogram name="Signin.Intercept.SessionStartupDuration.{Method}" units="ms" expires_after="2021-08-12"> + <obsolete> + Removed 2021-07. + </obsolete> <owner>alexilin@chromium.org</owner> <owner>droger@chromium.org</owner> <summary> @@ -611,6 +614,9 @@ <histogram name="Signin.Intercept.SessionStartupReconcileError" enum="BooleanPresent" expires_after="2021-12-19"> + <obsolete> + Removed 2021-07. + </obsolete> <owner>alexilin@chromium.org</owner> <owner>droger@chromium.org</owner> <summary> @@ -622,6 +628,9 @@ <histogram name="Signin.Intercept.SessionStartupResult" enum="SigninInterceptSessionStartupResult" expires_after="2021-08-12"> + <obsolete> + Removed 2021-07. + </obsolete> <owner>alexilin@chromium.org</owner> <owner>droger@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/histograms_xml/web_apk/histograms.xml b/tools/metrics/histograms/histograms_xml/web_apk/histograms.xml index 4814731..4855b8c 100644 --- a/tools/metrics/histograms/histograms_xml/web_apk/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/web_apk/histograms.xml
@@ -182,7 +182,7 @@ </histogram> <histogram name="WebApk.Notification.Permission.Status" - enum="BooleanWebApkNotificationPermission" expires_after="2021-08-01"> + enum="BooleanWebApkNotificationPermission" expires_after="2022-08-01"> <owner>hartmanng@chromium.org</owner> <owner> src/chrome/android/java/src/org/chromium/chrome/browser/webapps/OWNERS
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 082ab79..3d6a819 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -2,15 +2,15 @@ "trace_processor_shell": { "win": { "hash": "0b17dcefc3d3da9d145909566c7b3033c25976f9", - "remote_path": "perfetto_binaries/trace_processor_shell/win/56537d0732d7cda6c26453cc60eee9e63a7f106a/trace_processor_shell.exe" + "remote_path": "perfetto_binaries/trace_processor_shell/win/877dc7ed6cb58d247fedebf91ec5c62b9e902788/trace_processor_shell.exe" }, "mac": { "hash": "d2a7468024c382be38ae3479b955e1fb8b653302", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/56537d0732d7cda6c26453cc60eee9e63a7f106a/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/mac/877dc7ed6cb58d247fedebf91ec5c62b9e902788/trace_processor_shell" }, "linux": { "hash": "769df07b64589db07489e8991fdde2bb1b3a2e78", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/56537d0732d7cda6c26453cc60eee9e63a7f106a/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/linux/0a5707e2da14385726a41f0035be5303dbd4e093/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/traffic_annotation/summary/grouping.xml b/tools/traffic_annotation/summary/grouping.xml index 96a30c94..3a019f03 100644 --- a/tools/traffic_annotation/summary/grouping.xml +++ b/tools/traffic_annotation/summary/grouping.xml
@@ -405,9 +405,6 @@ <traffic_annotation unique_id="spellcheck_hunspell_dictionary"/> <traffic_annotation unique_id="spellcheck_lookup"/> </sender> - <sender name="Suggestions"> - <traffic_annotation unique_id="suggestions_service"/> - </sender> <sender name="Translate"> <traffic_annotation unique_id="translate_url_fetcher"/> </sender>
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/PropertyModel.java b/ui/android/java/src/org/chromium/ui/modelutil/PropertyModel.java index d37bb0e..765f23991 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/PropertyModel.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/PropertyModel.java
@@ -14,7 +14,7 @@ import androidx.appcompat.content.res.AppCompatResources; import androidx.core.util.ObjectsCompat; -import org.chromium.base.annotations.RemovableInRelease; +import org.chromium.build.BuildConfig; import java.util.ArrayList; import java.util.Collection; @@ -273,9 +273,8 @@ mData = startingValues; } - @RemovableInRelease private void validateKey(PropertyKey key) { - if (!mData.containsKey(key)) { + if (BuildConfig.ENABLE_ASSERTS && !mData.containsKey(key)) { throw new IllegalArgumentException( "Invalid key passed in: " + key + ". Current data is: " + mData.toString()); } @@ -465,9 +464,8 @@ mData = values; } - @RemovableInRelease private void validateKey(PropertyKey key) { - if (!mData.containsKey(key)) { + if (BuildConfig.ENABLE_ASSERTS && !mData.containsKey(key)) { throw new IllegalArgumentException("Invalid key passed in: " + key); } }
diff --git a/ui/android/junit/src/org/chromium/ui/modelutil/PropertyModelTest.java b/ui/android/junit/src/org/chromium/ui/modelutil/PropertyModelTest.java index 9c7b127..c79fb29 100644 --- a/ui/android/junit/src/org/chromium/ui/modelutil/PropertyModelTest.java +++ b/ui/android/junit/src/org/chromium/ui/modelutil/PropertyModelTest.java
@@ -18,6 +18,7 @@ import org.robolectric.annotation.Config; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.build.BuildConfig; import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableFloatPropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableIntPropertyKey; @@ -210,6 +211,8 @@ @Test public void ensureValidKey() { + if (!BuildConfig.ENABLE_ASSERTS) return; + PropertyModel model = new PropertyModel(BOOLEAN_PROPERTY_A, BOOLEAN_PROPERTY_B); thrown.expect(IllegalArgumentException.class); model.set(BOOLEAN_PROPERTY_C, true);
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn index 052ce8b..eb999f3 100644 --- a/ui/aura/BUILD.gn +++ b/ui/aura/BUILD.gn
@@ -245,7 +245,6 @@ "//ui/base/ime/init", "//ui/compositor:test_support", "//ui/display", - "//ui/display/manager", "//ui/events", "//ui/events:events_base", "//ui/events:test_support",
diff --git a/ui/aura/window_event_dispatcher.cc b/ui/aura/window_event_dispatcher.cc index 11e99e3..d6f4f33e 100644 --- a/ui/aura/window_event_dispatcher.cc +++ b/ui/aura/window_event_dispatcher.cc
@@ -201,8 +201,8 @@ held_event_factory_.InvalidateWeakPtrs(); } ++move_hold_count_; - TRACE_EVENT_ASYNC_BEGIN0("ui", "WindowEventDispatcher::HoldPointerMoves", - this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( + "ui", "WindowEventDispatcher::HoldPointerMoves", TRACE_ID_LOCAL(this)); } void WindowEventDispatcher::ReleasePointerMoves() { @@ -235,7 +235,8 @@ } } } - TRACE_EVENT_ASYNC_END0("ui", "WindowEventDispatcher::HoldPointerMoves", this); + TRACE_EVENT_NESTABLE_ASYNC_END0( + "ui", "WindowEventDispatcher::HoldPointerMoves", TRACE_ID_LOCAL(this)); } gfx::Point WindowEventDispatcher::GetLastMouseLocationInRoot() const {
diff --git a/ui/base/ui_base_features.cc b/ui/base/ui_base_features.cc index d085e653..f4c5ff7 100644 --- a/ui/base/ui_base_features.cc +++ b/ui/base/ui_base_features.cc
@@ -139,6 +139,7 @@ }; #if defined(OS_WIN) || defined(OS_ANDROID) +// Cached in Java as well, make sure defaults are updated together. const base::Feature kElasticOverscroll = {"ElasticOverscroll", base::FEATURE_DISABLED_BY_DEFAULT}; #endif // defined(OS_WIN) || defined(OS_ANDROID)
diff --git a/ui/base/ui_base_switches_util.cc b/ui/base/ui_base_switches_util.cc index f85d9c0..9e76a04 100644 --- a/ui/base/ui_base_switches_util.cc +++ b/ui/base/ui_base_switches_util.cc
@@ -24,8 +24,7 @@ #elif defined(OS_WIN) return base::FeatureList::IsEnabled(features::kElasticOverscroll); #elif defined(OS_ANDROID) - return base::android::BuildInfo::GetInstance()->sdk_int() >= - base::android::SDK_VERSION_R && + return base::android::BuildInfo::GetInstance()->IsAtLeastS() && !base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableOverscrollEdgeEffect) && base::FeatureList::IsEnabled(features::kElasticOverscroll);
diff --git a/ui/display/BUILD.gn b/ui/display/BUILD.gn index a51f475e..a7a8a47 100644 --- a/ui/display/BUILD.gn +++ b/ui/display/BUILD.gn
@@ -5,7 +5,6 @@ import("//build/config/chromeos/ui_mode.gni") import("//build/config/ui.gni") import("//testing/test.gni") -import("//ui/display/display.gni") component("display") { sources = [ @@ -122,23 +121,25 @@ } } -component("display_manager_test_api") { - testonly = true - sources = [ - "test/display_manager_test_api.cc", - "test/display_manager_test_api.h", - ] +if (is_chromeos_ash) { + component("display_manager_test_api") { + testonly = true + sources = [ + "test/display_manager_test_api.cc", + "test/display_manager_test_api.h", + ] - defines = [ "DISPLAY_IMPLEMENTATION" ] + defines = [ "DISPLAY_IMPLEMENTATION" ] - public_deps = [ "//ui/display/manager" ] + public_deps = [ "//ui/display/manager" ] - deps = [ - "//base", - "//build:chromeos_buildflags", - "//ui/display", - "//ui/display/types", - ] + deps = [ + "//base", + "//build:chromeos_buildflags", + "//ui/display", + "//ui/display/types", + ] + } } static_library("test_support") { @@ -152,6 +153,16 @@ "test/test_screen.cc", "test/test_screen.h", ] + public_deps = [ ":display" ] + deps = [ + "//base", + "//testing/gmock", + "//ui/display/types", + "//ui/events/devices", + "//ui/gfx", + "//ui/gfx:test_support", + "//ui/gfx/geometry", + ] if (is_win) { sources += [ @@ -169,7 +180,7 @@ ] } - if (build_display_configuration) { + if (is_chromeos_ash) { sources += [ "manager/test/action_logger.cc", "manager/test/action_logger.h", @@ -184,21 +195,8 @@ "manager/test/touch_transform_controller_test_api.cc", "manager/test/touch_transform_controller_test_api.h", ] + public_deps += [ "//ui/display/manager" ] } - - public_deps = [ - ":display", - "//ui/display/manager", - ] - deps = [ - "//base", - "//testing/gmock", - "//ui/display/types", - "//ui/events/devices", - "//ui/gfx", - "//ui/gfx:test_support", - "//ui/gfx/geometry", - ] } # This test covers all testable components in display. @@ -208,10 +206,6 @@ "display_layout_unittest.cc", "display_list_unittest.cc", "display_unittest.cc", - "fake/fake_display_snapshot_unittest.cc", - "manager/display_manager_utilities_unittest.cc", - "manager/json_converter_unittest.cc", - "manager/managed_display_info_unittest.cc", "mojom/display_list_mojom_traits_unittest.cc", "mojom/display_mojom_traits_unittest.cc", "mojom/screen_infos_mojom_traits_unittest.cc", @@ -228,24 +222,8 @@ ] } - if (build_display_configuration) { - sources += [ - "manager/apply_content_protection_task_unittest.cc", - "manager/configure_displays_task_unittest.cc", - "manager/content_protection_manager_unittest.cc", - "manager/display_change_observer_unittest.cc", - "manager/display_configurator_unittest.cc", - "manager/display_utils_unittest.cc", - "manager/query_content_protection_task_unittest.cc", - "manager/touch_device_manager_unittest.cc", - "manager/touch_transform_controller_unittest.cc", - "manager/update_display_configuration_task_unittest.cc", - ] - } - deps = [ ":display", - ":display_manager_test_api", ":test_support", "//base", "//base/test:test_support", @@ -256,7 +234,6 @@ "//testing/gmock", "//testing/gtest", "//ui/display/fake", - "//ui/display/manager", "//ui/display/mojom", "//ui/display/types", "//ui/display/util", @@ -273,6 +250,26 @@ } if (is_chromeos_ash) { - deps += [ "//ash/constants" ] + sources += [ + "fake/fake_display_snapshot_unittest.cc", + "manager/apply_content_protection_task_unittest.cc", + "manager/configure_displays_task_unittest.cc", + "manager/content_protection_manager_unittest.cc", + "manager/display_change_observer_unittest.cc", + "manager/display_configurator_unittest.cc", + "manager/display_manager_utilities_unittest.cc", + "manager/display_utils_unittest.cc", + "manager/json_converter_unittest.cc", + "manager/managed_display_info_unittest.cc", + "manager/query_content_protection_task_unittest.cc", + "manager/touch_device_manager_unittest.cc", + "manager/touch_transform_controller_unittest.cc", + "manager/update_display_configuration_task_unittest.cc", + ] + deps += [ + ":display_manager_test_api", + "//ash/constants", + "//ui/display/manager", + ] } }
diff --git a/ui/display/display.gni b/ui/display/display.gni deleted file mode 100644 index 22197b6d..0000000 --- a/ui/display/display.gni +++ /dev/null
@@ -1,10 +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. - -import("//build/config/chromeos/ui_mode.gni") - -declare_args() { - # Build Chrome OS display configuration code. - build_display_configuration = is_chromeos_ash -}
diff --git a/ui/display/manager/BUILD.gn b/ui/display/manager/BUILD.gn index 189edadd..e76c77e 100644 --- a/ui/display/manager/BUILD.gn +++ b/ui/display/manager/BUILD.gn
@@ -4,52 +4,20 @@ import("//build/config/chromeos/ui_mode.gni") import("//build/config/ui.gni") -import("//ui/display/display.gni") + +assert(is_chromeos_ash || is_chromecast) component("manager") { sources = [ - "display_layout_store.cc", - "display_layout_store.h", - "display_manager.cc", - "display_manager.h", "display_manager_export.h", "display_manager_utilities.cc", "display_manager_utilities.h", "display_util.cc", "display_util.h", - "json_converter.cc", - "json_converter.h", "managed_display_info.cc", "managed_display_info.h", ] - if (build_display_configuration) { - sources += [ - "apply_content_protection_task.cc", - "apply_content_protection_task.h", - "configure_displays_task.cc", - "configure_displays_task.h", - "content_protection_manager.cc", - "content_protection_manager.h", - "default_touch_transform_setter.cc", - "default_touch_transform_setter.h", - "display_change_observer.cc", - "display_change_observer.h", - "display_configurator.cc", - "display_configurator.h", - "display_layout_manager.h", - "query_content_protection_task.cc", - "query_content_protection_task.h", - "touch_device_manager.cc", - "touch_device_manager.h", - "touch_transform_controller.cc", - "touch_transform_controller.h", - "touch_transform_setter.h", - "update_display_configuration_task.cc", - "update_display_configuration_task.h", - ] - } - configs += [ "//build/config/compiler:wexit_time_destructors" ] public_deps = [ "//ui/display" ] @@ -68,6 +36,36 @@ defines = [ "DISPLAY_MANAGER_IMPLEMENTATION" ] if (is_chromeos_ash) { + sources += [ + "apply_content_protection_task.cc", + "apply_content_protection_task.h", + "configure_displays_task.cc", + "configure_displays_task.h", + "content_protection_manager.cc", + "content_protection_manager.h", + "default_touch_transform_setter.cc", + "default_touch_transform_setter.h", + "display_change_observer.cc", + "display_change_observer.h", + "display_configurator.cc", + "display_configurator.h", + "display_layout_manager.h", + "display_layout_store.cc", + "display_layout_store.h", + "display_manager.cc", + "display_manager.h", + "json_converter.cc", + "json_converter.h", + "query_content_protection_task.cc", + "query_content_protection_task.h", + "touch_device_manager.cc", + "touch_device_manager.h", + "touch_transform_controller.cc", + "touch_transform_controller.h", + "touch_transform_setter.h", + "update_display_configuration_task.cc", + "update_display_configuration_task.h", + ] deps += [ "//chromeos/system" ] } }
diff --git a/ui/display/manager/display_manager.cc b/ui/display/manager/display_manager.cc index 66bb1fa6..4b278ce8 100644 --- a/ui/display/manager/display_manager.cc +++ b/ui/display/manager/display_manager.cc
@@ -55,10 +55,6 @@ #include "ui/events/devices/touchscreen_device.h" #endif -#if defined(OS_WIN) -#include "base/win/windows_version.h" -#endif - namespace display { namespace { @@ -886,12 +882,6 @@ const DisplayInfoList& updated_display_info_list) { BeginEndNotifier notifier(this); -#if defined(OS_WIN) - DCHECK_EQ(1u, updated_display_info_list.size()) - << ": Multiple display test does not work on Windows bots. Please " - "skip (don't disable) the test."; -#endif - DisplayInfoList new_display_info_list = updated_display_info_list; std::sort(active_display_list_.begin(), active_display_list_.end(), DisplaySortFunctor());
diff --git a/ui/display/manager/managed_display_info.cc b/ui/display/manager/managed_display_info.cc index e89114c..82cc8d4 100644 --- a/ui/display/manager/managed_display_info.cc +++ b/ui/display/manager/managed_display_info.cc
@@ -26,11 +26,6 @@ #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/geometry/size_f.h" -#if defined(OS_WIN) -#include <windows.h> -#include "ui/display/win/dpi.h" -#endif - namespace display { namespace { @@ -161,10 +156,6 @@ ManagedDisplayInfo ManagedDisplayInfo::CreateFromSpecWithID( const std::string& spec, int64_t id) { -#if defined(OS_WIN) - gfx::Rect bounds_in_native( - gfx::Size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN))); -#else // Default bounds for a display. const int kDefaultHostWindowX = 200; const int kDefaultHostWindowY = 200; @@ -172,7 +163,6 @@ const int kDefaultHostWindowHeight = 768; gfx::Rect bounds_in_native(kDefaultHostWindowX, kDefaultHostWindowY, kDefaultHostWindowWidth, kDefaultHostWindowHeight); -#endif std::string main_spec = spec; float zoom_factor = 1.0f; @@ -214,11 +204,7 @@ } float device_scale_factor = 1.0f; - if (!GetDisplayBounds(main_spec, &bounds_in_native, &device_scale_factor)) { -#if defined(OS_WIN) - device_scale_factor = win::GetDPIScale(); -#endif - } + GetDisplayBounds(main_spec, &bounds_in_native, &device_scale_factor); ManagedDisplayModeList display_modes; parts = base::SplitString(main_spec, "#", base::KEEP_WHITESPACE,
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.cc b/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.cc index 89c86a5..bcb6733 100644 --- a/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.cc +++ b/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.cc
@@ -25,8 +25,9 @@ void DrmOverlayManagerGpu::SendOverlayValidationRequest( const std::vector<OverlaySurfaceCandidate>& candidates, gfx::AcceleratedWidget widget) { - TRACE_EVENT_ASYNC_BEGIN0( - "hwoverlays", "DrmOverlayManagerGpu::SendOverlayValidationRequest", this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( + "hwoverlays", "DrmOverlayManagerGpu::SendOverlayValidationRequest", + TRACE_ID_LOCAL(this)); SetClearCacheCallbackIfNecessary(); drm_thread_proxy_->CheckOverlayCapabilities( widget, candidates, @@ -38,9 +39,9 @@ DrmOverlayManagerGpu::SendOverlayValidationRequestSync( const std::vector<OverlaySurfaceCandidate>& candidates, gfx::AcceleratedWidget widget) { - TRACE_EVENT_ASYNC_BEGIN0( + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( "hwoverlays", "DrmOverlayManagerGpu::SendOverlayValidationRequestSync", - this); + TRACE_ID_LOCAL(this)); SetClearCacheCallbackIfNecessary(); return drm_thread_proxy_->CheckOverlayCapabilitiesSync(widget, candidates); } @@ -63,8 +64,9 @@ gfx::AcceleratedWidget widget, const std::vector<OverlaySurfaceCandidate>& candidates, const std::vector<OverlayStatus>& status) { - TRACE_EVENT_ASYNC_END0( - "hwoverlays", "DrmOverlayManagerGpu::SendOverlayValidationRequest", this); + TRACE_EVENT_NESTABLE_ASYNC_END0( + "hwoverlays", "DrmOverlayManagerGpu::SendOverlayValidationRequest", + TRACE_ID_LOCAL(this)); UpdateCacheForOverlayCandidates(candidates, widget, status); }
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc index 4708536..1ae0b8a 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection.cc +++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
@@ -218,7 +218,7 @@ // estabilished, initialize the event source and input objects. DCHECK(!event_source_); event_source_ = std::make_unique<WaylandEventSource>( - display(), event_queue_.get(), wayland_window_manager()); + display(), event_queue_.get(), wayland_window_manager(), this); wl_registry_add_listener(registry_.get(), ®istry_listener, this); while (!wayland_output_manager_ || @@ -299,8 +299,12 @@ bool WaylandConnection::IsDragInProgress() const { // |data_drag_controller_| can be null when running on headless weston. - return data_drag_controller_ && data_drag_controller_->state() != - WaylandDataDragController::State::kIdle; + return (data_drag_controller_ && + data_drag_controller_->state() != + WaylandDataDragController::State::kIdle) || + (window_drag_controller_ && + window_drag_controller_->state() != + WaylandWindowDragController::State::kIdle); } wl::Object<wl_surface> WaylandConnection::CreateSurface() { @@ -413,7 +417,7 @@ DCHECK(!window_drag_controller_); window_drag_controller_ = std::make_unique<WaylandWindowDragController>( - this, data_device_manager_.get(), event_source()); + this, data_device_manager_.get(), event_source(), event_source()); DCHECK(!clipboard_); clipboard_ =
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.cc b/ui/ozone/platform/wayland/host/wayland_event_source.cc index d84b914..69b031f 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_source.cc +++ b/ui/ozone/platform/wayland/host/wayland_event_source.cc
@@ -78,8 +78,10 @@ WaylandEventSource::WaylandEventSource(wl_display* display, wl_event_queue* event_queue, - WaylandWindowManager* window_manager) + WaylandWindowManager* window_manager, + WaylandConnection* connection) : window_manager_(window_manager), + connection_(connection), event_watcher_( std::make_unique<WaylandEventWatcher>(display, event_queue)) { DCHECK(window_manager_); @@ -341,6 +343,13 @@ } void WaylandEventSource::OnTouchCancelEvent() { + // Some compositors emit a TouchCancel event when a drag'n drop + // session is started on the server, eg Exo. + // On Chrome, this event would actually abort the whole drag'n drop + // session on the client side. + if (connection_->IsDragInProgress()) + return; + gfx::PointF location; base::TimeTicks timestamp = base::TimeTicks::Now(); for (auto& touch_point : touch_points_) { @@ -353,6 +362,13 @@ touch_points_.clear(); } +std::vector<PointerId> WaylandEventSource::GetActiveTouchPointIds() { + std::vector<PointerId> pointer_ids; + for (auto& touch_point : touch_points_) + pointer_ids.push_back(touch_point.first); + return pointer_ids; +} + void WaylandEventSource::OnPinchEvent(EventType event_type, const gfx::Vector2dF& delta, base::TimeTicks timestamp,
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.h b/ui/ozone/platform/wayland/host/wayland_event_source.h index 1f66403ec..d89d27d8 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_source.h +++ b/ui/ozone/platform/wayland/host/wayland_event_source.h
@@ -34,6 +34,7 @@ namespace ui { +class WaylandConnection; class WaylandWindow; class WaylandWindowManager; @@ -54,7 +55,8 @@ public: WaylandEventSource(wl_display* display, wl_event_queue* event_queue, - WaylandWindowManager* window_manager); + WaylandWindowManager* window_manager, + WaylandConnection* connection); WaylandEventSource(const WaylandEventSource&) = delete; WaylandEventSource& operator=(const WaylandEventSource&) = delete; ~WaylandEventSource() override; @@ -122,6 +124,7 @@ base::TimeTicks timestamp, PointerId id) override; void OnTouchCancelEvent() override; + std::vector<PointerId> GetActiveTouchPointIds() override; // WaylandZwpPointerGesture::Delegate: void OnPinchEvent(EventType event_type, @@ -170,6 +173,8 @@ WaylandWindowManager* const window_manager_; + WaylandConnection* const connection_; + // Bitmask of EventFlags used to keep track of the the pointer state. int pointer_flags_ = 0;
diff --git a/ui/ozone/platform/wayland/host/wayland_touch.h b/ui/ozone/platform/wayland/host/wayland_touch.h index 4c3e3b7..2f8a1bd 100644 --- a/ui/ozone/platform/wayland/host/wayland_touch.h +++ b/ui/ozone/platform/wayland/host/wayland_touch.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_TOUCH_H_ #define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_TOUCH_H_ +#include <vector> + #include "base/macros.h" #include "base/time/time.h" #include "ui/events/pointer_details.h" @@ -70,6 +72,7 @@ base::TimeTicks timestamp, PointerId id) = 0; virtual void OnTouchCancelEvent() = 0; + virtual std::vector<PointerId> GetActiveTouchPointIds() = 0; }; } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc index f1ccb840..85ed50f2 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc
@@ -37,7 +37,6 @@ #include "ui/ozone/platform/wayland/host/wayland_data_device_manager.h" #include "ui/ozone/platform/wayland/host/wayland_data_offer.h" #include "ui/ozone/platform/wayland/host/wayland_data_source.h" -#include "ui/ozone/platform/wayland/host/wayland_pointer.h" #include "ui/ozone/platform/wayland/host/wayland_surface.h" #include "ui/ozone/platform/wayland/host/wayland_window.h" #include "ui/ozone/platform/wayland/host/wayland_window_manager.h" @@ -83,14 +82,17 @@ WaylandWindowDragController::WaylandWindowDragController( WaylandConnection* connection, WaylandDataDeviceManager* device_manager, - WaylandPointer::Delegate* pointer_delegate) + WaylandPointer::Delegate* pointer_delegate, + WaylandTouch::Delegate* touch_delegate) : connection_(connection), data_device_manager_(device_manager), data_device_(device_manager->GetDevice()), window_manager_(connection_->wayland_window_manager()), - pointer_delegate_(pointer_delegate) { + pointer_delegate_(pointer_delegate), + touch_delegate_(touch_delegate) { DCHECK(data_device_); DCHECK(pointer_delegate_); + DCHECK(touch_delegate_); } WaylandWindowDragController::~WaylandWindowDragController() = default; @@ -107,6 +109,9 @@ VLOG(1) << "Starting DND session."; state_ = State::kAttached; + drag_source_ = connection_->event_serial().event_type == ET_TOUCH_PRESSED + ? DragSource::kTouch + : DragSource::kMouse; DCHECK(!data_source_); data_source_ = data_device_manager_->CreateSource(this); @@ -228,7 +233,16 @@ // Forward cursor location update info to the input handling delegate. should_process_drag_event_ = true; pointer_location_ = location; - pointer_delegate_->OnPointerMotionEvent(location); + + if (*drag_source_ == DragSource::kMouse) { + pointer_delegate_->OnPointerMotionEvent(location); + } else { + base::TimeTicks timestamp = base::TimeTicks::Now(); + auto touch_pointer_ids = touch_delegate_->GetActiveTouchPointIds(); + DCHECK_EQ(touch_pointer_ids.size(), 1u); + touch_delegate_->OnTouchMotionEvent(location, timestamp, + touch_pointer_ids[0]); + } } void WaylandWindowDragController::OnDragLeave() { @@ -331,8 +345,9 @@ DCHECK_EQ(state_, State::kDetached); DCHECK(base::CurrentUIThread::IsSet()); - if (event->type() == ET_MOUSE_MOVED || event->type() == ET_MOUSE_DRAGGED) { - HandleMotionEvent(event->AsMouseEvent()); + if (event->type() == ET_MOUSE_MOVED || event->type() == ET_MOUSE_DRAGGED || + event->type() == ET_TOUCH_MOVED) { + HandleMotionEvent(event->AsLocatedEvent()); return POST_DISPATCH_STOP_PROPAGATION; } return POST_DISPATCH_PERFORM_DEFAULT; @@ -362,7 +377,7 @@ origin_surface_ = origin_window_->TakeWaylandSurface(); } -void WaylandWindowDragController::HandleMotionEvent(MouseEvent* event) { +void WaylandWindowDragController::HandleMotionEvent(LocatedEvent* event) { DCHECK_EQ(state_, State::kDetached); DCHECK(dragged_window_); DCHECK(event); @@ -395,12 +410,20 @@ DCHECK(pointer_grab_owner_); VLOG(1) << "Notifying drop. window=" << pointer_grab_owner_; - EventFlags pointer_button = EF_LEFT_MOUSE_BUTTON; - pointer_delegate_->OnPointerButtonEvent(ET_MOUSE_RELEASED, pointer_button, - pointer_grab_owner_); + if (*drag_source_ == DragSource::kMouse) { + EventFlags pointer_button = EF_LEFT_MOUSE_BUTTON; + pointer_delegate_->OnPointerButtonEvent(ET_MOUSE_RELEASED, pointer_button, + pointer_grab_owner_); + } else { + base::TimeTicks timestamp = base::TimeTicks::Now(); + auto touch_pointer_ids = touch_delegate_->GetActiveTouchPointIds(); + DCHECK_EQ(touch_pointer_ids.size(), 1u); + touch_delegate_->OnTouchReleaseEvent(timestamp, touch_pointer_ids[0]); + } pointer_grab_owner_ = nullptr; state_ = State::kIdle; + drag_source_.reset(); } void WaylandWindowDragController::RunLoop() {
diff --git a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.h b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.h index 96da9124..e8f2d5c 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.h +++ b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.h
@@ -23,6 +23,7 @@ #include "ui/ozone/platform/wayland/host/wayland_data_source.h" #include "ui/ozone/platform/wayland/host/wayland_pointer.h" #include "ui/ozone/platform/wayland/host/wayland_toplevel_window.h" +#include "ui/ozone/platform/wayland/host/wayland_touch.h" #include "ui/ozone/platform/wayland/host/wayland_window_observer.h" namespace ui { @@ -52,10 +53,15 @@ kDropped, // Drop event was just received. kAttaching, // About to transition back to |kAttached|. }; + enum class DragSource { + kMouse, + kTouch, + }; WaylandWindowDragController(WaylandConnection* connection, WaylandDataDeviceManager* device_manager, - WaylandPointer::Delegate* pointer_delegate); + WaylandPointer::Delegate* pointer_delegate, + WaylandTouch::Delegate* touch_delegate); WaylandWindowDragController(const WaylandWindowDragController&) = delete; WaylandWindowDragController& operator=(const WaylandWindowDragController&) = delete; @@ -101,7 +107,7 @@ // Handles drag/move mouse |event|, while in |kDetached| mode, forwarding it // as a bounds change event to the upper layer handlers. - void HandleMotionEvent(MouseEvent* event); + void HandleMotionEvent(LocatedEvent* event); // Handles the mouse button release (i.e: drop). Dispatches the required // events and resets the internal state. void HandleDropAndResetState(); @@ -123,8 +129,11 @@ WaylandDataDevice* const data_device_; WaylandWindowManager* const window_manager_; WaylandPointer::Delegate* const pointer_delegate_; + WaylandTouch::Delegate* const touch_delegate_; State state_ = State::kIdle; + absl::optional<DragSource> drag_source_; + gfx::Vector2d drag_offset_; // The last known pointer location in DIP.
diff --git a/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc index 25de1de1..3ef8cab 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc
@@ -119,6 +119,32 @@ // // TODO(crbug.com/1116431): Support extended-drag in test compositor. void SendDndDrop() { SendDndCancelled(); } + + void SendTouchDown(WaylandWindow* window, + MockPlatformWindowDelegate* delegate, + int id, + const gfx::Point& location) override { + WaylandDragDropTest::SendTouchDown(window, delegate, id, location); + EXPECT_CALL(*delegate, DispatchEvent(_)).Times(1); + Sync(); + + EXPECT_EQ(window, window_manager()->GetCurrentFocusedWindow()); + } + void SendTouchMotion(WaylandWindow* window, + MockPlatformWindowDelegate* delegate, + int id, + const gfx::Point& location) override { + WaylandDragDropTest::SendTouchMotion(window, delegate, id, location); + + EXPECT_CALL(*delegate, DispatchEvent(_)).WillOnce([](Event* event) { + EXPECT_TRUE(event->IsTouchEvent()); + EXPECT_EQ(ET_TOUCH_MOVED, event->type()); + }); + Sync(); + + EXPECT_EQ(window->GetWidget(), + screen_->GetLocalProcessWidgetAtPoint(location, {})); + } }; // Check the following flow works as expected: @@ -210,6 +236,94 @@ } // Check the following flow works as expected: +// 1. With a single window open, +// 2. Touch down and move the touch point a bit (drag), +// 3. Run move loop, drag it within the window bounds and drop. +TEST_P(WaylandWindowDragControllerTest, DragInsideWindowAndDrop_TOUCH) { + // Ensure there is no window currently focused + EXPECT_FALSE(window_manager()->GetCurrentFocusedWindow()); + EXPECT_EQ(gfx::kNullAcceleratedWidget, + screen_->GetLocalProcessWidgetAtPoint({10, 10}, {})); + + SendTouchDown(window_.get(), &delegate_, 0 /*point id*/, {0, 0} /*location*/); + SendTouchMotion(window_.get(), &delegate_, 0 /*point id*/, + {10, 10} /*location*/); + + // Set up an "interaction flow", start the drag session and run move loop: + // - Event dispatching and bounds changes are monitored + // - At each event, emulates a new event at server side and proceeds to the + // next test step. + auto* wayland_extension = GetWaylandExtension(*window_); + wayland_extension->StartWindowDraggingSessionIfNeeded(); + EXPECT_EQ(State::kAttached, drag_controller()->state()); + + auto* move_loop_handler = GetWmMoveLoopHandler(*window_); + DCHECK(move_loop_handler); + + enum { kStarted, kDragging, kDropping, kDone } test_step = kStarted; + + EXPECT_CALL(delegate_, DispatchEvent(_)).WillRepeatedly([&](Event* event) { + switch (test_step) { + case kStarted: + // TODO(tonikitoo,nickdiego): Is it correct to emit a mouse enter here? + EXPECT_EQ(ET_MOUSE_ENTERED, event->type()); + EXPECT_EQ(State::kDetached, drag_controller()->state()); + // Ensure PlatformScreen keeps consistent. + EXPECT_EQ(window_->GetWidget(), + screen_->GetLocalProcessWidgetAtPoint({10, 10}, {})); + // Drag it a bit more. + SendDndMotion({20, 20}); + test_step = kDragging; + break; + case kDropping: + EXPECT_EQ(ET_TOUCH_RELEASED, event->type()); + EXPECT_EQ(State::kDropped, drag_controller()->state()); + // Ensure PlatformScreen keeps consistent. + EXPECT_EQ(gfx::Point(20, 20), screen_->GetCursorScreenPoint()); + EXPECT_EQ(window_->GetWidget(), + screen_->GetLocalProcessWidgetAtPoint({20, 20}, {})); + test_step = kDone; + break; + case kDone: + EXPECT_EQ(ET_MOUSE_EXITED, event->type()); + EXPECT_EQ(window_->GetWidget(), + screen_->GetLocalProcessWidgetAtPoint({20, 20}, {})); + break; + case kDragging: + default: + FAIL() << " event=" << event->GetName() + << " state=" << drag_controller()->state() + << " step=" << static_cast<int>(test_step); + return; + } + }); + + EXPECT_CALL(delegate_, OnBoundsChanged(_)) + .WillOnce([&](const PlatformWindowDelegate::BoundsChange& bounds) { + EXPECT_EQ(State::kDetached, drag_controller()->state()); + EXPECT_EQ(kDragging, test_step); + EXPECT_EQ(gfx::Point(20, 20), bounds.bounds.origin()); + + SendDndDrop(); + test_step = kDropping; + }); + + // RunMoveLoop() blocks until the dragging session ends, so resume test + // server's run loop until it returns. + server_.Resume(); + move_loop_handler->RunMoveLoop({}); + server_.Pause(); + + SendPointerEnter(window_.get(), &delegate_); + Sync(); + + EXPECT_EQ(State::kIdle, drag_controller()->state()); + EXPECT_EQ(window_.get(), window_manager()->GetCurrentFocusedWindow()); + EXPECT_EQ(window_->GetWidget(), + screen_->GetLocalProcessWidgetAtPoint({20, 20}, {})); +} + +// Check the following flow works as expected: // 1. With only 1 window open; // 2. Move pointer into it, press left button, move cursor a bit (drag); // 3. Run move loop,
diff --git a/ui/ozone/platform/wayland/test/wayland_drag_drop_test.cc b/ui/ozone/platform/wayland/test/wayland_drag_drop_test.cc index 739e424..0a7841d 100644 --- a/ui/ozone/platform/wayland/test/wayland_drag_drop_test.cc +++ b/ui/ozone/platform/wayland/test/wayland_drag_drop_test.cc
@@ -19,6 +19,7 @@ #include "ui/ozone/platform/wayland/test/test_data_device_manager.h" #include "ui/ozone/platform/wayland/test/test_data_offer.h" #include "ui/ozone/platform/wayland/test/test_data_source.h" +#include "ui/ozone/platform/wayland/test/test_touch.h" using testing::_; @@ -85,15 +86,40 @@ state); } +void WaylandDragDropTest::SendTouchDown(WaylandWindow* window, + MockPlatformWindowDelegate* delegate, + int id, + const gfx::Point& location) { + auto* surface = server_.GetObject<wl::MockSurface>( + window->root_surface()->GetSurfaceId()); + wl_touch_send_down( + touch_->resource(), NextSerial(), NextTime(), surface->resource(), id, + wl_fixed_from_double(location.x()), wl_fixed_from_double(location.y())); +} + +void WaylandDragDropTest::SendTouchMotion(WaylandWindow* window, + MockPlatformWindowDelegate* delegate, + int id, + const gfx::Point& location) { + wl_touch_send_motion(touch_->resource(), NextSerial(), id, + wl_fixed_from_double(location.x()), + wl_fixed_from_double(location.y())); +} + void WaylandDragDropTest::SetUp() { WaylandTest::SetUp(); - wl_seat_send_capabilities(server_.seat()->resource(), - WL_SEAT_CAPABILITY_POINTER); + wl_seat_send_capabilities( + server_.seat()->resource(), + WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); + Sync(); pointer_ = server_.seat()->pointer(); ASSERT_TRUE(pointer_); + touch_ = server_.seat()->touch(); + ASSERT_TRUE(touch_); + data_device_manager_ = server_.data_device_manager(); ASSERT_TRUE(data_device_manager_);
diff --git a/ui/ozone/platform/wayland/test/wayland_drag_drop_test.h b/ui/ozone/platform/wayland/test/wayland_drag_drop_test.h index cd7a238..b32b16ae 100644 --- a/ui/ozone/platform/wayland/test/wayland_drag_drop_test.h +++ b/ui/ozone/platform/wayland/test/wayland_drag_drop_test.h
@@ -51,6 +51,15 @@ int button, bool pressed); + virtual void SendTouchDown(WaylandWindow* window, + MockPlatformWindowDelegate* delegate, + int id, + const gfx::Point& location); + virtual void SendTouchMotion(WaylandWindow* window, + MockPlatformWindowDelegate* delegate, + int id, + const gfx::Point& location); + protected: // WaylandTest: void SetUp() override; @@ -75,6 +84,7 @@ wl::TestDataDeviceManager* data_device_manager_; wl::TestDataSource* data_source_; wl::MockPointer* pointer_; + wl::TestTouch* touch_; }; } // namespace ui
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index 9929ffc..c713367f 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -1307,6 +1307,15 @@ ] } + if (is_fuchsia) { + additional_manifest_fragments = [ + "//build/config/fuchsia/test/font_capabilities.test-cmx", + "//build/config/fuchsia/test/jit_capabilities.test-cmx", + "//build/config/fuchsia/test/present_view_capabilities.test-cmx", + "//build/config/fuchsia/test/vulkan_capabilities.test-cmx", + ] + } + if (use_aura) { sources += [ "accessibility/accessibility_alert_window_unittest.cc",