diff --git a/DEPS b/DEPS index d3c22a8..c8e14e6 100644 --- a/DEPS +++ b/DEPS
@@ -308,7 +308,7 @@ # 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': '6937e7b311221aaff448abce8636bb09f2874962', + 'skia_revision': '9afb9e561f6131a36d951dd988551039d25ade88', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -316,7 +316,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': 'be8aa9e9fbaa9278d5a0ebd18fd43357829d8c87', + 'angle_revision': '309520d0c1c9f38528db1cb32670f6e4630fbc59', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -335,7 +335,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Fuchsia sdk # and whatever else without interference from each other. - 'fuchsia_version': 'version:9.20221003.3.1', + 'fuchsia_version': 'version:9.20221004.0.1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling google-toolbox-for-mac # and whatever else without interference from each other. @@ -359,7 +359,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. - 'freetype_revision': '8faf57dd17088c37fa947fd565870648bbdbad18', + 'freetype_revision': '0417527d5b5abc3ee9426f31bd95209ca97502a5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -387,7 +387,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': '23179707af80429b41360ac4066fb79608f8aa48', + 'devtools_frontend_revision': 'e77792ecc5a8dcfc99d5a4c949007174980b8063', # 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. @@ -423,7 +423,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '4c569d14ab6573deb118cc916440d714eb9c7e8c', + 'dawn_revision': '0c2909e4d4c8f4174acaa5db2bc3d578281f9c4e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -487,7 +487,7 @@ # If you change this, also update the libc++ revision in # //buildtools/deps_revisions.gni. - 'libcxx_revision': '2e919977e0030ce61bd19c40cefe31b995f1e2d4', + 'libcxx_revision': '7261e95e5175e95172404e84c43625dc61386470', # GN CIPD package version. 'gn_version': 'git_revision:cc28efe62ef0c2fb32455f414a29c4a55bb7fbc4', @@ -993,7 +993,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'tlL4NXCU9VloHEQBuJdPXXhRoEmQlCqfefFTxshooSUC', + 'version': 'WmYFNmUFDQMSQ8gF_eefj5NuqX1dts_zlowVIHYrMIYC', }, ], 'condition': 'checkout_android', @@ -1242,7 +1242,7 @@ Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + 'abc7a6bc6df55e64128f6f3ef10447a3141641ee', + 'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + '6fb6e4a17a9e72a02d0b9d86635bfe52368bf022', 'condition': 'checkout_src_internal', }, @@ -1654,7 +1654,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '6b54769fde8e593a5ad7142596935d8198b511f1', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'ad82476afb8e871871290f5e26b6477b9953db81', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1839,7 +1839,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'e84b11b1d90efe59e94bb24d1f1276071f50481e', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'ef51274188d7cf4611bb869ca1304e2f85c3d943', + Var('webrtc_git') + '/src.git' + '@' + 'c11b0fec74fabff3d93fa0d340a133867533d73d', # Wuffs' canonical repository is at github.com/google/wuffs, but we use # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file. @@ -1909,7 +1909,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@5ac75be1959dbcaf6c06a91ef7ea7e36a3e39637', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@b227aeb64ccc02341fde87ad1d97c131fe1a27c9', 'condition': 'checkout_src_internal', }, @@ -1928,7 +1928,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/eche_app/app', - 'version': '3dcivv2X5VtogWZ3_o3BLhuDQr4rdtznPv1GUjlF0DcC', + 'version': 'yesiSRdiGQK7STQgGw0zFkf-x7WzV1e1NrQ8w995Wo4C', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1961,7 +1961,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/projector_app/app', - 'version': 'nANRyXGXTuCHYDryhEHNSWohMk_zz8IzlnIpPpEkNDMC', + 'version': 'W2N9Xp3ERgDWhNhfO9NlgNbHfoR00vjBV94S1kYssJwC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/WATCHLISTS b/WATCHLISTS index be8d5b9..abc8185 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -3068,7 +3068,8 @@ 'cbiesinger@chromium.org', 'icer@chromium.org', 'npm+watch@chromium.org'], - 'weblayer': ['cricke+watch@chromium.org'], + 'weblayer': ['cricke+watch@chromium.org', + 'rayankans+watch@chromium.org'], 'weblayer_safe_browsing' : ['carlosil+watch@chromium.org'], 'weblayer_ssl' : ['carlosil+watch@chromium.org'], 'webotp': ['yigu+watch@chromium.org'],
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java index 918391b..e1f1ed1 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java +++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -377,6 +377,8 @@ "This persists client hints between top-level navigations."), Flag.commandLine(CcFeatures.USE_DMSAA_FOR_TILES, "Switches skia to use DMSAA instead of MSAA for tile raster"), + Flag.baseFeature( + CcFeatures.AVOID_RASTER_DURING_ELASTIC_OVERSCROLL, "No effect on webview"), // Add new commandline switches and features above. The final entry should have a // trailing comma for cleaner diffs.
diff --git a/base/BUILD.gn b/base/BUILD.gn index dff82914..4ce40ab 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -3688,6 +3688,7 @@ "android/linker/modern_linker_jni.h", "android/linker/modern_linker_unittest.cc", "android/path_utils_unittest.cc", + "android/radio_utils_unittest.cc", "android/reached_addresses_bitset_unittest.cc", "android/scoped_java_ref_unittest.cc", "android/sys_utils_unittest.cc",
diff --git a/base/allocator/partition_allocator/address_pool_manager.cc b/base/allocator/partition_allocator/address_pool_manager.cc index f3b2a144..397b2792 100644 --- a/base/allocator/partition_allocator/address_pool_manager.cc +++ b/base/allocator/partition_allocator/address_pool_manager.cc
@@ -47,18 +47,14 @@ } // namespace -pool_handle AddressPoolManager::Add(uintptr_t ptr, size_t length) { +void AddressPoolManager::Add(pool_handle handle, uintptr_t ptr, size_t length) { PA_DCHECK(!(ptr & kSuperPageOffsetMask)); PA_DCHECK(!((ptr + length) & kSuperPageOffsetMask)); + PA_CHECK(handle > 0 && handle <= std::size(pools_)); - for (pool_handle i = 0; i < std::size(pools_); ++i) { - if (!pools_[i].IsInitialized()) { - pools_[i].Initialize(ptr, length); - return i + 1; - } - } - PA_NOTREACHED(); - return 0; + Pool* pool = GetPool(handle); + PA_CHECK(!pool->IsInitialized()); + pool->Initialize(ptr, length); } void AddressPoolManager::GetPoolUsedSuperPages(
diff --git a/base/allocator/partition_allocator/address_pool_manager.h b/base/allocator/partition_allocator/address_pool_manager.h index afaf06a..1a1dbd68 100644 --- a/base/allocator/partition_allocator/address_pool_manager.h +++ b/base/allocator/partition_allocator/address_pool_manager.h
@@ -54,7 +54,7 @@ AddressPoolManager& operator=(const AddressPoolManager&) = delete; #if defined(PA_HAS_64_BITS_POINTERS) - pool_handle Add(uintptr_t address, size_t length); + void Add(pool_handle handle, uintptr_t address, size_t length); void Remove(pool_handle handle); // Populate a |used| bitset of superpages currently in use.
diff --git a/base/allocator/partition_allocator/address_pool_manager_unittest.cc b/base/allocator/partition_allocator/address_pool_manager_unittest.cc index 3705997fe..127a19c 100644 --- a/base/allocator/partition_allocator/address_pool_manager_unittest.cc +++ b/base/allocator/partition_allocator/address_pool_manager_unittest.cc
@@ -59,7 +59,8 @@ PageAccessibilityConfiguration::kInaccessible, PageTag::kPartitionAlloc); ASSERT_TRUE(base_address_); - pool_ = manager_->Add(base_address_, kPoolSize); + manager_->Add(kRegularPoolHandle, base_address_, kPoolSize); + pool_ = kRegularPoolHandle; } void TearDown() override { @@ -80,9 +81,13 @@ TEST_F(PartitionAllocAddressPoolManagerTest, TooLargePool) { uintptr_t base_addr = 0x4200000; + const pool_handle extra_pool = 2; + static_assert(kNumPools >= 2); EXPECT_DEATH_IF_SUPPORTED( - GetAddressPoolManager()->Add(base_addr, kPoolSize + kSuperPageSize), ""); + GetAddressPoolManager()->Add(extra_pool, base_addr, + kPoolSize + kSuperPageSize), + ""); } TEST_F(PartitionAllocAddressPoolManagerTest, ManyPages) {
diff --git a/base/allocator/partition_allocator/glossary.md b/base/allocator/partition_allocator/glossary.md index ca18a1e7..6ed14361 100644 --- a/base/allocator/partition_allocator/glossary.md +++ b/base/allocator/partition_allocator/glossary.md
@@ -89,21 +89,22 @@ holds some not-too-large memory chunks, ready to be allocated. This speeds up in-thread allocation by reducing a lock hold to a thread-local storage lookup, improving cache locality. -* **Pool**: A large (and contiguous on 64-bit) memory region, housing +* **Pool**: A large (and contiguous on 64-bit) virtual address region, housing super pages, etc. from which PartitionAlloc services allocations. The primary purpose of the pools is to provide a fast answer to the question, "Did PartitionAlloc allocate the memory for this pointer from this pool?" with a single bit-masking operation. - * The regular pool contains all non-BackupRefPtr allocations. - * The BRP pool contains all the BRP allocations. - * Pools are downgraded into a logical concept in 32-bit environments, - tracking a non-contiguous set of allocations using a bitmap. + * The regular pool is a general purpose pool that contains allocations that + aren't protected by BackupRefPtr. + * The BRP pool contains all allocations protected by BackupRefPtr. + * [64-bit only] The configurable pool is named generically, because its + primary user (the [V8 Sandbox][v8-sandbox]) can configure it at runtime, + providing a pre-existing mapping. Its allocations aren't protected by + BackupRefPtr. *** promo -A third pool is provided in 64-bit environments. It is generically -named the "configurable" pool, because its primary user (the -[V8 Sandbox][v8-sandbox]) can configure it at runtime, providing a -pre-existing mapping. +Pools are downgraded into a logical concept in 32-bit environments, +tracking a non-contiguous set of allocations using a bitmap. *** * **Payload**: The usable area of a super page in which slot spans
diff --git a/base/allocator/partition_allocator/hardening_unittest.cc b/base/allocator/partition_allocator/hardening_unittest.cc index 760d0caf..508d275 100644 --- a/base/allocator/partition_allocator/hardening_unittest.cc +++ b/base/allocator/partition_allocator/hardening_unittest.cc
@@ -112,7 +112,9 @@ #endif // !BUILDFLAG(IS_ANDROID) && defined(GTEST_HAS_DEATH_TEST) && // defined(PA_HAS_FREELIST_SHADOW_ENTRY) -// Below test also misbehaves on Android, crbug.com/1370048 +// Below test also misbehaves on Android; as above, death tests don't +// quite work (crbug.com/1240184), and having free slot bitmaps enabled +// force the expectations below to crash. #if !BUILDFLAG(IS_ANDROID) TEST(HardeningTest, SuccessfulCorruption) {
diff --git a/base/allocator/partition_allocator/partition_address_space.cc b/base/allocator/partition_allocator/partition_address_space.cc index e19f7cd..c0bcd04 100644 --- a/base/allocator/partition_allocator/partition_address_space.cc +++ b/base/allocator/partition_allocator/partition_address_space.cc
@@ -183,9 +183,8 @@ setup_.regular_pool_base_mask_ = ~(regular_pool_size - 1); #endif PA_DCHECK(!(setup_.regular_pool_base_address_ & (regular_pool_size - 1))); - pool_handle pool = AddressPoolManager::GetInstance().Add( - setup_.regular_pool_base_address_, regular_pool_size); - PA_CHECK(pool == kRegularPoolHandle); + AddressPoolManager::GetInstance().Add( + kRegularPoolHandle, setup_.regular_pool_base_address_, regular_pool_size); PA_DCHECK(!IsInRegularPool(setup_.regular_pool_base_address_ - 1)); PA_DCHECK(IsInRegularPool(setup_.regular_pool_base_address_)); PA_DCHECK(IsInRegularPool(setup_.regular_pool_base_address_ + @@ -216,9 +215,8 @@ setup_.brp_pool_base_mask_ = ~(brp_pool_size - 1); #endif PA_DCHECK(!(setup_.brp_pool_base_address_ & (brp_pool_size - 1))); - pool = AddressPoolManager::GetInstance().Add(setup_.brp_pool_base_address_, - brp_pool_size); - PA_CHECK(pool == kBRPPoolHandle); + AddressPoolManager::GetInstance().Add( + kBRPPoolHandle, setup_.brp_pool_base_address_, brp_pool_size); PA_DCHECK(!IsInBRPPool(setup_.brp_pool_base_address_ - 1)); PA_DCHECK(IsInBRPPool(setup_.brp_pool_base_address_)); PA_DCHECK(IsInBRPPool(setup_.brp_pool_base_address_ + brp_pool_size - 1)); @@ -270,9 +268,8 @@ setup_.configurable_pool_base_address_ = pool_base; setup_.configurable_pool_base_mask_ = ~(size - 1); - pool_handle pool = AddressPoolManager::GetInstance().Add( - setup_.configurable_pool_base_address_, size); - PA_CHECK(pool == kConfigurablePoolHandle); + AddressPoolManager::GetInstance().Add( + kConfigurablePoolHandle, setup_.configurable_pool_base_address_, size); } void PartitionAddressSpace::UninitForTesting() {
diff --git a/base/allocator/partition_allocator/partition_address_space.h b/base/allocator/partition_allocator/partition_address_space.h index d32f380..5772b68 100644 --- a/base/allocator/partition_allocator/partition_address_space.h +++ b/base/allocator/partition_allocator/partition_address_space.h
@@ -31,11 +31,8 @@ namespace internal { -// Reserves address space for PartitionAllocator. -// -// This reserves space for the regular and BRP pools. If callers would -// like to use the configurable pool, they must manually set up the -// address space themselves and provide the mapping to PartitionAlloc. +// Manages PartitionAlloc address space, which is split into pools. +// See `glossary.md`. class PA_COMPONENT_EXPORT(PARTITION_ALLOC) PartitionAddressSpace { public: #if defined(PA_DYNAMICALLY_SELECT_POOL_SIZE) @@ -80,14 +77,15 @@ return kConfigurablePoolMinSize; } - // Initialize pools. + // Initialize pools (except for the configurable one). // // This function must only be called from the main thread. static void Init(); // Initialize the ConfigurablePool at the given address |pool_base|. It must // be aligned to the size of the pool. The size must be a power of two and - // must be within [ConfigurablePoolMinSize(), ConfigurablePoolMaxSize()]. This - // function must only be called from the main thread. + // must be within [ConfigurablePoolMinSize(), ConfigurablePoolMaxSize()]. + // + // This function must only be called from the main thread. static void InitConfigurablePool(uintptr_t pool_base, size_t size); static void UninitForTesting(); static void UninitConfigurablePoolForTesting(); @@ -133,6 +131,12 @@ #endif return (address & brp_pool_base_mask) == setup_.brp_pool_base_address_; } + + static PA_ALWAYS_INLINE uintptr_t OffsetInBRPPool(uintptr_t address) { + PA_DCHECK(IsInBRPPool(address)); + return address - setup_.brp_pool_base_address_; + } + // Returns false for nullptr. static PA_ALWAYS_INLINE bool IsInConfigurablePool(uintptr_t address) { return (address & setup_.configurable_pool_base_mask_) == @@ -143,11 +147,6 @@ return setup_.configurable_pool_base_address_; } - static PA_ALWAYS_INLINE uintptr_t OffsetInBRPPool(uintptr_t address) { - PA_DCHECK(IsInBRPPool(address)); - return address - setup_.brp_pool_base_address_; - } - #if defined(PA_ENABLE_SHADOW_METADATA) static PA_ALWAYS_INLINE std::ptrdiff_t ShadowPoolOffset(pool_handle pool) { if (pool == kRegularPoolHandle) { @@ -192,16 +191,16 @@ // Pool sizes have to be the power of two. Each pool will be aligned at its // own size boundary. // - // NOTE! The BRP pool must be preceded by a reserved region, where allocations - // are forbidden. This is to prevent a pointer to the end of a non-BRP-pool - // allocation from falling into the BRP pool, thus triggering BRP mechanism - // and likely crashing. This "forbidden zone" can be as small as 1B, but it's - // simpler to just reserve an allocation granularity unit. + // NOTE! The BRP pool must be preceded by an inaccessible region. This is to + // prevent a pointer to the end of a non-BRP-pool allocation from falling into + // the BRP pool, thus triggering BRP mechanism and likely crashing. This + // "forbidden zone" can be as small as 1B, but it's simpler to just reserve an + // allocation granularity unit. // // The ConfigurablePool is an optional Pool that can be created inside an - // existing mapping by the embedder. This Pool can be used when certain PA - // allocations must be located inside a given virtual address region. One - // use case for this Pool is V8's virtual memory cage, which requires that + // existing mapping provided by the embedder. This Pool can be used when + // certain PA allocations must be located inside a given virtual address + // region. One use case for this Pool is V8 Sandbox, which requires that // ArrayBuffers be located inside of it. static constexpr size_t kRegularPoolSize = kPoolMaxSize; static constexpr size_t kBRPPoolSize = kPoolMaxSize;
diff --git a/base/allocator/partition_allocator/partition_alloc_constants.h b/base/allocator/partition_allocator/partition_alloc_constants.h index d8bf5bf..f6eaf71 100644 --- a/base/allocator/partition_allocator/partition_alloc_constants.h +++ b/base/allocator/partition_allocator/partition_alloc_constants.h
@@ -259,10 +259,8 @@ constexpr size_t kSuperPageOffsetMask = kSuperPageAlignment - 1; constexpr size_t kSuperPageBaseMask = ~kSuperPageOffsetMask; -// PartitionAlloc's address space is primarily split into two pools. -// See `glossary.md`. +// PartitionAlloc's address space is split into pools. See `glossary.md`. #if defined(PA_HAS_64_BITS_POINTERS) -// The 3rd, Configurable Pool is only available in 64-bit mode. constexpr size_t kNumPools = 3; // Maximum pool size. With exception of Configurable Pool, it is also // the actual size, unless PA_DYNAMICALLY_SELECT_POOL_SIZE is set, which
diff --git a/base/android/radio_utils.cc b/base/android/radio_utils.cc index 45fcb59..0e082eae 100644 --- a/base/android/radio_utils.cc +++ b/base/android/radio_utils.cc
@@ -11,18 +11,35 @@ namespace android { namespace { + +RadioUtils::OverrideForTesting* g_overrider_for_tests = nullptr; + bool InitializeIsSupported() { JNIEnv* env = AttachCurrentThread(); return Java_RadioUtils_isSupported(env); } } // namespace +RadioUtils::OverrideForTesting::OverrideForTesting() { + DCHECK(!g_overrider_for_tests); + g_overrider_for_tests = this; +} + +RadioUtils::OverrideForTesting::~OverrideForTesting() { + DCHECK(g_overrider_for_tests); + g_overrider_for_tests = nullptr; +} + bool RadioUtils::IsSupported() { static const bool kIsSupported = InitializeIsSupported(); return kIsSupported; } RadioConnectionType RadioUtils::GetConnectionType() { + if (g_overrider_for_tests) { + // If GetConnectionType is being used in tests + return g_overrider_for_tests->GetConnectionType(); + } if (!IsSupported()) return RadioConnectionType::kUnknown;
diff --git a/base/android/radio_utils.h b/base/android/radio_utils.h index 9360db08..959647c 100644 --- a/base/android/radio_utils.h +++ b/base/android/radio_utils.h
@@ -39,6 +39,20 @@ class BASE_EXPORT RadioUtils { public: + class OverrideForTesting { + public: + OverrideForTesting(); + ~OverrideForTesting(); + + void SetConnectionTypeForTesting(RadioConnectionType connection_type) { + connection_type_ = connection_type; + } + + RadioConnectionType GetConnectionType() { return connection_type_; } + + private: + RadioConnectionType connection_type_; + }; static bool IsSupported(); static RadioConnectionType GetConnectionType(); static absl::optional<RadioSignalLevel> GetCellSignalLevel();
diff --git a/base/android/radio_utils_unittest.cc b/base/android/radio_utils_unittest.cc new file mode 100644 index 0000000..e5dc3df --- /dev/null +++ b/base/android/radio_utils_unittest.cc
@@ -0,0 +1,26 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/android/radio_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { + +namespace android { + +TEST(RadioUtilsTest, ConnectionType) { + RadioUtils::OverrideForTesting radio_utils_test; + + radio_utils_test.SetConnectionTypeForTesting(RadioConnectionType::kUnknown); + EXPECT_EQ(RadioConnectionType::kUnknown, RadioUtils::GetConnectionType()); + + radio_utils_test.SetConnectionTypeForTesting(RadioConnectionType::kCell); + EXPECT_EQ(RadioConnectionType::kCell, RadioUtils::GetConnectionType()); + + radio_utils_test.SetConnectionTypeForTesting(RadioConnectionType::kWifi); + EXPECT_EQ(RadioConnectionType::kWifi, RadioUtils::GetConnectionType()); +} + +} // namespace android +} // namespace base \ No newline at end of file
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index 40464c1..4e581af8 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc
@@ -1059,7 +1059,12 @@ TestLauncher::~TestLauncher() { if (base::ThreadPoolInstance::Get()) { + // Clear the ThreadPoolInstance entirely to make it clear to final cleanup + // phases that they are happening in a single-threaded phase. Assertions in + // code like ~ScopedFeatureList are unhappy otherwise (crbug.com/1359095). base::ThreadPoolInstance::Get()->Shutdown(); + base::ThreadPoolInstance::Get()->JoinForTesting(); + base::ThreadPoolInstance::Set(nullptr); } }
diff --git a/base/trace_event/memory_infra_background_allowlist.cc b/base/trace_event/memory_infra_background_allowlist.cc index 3987bcc8..3dc4747f 100644 --- a/base/trace_event/memory_infra_background_allowlist.cc +++ b/base/trace_event/memory_infra_background_allowlist.cc
@@ -137,7 +137,7 @@ "gpu/gl/renderbuffers/context_group_0x?", "gpu/gl/textures/context_group_0x?", "gpu/gr_shader_cache/cache_0x?", - "gpu/shared_images/client_0x?", + "gpu/shared_images", "gpu/transfer_cache/cache_0x?", "gpu/transfer_cache/cache_0x?/avg_image_size", "history/delta_file_service/leveldb_0x?",
diff --git a/build/config/ios/swift_source_set.gni b/build/config/ios/swift_source_set.gni index 0f5cc07..825c2a1 100644 --- a/build/config/ios/swift_source_set.gni +++ b/build/config/ios/swift_source_set.gni
@@ -7,7 +7,19 @@ # with all "/" and ":" replaced with "_". template("swift_source_set") { _target_name = target_name - source_set(target_name) { + if (defined(invoker.bridge_header)) { + _header_name = _target_name + "_bridge_header" + source_set(_header_name) { + forward_variables_from(invoker, + [ + "deps", + "public_deps", + ]) + visibility = [ ":$_target_name" ] + sources = [ invoker.bridge_header ] + } + } + source_set(_target_name) { forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) if (!defined(module_name)) { @@ -18,8 +30,18 @@ module_name = string_replace(string_replace(_target_label, "/", "_"), ":", "_") } + + # Use an additional source_set target to allow `gn check` to check the + # dependencies needed for `bridge_header` are present. + if (defined(invoker.bridge_header)) { + if (!defined(public_deps)) { + public_deps = [] + } + public_deps += [ ":$_header_name" ] + } } } + set_defaults("swift_source_set") { configs = default_compiler_configs }
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni index 10fd90e..3a4e18a6 100644 --- a/buildtools/deps_revisions.gni +++ b/buildtools/deps_revisions.gni
@@ -5,5 +5,5 @@ declare_args() { # Used to cause full rebuilds on libc++ rolls. This should be kept in sync # with the libcxx_revision vars in //DEPS. - libcxx_revision = "2e919977e0030ce61bd19c40cefe31b995f1e2d4" + libcxx_revision = "7261e95e5175e95172404e84c43625dc61386470" }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index ba8edf5..8fc07cde 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -7160,6 +7160,9 @@ <message name="IDS_READ_ANYTHING_COLORS_COMBOBOX_LABEL" desc="Accessibility label for the colors combobox of the Read Anything feature." translateable="false"> Theme </message> + <message name="IDS_READ_ANYTHING_LINE_SPACING_COMBOBOX_LABEL" desc="Accessibility label for the line height combobox of the Read Anything feature." translateable="false"> + Line height + </message> <message name="IDS_READ_ANYTHING_LETTER_SPACING_COMBOBOX_LABEL" desc="Accessibility label for the letter spacing combobox of the Read Anything feature." translateable="false"> Letter spacing </message>
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn index 294fcf2..288b8fb4 100644 --- a/chrome/app/vector_icons/BUILD.gn +++ b/chrome/app/vector_icons/BUILD.gn
@@ -77,6 +77,7 @@ "laptop_and_smartphone.icon", "leading_scroll.icon", "letter_spacing.icon", + "line_spacing.icon", "media_controls_arrow_drop_down.icon", "media_controls_arrow_drop_up.icon", "media_toolbar_button.icon",
diff --git a/chrome/app/vector_icons/line_spacing.icon b/chrome/app/vector_icons/line_spacing.icon new file mode 100644 index 0000000..cf02fd9 --- /dev/null +++ b/chrome/app/vector_icons/line_spacing.icon
@@ -0,0 +1,36 @@ +// Copyright 2022 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. + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 3, 0, +LINE_TO, 0, 3, +R_H_LINE_TO, 2, +R_V_LINE_TO, 8, +H_LINE_TO, 0, +R_LINE_TO, 3, 3, +R_LINE_TO, 3, -3, +H_LINE_TO, 4, +V_LINE_TO, 3, +R_H_LINE_TO, 2, +LINE_TO, 3, 0, +CLOSE, +R_MOVE_TO, 4, 2, +R_H_LINE_TO, 9, +R_V_LINE_TO, 2, +H_LINE_TO, 7, +V_LINE_TO, 2, +CLOSE, +R_MOVE_TO, 2, 4, +H_LINE_TO, 7, +R_V_LINE_TO, 2, +R_H_LINE_TO, 9, +V_LINE_TO, 6, +H_LINE_TO, 9, +CLOSE, +R_MOVE_TO, -2, 4, +R_H_LINE_TO, 9, +R_V_LINE_TO, 2, +H_LINE_TO, 7, +R_V_LINE_TO, -2, +CLOSE \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 9b06cb8..31012e4 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -7668,6 +7668,8 @@ "supervised_user/child_accounts/kids_management_api.h", "supervised_user/child_accounts/permission_request_creator_apiary.cc", "supervised_user/child_accounts/permission_request_creator_apiary.h", + "supervised_user/kids_chrome_management/kids_access_token_fetcher.cc", + "supervised_user/kids_chrome_management/kids_access_token_fetcher.h", "supervised_user/kids_chrome_management/kids_chrome_management_client.cc", "supervised_user/kids_chrome_management/kids_chrome_management_client.h", "supervised_user/kids_chrome_management/kids_chrome_management_client_factory.cc",
diff --git a/chrome/browser/apps/app_service/metrics/website_metrics.cc b/chrome/browser/apps/app_service/metrics/website_metrics.cc index 377811a..6b11934 100644 --- a/chrome/browser/apps/app_service/metrics/website_metrics.cc +++ b/chrome/browser/apps/app_service/metrics/website_metrics.cc
@@ -8,6 +8,7 @@ #include "ash/shell.h" #include "base/containers/contains.h" +#include "base/debug/dump_without_crashing.h" #include "base/json/values_util.h" #include "base/rand_util.h" #include "chrome/browser/apps/app_service/metrics/app_platform_metrics_utils.h" @@ -399,6 +400,11 @@ // contents::WebContentsObserver::PrimaryPageChanged(), set the visible url as // default value for the ukm key url. webcontents_to_ukm_key_[web_contents] = web_contents->GetVisibleURL(); + + if (web_contents->GetVisibleURL().is_empty()) { + return; + } + auto it = window_to_web_contents_.find(window); bool is_activated = wm::IsActiveWindow(window) && it != window_to_web_contents_.end() && @@ -590,6 +596,15 @@ bool is_from_last_login) { auto source_id = ukm::UkmRecorder::GetSourceIdForWebsiteUrl( base::PassKey<WebsiteMetrics>(), url); + if (url.is_empty() || ukm::SourceIdObj::FromInt64(source_id).GetType() != + ukm::SourceIdType::DESKTOP_WEB_APP_ID) { + LOG(ERROR) << "WebsiteMetrics::EmitUkm url is " << url.spec() + << ", source id type is " + << (int)ukm::SourceIdObj::FromInt64(source_id).GetType(); + base::debug::DumpWithoutCrashing(); + return; + } + if (source_id != ukm::kInvalidSourceId) { ukm::builders::ChromeOS_WebsiteUsageTime builder(source_id); builder.SetDuration(usage_time)
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn index dc0f4ef0..dce017d 100644 --- a/chrome/browser/ash/BUILD.gn +++ b/chrome/browser/ash/BUILD.gn
@@ -1974,6 +1974,8 @@ "os_feedback/os_feedback_screenshot_manager.h", "ownership/fake_owner_settings_service.cc", "ownership/fake_owner_settings_service.h", + "ownership/owner_key_loader.cc", + "ownership/owner_key_loader.h", "ownership/owner_settings_service_ash.cc", "ownership/owner_settings_service_ash.h", "ownership/owner_settings_service_ash_factory.cc",
diff --git a/chrome/browser/ash/app_mode/arc/arc_kiosk_app_service.cc b/chrome/browser/ash/app_mode/arc/arc_kiosk_app_service.cc index 02c772e..a564671c 100644 --- a/chrome/browser/ash/app_mode/arc/arc_kiosk_app_service.cc +++ b/chrome/browser/ash/app_mode/arc/arc_kiosk_app_service.cc
@@ -159,7 +159,7 @@ return; } - for (const auto& detail : details->GetListDeprecated()) { + for (const auto& detail : details->GetList()) { const base::Value* const reason = detail.FindKeyOfType("nonComplianceReason", base::Value::Type::INTEGER); if (!reason || reason->GetInt() != kNonComplianceReasonAppNotInstalled)
diff --git a/chrome/browser/ash/app_restore/arc_ghost_window_delegate.cc b/chrome/browser/ash/app_restore/arc_ghost_window_delegate.cc index f9ece6f..3171082 100644 --- a/chrome/browser/ash/app_restore/arc_ghost_window_delegate.cc +++ b/chrome/browser/ash/app_restore/arc_ghost_window_delegate.cc
@@ -4,9 +4,7 @@ #include "chrome/browser/ash/app_restore/arc_ghost_window_delegate.h" -#include "chrome/browser/ash/app_restore/arc_ghost_window_shell_surface.h" #include "chrome/browser/ash/app_restore/arc_window_utils.h" -#include "chrome/browser/ash/arc/window_predictor/window_predictor_utils.h" #include "ui/display/display.h" #include "ui/display/screen.h" @@ -19,12 +17,10 @@ ArcGhostWindowDelegate::ArcGhostWindowDelegate( exo::ClientControlledShellSurface* shell_surface, int window_id, - const std::string& app_id, int64_t display_id, const gfx::Rect& bounds, chromeos::WindowStateType window_state) : window_id_(window_id), - app_id_(app_id), bounds_(gfx::Rect(bounds)), pending_close_(false), window_state_(window_state), @@ -149,20 +145,6 @@ UpdateWindowInfoToArc(); } -void ArcGhostWindowDelegate::OnAppStatesUpdate(const std::string& app_id, - bool ready, - bool need_fixup) { - if (app_id != app_id_) - return; - - // Currently the type update is oneway. If an App need fixup, is not able to - // become another state before it's ready. - if (need_fixup) { - static_cast<ArcGhostWindowShellSurface*>(shell_surface_) - ->SetWindowType(arc::GhostWindowType::kFixup); - } -} - bool ArcGhostWindowDelegate::SetDisplayId(int64_t display_id) { absl::optional<double> scale_factor = GetDisplayScaleFactor(display_id); if (!scale_factor.has_value()) {
diff --git a/chrome/browser/ash/app_restore/arc_ghost_window_delegate.h b/chrome/browser/ash/app_restore/arc_ghost_window_delegate.h index 40e9c64..1351f29 100644 --- a/chrome/browser/ash/app_restore/arc_ghost_window_delegate.h +++ b/chrome/browser/ash/app_restore/arc_ghost_window_delegate.h
@@ -21,7 +21,6 @@ public: ArcGhostWindowDelegate(exo::ClientControlledShellSurface* shell_surface, int window_id, - const std::string& app_id, int64_t display_id, const gfx::Rect& bounds, chromeos::WindowStateType window_state); @@ -51,16 +50,11 @@ void OnWindowCloseRequested(int window_id) override; - void OnAppStatesUpdate(const std::string& app_id, - bool ready, - bool need_fixup) override; - private: bool SetDisplayId(int64_t display_id); void UpdateWindowInfoToArc(); int window_id_; - std::string app_id_; gfx::Rect bounds_; bool pending_close_; int64_t display_id_;
diff --git a/chrome/browser/ash/app_restore/arc_ghost_window_handler.cc b/chrome/browser/ash/app_restore/arc_ghost_window_handler.cc index 2600dfe..a09086d 100644 --- a/chrome/browser/ash/app_restore/arc_ghost_window_handler.cc +++ b/chrome/browser/ash/app_restore/arc_ghost_window_handler.cc
@@ -128,18 +128,6 @@ return true; } -bool ArcGhostWindowHandler::UpdateArcGhostWindowType( - int32_t session_id, - arc::GhostWindowType window_type) { - auto it = session_id_to_shell_surface_.find(session_id); - if (it == session_id_to_shell_surface_.end()) - return false; - auto* shell_surface = - static_cast<ArcGhostWindowShellSurface*>(it->second.get()); - shell_surface->SetWindowType(window_type); - return true; -} - void ArcGhostWindowHandler::CloseWindow(int session_id) { auto it = session_id_to_shell_surface_.find(session_id); if (it == session_id_to_shell_surface_.end())
diff --git a/chrome/browser/ash/app_restore/arc_ghost_window_handler.h b/chrome/browser/ash/app_restore/arc_ghost_window_handler.h index d40ff77..a8cd7b0e 100644 --- a/chrome/browser/ash/app_restore/arc_ghost_window_handler.h +++ b/chrome/browser/ash/app_restore/arc_ghost_window_handler.h
@@ -16,10 +16,6 @@ struct AppRestoreData; } // namespace app_restore -namespace arc { -enum class GhostWindowType; -} // namespace arc - namespace ash::full_restore { // The ArcGhostWindowHandler class provides control for ARC ghost window. @@ -81,9 +77,6 @@ int32_t session_id, ::app_restore::AppRestoreData* restore_data); - bool UpdateArcGhostWindowType(int32_t session_id, - arc::GhostWindowType window_type); - void CloseWindow(int session_id); void AddObserver(Observer* observer);
diff --git a/chrome/browser/ash/app_restore/arc_ghost_window_shell_surface.cc b/chrome/browser/ash/app_restore/arc_ghost_window_shell_surface.cc index ea0d1d0..b755aeb 100644 --- a/chrome/browser/ash/app_restore/arc_ghost_window_shell_surface.cc +++ b/chrome/browser/ash/app_restore/arc_ghost_window_shell_surface.cc
@@ -121,7 +121,7 @@ // TODO(sstan): Add set_surface_destroyed_callback. shell_surface->set_delegate(std::make_unique<ArcGhostWindowDelegate>( - shell_surface.get(), window_id, app_id, display_id_value, local_bounds, + shell_surface.get(), window_id, display_id_value, local_bounds, window_state.value_or(chromeos::WindowStateType::kDefault))); shell_surface->set_close_callback(std::move(close_callback)); @@ -186,7 +186,6 @@ uint32_t theme_color) { auto view = std::make_unique<ArcGhostWindowView>(type_, kDiameter, theme_color); - view_observer_ = view.get(); view->LoadIcon(app_id); exo::ShellSurfaceBase::OverlayParams overlay_params(std::move(view)); overlay_params.translucent = true; @@ -211,10 +210,4 @@ property_handler->ClearProperty(app_restore::kAppIdKey); } -void ArcGhostWindowShellSurface::SetWindowType( - arc::GhostWindowType window_type) { - DCHECK(view_observer_); - view_observer_->SetType(window_type); -} - } // namespace ash::full_restore
diff --git a/chrome/browser/ash/app_restore/arc_ghost_window_shell_surface.h b/chrome/browser/ash/app_restore/arc_ghost_window_shell_surface.h index 088ce44..5256629 100644 --- a/chrome/browser/ash/app_restore/arc_ghost_window_shell_surface.h +++ b/chrome/browser/ash/app_restore/arc_ghost_window_shell_surface.h
@@ -23,8 +23,6 @@ // Explicitly identifies ARC ghost surface. extern const aura::WindowProperty<bool>* const kArcGhostSurface; -class ArcGhostWindowView; - // ArcGhostWindowShellSurface class is a shell surface which controlled its // root surface. class ArcGhostWindowShellSurface : public exo::ClientControlledShellSurface { @@ -44,8 +42,6 @@ void OverrideInitParams(views::Widget::InitParams* params) override; - void SetWindowType(arc::GhostWindowType window_type); - exo::Surface* controller_surface(); private: @@ -60,7 +56,6 @@ void SetShellAppId(ui::PropertyHandler* property_handler, const absl::optional<std::string>& id); - ArcGhostWindowView* view_observer_ = nullptr; arc::GhostWindowType type_; absl::optional<std::string> app_id_;
diff --git a/chrome/browser/ash/app_restore/arc_ghost_window_view.cc b/chrome/browser/ash/app_restore/arc_ghost_window_view.cc index 87ac436..dd79b12 100644 --- a/chrome/browser/ash/app_restore/arc_ghost_window_view.cc +++ b/chrome/browser/ash/app_restore/arc_ghost_window_view.cc
@@ -92,7 +92,14 @@ throbber->SetPreferredSize(gfx::Size(diameter, diameter)); throbber->GetViewAccessibility().OverrideRole(ax::mojom::Role::kImage); - SetType(type); + if (type == arc::GhostWindowType::kFixup) { + auto label = std::make_unique<views::Label>( + l10n_util::GetStringUTF16(IDS_ARC_GHOST_WINDOW_APP_FIXUP_MESSAGE)); + // TODO(sstan): Set font size or height, according to future UI update. + label->SetMultiLine(true); + message_label_ = label.get(); + AddChildView(std::move(label)); + } // TODO(sstan): Set window title and accessible name from saved data. } @@ -114,28 +121,6 @@ : std::move(icon_loaded_cb_for_testing_)); } -void ArcGhostWindowView::SetType(arc::GhostWindowType type) { - // Currently the only difference of App Fixup and other type of ghost window - // is that App Fixup ghost window has a message label. - if (type == arc::GhostWindowType::kFixup) { - if (!message_label_) { - auto label = std::make_unique<views::Label>( - l10n_util::GetStringUTF16(IDS_ARC_GHOST_WINDOW_APP_FIXUP_MESSAGE)); - // TODO(sstan): Set font size or height, according to future UI update. - label->SetMultiLine(true); - message_label_ = label.get(); - AddChildView(std::move(label)); - Layout(); - } - } else { - if (message_label_) { - RemoveChildView(message_label_); - message_label_ = nullptr; - Layout(); - } - } -} - void ArcGhostWindowView::OnIconLoaded(apps::IconValuePtr icon_value) { if (!icon_value || icon_value->icon_type != apps::IconType::kStandard) return;
diff --git a/chrome/browser/ash/app_restore/arc_ghost_window_view.h b/chrome/browser/ash/app_restore/arc_ghost_window_view.h index 7146aef..8e80eca 100644 --- a/chrome/browser/ash/app_restore/arc_ghost_window_view.h +++ b/chrome/browser/ash/app_restore/arc_ghost_window_view.h
@@ -38,20 +38,17 @@ void LoadIcon(const std::string& app_id); - void SetType(arc::GhostWindowType type); - private: FRIEND_TEST_ALL_PREFIXES(ArcGhostWindowViewTest, IconLoadTest); FRIEND_TEST_ALL_PREFIXES(ArcGhostWindowViewTest, FixupMessageTest); - FRIEND_TEST_ALL_PREFIXES(ArcGhostWindowViewTest, SetTypeTest); void InitLayout(arc::GhostWindowType type, uint32_t theme_color, int diameter); void OnIconLoaded(apps::IconValuePtr icon_value); - views::ImageView* icon_view_ = nullptr; - views::Label* message_label_ = nullptr; + views::ImageView* icon_view_; + views::Label* message_label_; base::OnceCallback<void(apps::IconValuePtr icon_value)> icon_loaded_cb_for_testing_;
diff --git a/chrome/browser/ash/app_restore/arc_ghost_window_view_unittest.cc b/chrome/browser/ash/app_restore/arc_ghost_window_view_unittest.cc index 40bb8f2..f8ad42c 100644 --- a/chrome/browser/ash/app_restore/arc_ghost_window_view_unittest.cc +++ b/chrome/browser/ash/app_restore/arc_ghost_window_view_unittest.cc
@@ -143,20 +143,4 @@ l10n_util::GetStringUTF16(IDS_ARC_GHOST_WINDOW_APP_FIXUP_MESSAGE)); } -TEST_F(ArcGhostWindowViewTest, SetTypeTest) { - const int kDiameter = 24; - const uint32_t kThemeColor = SK_ColorWHITE; - const std::string kAppId = "test_app"; - InstallApp(kAppId); - - CreateView(arc::GhostWindowType::kFullRestore, kDiameter, kThemeColor); - EXPECT_EQ(view()->message_label_, nullptr); - - view()->SetType(arc::GhostWindowType::kFixup); - EXPECT_NE(view()->message_label_, nullptr); - - view()->SetType(arc::GhostWindowType::kAppLaunch); - EXPECT_EQ(view()->message_label_, nullptr); -} - } // namespace ash::full_restore
diff --git a/chrome/browser/ash/cert_provisioning/cert_provisioning_scheduler.cc b/chrome/browser/ash/cert_provisioning/cert_provisioning_scheduler.cc index 4d15c67..a5c2bd3 100644 --- a/chrome/browser/ash/cert_provisioning/cert_provisioning_scheduler.cc +++ b/chrome/browser/ash/cert_provisioning/cert_provisioning_scheduler.cc
@@ -552,7 +552,7 @@ const base::Value& profile_list = pref_service_->GetValue(pref_name_); - for (const base::Value& cur_profile : profile_list.GetListDeprecated()) { + for (const base::Value& cur_profile : profile_list.GetList()) { const CertProfileId* id = cur_profile.FindStringKey(kCertProfileIdKey); if (!id || (*id != cert_profile_id)) { continue; @@ -570,7 +570,7 @@ const base::Value& profile_list = pref_service_->GetValue(pref_name_); std::vector<CertProfile> result_profiles; - for (const base::Value& cur_profile : profile_list.GetListDeprecated()) { + for (const base::Value& cur_profile : profile_list.GetList()) { absl::optional<CertProfile> p = CertProfile::MakeFromValue(cur_profile); if (!p) { LOG(WARNING) << "Failed to parse certificate profile";
diff --git a/chrome/browser/ash/file_manager/app_service_file_tasks.cc b/chrome/browser/ash/file_manager/app_service_file_tasks.cc index 4fd04aa1..62bf1d00 100644 --- a/chrome/browser/ash/file_manager/app_service_file_tasks.cc +++ b/chrome/browser/ash/file_manager/app_service_file_tasks.cc
@@ -51,8 +51,7 @@ #include "storage/browser/file_system/file_system_url.h" #include "url/gurl.h" -namespace file_manager { -namespace file_tasks { +namespace file_manager::file_tasks { extensions::api::file_manager_private::TaskResult ConvertLaunchResultToTaskResult(const apps::LaunchResult& result, @@ -76,7 +75,9 @@ } using extensions::api::file_manager_private::Verb; + namespace { + TaskType GetTaskType(apps::AppType app_type) { switch (app_type) { case apps::AppType::kArc: @@ -387,5 +388,4 @@ } } -} // namespace file_tasks -} // namespace file_manager +} // namespace file_manager::file_tasks
diff --git a/chrome/browser/ash/file_manager/app_service_file_tasks.h b/chrome/browser/ash/file_manager/app_service_file_tasks.h index 410a07c..ac4d2f4 100644 --- a/chrome/browser/ash/file_manager/app_service_file_tasks.h +++ b/chrome/browser/ash/file_manager/app_service_file_tasks.h
@@ -21,8 +21,7 @@ class FileSystemURL; } -namespace file_manager { -namespace file_tasks { +namespace file_manager::file_tasks { // Returns true if a file handler is enabled. Some handlers such as // import-crostini-image can be disabled at runtime by enterprise policy. @@ -51,7 +50,6 @@ const std::vector<std::string>& mime_types, FileTaskFinishedCallback done); -} // namespace file_tasks -} // namespace file_manager +} // namespace file_manager::file_tasks #endif // CHROME_BROWSER_ASH_FILE_MANAGER_APP_SERVICE_FILE_TASKS_H_
diff --git a/chrome/browser/ash/file_manager/arc_file_tasks.cc b/chrome/browser/ash/file_manager/arc_file_tasks.cc index 78e8d0e..33de8fcc 100644 --- a/chrome/browser/ash/file_manager/arc_file_tasks.cc +++ b/chrome/browser/ash/file_manager/arc_file_tasks.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/ash/arc/arc_util.h" #include "chrome/browser/ash/arc/fileapi/arc_content_file_system_url_util.h" #include "chrome/browser/ash/file_manager/app_id.h" +#include "chrome/browser/ash/file_manager/file_tasks.h" #include "chrome/browser/ash/file_manager/fileapi_util.h" #include "chrome/browser/ash/file_manager/path_util.h" #include "chrome/browser/ash/profiles/profile_helper.h" @@ -114,31 +115,29 @@ } // Below is the sequence of thread-hopping for loading ARC file tasks. -void OnArcHandlerList( - Profile* profile, - std::unique_ptr<std::vector<FullTaskDescriptor>> result_list, - FindTasksCallback callback, - std::vector<arc::mojom::IntentHandlerInfoPtr> handlers); +void OnArcHandlerList(Profile* profile, + std::unique_ptr<ResultingTasks> resulting_tasks, + FindTasksCallback callback, + std::vector<arc::mojom::IntentHandlerInfoPtr> handlers); void OnArcIconLoaded( - std::unique_ptr<std::vector<FullTaskDescriptor>> result_list, + std::unique_ptr<ResultingTasks> resulting_tasks, FindTasksCallback callback, std::vector<arc::mojom::IntentHandlerInfoPtr> handlers, std::unique_ptr<arc::ArcIntentHelperBridge::ActivityToIconsMap> icons); // Called after the handlers from ARC is obtained. Proceeds to OnArcIconLoaded. -void OnArcHandlerList( - Profile* profile, - std::unique_ptr<std::vector<FullTaskDescriptor>> result_list, - FindTasksCallback callback, - std::vector<arc::mojom::IntentHandlerInfoPtr> handlers) { +void OnArcHandlerList(Profile* profile, + std::unique_ptr<ResultingTasks> resulting_tasks, + FindTasksCallback callback, + std::vector<arc::mojom::IntentHandlerInfoPtr> handlers) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); auto* intent_helper_bridge = arc::ArcIntentHelperBridge::GetForBrowserContext(profile); if (!intent_helper_bridge) { LOG(ERROR) << "Failed to get ArcIntentHelperBridge"; - std::move(callback).Run(std::move(result_list)); + std::move(callback).Run(std::move(resulting_tasks)); return; } @@ -150,13 +149,13 @@ intent_helper_bridge->GetActivityIcons( activity_names, - base::BindOnce(&OnArcIconLoaded, std::move(result_list), + base::BindOnce(&OnArcIconLoaded, std::move(resulting_tasks), std::move(callback), std::move(handlers_filtered))); } // Called after icon data for ARC apps are loaded. Proceeds to OnArcIconEncoded. void OnArcIconLoaded( - std::unique_ptr<std::vector<FullTaskDescriptor>> result_list, + std::unique_ptr<ResultingTasks> resulting_tasks, FindTasksCallback callback, std::vector<arc::mojom::IntentHandlerInfoPtr> handlers, std::unique_ptr<arc::ArcIntentHelperBridge::ActivityToIconsMap> icons) { @@ -179,15 +178,15 @@ const GURL& icon_url = (it == icons->end() ? GURL::EmptyGURL() : it->second.icon16_dataurl->data); - result_list->push_back(FullTaskDescriptor( + resulting_tasks->tasks.emplace_back( TaskDescriptor( ActivityNameToAppId(handler->package_name, handler->activity_name), TASK_TYPE_ARC_APP, ArcActionToFileTaskActionId(action)), name, handler_verb, icon_url, false /* is_default */, action != arc::kIntentActionView /* is_generic */, - false /* is_file_extension_match */)); + false /* is_file_extension_match */); } - std::move(callback).Run(std::move(result_list)); + std::move(callback).Run(std::move(resulting_tasks)); } // |ignore_paths_to_share| contains the paths to be shared to @@ -196,7 +195,7 @@ void FindArcTasksAfterContentUrlsResolved( Profile* profile, const std::vector<extensions::EntryInfo>& entries, - std::unique_ptr<std::vector<FullTaskDescriptor>> result_list, + std::unique_ptr<ResultingTasks> resulting_tasks, FindTasksCallback callback, const std::vector<GURL>& content_urls, const std::vector<base::FilePath>& ignore_paths_to_share) { @@ -217,7 +216,7 @@ } if (!arc_intent_helper) { LOG(ERROR) << "Failed to get arc_intent_helper"; - std::move(callback).Run(std::move(result_list)); + std::move(callback).Run(std::move(resulting_tasks)); return; } @@ -227,12 +226,12 @@ const GURL& content_url = content_urls[i]; if (entry.is_directory) { // ARC apps don't support directories. - std::move(callback).Run(std::move(result_list)); + std::move(callback).Run(std::move(resulting_tasks)); return; } if (!content_url.is_valid()) { - std::move(callback).Run(std::move(result_list)); + std::move(callback).Run(std::move(resulting_tasks)); return; } @@ -246,7 +245,7 @@ arc_intent_helper->RequestUrlListHandlerList( std::move(urls), base::BindOnce(&OnArcHandlerList, base::Unretained(profile), - std::move(result_list), std::move(callback))); + std::move(resulting_tasks), std::move(callback))); } void ExecuteArcTaskAfterContentUrlsResolved( @@ -258,11 +257,11 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_EQ(content_urls.size(), mime_types.size()); - for (size_t i = 0; i < content_urls.size(); ++i) { - if (!content_urls[i].is_valid()) { + for (const GURL& content_url : content_urls) { + if (!content_url.is_valid()) { std::move(done).Run( extensions::api::file_manager_private::TASK_RESULT_FAILED, - "Invalid url: " + content_urls[i].possibly_invalid_spec()); + "Invalid url: " + content_url.possibly_invalid_spec()); return; } } @@ -312,7 +311,7 @@ void FindArcTasks(Profile* profile, const std::vector<extensions::EntryInfo>& entries, const std::vector<GURL>& file_urls, - std::unique_ptr<std::vector<FullTaskDescriptor>> result_list, + std::unique_ptr<ResultingTasks> resulting_tasks, FindTasksCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_EQ(entries.size(), file_urls.size()); @@ -331,8 +330,8 @@ file_manager::util::ConvertToContentUrls( ProfileManager::GetPrimaryUserProfile(), file_system_urls, base::BindOnce(&FindArcTasksAfterContentUrlsResolved, - base::Unretained(profile), entries, std::move(result_list), - std::move(callback))); + base::Unretained(profile), entries, + std::move(resulting_tasks), std::move(callback))); } void ExecuteArcTask(Profile* profile,
diff --git a/chrome/browser/ash/file_manager/arc_file_tasks.h b/chrome/browser/ash/file_manager/arc_file_tasks.h index 0507bc86..f0aedfd 100644 --- a/chrome/browser/ash/file_manager/arc_file_tasks.h +++ b/chrome/browser/ash/file_manager/arc_file_tasks.h
@@ -21,15 +21,14 @@ class FileSystemURL; } -namespace file_manager { -namespace file_tasks { +namespace file_manager::file_tasks { -// Finds the ARC tasks that can handle |entries|, appends them to |result_list|, -// and calls back to |callback|. +// Finds the ARC tasks that can handle |entries|, appends them to +// |resulting_tasks|, and calls back to |callback|. void FindArcTasks(Profile* profile, const std::vector<extensions::EntryInfo>& entries, const std::vector<GURL>& file_urls, - std::unique_ptr<std::vector<FullTaskDescriptor>> result_list, + std::unique_ptr<ResultingTasks> resulting_tasks, FindTasksCallback callback); // Executes the specified task by ARC. @@ -39,7 +38,6 @@ const std::vector<std::string>& mime_types, FileTaskFinishedCallback done); -} // namespace file_tasks -} // namespace file_manager +} // namespace file_manager::file_tasks #endif // CHROME_BROWSER_ASH_FILE_MANAGER_ARC_FILE_TASKS_H_
diff --git a/chrome/browser/ash/file_manager/file_manager_test_util.cc b/chrome/browser/ash/file_manager/file_manager_test_util.cc index 15dd050..4578d7966 100644 --- a/chrome/browser/ash/file_manager/file_manager_test_util.cc +++ b/chrome/browser/ash/file_manager/file_manager_test_util.cc
@@ -11,6 +11,7 @@ #include "base/test/bind.h" #include "chrome/browser/apps/app_service/app_service_proxy_ash.h" #include "chrome/browser/ash/file_manager/app_id.h" +#include "chrome/browser/ash/file_manager/file_tasks.h" #include "chrome/browser/ash/file_manager/path_util.h" #include "chrome/browser/ash/file_manager/volume_manager_observer.h" #include "chrome/browser/ash/profiles/profile_helper.h" @@ -192,8 +193,8 @@ std::vector<file_tasks::FullTaskDescriptor> result; bool invoked_synchronously = false; auto callback = base::BindLambdaForTesting( - [&](std::unique_ptr<std::vector<file_tasks::FullTaskDescriptor>> tasks) { - result = *tasks; + [&](std::unique_ptr<file_tasks::ResultingTasks> resulting_tasks) { + result = std::move(resulting_tasks->tasks); invoked_synchronously = true; });
diff --git a/chrome/browser/ash/file_manager/file_tasks.cc b/chrome/browser/ash/file_manager/file_tasks.cc index 890b32f3..1515da0 100644 --- a/chrome/browser/ash/file_manager/file_tasks.cc +++ b/chrome/browser/ash/file_manager/file_tasks.cc
@@ -19,6 +19,7 @@ #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" +#include "base/notreached.h" #include "base/ranges/algorithm.h" #include "base/strings/strcat.h" #include "base/strings/string_split.h" @@ -66,6 +67,7 @@ #include "components/prefs/scoped_user_pref_update.h" #include "components/services/app_service/public/cpp/app_launch_util.h" #include "components/services/app_service/public/cpp/app_types.h" +#include "components/services/app_service/public/cpp/app_update.h" #include "components/services/app_service/public/cpp/file_handler.h" #include "components/services/app_service/public/cpp/file_handler_info.h" #include "components/services/app_service/public/mojom/types.mojom.h" @@ -323,16 +325,15 @@ } } -void PostProcessFoundTasks( - Profile* profile, - const std::vector<extensions::EntryInfo>& entries, - FindTasksCallback callback, - std::unique_ptr<std::vector<FullTaskDescriptor>> result_list) { - AdjustTasksForMediaApp(entries, result_list.get()); +void PostProcessFoundTasks(Profile* profile, + const std::vector<extensions::EntryInfo>& entries, + FindTasksCallback callback, + std::unique_ptr<ResultingTasks> resulting_tasks) { + AdjustTasksForMediaApp(entries, &resulting_tasks->tasks); // Google documents can only be handled by internal handlers. if (ContainsGoogleDocument(entries)) - KeepOnlyFileManagerInternalTasks(result_list.get()); + KeepOnlyFileManagerInternalTasks(&resulting_tasks->tasks); std::set<std::string> disabled_actions; @@ -346,14 +347,15 @@ disabled_actions.emplace(kActionIdWebDriveOfficePowerPoint); } else { // Hide the office PWA File Handler. - RemoveActionsForApp(extension_misc::kOfficePwaAppId, result_list.get()); + RemoveActionsForApp(extension_misc::kOfficePwaAppId, + &resulting_tasks->tasks); // Hack around the fact that App Service will only return one task for each // app. We want both tasks to be available, so add the office task if the // WebDrive task is available. // TODO(petermarshall): Find a better way to enable both tasks. - auto it = - base::ranges::find_if(*result_list, [](const FullTaskDescriptor& task) { + auto it = base::ranges::find_if( + resulting_tasks->tasks, [](const FullTaskDescriptor& task) { if (!IsFilesAppId(task.task_descriptor.app_id)) { return false; } @@ -363,19 +365,19 @@ action_id == kActionIdWebDriveOfficeExcel || action_id == kActionIdWebDriveOfficePowerPoint; }); - if (it != result_list->end()) { + if (it != resulting_tasks->tasks.end()) { FullTaskDescriptor office_task(*it); office_task.task_descriptor.action_id = base::StrCat({kChromeUIFileManagerURL, "?", kActionIdOpenInOffice}); - result_list->push_back(office_task); + resulting_tasks->tasks.push_back(office_task); } } if (!disabled_actions.empty()) - RemoveFileManagerInternalActions(disabled_actions, result_list.get()); + RemoveFileManagerInternalActions(disabled_actions, &resulting_tasks->tasks); - ChooseAndSetDefaultTask(profile, entries, result_list.get()); - std::move(callback).Run(std::move(result_list)); + ChooseAndSetDefaultTask(profile, entries, resulting_tasks.get()); + std::move(callback).Run(std::move(resulting_tasks)); } // Returns true if |extension_id| and |action_id| indicate that the file @@ -560,6 +562,9 @@ } // namespace +ResultingTasks::ResultingTasks() = default; +ResultingTasks::~ResultingTasks() = default; + void RegisterProfilePrefs(PrefRegistrySimple* registry) { registry->RegisterDictionaryPref(prefs::kDefaultHandlersForFileExtensions); } @@ -952,23 +957,23 @@ return result; } -void FindExtensionAndAppTasks( - Profile* profile, - const std::vector<extensions::EntryInfo>& entries, - const std::vector<GURL>& file_urls, - FindTasksCallback callback, - std::unique_ptr<std::vector<FullTaskDescriptor>> result_list) { - std::vector<FullTaskDescriptor>* result_list_ptr = result_list.get(); +void FindExtensionAndAppTasks(Profile* profile, + const std::vector<extensions::EntryInfo>& entries, + const std::vector<GURL>& file_urls, + FindTasksCallback callback, + std::unique_ptr<ResultingTasks> resulting_tasks) { + auto* tasks = &resulting_tasks->tasks; // 2. Web tasks file_handlers (View/Open With), Chrome app file_handlers, and // extension file_browser_handlers. - FindAppServiceTasks(profile, entries, file_urls, result_list_ptr); + FindAppServiceTasks(profile, entries, file_urls, tasks); // 3. Find and append Guest OS tasks. - FindGuestOsTasks(profile, entries, file_urls, result_list_ptr, - // Done. Apply post-filtering and callback. - base::BindOnce(PostProcessFoundTasks, profile, entries, - std::move(callback), std::move(result_list))); + FindGuestOsTasks( + profile, entries, file_urls, tasks, + // Done. Apply post-filtering and callback. + base::BindOnce(PostProcessFoundTasks, profile, entries, + std::move(callback), std::move(resulting_tasks))); } void FindAllTypesOfTasks(Profile* profile, @@ -976,18 +981,17 @@ const std::vector<GURL>& file_urls, FindTasksCallback callback) { DCHECK(profile); - std::unique_ptr<std::vector<FullTaskDescriptor>> result_list( - new std::vector<FullTaskDescriptor>); + auto resulting_tasks = std::make_unique<ResultingTasks>(); if (ash::features::ShouldArcAndGuestOsFileTasksUseAppService()) { // Skip FindArcTasks and FindGuestOsTasks since these tasks are now found in // App Service. - FindAppServiceTasks(profile, entries, file_urls, result_list.get()); + FindAppServiceTasks(profile, entries, file_urls, &resulting_tasks->tasks); PostProcessFoundTasks(profile, entries, std::move(callback), - std::move(result_list)); + std::move(resulting_tasks)); } else { // 1. Find and append ARC handler tasks. - FindArcTasks(profile, entries, file_urls, std::move(result_list), + FindArcTasks(profile, entries, file_urls, std::move(resulting_tasks), base::BindOnce(&FindExtensionAndAppTasks, profile, entries, file_urls, std::move(callback))); } @@ -995,9 +999,9 @@ void ChooseAndSetDefaultTask(Profile* profile, const std::vector<extensions::EntryInfo>& entries, - std::vector<FullTaskDescriptor>* tasks) { + ResultingTasks* resulting_tasks) { // Collect the default tasks from the preferences into a set. - std::set<TaskDescriptor> default_tasks; + base::flat_set<TaskDescriptor> default_tasks; for (const extensions::EntryInfo& entry : entries) { const base::FilePath& file_path = entry.path; const std::string& mime_type = entry.mime_type; @@ -1041,9 +1045,11 @@ } } + auto& tasks = resulting_tasks->tasks; + // Go through all the tasks from the beginning and see if there is any // default task. If found, pick and set it as default and return. - for (FullTaskDescriptor& task : *tasks) { + for (FullTaskDescriptor& task : tasks) { DCHECK(!task.is_default); if (base::Contains(default_tasks, task.task_descriptor)) { task.is_default = true; @@ -1053,7 +1059,7 @@ // No default task. If the "Open in Docs/Sheets/Slides through Drive" workflow // is available for Office files, set as default. - for (FullTaskDescriptor& task : *tasks) { + for (FullTaskDescriptor& task : tasks) { if (IsWebDriveOfficeTask(task.task_descriptor)) { task.is_default = true; return; @@ -1063,7 +1069,7 @@ // Check for an explicit file extension match (without MIME match) in the // extension manifest and pick that over the fallback handlers below (see // crbug.com/803930) - for (FullTaskDescriptor& task : *tasks) { + for (FullTaskDescriptor& task : tasks) { if (task.is_file_extension_match && !task.is_generic_file_handler && !IsFallbackFileHandler(task)) { task.is_default = true; @@ -1073,7 +1079,7 @@ // Prefer a fallback app over viewing in the browser (crbug.com/1111399). // Unless it's HTML which should open in the browser (crbug.com/1121396). - for (FullTaskDescriptor& task : *tasks) { + for (FullTaskDescriptor& task : tasks) { if (IsFallbackFileHandler(task) && ParseFilesAppActionId(task.task_descriptor.action_id) != "view-in-browser") { @@ -1090,7 +1096,7 @@ // No default tasks found. If there is any fallback file browser handler, // make it as default task, so it's selected by default. - for (FullTaskDescriptor& task : *tasks) { + for (FullTaskDescriptor& task : tasks) { DCHECK(!task.is_default); if (IsFallbackFileHandler(task)) { task.is_default = true;
diff --git a/chrome/browser/ash/file_manager/file_tasks.h b/chrome/browser/ash/file_manager/file_tasks.h index c9b4fc88..dbe8202 100644 --- a/chrome/browser/ash/file_manager/file_tasks.h +++ b/chrome/browser/ash/file_manager/file_tasks.h
@@ -101,7 +101,6 @@ #include "base/callback_forward.h" #include "chrome/common/extensions/api/file_manager_private.h" #include "components/prefs/pref_registry_simple.h" -#include "extensions/browser/api/file_handlers/app_file_handler_util.h" #include "url/gurl.h" class PrefService; @@ -250,6 +249,29 @@ bool is_file_extension_match; }; +// Describes how admin policy affects the default task in a ResultingTasks. +enum class PolicyDefaultHandlerStatus { + // Indicates that the default task was selected according to the policy + // settings. + kDefaultHandlerAssignedByPolicy, + + // Indicates that no default task was set due to some assignment conflicts. + // Possible reasons are: + // * The user is trying to open multiple files which have different policy + // default handlers; + // * The admin-specified handler was not found in the list of tasks. + kIncorrectAssignment +}; + +// Represents a set of tasks capable of handling file entries. +struct ResultingTasks { + ResultingTasks(); + ~ResultingTasks(); + + std::vector<FullTaskDescriptor> tasks; + absl::optional<PolicyDefaultHandlerStatus> policy_default_handler_status; +}; + // Registers profile prefs related to file_manager. void RegisterProfilePrefs(PrefRegistrySimple*); @@ -318,7 +340,7 @@ // Callback function type for FindAllTypesOfTasks. typedef base::OnceCallback<void( - std::unique_ptr<std::vector<FullTaskDescriptor>> result)> + std::unique_ptr<ResultingTasks> resulting_tasks)> FindTasksCallback; // Finds all types (file handlers, file browser handlers) of @@ -333,12 +355,13 @@ const std::vector<GURL>& file_urls, FindTasksCallback callback); -// Chooses the default task in |tasks| and sets it as default, if the default -// task is found (i.e. the default task may not exist in |tasks|). No tasks -// should be set as default before calling this function. +// Chooses the default task in |resulting_tasks| and sets it as default, if the +// default task is found (i.e. the default task may not exist in +// |resulting_tasks|). No tasks should be set as default before calling this +// function. void ChooseAndSetDefaultTask(Profile* profile, const std::vector<extensions::EntryInfo>& entries, - std::vector<FullTaskDescriptor>* tasks); + ResultingTasks* resulting_tasks); // Returns whether |path| is an HTML file according to its extension. bool IsHtmlFile(const base::FilePath& path);
diff --git a/chrome/browser/ash/file_manager/file_tasks_browsertest.cc b/chrome/browser/ash/file_manager/file_tasks_browsertest.cc index 6e5af78..4911562 100644 --- a/chrome/browser/ash/file_manager/file_tasks_browsertest.cc +++ b/chrome/browser/ash/file_manager/file_tasks_browsertest.cc
@@ -67,27 +67,29 @@ // asynchronously). void VerifyTasks(int* remaining, Expectation expectation, - std::unique_ptr<std::vector<FullTaskDescriptor>> result) { - ASSERT_TRUE(result) << expectation.file_extensions; + std::unique_ptr<ResultingTasks> resulting_tasks) { + ASSERT_TRUE(resulting_tasks) << expectation.file_extensions; --*remaining; - auto default_task = - base::ranges::find_if(*result, &FullTaskDescriptor::is_default); + auto default_task = base::ranges::find_if(resulting_tasks->tasks, + &FullTaskDescriptor::is_default); // Early exit for the uncommon situation where no default should be set. if (!expectation.app_id) { - EXPECT_TRUE(default_task == result->end()) << expectation.file_extensions; + EXPECT_TRUE(default_task == resulting_tasks->tasks.end()) + << expectation.file_extensions; return; } - ASSERT_TRUE(default_task != result->end()) << expectation.file_extensions; + ASSERT_TRUE(default_task != resulting_tasks->tasks.end()) + << expectation.file_extensions; EXPECT_EQ(expectation.app_id, default_task->task_descriptor.app_id) << " for extension: " << expectation.file_extensions; // Verify no other task is set as default. - EXPECT_EQ(1, std::count_if(result->begin(), result->end(), - [](const auto& task) { return task.is_default; })) + EXPECT_EQ(1, base::ranges::count_if(resulting_tasks->tasks, + &FullTaskDescriptor::is_default)) << expectation.file_extensions; } @@ -95,8 +97,8 @@ void VerifyAsyncTask(int* remaining, Expectation expectation, base::OnceClosure quit_closure, - std::unique_ptr<std::vector<FullTaskDescriptor>> result) { - VerifyTasks(remaining, expectation, std::move(result)); + std::unique_ptr<ResultingTasks> resulting_tasks) { + VerifyTasks(remaining, expectation, std::move(resulting_tasks)); std::move(quit_closure).Run(); } @@ -141,7 +143,7 @@ } else { EXPECT_FALSE(mime_type.empty()) << "No mime type for " << path; } - entries.push_back({path, mime_type, false}); + entries.emplace_back(path, mime_type, false); GURL url = GURL(base::JoinString( {"filesystem:https://site.com/isolated/foo.", extension}, "")); ASSERT_TRUE(url.is_valid());
diff --git a/chrome/browser/ash/file_manager/file_tasks_unittest.cc b/chrome/browser/ash/file_manager/file_tasks_unittest.cc index 9ce0f01..08a371c 100644 --- a/chrome/browser/ash/file_manager/file_tasks_unittest.cc +++ b/chrome/browser/ash/file_manager/file_tasks_unittest.cc
@@ -66,8 +66,7 @@ using extensions::api::file_manager_private::Verb; -namespace file_manager { -namespace file_tasks { +namespace file_manager::file_tasks { TEST(FileManagerFileTasksTest, FullTaskDescriptor_WithIconAndDefault) { FullTaskDescriptor full_descriptor( @@ -233,7 +232,10 @@ "action-id"); TaskDescriptor nice_app_task("nice-app-id", TASK_TYPE_FILE_HANDLER, "action-id"); - std::vector<FullTaskDescriptor> tasks; + + auto resulting_tasks = std::make_unique<ResultingTasks>(); + std::vector<FullTaskDescriptor>& tasks = resulting_tasks->tasks; + tasks.emplace_back( text_app_task, "Text.app", Verb::VERB_OPEN_WITH, GURL("http://example.com/text_app.png"), false /* is_default */, @@ -248,7 +250,7 @@ // None of them should be chosen as default, as nothing is set in the // preferences. - ChooseAndSetDefaultTask(profile(), entries, &tasks); + ChooseAndSetDefaultTask(profile(), entries, resulting_tasks.get()); EXPECT_FALSE(tasks[0].is_default); EXPECT_FALSE(tasks[1].is_default); @@ -259,7 +261,7 @@ UpdateDefaultTaskPreferences(mime_types, empty); // Text.app should be chosen as default. - ChooseAndSetDefaultTask(profile(), entries, &tasks); + ChooseAndSetDefaultTask(profile(), entries, resulting_tasks.get()); EXPECT_TRUE(tasks[0].is_default); EXPECT_FALSE(tasks[1].is_default); @@ -268,7 +270,7 @@ // Clear the preferences and make sure none of them are default. UpdateDefaultTaskPreferences(empty, empty); - ChooseAndSetDefaultTask(profile(), entries, &tasks); + ChooseAndSetDefaultTask(profile(), entries, resulting_tasks.get()); EXPECT_FALSE(tasks[0].is_default); EXPECT_FALSE(tasks[1].is_default); @@ -278,7 +280,7 @@ UpdateDefaultTaskPreferences(empty, suffixes); // Now Nice.app should be chosen as default. - ChooseAndSetDefaultTask(profile(), entries, &tasks); + ChooseAndSetDefaultTask(profile(), entries, resulting_tasks.get()); EXPECT_FALSE(tasks[0].is_default); EXPECT_TRUE(tasks[1].is_default); } @@ -291,7 +293,10 @@ // "foo.txt". TaskDescriptor files_app_task( kFileManagerAppId, TASK_TYPE_FILE_BROWSER_HANDLER, "view-in-browser"); - std::vector<FullTaskDescriptor> tasks; + + auto resulting_tasks = std::make_unique<ResultingTasks>(); + std::vector<FullTaskDescriptor>& tasks = resulting_tasks->tasks; + tasks.emplace_back( files_app_task, "View in browser", Verb::VERB_OPEN_WITH, GURL("http://example.com/some_icon.png"), false /* is_default */, @@ -302,7 +307,7 @@ // The internal file browser handler should be chosen as default, as it's a // fallback file browser handler. - ChooseAndSetDefaultTask(profile(), entries, &tasks); + ChooseAndSetDefaultTask(profile(), entries, resulting_tasks.get()); EXPECT_TRUE(tasks[0].is_default); } @@ -316,7 +321,10 @@ // Define the text editor app for "foo.txt". TaskDescriptor text_app_task(kTextEditorAppId, TASK_TYPE_FILE_HANDLER, "Text"); - std::vector<FullTaskDescriptor> tasks; + + auto resulting_tasks = std::make_unique<ResultingTasks>(); + std::vector<FullTaskDescriptor>& tasks = resulting_tasks->tasks; + tasks.emplace_back( files_app_task, "View in browser", Verb::VERB_OPEN_WITH, GURL("http://example.com/some_icon.png"), false /* is_default */, @@ -332,7 +340,7 @@ // The text editor app should be chosen as default, as it's a fallback file // browser handler. - ChooseAndSetDefaultTask(profile(), entries, &tasks); + ChooseAndSetDefaultTask(profile(), entries, resulting_tasks.get()); EXPECT_TRUE(tasks[1].is_default); } @@ -346,7 +354,10 @@ // Define the text editor app for "foo.html". TaskDescriptor text_app_task(kTextEditorAppId, TASK_TYPE_FILE_HANDLER, "Text"); - std::vector<FullTaskDescriptor> tasks; + + auto resulting_tasks = std::make_unique<ResultingTasks>(); + std::vector<FullTaskDescriptor>& tasks = resulting_tasks->tasks; + tasks.emplace_back( files_app_task, "View in browser", Verb::VERB_OPEN_WITH, GURL("http://example.com/some_icon.png"), false /* is_default */, @@ -362,7 +373,7 @@ // The internal file browser handler should be chosen as default, // as it's a fallback file browser handler. - ChooseAndSetDefaultTask(profile(), entries, &tasks); + ChooseAndSetDefaultTask(profile(), entries, resulting_tasks.get()); EXPECT_TRUE(tasks[0].is_default); } @@ -374,7 +385,10 @@ TaskDescriptor files_app_task( extension_misc::kQuickOfficeComponentExtensionId, TASK_TYPE_FILE_HANDLER, "Office Editing for Docs, Sheets & Slides"); - std::vector<FullTaskDescriptor> tasks; + + auto resulting_tasks = std::make_unique<ResultingTasks>(); + std::vector<FullTaskDescriptor>& tasks = resulting_tasks->tasks; + tasks.emplace_back( files_app_task, "Office Editing for Docs, Sheets & Slides", Verb::VERB_OPEN_WITH, @@ -387,7 +401,7 @@ // The Office Editing app should be chosen as default, as it's a fallback // file browser handler. - ChooseAndSetDefaultTask(profile(), entries, &tasks); + ChooseAndSetDefaultTask(profile(), entries, resulting_tasks.get()); EXPECT_TRUE(tasks[0].is_default); } @@ -449,7 +463,10 @@ // Create the file task descriptors to match against. TaskDescriptor app_service_file_task(app_id, task_type, activity); TaskDescriptor other_task("other", TASK_TYPE_FILE_BROWSER_HANDLER, "view"); - std::vector<FullTaskDescriptor> tasks; + + auto resulting_tasks = std::make_unique<ResultingTasks>(); + std::vector<FullTaskDescriptor>& tasks = resulting_tasks->tasks; + tasks.emplace_back( app_service_file_task, "View Images", Verb::VERB_NONE, GURL("http://example.com/some_icon.png"), false /* is_default */, @@ -463,7 +480,7 @@ false); // Check if the correct task matched against the default preference. - ChooseAndSetDefaultTask(profile(), entries, &tasks); + ChooseAndSetDefaultTask(profile(), entries, resulting_tasks.get()); ASSERT_TRUE(tasks[0].is_default); ASSERT_FALSE(tasks[1].is_default); } @@ -584,17 +601,16 @@ void Call(Profile* profile, const std::vector<extensions::EntryInfo>& entries, const std::vector<GURL>& file_urls, - std::vector<FullTaskDescriptor>* result) { + ResultingTasks* resulting_tasks) { FindAllTypesOfTasks( profile, entries, file_urls, base::BindOnce(&FindAllTypesOfTasksSynchronousWrapper::OnReply, - base::Unretained(this), result)); + base::Unretained(this), resulting_tasks)); run_loop_.Run(); } private: - void OnReply(std::vector<FullTaskDescriptor>* out, - std::unique_ptr<std::vector<FullTaskDescriptor>> result) { + void OnReply(ResultingTasks* out, std::unique_ptr<ResultingTasks> result) { *out = *result; run_loop_.Quit(); } @@ -696,17 +712,19 @@ {crostini_folder_.Append("foo.txt"), "text/plain", false}}; std::vector<GURL> file_urls{PathToURL("dir/foo.txt")}; - std::vector<FullTaskDescriptor> tasks; - FindAllTypesOfTasksSynchronousWrapper().Call(test_profile_.get(), entries, - file_urls, &tasks); + auto resulting_tasks = std::make_unique<ResultingTasks>(); + std::vector<FullTaskDescriptor>& tasks = resulting_tasks->tasks; + + FindAllTypesOfTasksSynchronousWrapper().Call( + test_profile_.get(), entries, file_urls, resulting_tasks.get()); ASSERT_EQ(1U, tasks.size()); EXPECT_EQ(text_app_id_, tasks[0].task_descriptor.app_id); // Multiple text files entries.emplace_back(crostini_folder_.Append("bar.txt"), "text/plain", false); file_urls.emplace_back(PathToURL("dir/bar.txt")); - FindAllTypesOfTasksSynchronousWrapper().Call(test_profile_.get(), entries, - file_urls, &tasks); + FindAllTypesOfTasksSynchronousWrapper().Call( + test_profile_.get(), entries, file_urls, resulting_tasks.get()); ASSERT_EQ(1U, tasks.size()); EXPECT_EQ(text_app_id_, tasks[0].task_descriptor.app_id); } @@ -715,15 +733,18 @@ std::vector<extensions::EntryInfo> entries{ {crostini_folder_.Append("dir"), "", true}}; std::vector<GURL> file_urls{PathToURL("dir/dir")}; - std::vector<FullTaskDescriptor> tasks; - FindAllTypesOfTasksSynchronousWrapper().Call(test_profile_.get(), entries, - file_urls, &tasks); + + auto resulting_tasks = std::make_unique<ResultingTasks>(); + std::vector<FullTaskDescriptor>& tasks = resulting_tasks->tasks; + + FindAllTypesOfTasksSynchronousWrapper().Call( + test_profile_.get(), entries, file_urls, resulting_tasks.get()); EXPECT_EQ(0U, tasks.size()); entries.emplace_back(crostini_folder_.Append("foo.txt"), "text/plain", false); file_urls.emplace_back(PathToURL("dir/foo.txt")); - FindAllTypesOfTasksSynchronousWrapper().Call(test_profile_.get(), entries, - file_urls, &tasks); + FindAllTypesOfTasksSynchronousWrapper().Call( + test_profile_.get(), entries, file_urls, resulting_tasks.get()); EXPECT_EQ(0U, tasks.size()); } @@ -734,9 +755,11 @@ std::vector<GURL> file_urls{PathToURL("dir/foo.gif"), PathToURL("dir/bar.gif")}; - std::vector<FullTaskDescriptor> tasks; - FindAllTypesOfTasksSynchronousWrapper().Call(test_profile_.get(), entries, - file_urls, &tasks); + auto resulting_tasks = std::make_unique<ResultingTasks>(); + std::vector<FullTaskDescriptor>& tasks = resulting_tasks->tasks; + + FindAllTypesOfTasksSynchronousWrapper().Call( + test_profile_.get(), entries, file_urls, resulting_tasks.get()); // The returned values happen to be ordered alphabetically by app_id, so we // rely on this to keep the test simple. EXPECT_LT(gif_app_id_, image_app_id_); @@ -752,16 +775,18 @@ std::vector<GURL> file_urls{PathToURL("dir/foo.gif"), PathToURL("dir/bar.png")}; - std::vector<FullTaskDescriptor> tasks; - FindAllTypesOfTasksSynchronousWrapper().Call(test_profile_.get(), entries, - file_urls, &tasks); + auto resulting_tasks = std::make_unique<ResultingTasks>(); + std::vector<FullTaskDescriptor>& tasks = resulting_tasks->tasks; + + FindAllTypesOfTasksSynchronousWrapper().Call( + test_profile_.get(), entries, file_urls, resulting_tasks.get()); ASSERT_EQ(1U, tasks.size()); EXPECT_EQ(image_app_id_, tasks[0].task_descriptor.app_id); entries.emplace_back(crostini_folder_.Append("qux.mp4"), "video/mp4", false); file_urls.emplace_back(PathToURL("dir/qux.mp4")); - FindAllTypesOfTasksSynchronousWrapper().Call(test_profile_.get(), entries, - file_urls, &tasks); + FindAllTypesOfTasksSynchronousWrapper().Call( + test_profile_.get(), entries, file_urls, resulting_tasks.get()); EXPECT_EQ(0U, tasks.size()); } @@ -772,12 +797,13 @@ std::vector<GURL> file_urls{PathToURL("dir/bar1.foo"), PathToURL("dir/bar2.foo")}; - std::vector<FullTaskDescriptor> tasks; - FindAllTypesOfTasksSynchronousWrapper().Call(test_profile_.get(), entries, - file_urls, &tasks); + auto resulting_tasks = std::make_unique<ResultingTasks>(); + std::vector<FullTaskDescriptor>& tasks = resulting_tasks->tasks; + + FindAllTypesOfTasksSynchronousWrapper().Call( + test_profile_.get(), entries, file_urls, resulting_tasks.get()); ASSERT_EQ(1U, tasks.size()); EXPECT_EQ(alt_mime_app_id_, tasks[0].task_descriptor.app_id); } -} // namespace file_tasks -} // namespace file_manager. +} // namespace file_manager::file_tasks
diff --git a/chrome/browser/ash/file_manager/open_util.cc b/chrome/browser/ash/file_manager/open_util.cc index b841e53..7430517 100644 --- a/chrome/browser/ash/file_manager/open_util.cc +++ b/chrome/browser/ash/file_manager/open_util.cc
@@ -33,8 +33,7 @@ using content::BrowserThread; using storage::FileSystemURL; -namespace file_manager { -namespace util { +namespace file_manager::util { namespace { bool shell_operations_allowed = true; @@ -82,11 +81,11 @@ Profile* profile, const GURL& url, platform_util::OpenOperationCallback callback, - std::unique_ptr<std::vector<file_tasks::FullTaskDescriptor>> tasks) { + std::unique_ptr<file_tasks::ResultingTasks> resulting_tasks) { // Select a default handler. If a default handler is not available, select // the first non-generic file handler. const file_tasks::FullTaskDescriptor* chosen_task = nullptr; - for (const auto& task : *tasks) { + for (const auto& task : resulting_tasks->tasks) { if (!task.is_generic_file_handler) { if (task.is_default) { chosen_task = &task; @@ -233,5 +232,4 @@ shell_operations_allowed = false; } -} // namespace util -} // namespace file_manager +} // namespace file_manager::util
diff --git a/chrome/browser/ash/file_manager/open_util.h b/chrome/browser/ash/file_manager/open_util.h index a00de535..5af914c 100644 --- a/chrome/browser/ash/file_manager/open_util.h +++ b/chrome/browser/ash/file_manager/open_util.h
@@ -17,8 +17,7 @@ class FilePath; } -namespace file_manager { -namespace util { +namespace file_manager::util { // If |item_type| is OPEN_FILE: Opens an item using a file handler, a file // browser handler, or the browser (open in a tab). The default handler has @@ -48,7 +47,6 @@ // extensions including a file browser. void DisableShellOperationsForTesting(); -} // namespace util -} // namespace file_manager +} // namespace file_manager::util #endif // CHROME_BROWSER_ASH_FILE_MANAGER_OPEN_UTIL_H_
diff --git a/chrome/browser/ash/login/existing_user_controller.cc b/chrome/browser/ash/login/existing_user_controller.cc index 824dd41..8bcef8cd 100644 --- a/chrome/browser/ash/login/existing_user_controller.cc +++ b/chrome/browser/ash/login/existing_user_controller.cc
@@ -1303,8 +1303,8 @@ .Get(policy::key::kSessionLocales); if (entry && entry->level == policy::POLICY_LEVEL_RECOMMENDED && entry->value(base::Value::Type::LIST)) { - base::Value::ConstListView list = - entry->value(base::Value::Type::LIST)->GetListDeprecated(); + const base::Value::List& list = + entry->value(base::Value::Type::LIST)->GetList(); if (!list.empty() && list[0].is_string()) { locale = list[0].GetString(); new_user_context.SetPublicSessionLocale(locale);
diff --git a/chrome/browser/ash/login/saml/password_sync_token_fetcher.cc b/chrome/browser/ash/login/saml/password_sync_token_fetcher.cc index 3272f65..ea7ac57c 100644 --- a/chrome/browser/ash/login/saml/password_sync_token_fetcher.cc +++ b/chrome/browser/ash/login/saml/password_sync_token_fetcher.cc
@@ -343,8 +343,7 @@ consumer_->OnApiCallFailed(ErrorType::kGetNoList); return; } - base::Value::ConstListView list_of_tokens = - token_list_entry->GetListDeprecated(); + const base::Value::List& list_of_tokens = token_list_entry->GetList(); if (list_of_tokens.size() > 0) { const auto* sync_token_value = list_of_tokens[0].FindKeyOfType(kToken, base::Value::Type::STRING);
diff --git a/chrome/browser/ash/login/screens/active_directory_login_screen.cc b/chrome/browser/ash/login/screens/active_directory_login_screen.cc index b3420900..1cc1e26 100644 --- a/chrome/browser/ash/login/screens/active_directory_login_screen.cc +++ b/chrome/browser/ash/login/screens/active_directory_login_screen.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/ash/login/ui/login_display_host.h" #include "chrome/browser/ash/login/ui/signin_ui.h" #include "chrome/browser/ash/login/wizard_controller.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/ui/webui/chromeos/login/active_directory_login_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h" @@ -138,7 +139,8 @@ DCHECK(account_info.has_account_id() && !account_info.account_id().empty() && LoginDisplayHost::default_host()); - const AccountId account_id(user_manager::known_user::GetAccountId( + user_manager::KnownUser known_user(g_browser_process->local_state()); + const AccountId account_id(known_user.GetAccountId( username, account_info.account_id(), AccountType::ACTIVE_DIRECTORY)); LoginDisplayHost::default_host()->SetDisplayAndGivenName( account_info.display_name(), account_info.given_name());
diff --git a/chrome/browser/ash/login/screens/active_directory_password_change_screen.cc b/chrome/browser/ash/login/screens/active_directory_password_change_screen.cc index 2aeae76..247b55e 100644 --- a/chrome/browser/ash/login/screens/active_directory_password_change_screen.cc +++ b/chrome/browser/ash/login/screens/active_directory_password_change_screen.cc
@@ -10,6 +10,7 @@ #include "base/check_op.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/ash/login/ui/login_display_host.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" #include "chrome/grit/generated_resources.h" @@ -114,7 +115,8 @@ case authpolicy::ERROR_NONE: { DCHECK(account_info.has_account_id() && !account_info.account_id().empty()); - const AccountId account_id = user_manager::known_user::GetAccountId( + user_manager::KnownUser known_user(g_browser_process->local_state()); + const AccountId account_id = known_user.GetAccountId( username, account_info.account_id(), AccountType::ACTIVE_DIRECTORY); DCHECK(LoginDisplayHost::default_host()); LoginDisplayHost::default_host()->SetDisplayAndGivenName(
diff --git a/chrome/browser/ash/login/screens/chrome_user_selection_screen.cc b/chrome/browser/ash/login/screens/chrome_user_selection_screen.cc index 938e857..7c255fa 100644 --- a/chrome/browser/ash/login/screens/chrome_user_selection_screen.cc +++ b/chrome/browser/ash/login/screens/chrome_user_selection_screen.cc
@@ -82,7 +82,8 @@ void ChromeUserSelectionScreen::CheckForPublicSessionDisplayNameChange( policy::DeviceLocalAccountPolicyBroker* broker) { - const AccountId& account_id = user_manager::known_user::GetAccountId( + user_manager::KnownUser known_user(g_browser_process->local_state()); + const AccountId account_id = known_user.GetAccountId( broker->user_id(), std::string() /* id */, AccountType::UNKNOWN); DCHECK(account_id.is_valid()); const std::string& display_name = broker->GetDisplayName(); @@ -113,7 +114,8 @@ void ChromeUserSelectionScreen::CheckForPublicSessionLocalePolicyChange( policy::DeviceLocalAccountPolicyBroker* broker) { - const AccountId& account_id = user_manager::known_user::GetAccountId( + user_manager::KnownUser known_user(g_browser_process->local_state()); + const AccountId account_id = known_user.GetAccountId( broker->user_id(), std::string() /* id */, AccountType::UNKNOWN); DCHECK(account_id.is_valid()); const policy::PolicyMap::Entry* entry =
diff --git a/chrome/browser/ash/login/screens/network_screen.cc b/chrome/browser/ash/login/screens/network_screen.cc index dc66588..19a16ac4 100644 --- a/chrome/browser/ash/login/screens/network_screen.cc +++ b/chrome/browser/ash/login/screens/network_screen.cc
@@ -32,17 +32,11 @@ // static std::string NetworkScreen::GetResultString(Result result) { switch (result) { - case Result::CONNECTED_REGULAR: - case Result::CONNECTED_DEMO: - case Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT: + case Result::CONNECTED: return "Connected"; - case Result::BACK_REGULAR: - case Result::BACK_DEMO: - case Result::BACK_OS_INSTALL: + case Result::BACK: return "Back"; case Result::NOT_APPLICABLE: - case Result::NOT_APPLICABLE_CONSOLIDATED_CONSENT: - case Result::NOT_APPLICABLE_CONNECTED_DEMO: return BaseScreen::kNotApplicable; } } @@ -130,14 +124,7 @@ } void NetworkScreen::NotifyOnConnection() { - if (DemoSetupController::IsOobeDemoSetupFlowInProgress()) { - exit_callback_.Run(Result::CONNECTED_DEMO); - } else { - if (chromeos::features::IsOobeConsolidatedConsentEnabled()) - exit_callback_.Run(Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); - else - exit_callback_.Run(Result::CONNECTED_REGULAR); - } + exit_callback_.Run(Result::CONNECTED); } void NetworkScreen::OnConnectionTimeout() { @@ -202,12 +189,7 @@ if (view_) view_->ClearErrors(); - if (DemoSetupController::IsOobeDemoSetupFlowInProgress()) - exit_callback_.Run(Result::BACK_DEMO); - else if (switches::IsOsInstallAllowed()) - exit_callback_.Run(Result::BACK_OS_INSTALL); - else - exit_callback_.Run(Result::BACK_REGULAR); + exit_callback_.Run(Result::BACK); } void NetworkScreen::OnContinueButtonClicked() { @@ -239,22 +221,10 @@ if (is_hidden()) { // Screen not shown yet: skipping it. - if (DemoSetupController::IsOobeDemoSetupFlowInProgress()) { - exit_callback_.Run(Result::NOT_APPLICABLE_CONNECTED_DEMO); - } else { - if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { - exit_callback_.Run(Result::NOT_APPLICABLE_CONSOLIDATED_CONSENT); - } else { - exit_callback_.Run(Result::NOT_APPLICABLE); - } - } + exit_callback_.Run(Result::NOT_APPLICABLE); } else { // Screen already shown: automatically continuing. - if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { - exit_callback_.Run(Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); - } else { - exit_callback_.Run(Result::CONNECTED_REGULAR); - } + exit_callback_.Run(Result::CONNECTED); } return true;
diff --git a/chrome/browser/ash/login/screens/network_screen.h b/chrome/browser/ash/login/screens/network_screen.h index fd07cd8..c937784 100644 --- a/chrome/browser/ash/login/screens/network_screen.h +++ b/chrome/browser/ash/login/screens/network_screen.h
@@ -29,15 +29,9 @@ using TView = NetworkScreenView; enum class Result { - CONNECTED_REGULAR, - CONNECTED_DEMO, - CONNECTED_REGULAR_CONSOLIDATED_CONSENT, - BACK_REGULAR, - BACK_DEMO, - BACK_OS_INSTALL, + CONNECTED, + BACK, NOT_APPLICABLE, - NOT_APPLICABLE_CONSOLIDATED_CONSENT, - NOT_APPLICABLE_CONNECTED_DEMO, }; static std::string GetResultString(Result result);
diff --git a/chrome/browser/ash/login/screens/network_screen_browsertest.cc b/chrome/browser/ash/login/screens/network_screen_browsertest.cc index 08e9f8f7..7d40f36 100644 --- a/chrome/browser/ash/login/screens/network_screen_browsertest.cc +++ b/chrome/browser/ash/login/screens/network_screen_browsertest.cc
@@ -81,14 +81,7 @@ network_screen->OnContinueButtonClicked(); base::RunLoop().RunUntilIdle(); - ASSERT_TRUE(last_screen_result_.has_value()); - if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { - EXPECT_EQ(NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT, - last_screen_result_.value()); - } else { - EXPECT_EQ(NetworkScreen::Result::CONNECTED_REGULAR, - last_screen_result_.value()); - } + CheckResult(NetworkScreen::Result::CONNECTED); } void SetDefaultNetworkStateHelperExpectations() { @@ -208,10 +201,7 @@ network_screen()->UpdateStatus(); WaitForScreenExit(); - if (chromeos::features::IsOobeConsolidatedConsentEnabled()) - CheckResult(NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); - else - CheckResult(NetworkScreen::Result::CONNECTED_REGULAR); + CheckResult(NetworkScreen::Result::CONNECTED); } // The network screen should NOT be skipped if the connection times out, even if @@ -248,10 +238,7 @@ ShowNetworkScreen(); WaitForScreenExit(); - if (chromeos::features::IsOobeConsolidatedConsentEnabled()) - CheckResult(NetworkScreen::Result::NOT_APPLICABLE_CONSOLIDATED_CONSENT); - else - CheckResult(NetworkScreen::Result::NOT_APPLICABLE); + CheckResult(NetworkScreen::Result::NOT_APPLICABLE); histogram_tester_.ExpectTotalCount( "OOBE.StepCompletionTimeByExitReason.Network-selection.Connected", 0); @@ -288,10 +275,7 @@ network_screen()->UpdateStatus(); WaitForScreenExit(); - if (chromeos::features::IsOobeConsolidatedConsentEnabled()) - CheckResult(NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); - else - CheckResult(NetworkScreen::Result::CONNECTED_REGULAR); + CheckResult(NetworkScreen::Result::CONNECTED); // Showing screen again to test skip doesn't work now. ShowNetworkScreen();
diff --git a/chrome/browser/ash/login/screens/network_screen_unittest.cc b/chrome/browser/ash/login/screens/network_screen_unittest.cc index 9b4e0c2..b20478c 100644 --- a/chrome/browser/ash/login/screens/network_screen_unittest.cc +++ b/chrome/browser/ash/login/screens/network_screen_unittest.cc
@@ -88,14 +88,7 @@ EXPECT_EQ(1, network_screen_->continue_attempts_); ASSERT_TRUE(last_screen_result_.has_value()); - - if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { - EXPECT_EQ(NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT, - last_screen_result_.value()); - } else { - EXPECT_EQ(NetworkScreen::Result::CONNECTED_REGULAR, - last_screen_result_.value()); - } + EXPECT_EQ(NetworkScreen::Result::CONNECTED, last_screen_result_.value()); } TEST_F(NetworkScreenUnitTest, ContinuesOnlyOnce) { @@ -114,13 +107,7 @@ ASSERT_EQ(1, network_screen_->continue_attempts_); ASSERT_TRUE(last_screen_result_.has_value()); - if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { - EXPECT_EQ(NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT, - last_screen_result_.value()); - } else { - EXPECT_EQ(NetworkScreen::Result::CONNECTED_REGULAR, - last_screen_result_.value()); - } + EXPECT_EQ(NetworkScreen::Result::CONNECTED, last_screen_result_.value()); // Stop waiting for another network, net1. network_screen_->StopWaitingForConnection(u"net1");
diff --git a/chrome/browser/ash/login/screens/offline_login_screen.cc b/chrome/browser/ash/login/screens/offline_login_screen.cc index 957cbb0..219d394 100644 --- a/chrome/browser/ash/login/screens/offline_login_screen.cc +++ b/chrome/browser/ash/login/screens/offline_login_screen.cc
@@ -132,7 +132,8 @@ void OfflineLoginScreen::HandleCompleteAuth(const std::string& email, const std::string& password) { const std::string sanitized_email = gaia::SanitizeEmail(email); - const AccountId account_id = user_manager::known_user::GetAccountId( + user_manager::KnownUser known_user(g_browser_process->local_state()); + const AccountId account_id = known_user.GetAccountId( sanitized_email, std::string() /* id */, AccountType::UNKNOWN); const user_manager::User* user = user_manager::UserManager::Get()->FindUser(account_id);
diff --git a/chrome/browser/ash/login/screens/user_selection_screen.cc b/chrome/browser/ash/login/screens/user_selection_screen.cc index ba30117..22542f4d 100644 --- a/chrome/browser/ash/login/screens/user_selection_screen.cc +++ b/chrome/browser/ash/login/screens/user_selection_screen.cc
@@ -144,7 +144,8 @@ AccountId GetOwnerAccountId() { std::string owner_email; CrosSettings::Get()->GetString(kDeviceOwner, &owner_email); - const AccountId owner = user_manager::known_user::GetAccountId( + user_manager::KnownUser known_user(g_browser_process->local_state()); + const AccountId owner = known_user.GetAccountId( owner_email, std::string() /* id */, AccountType::UNKNOWN); return owner; }
diff --git a/chrome/browser/ash/login/test/session_flags_manager.cc b/chrome/browser/ash/login/test/session_flags_manager.cc index 89a86c6..adb3b92 100644 --- a/chrome/browser/ash/login/test/session_flags_manager.cc +++ b/chrome/browser/ash/login/test/session_flags_manager.cc
@@ -136,7 +136,7 @@ base::Value* user_flags = value->FindListKey(kUserFlagsKey); if (user_flags) { user_flags_ = std::vector<Switch>(); - for (const base::Value& flag : user_flags->GetListDeprecated()) { + for (const base::Value& flag : user_flags->GetList()) { DCHECK(flag.is_dict()); user_flags_->emplace_back( std::make_pair(*flag.FindStringKey(kFlagNameKey), @@ -147,7 +147,7 @@ base::Value* restart_job = value->FindListKey(kRestartJobKey); if (restart_job) { restart_job_ = std::vector<Switch>(); - for (const base::Value& job_switch : restart_job->GetListDeprecated()) { + for (const base::Value& job_switch : restart_job->GetList()) { DCHECK(job_switch.is_dict()); restart_job_->emplace_back( std::make_pair(*job_switch.FindStringKey(kFlagNameKey),
diff --git a/chrome/browser/ash/login/wizard_controller.cc b/chrome/browser/ash/login/wizard_controller.cc index 58c1a106..c9443f42 100644 --- a/chrome/browser/ash/login/wizard_controller.cc +++ b/chrome/browser/ash/login/wizard_controller.cc
@@ -1346,7 +1346,7 @@ if (!chromeos::features::IsOobeConsolidatedConsentEnabled()) StartupUtils::MarkEulaAccepted(); - PerformPostEulaActions(); + PerformPostNetworkScreenActions(); OnDeviceDisabledChecked(false /* device_disabled */); } @@ -1420,43 +1420,68 @@ void WizardController::OnQuickStartScreenExit(QuickStartScreen::Result result) { } +// The network screen is part of 3 different flows: +// * Regular Flow: Welcome Screen -> Network Screen -> Update Screen. +// * Demo Flow: Welcome Screen -> Network Screen -> Demo Preferences Screen. +// * OS Install Flow: OS Trial Screen -> Network Screen -> Update Screen. void WizardController::OnNetworkScreenExit(NetworkScreen::Result result) { OnScreenExit(NetworkScreenView::kScreenId, NetworkScreen::GetResultString(result)); + // Demo mode flow. + if (DemoSetupController::IsOobeDemoSetupFlowInProgress()) { + switch (result) { + case NetworkScreen::Result::CONNECTED: + case NetworkScreen::Result::NOT_APPLICABLE: + demo_setup_controller_->set_demo_config( + DemoSession::DemoModeConfig::kOnline); + ShowDemoModePreferencesScreen(); + break; + case NetworkScreen::Result::BACK: + demo_setup_controller_.reset(); + ShowWelcomeScreen(); + break; + } + return; + } + + // OS Install flow. + bool is_consolidated_consent_enabled = + chromeos::features::IsOobeConsolidatedConsentEnabled(); + if (switches::IsOsInstallAllowed()) { + switch (result) { + case NetworkScreen::Result::CONNECTED: + case NetworkScreen::Result::NOT_APPLICABLE: + if (is_consolidated_consent_enabled) { + MaybeTakeTPMOwnership(); + PerformPostNetworkScreenActions(); + InitiateOOBEUpdate(); + } else { + ShowEulaScreen(); + } + break; + case NetworkScreen::Result::BACK: + ShowOsTrialScreen(); + break; + } + return; + } + + // Regular flow. switch (result) { - case NetworkScreen::Result::CONNECTED_REGULAR: + case NetworkScreen::Result::CONNECTED: case NetworkScreen::Result::NOT_APPLICABLE: - DCHECK(!demo_setup_controller_); - ShowEulaScreen(); + if (is_consolidated_consent_enabled) { + MaybeTakeTPMOwnership(); + PerformPostNetworkScreenActions(); + InitiateOOBEUpdate(); + } else { + ShowEulaScreen(); + } break; - case NetworkScreen::Result::CONNECTED_DEMO: - case NetworkScreen::Result::NOT_APPLICABLE_CONNECTED_DEMO: - DCHECK(demo_setup_controller_); - demo_setup_controller_->set_demo_config( - DemoSession::DemoModeConfig::kOnline); - ShowDemoModePreferencesScreen(); - break; - case NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT: - case NetworkScreen::Result::NOT_APPLICABLE_CONSOLIDATED_CONSENT: - DCHECK(!demo_setup_controller_); - MaybeTakeTPMOwnership(); - PerformPostEulaActions(); - InitiateOOBEUpdate(); - break; - case NetworkScreen::Result::BACK_DEMO: - DCHECK(demo_setup_controller_); - demo_setup_controller_.reset(); + case NetworkScreen::Result::BACK: ShowWelcomeScreen(); break; - case NetworkScreen::Result::BACK_REGULAR: - DCHECK(!demo_setup_controller_); - ShowWelcomeScreen(); - break; - case NetworkScreen::Result::BACK_OS_INSTALL: - DCHECK(!demo_setup_controller_); - ShowOsTrialScreen(); - break; } } @@ -1502,7 +1527,7 @@ AdvanceToScreen(HWDataCollectionView::kScreenId); return; } - PerformPostEulaActions(); + PerformPostNetworkScreenActions(); if (arc::IsArcTermsOfServiceOobeNegotiationNeeded()) { ShowArcTermsOfServiceScreen(); @@ -1676,7 +1701,7 @@ demo_setup_controller_->set_demo_config( DemoSession::DemoModeConfig::kOnline); MaybeTakeTPMOwnership(); - PerformPostEulaActions(); + PerformPostNetworkScreenActions(); InitiateOOBEUpdate(); break; case DemoPreferencesScreen::Result::CANCELED: @@ -2023,13 +2048,12 @@ weak_factory_.GetWeakPtr())); } -void WizardController::PerformPostEulaActions() { +void WizardController::PerformPostNetworkScreenActions() { StartNetworkTimezoneResolve(); DelayNetworkCall(base::Milliseconds(kDefaultNetworkRetryDelayMS), ServicesCustomizationDocument::GetInstance() ->EnsureCustomizationAppliedClosure()); - // Now that EULA has been accepted (for official builds), enable portal check. // ChromiumOS builds would go though this code path too. GetAutoEnrollmentController()->Start(); network_portal_detector::GetInstance()->Enable();
diff --git a/chrome/browser/ash/login/wizard_controller.h b/chrome/browser/ash/login/wizard_controller.h index 5ba6a871..737ab0e 100644 --- a/chrome/browser/ash/login/wizard_controller.h +++ b/chrome/browser/ash/login/wizard_controller.h
@@ -397,9 +397,11 @@ // Retrieve filtered OOBE configuration and apply relevant values. void UpdateOobeConfiguration(); - // Actions that should be done right after EULA is accepted, - // before update check. - void PerformPostEulaActions(); + // Actions that should be done right after Network Screen if + // OobeConsolidatedConsent is enabled, and should be done right after EULA is + // accepted if OobeConsolidatedConsent is disabled. These actions should be + // done before the update check. + void PerformPostNetworkScreenActions(); // Actions that should be done right after update stage is finished. void PerformOOBECompletedActions();
diff --git a/chrome/browser/ash/login/wizard_controller_browsertest.cc b/chrome/browser/ash/login/wizard_controller_browsertest.cc index d5b69b45..15531c5 100644 --- a/chrome/browser/ash/login/wizard_controller_browsertest.cc +++ b/chrome/browser/ash/login/wizard_controller_browsertest.cc
@@ -738,12 +738,10 @@ EXPECT_CALL(*mock_update_screen_, ShowImpl()).Times(1); if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); // Login shelf should still be visible. @@ -855,11 +853,10 @@ if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_eula_screen_, HideImpl()).Times(1); @@ -899,11 +896,10 @@ if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_eula_screen_, HideImpl()).Times(1); @@ -948,11 +944,10 @@ .Times(1); EXPECT_CALL(*mock_auto_enrollment_check_screen_, ShowImpl()).Times(0); EXPECT_CALL(*mock_enrollment_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_eula_screen_, HideImpl()).Times(1); @@ -995,7 +990,7 @@ EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); EXPECT_CALL(*mock_network_screen_, HideImpl()).Times(1); EXPECT_CALL(*mock_update_screen_, ShowImpl()).Times(0); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_network_screen_, ShowImpl()).Times(1); @@ -1104,11 +1099,10 @@ if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); @@ -1227,11 +1221,10 @@ if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_eula_screen_, HideImpl()).Times(1); @@ -1267,15 +1260,18 @@ std::move(device_state)); EXPECT_CALL(*mock_network_screen_, ShowImpl()).Times(1); - EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); + if (!chromeos::features::IsOobeConsolidatedConsentEnabled()) + EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); EXPECT_CALL(*mock_update_screen_, ShowImpl()).Times(1); EXPECT_CALL(*mock_auto_enrollment_check_screen_, ShowImpl()).Times(1); EXPECT_CALL(*mock_enrollment_screen_, ShowImpl()).Times(1); mock_welcome_screen_->ExitScreen(WelcomeScreen::Result::NEXT); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); - mock_eula_screen_->ExitScreen( - EulaScreen::Result::ACCEPTED_WITHOUT_USAGE_STATS_REPORTING); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); + if (!chromeos::features::IsOobeConsolidatedConsentEnabled()) { + mock_eula_screen_->ExitScreen( + EulaScreen::Result::ACCEPTED_WITHOUT_USAGE_STATS_REPORTING); + } base::RunLoop().RunUntilIdle(); mock_update_screen_->RunExit(UpdateScreen::Result::UPDATE_NOT_REQUIRED); mock_auto_enrollment_check_screen_->ExitScreen(); @@ -1306,11 +1302,10 @@ if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_eula_screen_, HideImpl()).Times(1); @@ -1409,11 +1404,10 @@ if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_eula_screen_, HideImpl()).Times(1); @@ -1502,11 +1496,10 @@ if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_eula_screen_, HideImpl()).Times(1); @@ -1653,12 +1646,10 @@ if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_eula_screen_, HideImpl()).Times(1); @@ -1768,11 +1759,10 @@ if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_eula_screen_, HideImpl()).Times(1); @@ -1860,11 +1850,10 @@ if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_eula_screen_, HideImpl()).Times(1); @@ -1905,11 +1894,10 @@ if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_eula_screen_, HideImpl()).Times(1); @@ -1964,11 +1952,10 @@ if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_eula_screen_, HideImpl()).Times(1); @@ -2024,11 +2011,10 @@ if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_eula_screen_, HideImpl()).Times(1); @@ -2308,11 +2294,10 @@ if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_eula_screen_, HideImpl()).Times(1); @@ -2358,11 +2343,10 @@ if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { // EULA screen is skipped when OobeConsolidatedConsent is enabled. - mock_network_screen_->ExitScreen( - NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); } else { EXPECT_CALL(*mock_eula_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_REGULAR); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(EulaView::kScreenId); EXPECT_CALL(*mock_eula_screen_, HideImpl()).Times(1); @@ -2540,7 +2524,7 @@ EXPECT_CALL(*mock_network_screen_, HideImpl()).Times(1); EXPECT_CALL(*mock_demo_preferences_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_DEMO); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(DemoPreferencesScreenView::kScreenId); EXPECT_TRUE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); @@ -2634,7 +2618,7 @@ EXPECT_CALL(*mock_network_screen_, HideImpl()).Times(1); EXPECT_CALL(*mock_demo_preferences_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_DEMO); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(DemoPreferencesScreenView::kScreenId); EXPECT_TRUE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); @@ -2736,7 +2720,7 @@ EXPECT_CALL(*mock_network_screen_, HideImpl()).Times(1); EXPECT_CALL(*mock_welcome_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::BACK_DEMO); + mock_network_screen_->ExitScreen(NetworkScreen::Result::BACK); EXPECT_FALSE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); } @@ -2752,7 +2736,7 @@ EXPECT_CALL(*mock_network_screen_, HideImpl()).Times(1); EXPECT_CALL(*mock_welcome_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::BACK_DEMO); + mock_network_screen_->ExitScreen(NetworkScreen::Result::BACK); CheckCurrentScreen(WelcomeView::kScreenId); EXPECT_FALSE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); @@ -2867,7 +2851,7 @@ EXPECT_CALL(*mock_network_screen_, HideImpl()).Times(1); EXPECT_CALL(*mock_demo_preferences_screen_, ShowImpl()).Times(1); - mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED_DEMO); + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); CheckCurrentScreen(DemoPreferencesScreenView::kScreenId); EXPECT_TRUE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); @@ -3213,7 +3197,7 @@ ASSERT_TRUE(network_list); ASSERT_TRUE(network_list->is_list()); - const base::Value& network = network_list->GetListDeprecated()[0]; + const base::Value& network = network_list->GetList()[0]; ASSERT_TRUE(network.is_dict()); const std::string* guid = network.FindStringKey("GUID");
diff --git a/chrome/browser/ash/ownership/owner_key_loader.cc b/chrome/browser/ash/ownership/owner_key_loader.cc new file mode 100644 index 0000000..471b90d --- /dev/null +++ b/chrome/browser/ash/ownership/owner_key_loader.cc
@@ -0,0 +1,308 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/ownership/owner_key_loader.h" + +#include "base/check_is_test.h" +#include "base/task/thread_pool.h" +#include "chrome/browser/ash/settings/device_settings_service.h" +#include "chrome/browser/net/nss_service.h" +#include "chrome/browser/net/nss_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "components/ownership/owner_key_util.h" +#include "components/policy/proto/device_management_backend.pb.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "net/cert/nss_cert_database.h" + +namespace ash { + +namespace { + +// Max number of attempts to generate a new owner key. +constexpr int kMaxGenerateAttempts = 5; + +void LoadPublicKeyOnlyOnWorkerThread( + scoped_refptr<ownership::OwnerKeyUtil> owner_key_util, + base::OnceCallback<void(scoped_refptr<ownership::PublicKey>)> + ui_thread_callback) { + scoped_refptr<ownership::PublicKey> public_key = + owner_key_util->ImportPublicKey(); + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(ui_thread_callback), public_key)); +} + +void LoadPrivateKeyOnWorkerThread( + scoped_refptr<ownership::OwnerKeyUtil> owner_key_util, + scoped_refptr<ownership::PublicKey> public_key, + base::OnceCallback<void(scoped_refptr<ownership::PrivateKey>)> + ui_thread_callback, + net::NSSCertDatabase* database) { + // TODO(davidben): FindPrivateKeyInSlot internally checks for a null slot if + // needbe. The null check should be in the caller rather than internally in + // the OwnerKeyUtil implementation. The tests currently get a null + // private_slot and expect the mock OwnerKeyUtil to still be called. + scoped_refptr<ownership::PrivateKey> private_key = + base::MakeRefCounted<ownership::PrivateKey>( + owner_key_util->FindPrivateKeyInSlot( + public_key->data(), database->GetPrivateSlot().get())); + if (!private_key->key()) { + private_key = base::MakeRefCounted<ownership::PrivateKey>( + owner_key_util->FindPrivateKeyInSlot(public_key->data(), + database->GetPublicSlot().get())); + } + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(ui_thread_callback), private_key)); +} + +void GenerateNewOwnerKeyOnWorkerThread( + scoped_refptr<ownership::OwnerKeyUtil> owner_key_util, + base::OnceCallback<void(scoped_refptr<ownership::PublicKey>, + scoped_refptr<ownership::PrivateKey>)> + ui_thread_callback, + net::NSSCertDatabase* nss_db) { + crypto::ScopedSECKEYPrivateKey sec_priv_key = + owner_key_util->GenerateKeyPair(nss_db->GetPublicSlot().get()); + if (!sec_priv_key) { + LOG(ERROR) << "Failed to generete owner key"; + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce(std::move(ui_thread_callback), nullptr, nullptr)); + return; + } + + crypto::ScopedSECKEYPublicKey sec_pub_key( + SECKEY_ConvertToPublicKey(sec_priv_key.get())); + crypto::ScopedSECItem sec_pub_key_der( + SECKEY_EncodeDERSubjectPublicKeyInfo(sec_pub_key.get())); + if (!sec_pub_key_der.get()) { + LOG(ERROR) << "Failed to extract public key"; + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce(std::move(ui_thread_callback), nullptr, nullptr)); + return; + } + + scoped_refptr<ownership::PublicKey> public_key = + base::MakeRefCounted<ownership::PublicKey>( + /*is_persisted=*/false, + std::vector<uint8_t>(sec_pub_key_der->data, + sec_pub_key_der->data + sec_pub_key_der->len)); + scoped_refptr<ownership::PrivateKey> private_key = + base::MakeRefCounted<ownership::PrivateKey>(std::move(sec_priv_key)); + + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(ui_thread_callback), + std::move(public_key), std::move(private_key))); +} + +void PostOnWorkerThreadWithCertDb( + base::OnceCallback<void(net::NSSCertDatabase*)> worker_task, + net::NSSCertDatabase* nss_db) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + + // TODO(eseckler): It seems loading the key is important for the UsersPrivate + // extension API to work correctly during startup, which is why we cannot + // currently use the BEST_EFFORT TaskPriority here. + base::ThreadPool::PostTask( + FROM_HERE, + {base::MayBlock(), base::TaskPriority::USER_VISIBLE, + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::BindOnce(std::move(worker_task), nss_db)); +} + +void GetCertDbAndPostOnWorkerThreadOnIO( + NssCertDatabaseGetter nss_getter, + base::OnceCallback<void(net::NSSCertDatabase*)> worker_task) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + + // Running |nss_getter| may either return a non-null pointer + // synchronously or invoke the given callback asynchronously with a non-null + // pointer. |callback_split| is used here to handle both cases. + auto callback_split = base::SplitOnceCallback( + base::BindOnce(&PostOnWorkerThreadWithCertDb, std::move(worker_task))); + + net::NSSCertDatabase* database = + std::move(nss_getter).Run(std::move(callback_split.first)); + if (database) + std::move(callback_split.second).Run(database); +} + +void GetCertDbAndPostOnWorkerThread( + Profile* profile, + base::OnceCallback<void(net::NSSCertDatabase*)> worker_task) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&GetCertDbAndPostOnWorkerThreadOnIO, + NssServiceFactory::GetForContext(profile) + ->CreateNSSCertDatabaseGetterForIOThread(), + std::move(worker_task))); +} + +} // namespace + +OwnerKeyLoader::OwnerKeyLoader( + Profile* profile, + DeviceSettingsService* device_settings_service, + scoped_refptr<ownership::OwnerKeyUtil> owner_key_util, + KeypairCallback callback) + : profile_(profile), + device_settings_service_(device_settings_service), + owner_key_util_(std::move(owner_key_util)), + callback_(std::move(callback)) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(profile_); + DCHECK(owner_key_util_); + DCHECK(callback_); + if (!device_settings_service_) { + CHECK_IS_TEST(); + } +} +OwnerKeyLoader::~OwnerKeyLoader() = default; + +void OwnerKeyLoader::Run() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(callback_) << "Run() can only be called once."; + + if (!device_settings_service_) { + CHECK_IS_TEST(); + std::move(callback_).Run(/*public_key=*/nullptr, /*private_key=*/nullptr); + // `this` might be deleted here. + return; + } + + // device_settings_service_ indicates that the current user should become the + // owner, generate a new owner key pair for them. + if (device_settings_service_->GetWillEstablishConsumerOwnership()) { + LOG(WARNING) << "Establishing consumer ownership."; + GetCertDbAndPostOnWorkerThread( + profile_, + base::BindOnce(&GenerateNewOwnerKeyOnWorkerThread, owner_key_util_, + base::BindOnce(&OwnerKeyLoader::OnNewKeyGenerated, + weak_factory_.GetWeakPtr()))); + return; + } + + // Otherwise it might be the owner or not, start with loading the public key. + base::ThreadPool::PostTask( + FROM_HERE, + {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::BindOnce(&LoadPublicKeyOnlyOnWorkerThread, owner_key_util_, + base::BindOnce(&OwnerKeyLoader::OnPublicKeyLoaded, + weak_factory_.GetWeakPtr()))); +} + +void OwnerKeyLoader::OnPublicKeyLoaded( + scoped_refptr<ownership::PublicKey> public_key) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + if (!public_key || public_key->is_empty()) { + // This should not happen. For the very first user that doesn't have the + // public key yet, device_settings_service_ should indicate that. For other + // users, they should either have the public key or session_manager should + // recover it from the policies or session_manager should initiate powerwash + // if both policies and the public key were lost. + LOG(ERROR) << "Failed to load public key."; + std::move(callback_).Run( + /*public_key=*/nullptr, /*private_key=*/nullptr); + // `this` might be deleted here. + return; + } + public_key_ = public_key; + + // Now check whether the current user has access to the private key associated + // with the public key. + GetCertDbAndPostOnWorkerThread( + profile_, base::BindOnce( + &LoadPrivateKeyOnWorkerThread, owner_key_util_, public_key_, + base::BindOnce(&OwnerKeyLoader::OnPrivateKeyLoaded, + weak_factory_.GetWeakPtr()))); +} + +void OwnerKeyLoader::OnPrivateKeyLoaded( + scoped_refptr<ownership::PrivateKey> private_key) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (private_key && private_key->key()) { + // Success: both keys were loaded, the current user is the owner. + std::move(callback_).Run(public_key_, private_key); + // `this` might be deleted here. + return; + } + + // Private key failed to load. Maybe the current user is not the owner. Or + // the private key was lost. Check the policies to make the decision. + if (device_settings_service_->policy_data()) { + MaybeRegenerateLostKey(device_settings_service_->policy_data()); + return; + } + // If policy data is not available yet, try waiting for it. The assumption is + // that it can be loaded before this class finishes its work. The public key + // is usually required to load the policies, but device_settings_service_ also + // independently loads it for itself. + device_settings_service_->GetPolicyDataAsync(base::BindOnce( + &OwnerKeyLoader::OnPolicyDataReady, weak_factory_.GetWeakPtr())); +} + +void OwnerKeyLoader::OnNewKeyGenerated( + scoped_refptr<ownership::PublicKey> public_key, + scoped_refptr<ownership::PrivateKey> private_key) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (private_key && private_key->key()) { + LOG(WARNING) << "New owner key pair was generated."; + std::move(callback_).Run(public_key, private_key); + // `this` might be deleted here. + return; + } + + if (++generate_attempt_counter_ <= kMaxGenerateAttempts) { + // Key generation is not expected to fail, but it is too important to simply + // give up. Retry up to `kMaxGenerateAttempts` times if needed. + GetCertDbAndPostOnWorkerThread( + profile_, + base::BindOnce(&GenerateNewOwnerKeyOnWorkerThread, owner_key_util_, + base::BindOnce(&OwnerKeyLoader::OnNewKeyGenerated, + weak_factory_.GetWeakPtr()))); + return; + } + + LOG(ERROR) << "Failed to generate new owner key."; + // Return at least the public key, if it was loaded. If Chrome is taking + // ownership for the first time, it should be null. If recovering from a lost + // private key, it should be not null. + std::move(callback_).Run(public_key_, nullptr); + // `this` might be deleted here. +} + +// This method is needed just to convert non-const pointer to a const one. +// OnceCallback struggles to do it itself. +void OwnerKeyLoader::OnPolicyDataReady( + enterprise_management::PolicyData* policy_data) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + MaybeRegenerateLostKey(policy_data); +} + +void OwnerKeyLoader::MaybeRegenerateLostKey( + const enterprise_management::PolicyData* policy_data) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + // If the policy says that the current user is the owner, generate a new key + // pair for them. Also, in theory ChromeOS is allowed to lose the policies and + // recover, so be prepared for them to still be empty. + if (policy_data && policy_data->has_username() && + (policy_data->username() == profile_->GetProfileUserName())) { + LOG(WARNING) << "The owner key was lost. Generating a new one."; + GetCertDbAndPostOnWorkerThread( + profile_, + base::BindOnce(&GenerateNewOwnerKeyOnWorkerThread, owner_key_util_, + base::BindOnce(&OwnerKeyLoader::OnNewKeyGenerated, + weak_factory_.GetWeakPtr()))); + return; + } + + // The user doesn't seem to be the owner, return just the public key. + std::move(callback_).Run(public_key_, /*private_key=*/nullptr); + // `this` might be deleted here. +} + +} // namespace ash
diff --git a/chrome/browser/ash/ownership/owner_key_loader.h b/chrome/browser/ash/ownership/owner_key_loader.h new file mode 100644 index 0000000..969ddab --- /dev/null +++ b/chrome/browser/ash/ownership/owner_key_loader.h
@@ -0,0 +1,71 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ASH_OWNERSHIP_OWNER_KEY_LOADER_H_ +#define CHROME_BROWSER_ASH_OWNERSHIP_OWNER_KEY_LOADER_H_ + +#include "base/callback.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "components/ownership/owner_key_util.h" + +class Profile; + +namespace enterprise_management { +class PolicyData; +} + +namespace ash { + +class DeviceSettingsService; + +// A helper single-use class to load the owner key. +// Determines whether the current user is the owner or not. +// For the non-owner just loads the public owner key (which can be used to +// verify signature on the device policies). +// For the owner loads both public and private key or generates new ones if the +// previous ones were lost. +// For the first user that should become the owner generates a new key pair. +// All public methods might depend on the profile and therefore should be run on +// the UI thread. +class OwnerKeyLoader { + public: + using KeypairCallback = base::OnceCallback<void( + scoped_refptr<ownership::PublicKey> public_key, + scoped_refptr<ownership::PrivateKey> private_key)>; + + OwnerKeyLoader(Profile* profile, + DeviceSettingsService* device_settings_service, + scoped_refptr<ownership::OwnerKeyUtil> owner_key_util, + KeypairCallback callback); + OwnerKeyLoader(const OwnerKeyLoader&) = delete; + auto operator=(const OwnerKeyLoader&) = delete; + ~OwnerKeyLoader(); + + // Starts the loading of the key(s). Can be called only once per instance of + // the class. + void Run(); + + private: + void OnPublicKeyLoaded(scoped_refptr<ownership::PublicKey> public_key); + void OnPrivateKeyLoaded(scoped_refptr<ownership::PrivateKey> private_key); + void OnNewKeyGenerated(scoped_refptr<ownership::PublicKey> public_key, + scoped_refptr<ownership::PrivateKey> private_key); + void OnPolicyDataReady(enterprise_management::PolicyData* policy_data); + void MaybeRegenerateLostKey( + const enterprise_management::PolicyData* policy_data); + + Profile* const profile_; + DeviceSettingsService* const device_settings_service_; + scoped_refptr<ownership::OwnerKeyUtil> owner_key_util_; + scoped_refptr<ownership::PublicKey> public_key_; + KeypairCallback callback_; + int generate_attempt_counter_ = 0; + + base::WeakPtrFactory<OwnerKeyLoader> weak_factory_{this}; +}; + +} // namespace ash + +#endif // CHROME_BROWSER_ASH_OWNERSHIP_OWNER_KEY_LOADER_H_
diff --git a/chrome/browser/ash/ownership/owner_key_loader_unittest.cc b/chrome/browser/ash/ownership/owner_key_loader_unittest.cc new file mode 100644 index 0000000..b1ca912 --- /dev/null +++ b/chrome/browser/ash/ownership/owner_key_loader_unittest.cc
@@ -0,0 +1,188 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/ownership/owner_key_loader.h" + +#include <memory> +#include <vector> + +#include "base/test/test_future.h" +#include "chrome/browser/ash/policy/core/device_policy_builder.h" +#include "chrome/browser/ash/settings/device_settings_service.h" +#include "chrome/browser/net/fake_nss_service.h" +#include "chrome/test/base/testing_profile.h" +#include "components/ownership/mock_owner_key_util.h" +#include "content/public/test/browser_task_environment.h" +#include "crypto/rsa_private_key.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace ash { + +std::vector<uint8_t> ExtractBytes( + const std::unique_ptr<crypto::RSAPrivateKey>& key) { + std::vector<uint8_t> bytes; + key->ExportPublicKey(&bytes); + return bytes; +} + +class OwnerKeyLoaderTest : public testing::Test { + public: + // testing::Test: + void SetUp() override { + owner_key_util_ = base::MakeRefCounted<ownership::MockOwnerKeyUtil>(); + + device_settings_service_.SetSessionManager(&session_manager_client_, + owner_key_util_); + + profile_ = TestingProfile::Builder().Build(); + + FakeNssService::InitializeForBrowserContext(profile_.get(), + /*enable_system_slot=*/false); + + key_loader_ = std::make_unique<OwnerKeyLoader>( + profile_.get(), &device_settings_service_, owner_key_util_, + result_observer_.GetCallback()); + } + + protected: + std::unique_ptr<crypto::RSAPrivateKey> ConfigureExistingPolicies( + const std::string& owner_username) { + // The actual content of the policies doesn't matter, OwnerKeyLoader only + // looks at the username that created them (i.e. at the user that was + // recognised as the owner when they were created). + policy::DevicePolicyBuilder policy_builder; + policy_builder.policy_data().set_username(owner_username); + policy_builder.Build(); + session_manager_client_.set_device_policy(policy_builder.GetBlob()); + return policy_builder.GetSigningKey(); + } + + content::BrowserTaskEnvironment task_environment_; + + scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util_; + FakeSessionManagerClient session_manager_client_; + std::unique_ptr<TestingProfile> profile_; + ash::DeviceSettingsService device_settings_service_; + std::unique_ptr<OwnerKeyLoader> key_loader_; + base::test::TestFuture<scoped_refptr<ownership::PublicKey>, + scoped_refptr<ownership::PrivateKey>> + result_observer_; +}; + +// Test that the first user generates a new owner key. +TEST_F(OwnerKeyLoaderTest, FirstUserGeneratesOwnerKey) { + // In real code DeviceSettingsService must call this for the first user. + device_settings_service_.MarkWillEstablishConsumerOwnership(); + // Do not prepare any keys, so key_loader_ has to generate a new one. + + key_loader_->Run(); + + EXPECT_FALSE(result_observer_.Get<0>()->is_empty()); + EXPECT_TRUE(result_observer_.Get<1>()->key()); +} + +// Test that the second user doesn't try to generate a new owner key. +TEST_F(OwnerKeyLoaderTest, SecondUserDoesNotTakeOwnership) { + // In real code the first user would have created some device policies and + // saved the public owner key on disk. Emulate that. + auto signing_key = ConfigureExistingPolicies("owner@example.com"); + owner_key_util_->SetPublicKeyFromPrivateKey(*signing_key); + device_settings_service_.LoadImmediately(); // Reload policies. + + key_loader_->Run(); + + EXPECT_FALSE(result_observer_.Get<0>()->is_empty()); + EXPECT_EQ(result_observer_.Get<0>()->data(), ExtractBytes(signing_key)); + EXPECT_FALSE(result_observer_.Get<1>()); +} + +// Test that an owner user gets recognized as the owner when it's mentioned in +// the existing device policies and owns the key. +TEST_F(OwnerKeyLoaderTest, OwnerUserLoadsExistingKey) { + // Configure existing device policies and the owner key. + auto signing_key = ConfigureExistingPolicies(profile_->GetProfileUserName()); + owner_key_util_->ImportPrivateKeyAndSetPublicKey(signing_key->Copy()); + device_settings_service_.LoadImmediately(); // Reload policies. + + key_loader_->Run(); + + EXPECT_FALSE(result_observer_.Get<0>()->is_empty()); + EXPECT_EQ(result_observer_.Get<0>()->data(), ExtractBytes(signing_key)); + EXPECT_TRUE(result_observer_.Get<1>()->key()); +} + +// Test that even without existing device policies the owner key gets loaded +// (that will help Chrome to recognize the current user as the owner). +TEST_F(OwnerKeyLoaderTest, OwnerUserLoadsExistingKeyWithoutPolicies) { + policy::DevicePolicyBuilder policy_builder; + auto signing_key = policy_builder.GetSigningKey(); + + owner_key_util_->ImportPrivateKeyAndSetPublicKey(signing_key->Copy()); + + key_loader_->Run(); + + EXPECT_FALSE(result_observer_.Get<0>()->is_empty()); + EXPECT_EQ(result_observer_.Get<0>()->data(), ExtractBytes(signing_key)); + EXPECT_TRUE(result_observer_.Get<1>()->key()); +} + +// Test that the second user is not falsely recognized as the owner even if +// policies fail to load and does not have the owner key. +TEST_F(OwnerKeyLoaderTest, SecondaryUserWithoutPolicies) { + policy::DevicePolicyBuilder policy_builder; + auto signing_key = policy_builder.GetSigningKey(); + + owner_key_util_->SetPublicKeyFromPrivateKey(*signing_key); + + key_loader_->Run(); + + EXPECT_FALSE(result_observer_.Get<0>()->is_empty()); + EXPECT_EQ(result_observer_.Get<0>()->data(), ExtractBytes(signing_key)); + EXPECT_FALSE(result_observer_.Get<1>()); +} + +// Test that an owner user still gets recognized as the owner when it's +// mentioned in the existing device policies, but the owner key was lost. +// The key must be re-generated in such a case. +TEST_F(OwnerKeyLoaderTest, OwnerUserRegeneratesMissingKey) { + auto signing_key = ConfigureExistingPolicies(profile_->GetProfileUserName()); + // Configure that the public key is on disk, but the private key doesn't + // exist. + owner_key_util_->SetPublicKeyFromPrivateKey(*signing_key); + device_settings_service_.LoadImmediately(); // Reload policies. + + key_loader_->Run(); + + EXPECT_FALSE(result_observer_.Get<0>()->is_empty()); + EXPECT_NE(result_observer_.Get<0>()->data(), ExtractBytes(signing_key)); + EXPECT_TRUE(result_observer_.Get<1>()->key()); +} + +// Test that OwnerKeyLoader makes several attempts to generate the owner key +// pair. +TEST_F(OwnerKeyLoaderTest, KeyGenerationRetriedSuccessfully) { + // Make key_loader_ generate the key for the first user. + device_settings_service_.MarkWillEstablishConsumerOwnership(); + owner_key_util_->SimulateGenerateKeyFailure(/*fail_times=*/5); + + key_loader_->Run(); + + EXPECT_FALSE(result_observer_.Get<0>()->is_empty()); + EXPECT_TRUE(result_observer_.Get<1>()->key()); +} + +// Test that OwnerKeyLoader gives up to generate the owner key pair after a +// certain amount of attempts. +TEST_F(OwnerKeyLoaderTest, KeyGenerationRetriedUnsuccessfully) { + // Make key_loader_ generate the key for the first user. + device_settings_service_.MarkWillEstablishConsumerOwnership(); + owner_key_util_->SimulateGenerateKeyFailure(/*fail_times=*/10); + + key_loader_->Run(); + + EXPECT_FALSE(result_observer_.Get<0>()); + EXPECT_FALSE(result_observer_.Get<1>()); +} + +} // namespace ash
diff --git a/chrome/browser/ash/ownership/owner_settings_service_ash.cc b/chrome/browser/ash/ownership/owner_settings_service_ash.cc index d9080dd..419a192 100644 --- a/chrome/browser/ash/ownership/owner_settings_service_ash.cc +++ b/chrome/browser/ash/ownership/owner_settings_service_ash.cc
@@ -82,17 +82,14 @@ crypto::ScopedPK11Slot public_slot, crypto::ScopedPK11Slot private_slot, ReloadKeyCallback callback) { - std::vector<uint8_t> public_key_data; - scoped_refptr<PublicKey> public_key; - if (!owner_key_util->ImportPublicKey(&public_key_data)) { + scoped_refptr<PublicKey> public_key = owner_key_util->ImportPublicKey(); + if (!public_key) { scoped_refptr<PrivateKey> private_key; content::GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(std::move(callback), public_key, private_key)); return; } - public_key = new PublicKey(); - public_key->data().swap(public_key_data); // If private slot is already available, this will check it. If not, we'll get // called again later when the TPM Token is ready, and the slot will be @@ -156,11 +153,11 @@ bool DoesPrivateKeyExistAsyncHelper( const scoped_refptr<OwnerKeyUtil>& owner_key_util) { - std::vector<uint8_t> public_key; - if (!owner_key_util->ImportPublicKey(&public_key)) + scoped_refptr<PublicKey> public_key = owner_key_util->ImportPublicKey(); + if (!public_key) return false; crypto::ScopedSECKEYPrivateKey key = - crypto::FindNSSKeyFromPublicKeyInfo(public_key); + crypto::FindNSSKeyFromPublicKeyInfo(public_key->data()); return key && SECKEY_GetPrivateKeyType(key.get()) == rsaKey; }
diff --git a/chrome/browser/ash/policy/core/device_cloud_policy_store_ash.cc b/chrome/browser/ash/policy/core/device_cloud_policy_store_ash.cc index d7a6b27..ba030a8 100644 --- a/chrome/browser/ash/policy/core/device_cloud_policy_store_ash.cc +++ b/chrome/browser/ash/policy/core/device_cloud_policy_store_ash.cc
@@ -79,13 +79,13 @@ device_settings_service_->GetPublicKey()); if (!install_attributes_->IsCloudManaged() || !device_settings_service_->policy_data() || !public_key.get() || - !public_key->is_loaded()) { + public_key->is_empty()) { LOG(ERROR) << "Policy store failed, is_cloud_managed: " << install_attributes_->IsCloudManaged() << ", policy_data: " << (device_settings_service_->policy_data() != nullptr) << ", public_key: " << (public_key.get() != nullptr) << ", public_key_is_loaded: " - << (public_key.get() ? public_key->is_loaded() : false); + << (public_key.get() ? !public_key->is_empty() : false); status_ = STATUS_BAD_STATE; NotifyStoreError(); return;
diff --git a/chrome/browser/ash/policy/core/device_local_account_policy_store.cc b/chrome/browser/ash/policy/core/device_local_account_policy_store.cc index 9ea313a..313ac4ff 100644 --- a/chrome/browser/ash/policy/core/device_local_account_policy_store.cc +++ b/chrome/browser/ash/policy/core/device_local_account_policy_store.cc
@@ -221,9 +221,9 @@ // updated only after the successful installation of the policy. scoped_refptr<ownership::PublicKey> key = device_settings_service_->GetPublicKey(); - if (!key.get() || !key->is_loaded() || !device_policy_data) { + if (!key.get() || key->is_empty() || !device_policy_data) { LOG(ERROR) << "Failed policy validation, key: " << (key.get() != nullptr) - << ", is_loaded: " << (key.get() ? key->is_loaded() : false) + << ", is_loaded: " << (key.get() ? !key->is_empty() : false) << ", device_policy_data: " << (device_policy_data != nullptr); std::move(callback).Run(/*signature_validation_public_key=*/std::string(), /*validator=*/nullptr);
diff --git a/chrome/browser/ash/policy/external_data/handlers/cloud_external_data_policy_handler.cc b/chrome/browser/ash/policy/external_data/handlers/cloud_external_data_policy_handler.cc index 1b46b2a..2810e1f9 100644 --- a/chrome/browser/ash/policy/external_data/handlers/cloud_external_data_policy_handler.cc +++ b/chrome/browser/ash/policy/external_data/handlers/cloud_external_data_policy_handler.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ash/policy/external_data/handlers/cloud_external_data_policy_handler.h" +#include "chrome/browser/browser_process.h" #include "components/user_manager/known_user.h" namespace policy { @@ -13,8 +14,9 @@ // static AccountId CloudExternalDataPolicyHandler::GetAccountId( const std::string& user_id) { - return user_manager::known_user::GetAccountId(user_id, std::string() /* id */, - AccountType::UNKNOWN); + user_manager::KnownUser known_user(g_browser_process->local_state()); + return known_user.GetAccountId(user_id, std::string() /* id */, + AccountType::UNKNOWN); } } // namespace policy
diff --git a/chrome/browser/ash/policy/handlers/system_proxy_handler.cc b/chrome/browser/ash/policy/handlers/system_proxy_handler.cc index 3dec089e..95b3d2a 100644 --- a/chrome/browser/ash/policy/handlers/system_proxy_handler.cc +++ b/chrome/browser/ash/policy/handlers/system_proxy_handler.cc
@@ -61,7 +61,7 @@ std::vector<std::string> system_services_auth_schemes; if (auth_schemes) { - for (const auto& auth_scheme : auth_schemes->GetListDeprecated()) + for (const auto& auth_scheme : auth_schemes->GetList()) system_services_auth_schemes.push_back(auth_scheme.GetString()); }
diff --git a/chrome/browser/ash/policy/networking/euicc_status_uploader.cc b/chrome/browser/ash/policy/networking/euicc_status_uploader.cc index 18cdcf7..6a4ba9ed3 100644 --- a/chrome/browser/ash/policy/networking/euicc_status_uploader.cc +++ b/chrome/browser/ash/policy/networking/euicc_status_uploader.cc
@@ -128,7 +128,7 @@ auto* mutable_esim_profiles = upload_request->mutable_esim_profiles(); for (const auto& esim_profile : status.FindListPath(kLastUploadedEuiccStatusESimProfilesKey) - ->GetListDeprecated()) { + ->GetList()) { enterprise_management::ESimProfileInfo esim_profile_info; esim_profile_info.set_iccid(*esim_profile.FindStringKey( kLastUploadedEuiccStatusESimProfilesIccidKey));
diff --git a/chrome/browser/ash/policy/reporting/arc_app_install_event_logger.cc b/chrome/browser/ash/policy/reporting/arc_app_install_event_logger.cc index e5b4334..fbbd7e95 100644 --- a/chrome/browser/ash/policy/reporting/arc_app_install_event_logger.cc +++ b/chrome/browser/ash/policy/reporting/arc_app_install_event_logger.cc
@@ -146,7 +146,7 @@ GetPackagesFromPref(arc::prefs::kArcPushInstallAppsPending); std::set<std::string> noncompliant_apps_in_report; - for (const auto& detail : details->GetListDeprecated()) { + for (const auto& detail : details->GetList()) { const base::Value* const reason = detail.FindKeyOfType("nonComplianceReason", base::Value::Type::INTEGER); if (!reason || reason->GetInt() != kNonComplianceReasonAppNotInstalled) {
diff --git a/chrome/browser/ash/settings/about_flags.cc b/chrome/browser/ash/settings/about_flags.cc index 7f5cfb3..c6fc4cc 100644 --- a/chrome/browser/ash/settings/about_flags.cc +++ b/chrome/browser/ash/settings/about_flags.cc
@@ -47,7 +47,7 @@ return flags; } - for (const auto& flag : flags_list.value().GetListDeprecated()) { + for (const auto& flag : flags_list.value().GetList()) { if (!flag.is_string()) { LOG(WARNING) << "Invalid entry in encoded feature flags"; continue;
diff --git a/chrome/browser/ash/settings/device_settings_service.cc b/chrome/browser/ash/settings/device_settings_service.cc index 65c84a00..2e82985 100644 --- a/chrome/browser/ash/settings/device_settings_service.cc +++ b/chrome/browser/ash/settings/device_settings_service.cc
@@ -133,6 +133,17 @@ } } +void DeviceSettingsService::GetPolicyDataAsync(PolicyDataCallback callback) { + if (policy_data_) { + std::move(callback).Run(policy_data_.get()); + return; + } + + pending_policy_data_callbacks_.push_back(std::move(callback)); + if (pending_operations_.empty()) + EnqueueLoad(false); +} + scoped_refptr<PublicKey> DeviceSettingsService::GetPublicKey() { return public_key_; } @@ -172,9 +183,9 @@ } DeviceSettingsService::OwnershipStatus - DeviceSettingsService::GetOwnershipStatus() { +DeviceSettingsService::GetOwnershipStatus() { if (public_key_.get()) - return public_key_->is_loaded() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE; + return public_key_->is_empty() ? OWNERSHIP_NONE : OWNERSHIP_TAKEN; if (device_mode_ == policy::DEVICE_MODE_ENTERPRISE_AD) return OWNERSHIP_TAKEN; return OWNERSHIP_UNKNOWN; @@ -308,8 +319,8 @@ void DeviceSettingsService::StartNextOperation() { if (!pending_operations_.empty() && session_manager_client_ && owner_key_util_.get()) { - pending_operations_.front()->Start( - session_manager_client_, owner_key_util_, public_key_); + pending_operations_.front()->Start(session_manager_client_, owner_key_util_, + public_key_); } } @@ -360,6 +371,10 @@ NotifyDeviceSettingsUpdated(); RunPendingOwnershipStatusCallbacks(); + if ((status == STORE_SUCCESS) || (status == STORE_NO_POLICY)) { + RunPendingPolicyDataCallbacks(); + } + // The completion callback happens after the notification so clients can // filter self-triggered updates. if (!callback.is_null()) @@ -384,6 +399,14 @@ } } +void DeviceSettingsService::RunPendingPolicyDataCallbacks() { + std::vector<PolicyDataCallback> callbacks; + callbacks.swap(pending_policy_data_callbacks_); + for (auto& callback : callbacks) { + std::move(callback).Run(policy_data_.get()); + } +} + ScopedTestDeviceSettingsService::ScopedTestDeviceSettingsService() { DeviceSettingsService::Initialize(); }
diff --git a/chrome/browser/ash/settings/device_settings_service.h b/chrome/browser/ash/settings/device_settings_service.h index 53ab4c2..223e0c1 100644 --- a/chrome/browser/ash/settings/device_settings_service.h +++ b/chrome/browser/ash/settings/device_settings_service.h
@@ -24,7 +24,7 @@ namespace ownership { class OwnerKeyUtil; class PublicKey; -} +} // namespace ownership namespace policy { namespace off_hours { @@ -60,7 +60,9 @@ OWNERSHIP_TAKEN }; - typedef base::OnceCallback<void(OwnershipStatus)> OwnershipStatusCallback; + using OwnershipStatusCallback = base::OnceCallback<void(OwnershipStatus)>; + using PolicyDataCallback = + base::OnceCallback<void(enterprise_management::PolicyData*)>; // Status codes for Load() and Store(). // These values are logged to UMA. Entries should not be renumbered and @@ -127,6 +129,13 @@ return policy_data_.get(); } + // Asynchronously return policy data. If Chrome doesn't have any policy data + // yet, it will enqueue a new policy load. The callback will be called on + // success or if policy loaded successfully, but it it was empty (i.e. + // STORE_NO_POLICY). If failed to load, the callback is expected to be called + // some time later on the next successful load (requested by something else). + void GetPolicyDataAsync(PolicyDataCallback callback); + const enterprise_management::PolicyFetchResponse* policy_fetch_response() const { return policy_fetch_response_.get(); @@ -134,8 +143,8 @@ // Returns the currently active device settings. Returns nullptr if the device // settings have not been retrieved from session_manager yet. - const enterprise_management::ChromeDeviceSettingsProto* - device_settings() const { + const enterprise_management::ChromeDeviceSettingsProto* device_settings() + const { return device_settings_.get(); } @@ -209,6 +218,12 @@ // of owner is fully loaded. void MarkWillEstablishConsumerOwnership(); + // Returns whether the current user should take ownership of the device + // (effectively whether the user is the first consumer user on the device). + bool GetWillEstablishConsumerOwnership() const { + return will_establish_consumer_ownership_; + } + // Adds an observer. void AddObserver(Observer* observer); // Removes an observer. @@ -259,12 +274,16 @@ // Processes pending callbacks from GetOwnershipStatusAsync(). void RunPendingOwnershipStatusCallbacks(); + // Processes pending callbacks from GetPolicyDataAsync(). + void RunPendingPolicyDataCallbacks(); + SessionManagerClient* session_manager_client_ = nullptr; scoped_refptr<ownership::OwnerKeyUtil> owner_key_util_; Status store_status_ = STORE_SUCCESS; std::vector<OwnershipStatusCallback> pending_ownership_status_callbacks_; + std::vector<PolicyDataCallback> pending_policy_data_callbacks_; std::string username_; scoped_refptr<ownership::PublicKey> public_key_;
diff --git a/chrome/browser/ash/settings/device_settings_service_unittest.cc b/chrome/browser/ash/settings/device_settings_service_unittest.cc index 4a6fd73..5b155080 100644 --- a/chrome/browser/ash/settings/device_settings_service_unittest.cc +++ b/chrome/browser/ash/settings/device_settings_service_unittest.cc
@@ -225,7 +225,7 @@ FlushDeviceSettings(); EXPECT_FALSE(device_settings_service_->HasPrivateOwnerKey()); ASSERT_TRUE(device_settings_service_->GetPublicKey().get()); - EXPECT_FALSE(device_settings_service_->GetPublicKey()->is_loaded()); + EXPECT_TRUE(device_settings_service_->GetPublicKey()->is_empty()); EXPECT_EQ(DeviceSettingsService::OWNERSHIP_NONE, device_settings_service_->GetOwnershipStatus()); EXPECT_EQ(DeviceSettingsService::OWNERSHIP_NONE, ownership_status_); @@ -237,7 +237,7 @@ FlushDeviceSettings(); EXPECT_FALSE(device_settings_service_->HasPrivateOwnerKey()); ASSERT_TRUE(device_settings_service_->GetPublicKey().get()); - ASSERT_TRUE(device_settings_service_->GetPublicKey()->is_loaded()); + ASSERT_FALSE(device_settings_service_->GetPublicKey()->is_empty()); EXPECT_EQ(device_policy_->GetPublicSigningKeyAsString(), device_settings_service_->GetPublicKey()->as_string()); EXPECT_EQ(DeviceSettingsService::OWNERSHIP_TAKEN, @@ -253,7 +253,7 @@ FlushDeviceSettings(); EXPECT_TRUE(device_settings_service_->HasPrivateOwnerKey()); ASSERT_TRUE(device_settings_service_->GetPublicKey().get()); - ASSERT_TRUE(device_settings_service_->GetPublicKey()->is_loaded()); + ASSERT_FALSE(device_settings_service_->GetPublicKey()->is_empty()); EXPECT_EQ(device_policy_->GetPublicSigningKeyAsString(), device_settings_service_->GetPublicKey()->as_string()); EXPECT_EQ(DeviceSettingsService::OWNERSHIP_TAKEN, @@ -290,7 +290,7 @@ EXPECT_FALSE(device_settings_service_->HasPrivateOwnerKey()); ASSERT_TRUE(device_settings_service_->GetPublicKey().get()); - ASSERT_TRUE(device_settings_service_->GetPublicKey()->is_loaded()); + ASSERT_FALSE(device_settings_service_->GetPublicKey()->is_empty()); EXPECT_EQ(device_policy_->GetPublicSigningKeyAsString(), device_settings_service_->GetPublicKey()->as_string()); EXPECT_EQ(DeviceSettingsService::OWNERSHIP_TAKEN, @@ -302,7 +302,7 @@ EXPECT_FALSE(device_settings_service_->HasPrivateOwnerKey()); ASSERT_TRUE(device_settings_service_->GetPublicKey().get()); - ASSERT_TRUE(device_settings_service_->GetPublicKey()->is_loaded()); + ASSERT_FALSE(device_settings_service_->GetPublicKey()->is_empty()); EXPECT_EQ(device_policy_->GetPublicSigningKeyAsString(), device_settings_service_->GetPublicKey()->as_string()); EXPECT_FALSE(device_settings_service_->HasPrivateOwnerKey()); @@ -330,7 +330,7 @@ EXPECT_FALSE(device_settings_service_->HasPrivateOwnerKey()); ASSERT_TRUE(device_settings_service_->GetPublicKey().get()); - ASSERT_TRUE(device_settings_service_->GetPublicKey()->is_loaded()); + ASSERT_FALSE(device_settings_service_->GetPublicKey()->is_empty()); EXPECT_EQ(device_policy_->GetPublicSigningKeyAsString(), device_settings_service_->GetPublicKey()->as_string()); EXPECT_EQ(DeviceSettingsService::OWNERSHIP_TAKEN, @@ -343,7 +343,7 @@ EXPECT_TRUE(device_settings_service_->HasPrivateOwnerKey()); ASSERT_TRUE(device_settings_service_->GetPublicKey().get()); - ASSERT_TRUE(device_settings_service_->GetPublicKey()->is_loaded()); + ASSERT_FALSE(device_settings_service_->GetPublicKey()->is_empty()); EXPECT_EQ(device_policy_->GetPublicSigningKeyAsString(), device_settings_service_->GetPublicKey()->as_string()); } @@ -368,7 +368,7 @@ EXPECT_FALSE(device_settings_service_->HasPrivateOwnerKey()); ASSERT_TRUE(device_settings_service_->GetPublicKey().get()); - ASSERT_TRUE(device_settings_service_->GetPublicKey()->is_loaded()); + ASSERT_FALSE(device_settings_service_->GetPublicKey()->is_empty()); EXPECT_EQ(device_policy_->GetPublicSigningKeyAsString(), device_settings_service_->GetPublicKey()->as_string()); EXPECT_EQ(DeviceSettingsService::OWNERSHIP_TAKEN, @@ -382,7 +382,7 @@ EXPECT_TRUE(device_settings_service_->HasPrivateOwnerKey()); ASSERT_TRUE(device_settings_service_->GetPublicKey().get()); - ASSERT_TRUE(device_settings_service_->GetPublicKey()->is_loaded()); + ASSERT_FALSE(device_settings_service_->GetPublicKey()->is_empty()); EXPECT_EQ(device_policy_->GetPublicSigningKeyAsString(), device_settings_service_->GetPublicKey()->as_string()); EXPECT_EQ(DeviceSettingsService::OWNERSHIP_TAKEN, @@ -410,7 +410,7 @@ EXPECT_TRUE(device_settings_service_->HasPrivateOwnerKey()); ASSERT_TRUE(device_settings_service_->GetPublicKey().get()); - ASSERT_TRUE(device_settings_service_->GetPublicKey()->is_loaded()); + ASSERT_FALSE(device_settings_service_->GetPublicKey()->is_empty()); EXPECT_EQ(device_policy_->GetPublicSigningKeyAsString(), device_settings_service_->GetPublicKey()->as_string()); EXPECT_EQ(DeviceSettingsService::OWNERSHIP_TAKEN, @@ -427,7 +427,7 @@ EXPECT_TRUE(device_settings_service_->HasPrivateOwnerKey()); ASSERT_TRUE(device_settings_service_->GetPublicKey().get()); - ASSERT_TRUE(device_settings_service_->GetPublicKey()->is_loaded()); + ASSERT_FALSE(device_settings_service_->GetPublicKey()->is_empty()); EXPECT_EQ(device_policy_->GetPublicSigningKeyAsString(), device_settings_service_->GetPublicKey()->as_string()); EXPECT_EQ(DeviceSettingsService::OWNERSHIP_TAKEN, @@ -512,7 +512,7 @@ // Verify owner key is loaded and ownership status is updated. EXPECT_TRUE(device_settings_service_->HasPrivateOwnerKey()); ASSERT_TRUE(device_settings_service_->GetPublicKey().get()); - ASSERT_TRUE(device_settings_service_->GetPublicKey()->is_loaded()); + ASSERT_FALSE(device_settings_service_->GetPublicKey()->is_empty()); EXPECT_EQ(device_policy_->GetPublicSigningKeyAsString(), device_settings_service_->GetPublicKey()->as_string()); EXPECT_EQ(DeviceSettingsService::OWNERSHIP_TAKEN,
diff --git a/chrome/browser/ash/settings/session_manager_operation.cc b/chrome/browser/ash/settings/session_manager_operation.cc index 076b01c..5f4364e 100644 --- a/chrome/browser/ash/settings/session_manager_operation.cc +++ b/chrome/browser/ash/settings/session_manager_operation.cc
@@ -89,7 +89,7 @@ } void SessionManagerOperation::EnsurePublicKey(base::OnceClosure callback) { - if (force_key_load_ || !public_key_ || !public_key_->is_loaded()) { + if (force_key_load_ || !public_key_ || public_key_->is_empty()) { base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE, @@ -107,14 +107,18 @@ scoped_refptr<PublicKey> SessionManagerOperation::LoadPublicKey( scoped_refptr<OwnerKeyUtil> util, scoped_refptr<PublicKey> current_key) { - scoped_refptr<PublicKey> public_key(new PublicKey()); - // Keep already-existing public key. - if (current_key && current_key->is_loaded()) { - public_key->data() = current_key->data(); + if (current_key && !current_key->is_empty()) { + return current_key->clone(); } - if (!public_key->is_loaded() && util->IsPublicKeyPresent()) { - if (!util->ImportPublicKey(&public_key->data())) + + scoped_refptr<PublicKey> public_key = + base::MakeRefCounted<ownership::PublicKey>( + /*is_persisted=*/false, /*data=*/std::vector<uint8_t>()); + + if (util->IsPublicKeyPresent()) { + public_key = util->ImportPublicKey(); + if (!public_key || public_key->is_empty()) LOG(ERROR) << "Failed to load public owner key."; } @@ -126,7 +130,7 @@ force_key_load_ = false; public_key_ = new_key; - if (!public_key_ || !public_key_->is_loaded()) { + if (!public_key_ || public_key_->is_empty()) { ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE); return; }
diff --git a/chrome/browser/ash/settings/session_manager_operation_unittest.cc b/chrome/browser/ash/settings/session_manager_operation_unittest.cc index ef6bf2e..ad0d18f9 100644 --- a/chrome/browser/ash/settings/session_manager_operation_unittest.cc +++ b/chrome/browser/ash/settings/session_manager_operation_unittest.cc
@@ -106,7 +106,7 @@ void CheckPublicKeyLoaded(SessionManagerOperation* op) { ASSERT_TRUE(op->public_key().get()); - ASSERT_TRUE(op->public_key()->is_loaded()); + ASSERT_FALSE(op->public_key()->is_empty()); std::vector<uint8_t> public_key; ASSERT_TRUE(policy_.GetSigningKey()->ExportPublicKey(&public_key)); EXPECT_EQ(public_key, op->public_key()->data()); @@ -144,7 +144,7 @@ EXPECT_FALSE(op.policy_data().get()); EXPECT_FALSE(op.device_settings().get()); ASSERT_TRUE(op.public_key().get()); - EXPECT_FALSE(op.public_key()->is_loaded()); + EXPECT_TRUE(op.public_key()->is_empty()); } TEST_F(SessionManagerOperationTest, LoadOwnerKey) { @@ -233,7 +233,7 @@ // Verify the public_key() is properly set, but the callback is // not yet called. EXPECT_TRUE(op->public_key().get()); - EXPECT_TRUE(op->public_key()->is_loaded()); + EXPECT_FALSE(op->public_key()->is_empty()); Mock::VerifyAndClearExpectations(test); // Now install a different key and policy.
diff --git a/chrome/browser/autofill/autofill_browsertest.cc b/chrome/browser/autofill/autofill_browsertest.cc index 8e2b375f..3db2e6de 100644 --- a/chrome/browser/autofill/autofill_browsertest.cc +++ b/chrome/browser/autofill/autofill_browsertest.cc
@@ -912,8 +912,8 @@ }; AutofillTestFormSubmission() { - std::vector<base::Feature> enabled; - std::vector<base::Feature> disabled; + std::vector<base::test::FeatureRef> enabled; + std::vector<base::test::FeatureRef> disabled; if (std::get<0>(GetParam())) { enabled.push_back(features::kAutofillAllowDuplicateFormSubmissions); } else {
diff --git a/chrome/browser/browsing_data/access_context_audit_service_unittest.cc b/chrome/browser/browsing_data/access_context_audit_service_unittest.cc index cba58b5..5fb3e6c 100644 --- a/chrome/browser/browsing_data/access_context_audit_service_unittest.cc +++ b/chrome/browser/browsing_data/access_context_audit_service_unittest.cc
@@ -172,10 +172,10 @@ scoped_refptr<base::UpdateableSequencedTaskRunner> task_runner_; std::vector<AccessContextAuditDatabase::AccessRecord> records_; - virtual std::vector<base::Feature> enabled_features() { + virtual std::vector<base::test::FeatureRef> enabled_features() { return {features::kClientStorageAccessContextAuditing}; } - virtual std::vector<base::Feature> disabled_features() { + virtual std::vector<base::test::FeatureRef> disabled_features() { return {browsing_data::features::kEnableRemovingAllThirdPartyCookies}; } }; @@ -878,11 +878,13 @@ EXPECT_TRUE(records[0].top_frame_origin.opaque()); } - std::vector<base::Feature> enabled_features() override { + std::vector<base::test::FeatureRef> enabled_features() override { return {features::kClientStorageAccessContextAuditing, browsing_data::features::kEnableRemovingAllThirdPartyCookies}; } - std::vector<base::Feature> disabled_features() override { return {}; } + std::vector<base::test::FeatureRef> disabled_features() override { + return {}; + } }; // Test that when we enable user controls to clear third-party data, we do not
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc index 399975e..c5ca255 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc +++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
@@ -117,7 +117,7 @@ : public BrowsingDataRemoverBrowserTestBase { public: BrowsingDataRemoverBrowserTest() { - std::vector<base::Feature> enabled_features = {}; + std::vector<base::test::FeatureRef> enabled_features = {}; #if BUILDFLAG(ENABLE_LIBRARY_CDMS) enabled_features.push_back(media::kExternalClearKeyForTesting); #endif
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest_base.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest_base.cc index aa80907..4676d05 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_browsertest_base.cc +++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest_base.cc
@@ -139,7 +139,7 @@ default; void BrowsingDataRemoverBrowserTestBase::InitFeatureList( - std::vector<base::Feature> enabled_features) { + std::vector<base::test::FeatureRef> enabled_features) { feature_list_.InitWithFeatures(enabled_features, {}); }
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest_base.h b/chrome/browser/browsing_data/browsing_data_remover_browsertest_base.h index 42798619..52a16ac2 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_browsertest_base.h +++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest_base.h
@@ -18,7 +18,7 @@ BrowsingDataRemoverBrowserTestBase(); ~BrowsingDataRemoverBrowserTestBase() override; - void InitFeatureList(std::vector<base::Feature> enabled_features); + void InitFeatureList(std::vector<base::test::FeatureRef> enabled_features); void SetUpOnMainThread() override; // If `web_contents` is not specified, `GetActiveWebContents` will be used.
diff --git a/chrome/browser/browsing_data/incognito_browsing_data_browsertest.cc b/chrome/browser/browsing_data/incognito_browsing_data_browsertest.cc index 83e985bf..fc0f0f38 100644 --- a/chrome/browser/browsing_data/incognito_browsing_data_browsertest.cc +++ b/chrome/browser/browsing_data/incognito_browsing_data_browsertest.cc
@@ -64,7 +64,7 @@ : public BrowsingDataRemoverBrowserTestBase { public: IncognitoBrowsingDataBrowserTest() { - std::vector<base::Feature> enabled_features = {}; + std::vector<base::test::FeatureRef> enabled_features = {}; #if BUILDFLAG(ENABLE_LIBRARY_CDMS) enabled_features.push_back(media::kExternalClearKeyForTesting); #endif
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 099c082..879988f 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1634,6 +1634,7 @@ "../ash/notifications/request_system_proxy_credentials_view_unittest.cc", "../ash/notifications/update_required_notification_unittest.cc", "../ash/os_feedback/os_feedback_screenshot_manager_unittest.cc", + "../ash/ownership/owner_key_loader_unittest.cc", "../ash/ownership/owner_settings_service_ash_unittest.cc", "../ash/pcie_peripheral/ash_usb_detector_unittest.cc", "../ash/phonehub/browser_tabs_metadata_fetcher_impl_unittest.cc",
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.cc index 44f04f2..7ddf52f02 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.cc
@@ -17,6 +17,7 @@ #include "base/feature_list.h" #include "chrome/browser/ash/drive/file_system_util.h" #include "chrome/browser/ash/file_manager/app_id.h" +#include "chrome/browser/ash/file_manager/file_tasks.h" #include "chrome/browser/ash/file_manager/fileapi_util.h" #include "chrome/browser/ash/file_manager/filesystem_api_util.h" #include "chrome/browser/chromeos/fileapi/file_system_backend.h" @@ -45,14 +46,14 @@ // Make a set of unique filename suffixes out of the list of file URLs. std::set<std::string> GetUniqueSuffixes( - const std::vector<std::string>& url_list, + const std::vector<std::string>& file_urls, const storage::FileSystemContext* context) { std::set<std::string> suffixes; - for (size_t i = 0; i < url_list.size(); ++i) { + for (const auto& file_url : file_urls) { const FileSystemURL url = - context->CrackURLInFirstPartyContext(GURL(url_list[i])); + context->CrackURLInFirstPartyContext(GURL{file_url}); if (!url.is_valid() || url.path().empty()) - return std::set<std::string>(); + return {}; // We'll skip empty suffixes. if (!url.path().Extension().empty()) suffixes.insert(url.path().Extension()); @@ -64,8 +65,7 @@ std::set<std::string> GetUniqueMimeTypes( const std::vector<std::string>& mime_type_list) { std::set<std::string> mime_types; - for (size_t i = 0; i < mime_type_list.size(); ++i) { - const std::string mime_type = mime_type_list[i]; + for (const auto& mime_type : mime_type_list) { // We'll skip empty MIME types and existing MIME types. if (!mime_type.empty()) mime_types.insert(mime_type); @@ -105,9 +105,9 @@ profile, render_frame_host()); std::vector<FileSystemURL> urls; - for (size_t i = 0; i < params->urls.size(); i++) { + for (const auto& url_param : params->urls) { const FileSystemURL url = - file_system_context->CrackURLInFirstPartyContext(GURL(params->urls[i])); + file_system_context->CrackURLInFirstPartyContext(GURL{url_param}); if (!chromeos::FileSystemBackend::CanHandleURL(url)) { return RespondNow(Error(kInvalidFileUrl)); } @@ -159,8 +159,8 @@ // Collect all the URLs, convert them to GURLs, and crack all the urls into // file paths. - for (size_t i = 0; i < params->urls.size(); ++i) { - const GURL url(params->urls[i]); + for (const auto& url_param : params->urls) { + const GURL url{url_param}; storage::FileSystemURL file_system_url( file_system_context->CrackURLInFirstPartyContext(url)); if (!chromeos::FileSystemBackend::CanHandleURL(file_system_url)) @@ -211,12 +211,11 @@ } void FileManagerPrivateInternalGetFileTasksFunction::OnFileTasksListed( - std::unique_ptr<std::vector<file_manager::file_tasks::FullTaskDescriptor>> - tasks) { + std::unique_ptr<file_manager::file_tasks::ResultingTasks> resulting_tasks) { // Convert the tasks into JSON compatible objects. using api::file_manager_private::FileTask; std::vector<FileTask> results; - for (const file_manager::file_tasks::FullTaskDescriptor& task : *tasks) { + for (const auto& task : resulting_tasks->tasks) { FileTask converted; converted.descriptor.app_id = task.task_descriptor.app_id; converted.descriptor.task_type =
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.h b/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.h index 779bb4d..78e3d823 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.h +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.h
@@ -70,8 +70,8 @@ std::unique_ptr<std::set<base::FilePath>> path_directory_set); void OnFileTasksListed( - std::unique_ptr<std::vector<file_manager::file_tasks::FullTaskDescriptor>> - tasks); + std::unique_ptr<file_manager::file_tasks::ResultingTasks> + resulting_tasks); std::unique_ptr<app_file_handler_util::IsDirectoryCollector> is_directory_collector_;
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc index b697aac06..35d1dd4 100644 --- a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc +++ b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc
@@ -110,6 +110,14 @@ ); chrome.test.succeed(); }, + async function getTpmInfo() { + await chrome.test.assertPromiseRejects( + chrome.os.telemetry.getTpmInfo(), + 'Error: Unauthorized access to chrome.os.telemetry.getTpmInfo. ' + + '%s' + ); + chrome.test.succeed(); + }, async function getVpdInfo() { await chrome.test.assertPromiseRejects( chrome.os.telemetry.getVpdInfo(),
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api.cc b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api.cc index bbacad91..8d52a0f 100644 --- a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api.cc +++ b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api.cc
@@ -339,6 +339,32 @@ api::os_telemetry::GetStatefulPartitionInfo::Results::Create(result))); } +// OsTelemetryGetTpmInfoFunction ----------------------------------------------- + +OsTelemetryGetTpmInfoFunction::OsTelemetryGetTpmInfoFunction() = default; +OsTelemetryGetTpmInfoFunction::~OsTelemetryGetTpmInfoFunction() = default; + +void OsTelemetryGetTpmInfoFunction::RunIfAllowed() { + auto cb = base::BindOnce(&OsTelemetryGetTpmInfoFunction::OnResult, this); + + GetRemoteService()->ProbeTelemetryInfo( + {crosapi::mojom::ProbeCategoryEnum::kTpm}, std::move(cb)); +} + +void OsTelemetryGetTpmInfoFunction::OnResult( + crosapi::mojom::ProbeTelemetryInfoPtr ptr) { + if (!ptr || !ptr->tpm_result || !ptr->tpm_result->is_tpm_info()) { + Respond(Error("API internal error")); + return; + } + auto& tpm_info = ptr->tpm_result->get_tpm_info(); + + api::os_telemetry::TpmInfo result = + converters::ConvertPtr<api::os_telemetry::TpmInfo>(std::move(tpm_info)); + + Respond(ArgumentList(api::os_telemetry::GetTpmInfo::Results::Create(result))); +} + // OsTelemetryGetVpdInfoFunction ----------------------------------------------- OsTelemetryGetVpdInfoFunction::OsTelemetryGetVpdInfoFunction() = default;
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api.h b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api.h index ffe5731..a8f4e154 100644 --- a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api.h +++ b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api.h
@@ -214,6 +214,24 @@ void OnResult(crosapi::mojom::ProbeTelemetryInfoPtr ptr); }; +class OsTelemetryGetTpmInfoFunction : public TelemetryApiFunctionBase { + public: + DECLARE_EXTENSION_FUNCTION("os.telemetry.getTpmInfo", OS_TELEMETRY_GETTPMINFO) + + OsTelemetryGetTpmInfoFunction(); + OsTelemetryGetTpmInfoFunction(const OsTelemetryGetTpmInfoFunction&) = delete; + OsTelemetryGetTpmInfoFunction& operator=( + const OsTelemetryGetTpmInfoFunction&) = delete; + + private: + ~OsTelemetryGetTpmInfoFunction() override; + + // BaseTelemetryExtensionApiGuardFunction: + void RunIfAllowed() override; + + void OnResult(crosapi::mojom::ProbeTelemetryInfoPtr ptr); +}; + } // namespace chromeos #endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_TELEMETRY_API_TELEMETRY_API_H_
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_browsertest.cc b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_browsertest.cc index 7641a77..1f59250 100644 --- a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_browsertest.cc +++ b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_browsertest.cc
@@ -160,6 +160,14 @@ ); chrome.test.succeed(); }, + async function getTpmInfo() { + await chrome.test.assertPromiseRejects( + chrome.os.telemetry.getTpmInfo(), + 'Error: API chrome.os.telemetry.getTpmInfo failed. ' + + 'Not supported by ash browser' + ); + chrome.test.succeed(); + }, async function getVpdInfo() { await chrome.test.assertPromiseRejects( chrome.os.telemetry.getVpdInfo(), @@ -1078,6 +1086,127 @@ )"); } +IN_PROC_BROWSER_TEST_F(TelemetryExtensionTelemetryApiBrowserTest, + GetTpmInfo_Error) { +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // If Probe interface is not available on this version of ash-chrome, this + // test suite will no-op. + if (!IsServiceAvailable()) { + return; + } +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + + // Configure FakeProbeService. + { + auto fake_service_impl = std::make_unique<FakeProbeService>(); + fake_service_impl->SetExpectedLastRequestedCategories( + {crosapi::mojom::ProbeCategoryEnum::kTpm}); + + SetServiceForTesting(std::move(fake_service_impl)); + } + + CreateExtensionAndRunServiceWorker(R"( + chrome.test.runTests([ + async function getTpmInfo() { + await chrome.test.assertPromiseRejects( + chrome.os.telemetry.getTpmInfo(), + 'Error: API internal error' + ); + chrome.test.succeed(); + } + ]); + )"); +} + +IN_PROC_BROWSER_TEST_F(TelemetryExtensionTelemetryApiBrowserTest, + GetTpmInfo_Success) { +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // If Probe interface is not available on this version of ash-chrome, this + // test suite will no-op. + if (!IsServiceAvailable()) { + return; + } +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + + // Configure FakeProbeService. + { + auto telemetry_info = crosapi::mojom::ProbeTelemetryInfo::New(); + { + auto tpm_version = crosapi::mojom::ProbeTpmVersion::New(); + tpm_version->gsc_version = crosapi::mojom::ProbeTpmGSCVersion::kCr50; + tpm_version->family = crosapi::mojom::UInt32Value::New(120); + tpm_version->spec_level = crosapi::mojom::UInt64Value::New(1000); + tpm_version->manufacturer = crosapi::mojom::UInt32Value::New(42); + tpm_version->tpm_model = crosapi::mojom::UInt32Value::New(333); + tpm_version->firmware_version = crosapi::mojom::UInt64Value::New(10000); + tpm_version->vendor_specific = "VendorSpecific"; + + auto tpm_status = crosapi::mojom::ProbeTpmStatus::New(); + tpm_status->enabled = crosapi::mojom::BoolValue::New(true); + tpm_status->owned = crosapi::mojom::BoolValue::New(false); + tpm_status->owner_password_is_present = + crosapi::mojom::BoolValue::New(false); + + auto dictonary_attack = crosapi::mojom::ProbeTpmDictionaryAttack::New(); + dictonary_attack->counter = crosapi::mojom::UInt32Value::New(5); + dictonary_attack->threshold = crosapi::mojom::UInt32Value::New(1000); + dictonary_attack->lockout_in_effect = + crosapi::mojom::BoolValue::New(false); + dictonary_attack->lockout_seconds_remaining = + crosapi::mojom::UInt32Value::New(0); + + auto tpm_info = crosapi::mojom::ProbeTpmInfo::New(); + tpm_info->version = std::move(tpm_version); + tpm_info->status = std::move(tpm_status); + tpm_info->dictionary_attack = std::move(dictonary_attack); + + telemetry_info->tpm_result = + crosapi::mojom::ProbeTpmResult::NewTpmInfo(std::move(tpm_info)); + } + + auto fake_service_impl = std::make_unique<FakeProbeService>(); + fake_service_impl->SetProbeTelemetryInfoResponse(std::move(telemetry_info)); + fake_service_impl->SetExpectedLastRequestedCategories( + {crosapi::mojom::ProbeCategoryEnum::kTpm}); + + SetServiceForTesting(std::move(fake_service_impl)); + } + + CreateExtensionAndRunServiceWorker(R"( + chrome.test.runTests([ + async function getTpmInfo() { + const result = await chrome.os.telemetry.getTpmInfo(); + chrome.test.assertEq( + // The dictionary members are ordered lexicographically by the Unicode + // codepoints that comprise their identifiers. + { + version: { + gscVersion: "cr50", + family: 120, + specLevel: 1000, + manufacturer: 42, + tpmModel: 333, + firmwareVersion: 10000, + vendorSpecific: "VendorSpecific", + }, + status: { + enabled: true, + owned: false, + ownerPasswordIsPresent: false, + }, + dictionaryAttack: { + counter: 5, + threshold: 1000, + lockoutInEffect: false, + lockoutSecondsRemaining: 0, + }, + }, result); + chrome.test.succeed(); + } + ]); + )"); +} + class TelemetryExtensionTelemetryApiWithoutSerialNumberBrowserTest : public TelemetryExtensionTelemetryApiBrowserTest { public:
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters.cc b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters.cc index b85137fb..3f935fb 100644 --- a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters.cc +++ b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters.cc
@@ -163,6 +163,88 @@ return result; } +telemetry_api::TpmVersion UncheckedConvertPtr( + telemetry_service::ProbeTpmVersionPtr input) { + telemetry_api::TpmVersion result; + + result.gsc_version = Convert(input->gsc_version); + if (input->family) { + result.family = input->family->value; + } + if (input->spec_level) { + result.spec_level = input->spec_level->value; + } + if (input->manufacturer) { + result.manufacturer = input->manufacturer->value; + } + if (input->tpm_model) { + result.tpm_model = input->tpm_model->value; + } + if (input->firmware_version) { + result.firmware_version = input->firmware_version->value; + } + result.vendor_specific = input->vendor_specific; + + return result; +} + +telemetry_api::TpmStatus UncheckedConvertPtr( + telemetry_service::ProbeTpmStatusPtr input) { + telemetry_api::TpmStatus result; + + if (input->enabled) { + result.enabled = input->enabled->value; + } + if (input->owned) { + result.owned = input->owned->value; + } + if (input->owner_password_is_present) { + result.owner_password_is_present = input->owner_password_is_present->value; + } + + return result; +} + +telemetry_api::TpmDictionaryAttack UncheckedConvertPtr( + telemetry_service::ProbeTpmDictionaryAttackPtr input) { + telemetry_api::TpmDictionaryAttack result; + + if (input->counter) { + result.counter = input->counter->value; + } + if (input->threshold) { + result.threshold = input->threshold->value; + } + if (input->lockout_in_effect) { + result.lockout_in_effect = input->lockout_in_effect->value; + } + if (input->lockout_seconds_remaining) { + result.lockout_seconds_remaining = input->lockout_seconds_remaining->value; + } + + return result; +} + +telemetry_api::TpmInfo UncheckedConvertPtr( + telemetry_service::ProbeTpmInfoPtr input) { + telemetry_api::TpmInfo result; + + if (input->version) { + result.version = + ConvertPtr<telemetry_api::TpmVersion>(std::move(input->version)); + } + if (input->status) { + result.status = + ConvertPtr<telemetry_api::TpmStatus>(std::move(input->status)); + } + if (input->dictionary_attack) { + result.dictionary_attack = ConvertPtr<telemetry_api::TpmDictionaryAttack>( + std::move(input->dictionary_attack)); + } + + return result; +} + } // namespace unchecked telemetry_api::CpuArchitectureEnum Convert( @@ -230,5 +312,18 @@ NOTREACHED(); } +chromeos::api::os_telemetry::TpmGSCVersion Convert( + crosapi::mojom::ProbeTpmGSCVersion input) { + switch (input) { + case telemetry_service::ProbeTpmGSCVersion::kNotGSC: + return telemetry_api::TpmGSCVersion::TPM_GSC_VERSION_NOT_GSC; + case telemetry_service::ProbeTpmGSCVersion::kCr50: + return telemetry_api::TpmGSCVersion::TPM_GSC_VERSION_CR50; + case telemetry_service::ProbeTpmGSCVersion::kTi50: + return telemetry_api::TpmGSCVersion::TPM_GSC_VERSION_TI50; + } + NOTREACHED(); +} + } // namespace converters } // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters.h b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters.h index c188b76f..89f0bf4 100644 --- a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters.h +++ b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters.h
@@ -41,6 +41,9 @@ chromeos::api::os_telemetry::BatteryInfo UncheckedConvertPtr( crosapi::mojom::ProbeBatteryInfoPtr input); +chromeos::api::os_telemetry::NetworkInfo UncheckedConvertPtr( + chromeos::network_health::mojom::NetworkPtr input); + chromeos::api::os_telemetry::NonRemovableBlockDeviceInfo UncheckedConvertPtr( crosapi::mojom::ProbeNonRemovableBlockDeviceInfoPtr); @@ -50,8 +53,17 @@ chromeos::api::os_telemetry::StatefulPartitionInfo UncheckedConvertPtr( crosapi::mojom::ProbeStatefulPartitionInfoPtr input); -chromeos::api::os_telemetry::NetworkInfo UncheckedConvertPtr( - chromeos::network_health::mojom::NetworkPtr input); +chromeos::api::os_telemetry::TpmVersion UncheckedConvertPtr( + crosapi::mojom::ProbeTpmVersionPtr input); + +chromeos::api::os_telemetry::TpmStatus UncheckedConvertPtr( + crosapi::mojom::ProbeTpmStatusPtr input); + +chromeos::api::os_telemetry::TpmDictionaryAttack UncheckedConvertPtr( + crosapi::mojom::ProbeTpmDictionaryAttackPtr input); + +chromeos::api::os_telemetry::TpmInfo UncheckedConvertPtr( + crosapi::mojom::ProbeTpmInfoPtr input); } // namespace unchecked @@ -64,6 +76,9 @@ chromeos::api::os_telemetry::NetworkType Convert( chromeos::network_config::mojom::NetworkType input); +chromeos::api::os_telemetry::TpmGSCVersion Convert( + crosapi::mojom::ProbeTpmGSCVersion input); + template <class OutputT, class InputT> std::vector<OutputT> ConvertPtrVector(std::vector<InputT> input) { std::vector<OutputT> output;
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters_unittest.cc b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters_unittest.cc index 4fed4107..1cf030d9 100644 --- a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters_unittest.cc +++ b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters_unittest.cc
@@ -406,5 +406,179 @@ EXPECT_EQ(static_cast<double_t>(*result.signal_strength), kSignalStrength); } +TEST(TelemetryApiConverters, TpmVersion) { + constexpr uint32_t kFamily = 0x322e3000; + constexpr uint64_t kSpecLevel = 1000; + constexpr uint32_t kManufacturer = 42; + constexpr uint32_t kTpmModel = 101; + constexpr uint64_t kFirmwareVersion = 1001; + constexpr char kVendorSpecific[] = "info"; + + auto input = telemetry_service::ProbeTpmVersion::New(); + input->gsc_version = telemetry_service::ProbeTpmGSCVersion::kCr50; + input->family = telemetry_service::UInt32Value::New(kFamily); + input->spec_level = telemetry_service::UInt64Value::New(kSpecLevel); + input->manufacturer = telemetry_service::UInt32Value::New(kManufacturer); + input->tpm_model = telemetry_service::UInt32Value::New(kTpmModel); + input->firmware_version = + telemetry_service::UInt64Value::New(kFirmwareVersion); + input->vendor_specific = kVendorSpecific; + + auto result = ConvertPtr<telemetry_api::TpmVersion>(std::move(input)); + EXPECT_EQ(telemetry_api::TpmGSCVersion::TPM_GSC_VERSION_CR50, + result.gsc_version); + ASSERT_TRUE(result.family); + EXPECT_EQ(kFamily, static_cast<uint32_t>(*result.family)); + ASSERT_TRUE(result.spec_level); + EXPECT_EQ(kSpecLevel, static_cast<uint64_t>(*result.spec_level)); + ASSERT_TRUE(result.manufacturer); + EXPECT_EQ(kManufacturer, static_cast<uint32_t>(*result.manufacturer)); + ASSERT_TRUE(result.tpm_model); + EXPECT_EQ(kTpmModel, static_cast<uint32_t>(*result.tpm_model)); + ASSERT_TRUE(result.firmware_version); + EXPECT_EQ(kFirmwareVersion, static_cast<uint64_t>(*result.firmware_version)); + ASSERT_TRUE(result.vendor_specific); + EXPECT_EQ(kVendorSpecific, *result.vendor_specific); +} + +TEST(TelemetryApiConverters, TpmStatus) { + constexpr bool kEnabled = true; + constexpr bool kOwned = false; + constexpr bool kOwnerPasswortIsPresent = false; + + auto input = telemetry_service::ProbeTpmStatus::New(); + input->enabled = telemetry_service::BoolValue::New(kEnabled); + input->owned = telemetry_service::BoolValue::New(kOwned); + input->owner_password_is_present = + telemetry_service::BoolValue::New(kOwnerPasswortIsPresent); + + auto result = ConvertPtr<telemetry_api::TpmStatus>(std::move(input)); + ASSERT_TRUE(result.enabled); + EXPECT_EQ(kEnabled, *result.enabled); + ASSERT_TRUE(result.owned); + EXPECT_EQ(kOwned, *result.owned); + ASSERT_TRUE(result.owner_password_is_present); + EXPECT_EQ(kOwnerPasswortIsPresent, *result.owner_password_is_present); +} + +TEST(TelemetryApiConverters, TpmDictionaryAttack) { + constexpr uint32_t kCounter = 42; + constexpr uint32_t kThreshold = 100; + constexpr bool kLockOutInEffect = true; + constexpr uint32_t kLockoutSecondsRemaining = 5; + + auto input = telemetry_service::ProbeTpmDictionaryAttack::New(); + input->counter = telemetry_service::UInt32Value::New(kCounter); + input->threshold = telemetry_service::UInt32Value::New(kThreshold); + input->lockout_in_effect = + telemetry_service::BoolValue::New(kLockOutInEffect); + input->lockout_seconds_remaining = + telemetry_service::UInt32Value::New(kLockoutSecondsRemaining); + + auto result = + ConvertPtr<telemetry_api::TpmDictionaryAttack>(std::move(input)); + ASSERT_TRUE(result.counter); + EXPECT_EQ(kCounter, static_cast<uint32_t>(*result.counter)); + ASSERT_TRUE(result.threshold); + EXPECT_EQ(kThreshold, static_cast<uint32_t>(*result.threshold)); + ASSERT_TRUE(result.lockout_in_effect); + EXPECT_EQ(kLockOutInEffect, *result.lockout_in_effect); + ASSERT_TRUE(result.lockout_seconds_remaining); + EXPECT_EQ(kLockoutSecondsRemaining, + static_cast<uint32_t>(*result.lockout_seconds_remaining)); +} + +TEST(TelemetryApiConverters, TpmInfo) { + // TPM Version fields. + constexpr uint32_t kFamily = 0x322e3000; + constexpr uint64_t kSpecLevel = 1000; + constexpr uint32_t kManufacturer = 42; + constexpr uint32_t kTpmModel = 101; + constexpr uint64_t kFirmwareVersion = 1001; + constexpr char kVendorSpecific[] = "info"; + + // TPM Status fields. + constexpr bool kEnabled = true; + constexpr bool kOwned = false; + constexpr bool kOwnerPasswortIsPresent = false; + + // TPM dictionary attack fields. + constexpr uint32_t kCounter = 42; + constexpr uint32_t kThreshold = 100; + constexpr bool kLockOutInEffect = true; + constexpr uint32_t kLockoutSecondsRemaining = 5; + + auto tpm_version = telemetry_service::ProbeTpmVersion::New(); + tpm_version->gsc_version = telemetry_service::ProbeTpmGSCVersion::kCr50; + tpm_version->family = telemetry_service::UInt32Value::New(kFamily); + tpm_version->spec_level = telemetry_service::UInt64Value::New(kSpecLevel); + tpm_version->manufacturer = + telemetry_service::UInt32Value::New(kManufacturer); + tpm_version->tpm_model = telemetry_service::UInt32Value::New(kTpmModel); + tpm_version->firmware_version = + telemetry_service::UInt64Value::New(kFirmwareVersion); + tpm_version->vendor_specific = kVendorSpecific; + + auto tpm_status = telemetry_service::ProbeTpmStatus::New(); + tpm_status->enabled = telemetry_service::BoolValue::New(kEnabled); + tpm_status->owned = telemetry_service::BoolValue::New(kOwned); + tpm_status->owner_password_is_present = + telemetry_service::BoolValue::New(kOwnerPasswortIsPresent); + + auto dictionary_attack = telemetry_service::ProbeTpmDictionaryAttack::New(); + dictionary_attack->counter = telemetry_service::UInt32Value::New(kCounter); + dictionary_attack->threshold = + telemetry_service::UInt32Value::New(kThreshold); + dictionary_attack->lockout_in_effect = + telemetry_service::BoolValue::New(kLockOutInEffect); + dictionary_attack->lockout_seconds_remaining = + telemetry_service::UInt32Value::New(kLockoutSecondsRemaining); + + auto input = telemetry_service::ProbeTpmInfo::New(); + input->version = std::move(tpm_version); + input->status = std::move(tpm_status); + input->dictionary_attack = std::move(dictionary_attack); + + auto result = ConvertPtr<telemetry_api::TpmInfo>(std::move(input)); + + auto version_result = std::move(result.version); + EXPECT_EQ(telemetry_api::TpmGSCVersion::TPM_GSC_VERSION_CR50, + version_result.gsc_version); + ASSERT_TRUE(version_result.family); + EXPECT_EQ(kFamily, static_cast<uint32_t>(*version_result.family)); + ASSERT_TRUE(version_result.spec_level); + EXPECT_EQ(kSpecLevel, static_cast<uint64_t>(*version_result.spec_level)); + ASSERT_TRUE(version_result.manufacturer); + EXPECT_EQ(kManufacturer, static_cast<uint32_t>(*version_result.manufacturer)); + ASSERT_TRUE(version_result.tpm_model); + EXPECT_EQ(kTpmModel, static_cast<uint32_t>(*version_result.tpm_model)); + ASSERT_TRUE(version_result.firmware_version); + EXPECT_EQ(kFirmwareVersion, + static_cast<uint64_t>(*version_result.firmware_version)); + ASSERT_TRUE(version_result.vendor_specific); + EXPECT_EQ(kVendorSpecific, *version_result.vendor_specific); + + auto status_result = std::move(result.status); + ASSERT_TRUE(status_result.enabled); + EXPECT_EQ(kEnabled, *status_result.enabled); + ASSERT_TRUE(status_result.owned); + EXPECT_EQ(kOwned, *status_result.owned); + ASSERT_TRUE(status_result.owner_password_is_present); + EXPECT_EQ(kOwnerPasswortIsPresent, *status_result.owner_password_is_present); + + auto dictionary_attack_result = std::move(result.dictionary_attack); + ASSERT_TRUE(dictionary_attack_result.counter); + EXPECT_EQ(kCounter, static_cast<uint32_t>(*dictionary_attack_result.counter)); + ASSERT_TRUE(dictionary_attack_result.threshold); + EXPECT_EQ(kThreshold, + static_cast<uint32_t>(*dictionary_attack_result.threshold)); + ASSERT_TRUE(dictionary_attack_result.lockout_in_effect); + EXPECT_EQ(kLockOutInEffect, *dictionary_attack_result.lockout_in_effect); + ASSERT_TRUE(dictionary_attack_result.lockout_seconds_remaining); + EXPECT_EQ(kLockoutSecondsRemaining, + static_cast<uint32_t>( + *dictionary_attack_result.lockout_seconds_remaining)); +} + } // namespace converters } // namespace chromeos
diff --git a/chrome/browser/download/download_file_picker.cc b/chrome/browser/download/download_file_picker.cc index 2a1eed6..d8af81c 100644 --- a/chrome/browser/download/download_file_picker.cc +++ b/chrome/browser/download/download_file_picker.cc
@@ -24,8 +24,6 @@ #include "chrome/browser/ash/policy/dlp/dlp_files_controller.h" #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h" #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.h" -#include "chrome/browser/chromeos/policy/dlp/dlp_warn_dialog.h" -#include "chrome/browser/profiles/profile.h" #endif using download::DownloadItem; @@ -96,10 +94,17 @@ } #endif + const GURL* caller = +#if BUILDFLAG(IS_CHROMEOS) + &download_item_->GetURL(); +#else + nullptr; +#endif + select_file_dialog_->SelectFile( ui::SelectFileDialog::SELECT_SAVEAS_FILE, std::u16string(), suggested_path_, &file_type_info, 0, base::FilePath::StringType(), - owning_window, nullptr); + owning_window, /*params=*/nullptr, caller); } DownloadFilePicker::~DownloadFilePicker() {
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/management_service/BUILD.gn b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/management_service/BUILD.gn index 3ab21b2..83fc2eee 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/management_service/BUILD.gn +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/management_service/BUILD.gn
@@ -46,15 +46,12 @@ sources = [ "rotate_util.cc" ] - public_deps = [ - "//base", - "//chrome/browser/enterprise/connectors/device_trust/key_management/installer:elevated_rotation", - "//components/version_info", - ] + public_deps = [ "//components/version_info:channel" ] deps = [ + "//base", "//chrome/browser/enterprise/connectors/device_trust/key_management/core:constants", - "//chrome/common:channel_info", + "//chrome/browser/enterprise/connectors/device_trust/key_management/installer:elevated_rotation", "//third_party/abseil-cpp:absl", "//url", ]
diff --git a/chrome/browser/media/webrtc/region_capture_browsertest.cc b/chrome/browser/media/webrtc/region_capture_browsertest.cc index ab609c9..a9afaa1 100644 --- a/chrome/browser/media/webrtc/region_capture_browsertest.cc +++ b/chrome/browser/media/webrtc/region_capture_browsertest.cc
@@ -450,16 +450,8 @@ EXPECT_TRUE(tab.CropTo(crop_target, Frame::kTopLevelDocument)); } -// TODO(crbug.com/1359258): Flaky on Mac. -#if BUILDFLAG(IS_MAC) -#define MAYBE_CropToAllowedIfTopLevelCropsToElementInEmbedded \ - DISABLED_CropToAllowedIfTopLevelCropsToElementInEmbedded -#else -#define MAYBE_CropToAllowedIfTopLevelCropsToElementInEmbedded \ - CropToAllowedIfTopLevelCropsToElementInEmbedded -#endif IN_PROC_BROWSER_TEST_F(RegionCaptureBrowserTest, - MAYBE_CropToAllowedIfTopLevelCropsToElementInEmbedded) { + CropToAllowedIfTopLevelCropsToElementInEmbedded) { SetUpTest(Frame::kTopLevelDocument, /*self_capture=*/true); TabInfo& tab = tabs_[kMainTab]; @@ -729,16 +721,8 @@ } // Original track becomes unblocked for cropping after clone is GCed 1/3. -// Flaky on Mac crbug.com/1353349 -#if BUILDFLAG(IS_MAC) -#define MAYBE_CanCropOriginalTrackAfterCloneIsGarbageCollected \ - DISABLED_CanCropOriginalTrackAfterCloneIsGarbageCollected -#else -#define MAYBE_CanCropOriginalTrackAfterCloneIsGarbageCollected \ - CanCropOriginalTrackAfterCloneIsGarbageCollected -#endif IN_PROC_BROWSER_TEST_F(RegionCaptureClonesBrowserTest, - MAYBE_CanCropOriginalTrackAfterCloneIsGarbageCollected) { + CanCropOriginalTrackAfterCloneIsGarbageCollected) { ManualSetUp(); ASSERT_TRUE(CloneTrack()); @@ -750,17 +734,8 @@ } // Original track becomes unblocked for cropping after clone is GCed 2/3. -// Flaky on Mac crbug.com/1353349 -#if BUILDFLAG(IS_MAC) -#define MAYBE_CanRecropOriginalTrackAfterCloneIsGarbageCollected \ - DISABLED_CanRecropOriginalTrackAfterCloneIsGarbageCollected -#else -#define MAYBE_CanRecropOriginalTrackAfterCloneIsGarbageCollected \ - CanRecropOriginalTrackAfterCloneIsGarbageCollected -#endif -IN_PROC_BROWSER_TEST_F( - RegionCaptureClonesBrowserTest, - MAYBE_CanRecropOriginalTrackAfterCloneIsGarbageCollected) { +IN_PROC_BROWSER_TEST_F(RegionCaptureClonesBrowserTest, + CanRecropOriginalTrackAfterCloneIsGarbageCollected) { ManualSetUp(); ASSERT_TRUE(CropTo(kCropTarget0, Frame::kTopLevelDocument, Track::kOriginal));
diff --git a/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc b/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc index 2ced5558..4e04416d 100644 --- a/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc +++ b/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc
@@ -203,7 +203,7 @@ FakePasswordManagerLifecycleHelper* lifecycle_helper() { return lifecycle_helper_; } - syncer::SyncService* sync_service() { return &sync_service_; } + syncer::TestSyncService* sync_service() { return &sync_service_; } PasswordSyncControllerDelegateAndroid* sync_controller_delegate() { return sync_controller_delegate_; } @@ -227,10 +227,6 @@ /*sync_everything=*/false, /*types=*/{}); } - void SetSyncAuthError(GoogleServiceAuthError error) { - sync_service_.SetAuthError(error); - } - private: std::unique_ptr<PasswordStoreAndroidBackendBridge> CreateMockBridge() { auto unique_bridge = @@ -1069,10 +1065,7 @@ base::RepeatingClosure(), base::DoNothing()); backend().OnSyncServiceInitialized(sync_service()); - GoogleServiceAuthError transient_error( - GoogleServiceAuthError::CONNECTION_FAILED); - ASSERT_TRUE(transient_error.IsTransientError()); - SetSyncAuthError(transient_error); + sync_service()->SetTransientAuthError(); base::MockCallback<LoginsOrErrorReply> mock_reply; EXPECT_CALL(*bridge(), GetAllLogins).WillOnce(Return(kJobId)); @@ -1103,10 +1096,7 @@ base::RepeatingClosure(), base::DoNothing()); backend().OnSyncServiceInitialized(sync_service()); - GoogleServiceAuthError persistent_error( - GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); - ASSERT_TRUE(persistent_error.IsPersistentError()); - SetSyncAuthError(persistent_error); + sync_service()->SetPersistentAuthErrorOtherThanWebSignout(); base::MockCallback<LoginsOrErrorReply> mock_reply; EXPECT_CALL(*bridge(), GetAllLogins).WillOnce(Return(kJobId));
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index 75b522f..369bd34c 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -1013,12 +1013,17 @@ safe_browsing::kExtensionTelemetryPotentialPasswordTheft)) { return; } - // TODO(zackhan@): Create the struct directly without calling the construct - // method. And remove ConstructPasswordReuseInfo method to simplify the code. - safe_browsing::PasswordReuseInfo password_reuse_info = - pps->ConstructPasswordReuseInfo( - reused_password_hash, username, password_type, - GetMatchingDomains(matching_reused_credentials)); + // Construct password reuse info. + safe_browsing::PasswordReuseInfo password_reuse_info; + password_reuse_info.matches_signin_password = + password_type == PasswordType::PRIMARY_ACCOUNT_PASSWORD; + password_reuse_info.matching_domains = + GetMatchingDomains(matching_reused_credentials); + password_reuse_info.reused_password_account_type = + pps->GetPasswordProtectionReusedPasswordAccountType(password_type, + username); + password_reuse_info.count = 1; + password_reuse_info.reused_password_hash = reused_password_hash; // Extract the host part of an extension domain, which will be the extension // ID.
diff --git a/chrome/browser/password_manager/password_scripts_fetcher_factory.cc b/chrome/browser/password_manager/password_scripts_fetcher_factory.cc index b01a3f35..66f0e41 100644 --- a/chrome/browser/password_manager/password_scripts_fetcher_factory.cc +++ b/chrome/browser/password_manager/password_scripts_fetcher_factory.cc
@@ -5,23 +5,30 @@ #include "chrome/browser/password_manager/password_scripts_fetcher_factory.h" #include <memory> +#include <utility> #include "base/no_destructor.h" #include "chrome/browser/autofill_assistant/common_dependencies_chrome.h" +#include "chrome/browser/password_manager/account_password_store_factory.h" #include "chrome/browser/password_manager/password_store_factory.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "components/autofill_assistant/browser/public/autofill_assistant.h" #include "components/autofill_assistant/browser/public/autofill_assistant_factory.h" #include "components/password_manager/core/browser/capabilities_service_impl.h" #include "components/password_manager/core/browser/password_scripts_fetcher_impl.h" #include "components/password_manager/core/browser/saved_passwords_capabilities_fetcher.h" +#include "components/password_manager/core/browser/ui/saved_passwords_presenter.h" #include "components/password_manager/core/common/password_manager_features.h" #include "components/version_info/version_info.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition.h" PasswordScriptsFetcherFactory::PasswordScriptsFetcherFactory() - : ProfileKeyedServiceFactory("PasswordScriptsFetcher") {} + : ProfileKeyedServiceFactory("PasswordScriptsFetcher") { + DependsOn(PasswordStoreFactory::GetInstance()); + DependsOn(AccountPasswordStoreFactory::GetInstance()); +} PasswordScriptsFetcherFactory::~PasswordScriptsFetcherFactory() = default; @@ -53,10 +60,15 @@ std::make_unique<CapabilitiesServiceImpl>( std::move(autofill_assistant)); + Profile* profile = Profile::FromBrowserContext(browser_context); + return new password_manager::SavedPasswordsCapabilitiesFetcher( - std::move(service), PasswordStoreFactory::GetForProfile( - Profile::FromBrowserContext(browser_context), - ServiceAccessType::EXPLICIT_ACCESS)); + std::move(service), + std::make_unique<password_manager::SavedPasswordsPresenter>( + PasswordStoreFactory::GetForProfile( + profile, ServiceAccessType::EXPLICIT_ACCESS), + AccountPasswordStoreFactory::GetForProfile( + profile, ServiceAccessType::EXPLICIT_ACCESS))); } return new password_manager::PasswordScriptsFetcherImpl(
diff --git a/chrome/browser/resources/side_panel/read_anything/app.html b/chrome/browser/resources/side_panel/read_anything/app.html index 4401cb4..abd66db 100644 --- a/chrome/browser/resources/side_panel/read_anything/app.html +++ b/chrome/browser/resources/side_panel/read_anything/app.html
@@ -5,6 +5,7 @@ font-family: var(--font-family); font-size: var(--font-size); letter-spacing: var(--letter-spacing); + line-height: var(--line-height); padding: 20px; } </style>
diff --git a/chrome/browser/resources/side_panel/read_anything/app.ts b/chrome/browser/resources/side_panel/read_anything/app.ts index 14fab5b0..28124e1a 100644 --- a/chrome/browser/resources/side_panel/read_anything/app.ts +++ b/chrome/browser/resources/side_panel/read_anything/app.ts
@@ -144,11 +144,12 @@ SkColor = {value: chrome.readAnything.backgroundColor}; this.updateStyles({ - '--foreground-color': skColorToRgba(foregroundColor), '--background-color': skColorToRgba(backgroundColor), '--font-family': this.validatedFontName(), '--font-size': chrome.readAnything.fontSize + 'em', + '--foreground-color': skColorToRgba(foregroundColor), '--letter-spacing': chrome.readAnything.letterSpacing + 'em', + '--line-height': chrome.readAnything.lineSpacing, }); } }
diff --git a/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts b/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts index 6bae73a..7a8d604a 100644 --- a/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts +++ b/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts
@@ -18,6 +18,7 @@ let fontSize: number; let foregroundColor: number; let backgroundColor: number; + let lineSpacing: number; let letterSpacing: number; // Returns a list of AXNodeIDs corresponding to the unignored children of @@ -67,7 +68,8 @@ // Set the theme. Used by tests only. function setThemeForTesting( fontName: string, fontSize: number, foregroundColor: number, - backgroundColor: number, letterSpacing: number): void; + backgroundColor: number, lineSpacing: number, + letterSpacing: number): void; //////////////////////////////////////////////////////////////// // Implemented in read_anything/app.ts and called by native c++.
diff --git a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.cc b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.cc index 0f66d07..cb542e9 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.cc +++ b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.cc
@@ -60,11 +60,6 @@ persisted_at_write_interval); } -void RecordSignalType(ExtensionSignalType signal_type) { - base::UmaHistogramEnumeration( - "SafeBrowsing.ExtensionTelemetry.Signals.SignalType", signal_type); -} - static_assert(extensions::Manifest::NUM_LOAD_TYPES == 10, "ExtensionTelemetryReportRequest::ExtensionInfo::Type " "needs to match extensions::Manifest::Type."); @@ -178,6 +173,12 @@ SetEnabled(IsEnhancedProtectionEnabled(*pref_service_)); } +void ExtensionTelemetryService::RecordSignalType( + ExtensionSignalType signal_type) { + base::UmaHistogramEnumeration( + "SafeBrowsing.ExtensionTelemetry.Signals.SignalType", signal_type); +} + void ExtensionTelemetryService::OnPrefChanged() { SetEnabled(IsEnhancedProtectionEnabled(*pref_service_)); } @@ -312,7 +313,7 @@ ExtensionSignalType signal_type = signal->GetType(); RecordSignalType(signal_type); - DCHECK(base::Contains(signal_processors_, signal_type)); + DCHECK(base::Contains(signal_subscribers_, signal_type)); if (extension_store_.find(signal->extension_id()) == extension_store_.end()) { // This is the first signal triggered by this extension since the last
diff --git a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.h b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.h index c7a5eee..544e937 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.h +++ b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.h
@@ -69,6 +69,11 @@ ~ExtensionTelemetryService() override; + // Records the signal type when a signal is: + // - created externally and passed to extension service using AddSignal OR + // - created internally by a signal processor from other signals received. + static void RecordSignalType(ExtensionSignalType signal_type); + // Enables/disables the service. void SetEnabled(bool enable); bool enabled() const { return enabled_; }
diff --git a/chrome/browser/safe_browsing/extension_telemetry/potential_password_theft_signal_processor.cc b/chrome/browser/safe_browsing/extension_telemetry/potential_password_theft_signal_processor.cc index e178e01..33db2aa9 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/potential_password_theft_signal_processor.cc +++ b/chrome/browser/safe_browsing/extension_telemetry/potential_password_theft_signal_processor.cc
@@ -6,6 +6,7 @@ #include "base/check_op.h" #include "base/containers/contains.h" +#include "chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.h" #include "chrome/browser/safe_browsing/extension_telemetry/password_reuse_signal.h" #include "chrome/browser/safe_browsing/extension_telemetry/remote_host_contacted_signal.h" #include "components/safe_browsing/core/common/proto/csd.pb.h" @@ -200,6 +201,12 @@ remote_host_url_pb->set_count(remote_host_url_w_count_it.second); } + // Record the combined signal, kPotentialPasswordTheft, which is derived from + // kPasswordReuse and kRemoteHostContacted. The signal is created once every + // report creation time if there is potential password theft data available. + ExtensionTelemetryService::RecordSignalType( + ExtensionSignalType::kPotentialPasswordTheft); + // Clear the data in the stores. // Following two iters are guaranteed to exist because // password_hash_remote_host_url_pair_store_it is not null.
diff --git a/chrome/browser/signin/account_id_from_account_info.cc b/chrome/browser/signin/account_id_from_account_info.cc index 41f9c94b..8c9bc1a 100644 --- a/chrome/browser/signin/account_id_from_account_info.cc +++ b/chrome/browser/signin/account_id_from_account_info.cc
@@ -4,16 +4,13 @@ #include "chrome/browser/signin/account_id_from_account_info.h" #include "build/chromeos_buildflags.h" +#include "components/account_id/account_id.h" #include "google_apis/gaia/gaia_auth_util.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) -#include "components/user_manager/known_user.h" -#endif - AccountId AccountIdFromAccountInfo(const CoreAccountInfo& account_info) { #if BUILDFLAG(IS_CHROMEOS_ASH) - return user_manager::known_user::GetAccountId( - account_info.email, account_info.gaia, AccountType::GOOGLE); + return AccountId::FromNonCanonicalEmail(account_info.email, account_info.gaia, + AccountType::GOOGLE); #else if (account_info.email.empty() || account_info.gaia.empty()) return EmptyAccountId();
diff --git a/chrome/browser/storage_access_api/api_browsertest.cc b/chrome/browser/storage_access_api/api_browsertest.cc index f8da94a..fb18e59 100644 --- a/chrome/browser/storage_access_api/api_browsertest.cc +++ b/chrome/browser/storage_access_api/api_browsertest.cc
@@ -107,8 +107,8 @@ return enabled; } - virtual std::vector<base::Feature> GetDisabledFeatures() { - std::vector<base::Feature> disabled; + virtual std::vector<base::test::FeatureRef> GetDisabledFeatures() { + std::vector<base::test::FeatureRef> disabled; if (!is_storage_partitioned_) { disabled.push_back(net::features::kThirdPartyStoragePartitioning); } @@ -1031,7 +1031,7 @@ enable_standard_storage_access_api_(GetParam()) {} protected: - std::vector<base::Feature> GetDisabledFeatures() override { + std::vector<base::test::FeatureRef> GetDisabledFeatures() override { // The test should validate that either flag alone disables the API. // Note that enabling the extension and not the standard API means both are // disabled.
diff --git a/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc b/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc index 59fa790..f9ba075 100644 --- a/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc +++ b/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc
@@ -44,7 +44,7 @@ public: explicit StorageAccessGrantPermissionContextTest(bool saa_enabled) { std::vector<base::test::ScopedFeatureList::FeatureAndParams> enabled; - std::vector<base::Feature> disabled; + std::vector<base::test::FeatureRef> disabled; if (saa_enabled) { enabled.push_back({net::features::kStorageAccessAPI, {
diff --git a/chrome/browser/supervised_user/kids_chrome_management/kids_access_token_fetcher.cc b/chrome/browser/supervised_user/kids_chrome_management/kids_access_token_fetcher.cc new file mode 100644 index 0000000..ca4a806f --- /dev/null +++ b/chrome/browser/supervised_user/kids_chrome_management/kids_access_token_fetcher.cc
@@ -0,0 +1,72 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/supervised_user/kids_chrome_management/kids_access_token_fetcher.h" + +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "base/functional/bind.h" +#include "base/no_destructor.h" +#include "base/types/expected.h" +#include "components/signin/public/identity_manager/access_token_fetcher.h" +#include "components/signin/public/identity_manager/access_token_info.h" +#include "components/signin/public/identity_manager/identity_manager.h" +#include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h" +#include "google_apis/gaia/gaia_constants.h" +#include "google_apis/gaia/google_service_auth_error.h" +#include "google_apis/gaia/oauth2_access_token_manager.h" + +namespace { + +using ::base::BindOnce; +using ::base::expected; +using ::base::NoDestructor; +using ::base::unexpected; +using ::base::Unretained; +using ::signin::AccessTokenFetcher; +using ::signin::AccessTokenInfo; +using ::signin::ConsentLevel; +using ::signin::IdentityManager; +using ::signin::PrimaryAccountAccessTokenFetcher; + +expected<AccessTokenInfo, GoogleServiceAuthError> ToSingleReturnValue( + GoogleServiceAuthError error, + AccessTokenInfo access_token_info) { + if (error.state() == GoogleServiceAuthError::NONE) { + return access_token_info; + } + return unexpected(error); +} + +} // namespace + +KidsAccessTokenFetcher::KidsAccessTokenFetcher( + IdentityManager& identity_manager, + Consumer consumer) + : consumer_(std::move(consumer)) { + // base::Unretained(.) is safe, because no extra on-destroyed semantics are + // needed and this instance must outlive the callback execution. + primary_account_access_token_fetcher_ = + std::make_unique<PrimaryAccountAccessTokenFetcher>( + "family_info_fetcher", &identity_manager, Scopes(), + BindOnce(&KidsAccessTokenFetcher::OnAccessTokenFetchComplete, + Unretained(this)), + PrimaryAccountAccessTokenFetcher::Mode::kWaitUntilAvailable, + ConsentLevel::kSignin); +} +KidsAccessTokenFetcher::~KidsAccessTokenFetcher() = default; + +void KidsAccessTokenFetcher::OnAccessTokenFetchComplete( + GoogleServiceAuthError error, + signin::AccessTokenInfo access_token_info) { + std::move(consumer_).Run(ToSingleReturnValue(error, access_token_info)); +} + +const OAuth2AccessTokenManager::ScopeSet& KidsAccessTokenFetcher::Scopes() { + static auto nonce = NoDestructor<OAuth2AccessTokenManager::ScopeSet>( + {GaiaConstants::kKidFamilyReadonlyOAuth2Scope}); + return *nonce; +}
diff --git a/chrome/browser/supervised_user/kids_chrome_management/kids_access_token_fetcher.h b/chrome/browser/supervised_user/kids_chrome_management/kids_access_token_fetcher.h new file mode 100644 index 0000000..04a7028 --- /dev/null +++ b/chrome/browser/supervised_user/kids_chrome_management/kids_access_token_fetcher.h
@@ -0,0 +1,47 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SUPERVISED_USER_KIDS_CHROME_MANAGEMENT_KIDS_ACCESS_TOKEN_FETCHER_H_ +#define CHROME_BROWSER_SUPERVISED_USER_KIDS_CHROME_MANAGEMENT_KIDS_ACCESS_TOKEN_FETCHER_H_ + +#include <memory> + +#include "base/memory/singleton.h" +#include "base/types/expected.h" +#include "components/signin/public/identity_manager/access_token_fetcher.h" +#include "components/signin/public/identity_manager/access_token_info.h" +#include "components/signin/public/identity_manager/identity_manager.h" +#include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h" +#include "content/public/browser/browser_context.h" +#include "google_apis/gaia/gaia_constants.h" +#include "google_apis/gaia/google_service_auth_error.h" +#include "google_apis/gaia/oauth2_access_token_manager.h" + +// Responsible for initialing the access token workflow. Executes the consuming +// callback when the fetch is done, and then becomes disposable. +class KidsAccessTokenFetcher { + public: + // For convenience, the interface of signin::PrimaryAccountAccessTokenFetcher + // is wrapped into one value, so the decision how to handle errors is up to + // consumers of access token fetcher. + using Consumer = base::OnceCallback<void( + base::expected<signin::AccessTokenInfo, GoogleServiceAuthError>)>; + // Non copyable. + KidsAccessTokenFetcher() = delete; + explicit KidsAccessTokenFetcher(signin::IdentityManager& identity_manager, + Consumer consumer); + KidsAccessTokenFetcher(const KidsAccessTokenFetcher&) = delete; + KidsAccessTokenFetcher& operator=(const KidsAccessTokenFetcher&) = delete; + ~KidsAccessTokenFetcher(); + + private: + void OnAccessTokenFetchComplete(GoogleServiceAuthError error, + signin::AccessTokenInfo access_token_info); + static const OAuth2AccessTokenManager::ScopeSet& Scopes(); + Consumer consumer_; + std::unique_ptr<signin::PrimaryAccountAccessTokenFetcher> + primary_account_access_token_fetcher_; +}; + +#endif // CHROME_BROWSER_SUPERVISED_USER_KIDS_CHROME_MANAGEMENT_KIDS_ACCESS_TOKEN_FETCHER_H_
diff --git a/chrome/browser/supervised_user/kids_chrome_management/kids_management_service_unittest.cc b/chrome/browser/supervised_user/kids_chrome_management/kids_access_token_fetcher_unittest.cc similarity index 98% rename from chrome/browser/supervised_user/kids_chrome_management/kids_management_service_unittest.cc rename to chrome/browser/supervised_user/kids_chrome_management/kids_access_token_fetcher_unittest.cc index fdc35f3..b0c052b 100644 --- a/chrome/browser/supervised_user/kids_chrome_management/kids_management_service_unittest.cc +++ b/chrome/browser/supervised_user/kids_chrome_management/kids_access_token_fetcher_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h" +#include "chrome/browser/supervised_user/kids_chrome_management/kids_access_token_fetcher.h" #include "base/bind.h" #include "base/functional/callback.h"
diff --git a/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.cc b/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.cc index f945819..a0de0fe5 100644 --- a/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.cc +++ b/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.cc
@@ -4,75 +4,13 @@ #include "chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h" -#include <memory> -#include <utility> - -#include "base/bind.h" -#include "base/functional/bind.h" -#include "base/no_destructor.h" -#include "base/types/expected.h" #include "components/keyed_service/core/keyed_service.h" -#include "components/signin/public/identity_manager/access_token_fetcher.h" -#include "components/signin/public/identity_manager/access_token_info.h" -#include "components/signin/public/identity_manager/identity_manager.h" -#include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h" #include "content/public/browser/browser_context.h" -#include "google_apis/gaia/gaia_constants.h" -#include "google_apis/gaia/google_service_auth_error.h" -#include "google_apis/gaia/oauth2_access_token_manager.h" namespace { - -using ::base::BindOnce; -using ::base::expected; -using ::base::NoDestructor; -using ::base::unexpected; -using ::base::Unretained; using ::content::BrowserContext; -using ::signin::AccessTokenFetcher; -using ::signin::AccessTokenInfo; -using ::signin::ConsentLevel; -using ::signin::IdentityManager; -using ::signin::PrimaryAccountAccessTokenFetcher; - -expected<AccessTokenInfo, GoogleServiceAuthError> ToSingleReturnValue( - GoogleServiceAuthError error, - AccessTokenInfo access_token_info) { - if (error.state() == GoogleServiceAuthError::NONE) { - return access_token_info; - } - return unexpected(error); -} - } // namespace -KidsAccessTokenFetcher::KidsAccessTokenFetcher( - IdentityManager& identity_manager, - Consumer consumer) - : consumer_(std::move(consumer)) { - // base::Unretained(.) is safe, because no extra on-destroyed semantics are - // needed and this instance must outlive the callback execution. - primary_account_access_token_fetcher_ = - std::make_unique<PrimaryAccountAccessTokenFetcher>( - "family_info_fetcher", &identity_manager, Scopes(), - BindOnce(&KidsAccessTokenFetcher::OnAccessTokenFetchComplete, - Unretained(this)), - PrimaryAccountAccessTokenFetcher::Mode::kWaitUntilAvailable, - ConsentLevel::kSignin); -} -KidsAccessTokenFetcher::~KidsAccessTokenFetcher() = default; - -void KidsAccessTokenFetcher::OnAccessTokenFetchComplete( - GoogleServiceAuthError error, - signin::AccessTokenInfo access_token_info) { - std::move(consumer_).Run(ToSingleReturnValue(error, access_token_info)); -} - -const OAuth2AccessTokenManager::ScopeSet& KidsAccessTokenFetcher::Scopes() { - static auto nonce = NoDestructor<OAuth2AccessTokenManager::ScopeSet>( - {GaiaConstants::kKidFamilyReadonlyOAuth2Scope}); - return *nonce; -} // Builds the service instance and its local dependencies. // The profile dependency is needed to verify the dynamic child account status. KeyedService* KidsManagementServiceFactory::BuildServiceInstanceFor(
diff --git a/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h b/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h index a9acb84..9166091 100644 --- a/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h +++ b/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h
@@ -5,46 +5,10 @@ #ifndef CHROME_BROWSER_SUPERVISED_USER_KIDS_CHROME_MANAGEMENT_KIDS_MANAGEMENT_SERVICE_H_ #define CHROME_BROWSER_SUPERVISED_USER_KIDS_CHROME_MANAGEMENT_KIDS_MANAGEMENT_SERVICE_H_ -#include <memory> - #include "base/memory/singleton.h" -#include "base/types/expected.h" #include "chrome/browser/profiles/profile_keyed_service_factory.h" #include "components/keyed_service/core/keyed_service.h" -#include "components/signin/public/identity_manager/access_token_fetcher.h" -#include "components/signin/public/identity_manager/access_token_info.h" -#include "components/signin/public/identity_manager/identity_manager.h" -#include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h" #include "content/public/browser/browser_context.h" -#include "google_apis/gaia/gaia_constants.h" -#include "google_apis/gaia/google_service_auth_error.h" -#include "google_apis/gaia/oauth2_access_token_manager.h" - -// Responsible for initialing the access token workflow. Executes the consuming -// callback when the fetch is done, and then becomes disposable. -class KidsAccessTokenFetcher { - public: - // For convenience, the interface of signin::PrimaryAccountAccessTokenFetcher - // is wrapped into one value, so the decision how to handle errors is up to - // consumers of access token fetcher. - using Consumer = base::OnceCallback<void( - base::expected<signin::AccessTokenInfo, GoogleServiceAuthError>)>; - // Non copyable. - KidsAccessTokenFetcher() = delete; - explicit KidsAccessTokenFetcher(signin::IdentityManager& identity_manager, - Consumer consumer); - KidsAccessTokenFetcher(const KidsAccessTokenFetcher&) = delete; - KidsAccessTokenFetcher& operator=(const KidsAccessTokenFetcher&) = delete; - ~KidsAccessTokenFetcher(); - - private: - void OnAccessTokenFetchComplete(GoogleServiceAuthError error, - signin::AccessTokenInfo access_token_info); - static const OAuth2AccessTokenManager::ScopeSet& Scopes(); - Consumer consumer_; - std::unique_ptr<signin::PrimaryAccountAccessTokenFetcher> - primary_account_access_token_fetcher_; -}; // A keyed service aggregating services for respective RPCs in // KidsManagementAPI.
diff --git a/chrome/browser/supervised_user/parental_control_metrics_unittest.cc b/chrome/browser/supervised_user/parental_control_metrics_unittest.cc index 7d47ec0e..cc47601b 100644 --- a/chrome/browser/supervised_user/parental_control_metrics_unittest.cc +++ b/chrome/browser/supervised_user/parental_control_metrics_unittest.cc
@@ -154,10 +154,10 @@ // Blocks `kExampleHost0`. { - DictionaryPrefUpdate hosts_update(GetPrefs(), + ScopedDictPrefUpdate hosts_update(GetPrefs(), prefs::kSupervisedUserManualHosts); - base::Value* hosts = hosts_update.Get(); - hosts->SetBoolKey(kExampleHost0, false); + base::Value::Dict& hosts = hosts_update.Get(); + hosts.Set(kExampleHost0, false); } histogram_tester_.ExpectBucketCount( @@ -174,10 +174,10 @@ // Approves `kExampleHost0`. { - DictionaryPrefUpdate hosts_update(GetPrefs(), + ScopedDictPrefUpdate hosts_update(GetPrefs(), prefs::kSupervisedUserManualHosts); - base::Value* hosts = hosts_update.Get(); - hosts->SetBoolKey(kExampleHost0, true); + base::Value::Dict& hosts = hosts_update.Get(); + hosts.Set(kExampleHost0, true); } histogram_tester_.ExpectBucketCount( @@ -194,10 +194,10 @@ // Blocks `kExampleURL1`. { - DictionaryPrefUpdate urls_update(GetPrefs(), + ScopedDictPrefUpdate urls_update(GetPrefs(), prefs::kSupervisedUserManualURLs); - base::Value* urls = urls_update.Get(); - urls->SetBoolKey(kExampleURL1, false); + base::Value::Dict& urls = urls_update.Get(); + urls.Set(kExampleURL1, false); } histogram_tester_.ExpectBucketCount(
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc index 56845ed..64fcf00 100644 --- a/chrome/browser/supervised_user/supervised_user_service.cc +++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -870,22 +870,20 @@ const std::string& version, ApprovedExtensionChange type) { PrefService* pref_service = GetPrefService(); - DictionaryPrefUpdate update(pref_service, + ScopedDictPrefUpdate update(pref_service, prefs::kSupervisedUserApprovedExtensions); - base::Value* approved_extensions = update.Get(); - DCHECK(approved_extensions) - << "kSupervisedUserApprovedExtensions pref not found"; + base::Value::Dict& approved_extensions = update.Get(); bool success = false; switch (type) { case ApprovedExtensionChange::kAdd: - DCHECK(!approved_extensions->FindStringKey(extension_id)); - approved_extensions->SetStringKey(extension_id, std::move(version)); + DCHECK(!approved_extensions.FindString(extension_id)); + approved_extensions.Set(extension_id, std::move(version)); SupervisedUserExtensionsMetricsRecorder::RecordExtensionsUmaMetrics( SupervisedUserExtensionsMetricsRecorder::UmaExtensionState:: kApprovalGranted); break; case ApprovedExtensionChange::kRemove: - success = approved_extensions->RemoveKey(extension_id); + success = approved_extensions.Remove(extension_id); DCHECK(success); SupervisedUserExtensionsMetricsRecorder::RecordExtensionsUmaMetrics( SupervisedUserExtensionsMetricsRecorder::UmaExtensionState::
diff --git a/chrome/browser/sync/sync_startup_tracker_unittest.cc b/chrome/browser/sync/sync_startup_tracker_unittest.cc index 5bc05a4f..d1ab027 100644 --- a/chrome/browser/sync/sync_startup_tracker_unittest.cc +++ b/chrome/browser/sync/sync_startup_tracker_unittest.cc
@@ -58,8 +58,7 @@ sync_service_.SetDisableReasons(syncer::SyncService::DisableReasonSet()); sync_service_.SetTransportState( syncer::SyncService::TransportState::INITIALIZING); - sync_service_.SetAuthError( - GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); + sync_service_.SetPersistentAuthErrorOtherThanWebSignout(); EXPECT_CALL(callback_, Run(SyncStartupTracker::ServiceStartupState::kError)); SyncStartupTracker tracker(&sync_service_, callback_.Get()); } @@ -89,8 +88,7 @@ sync_service_.SetDisableReasons(syncer::SyncService::DisableReasonSet()); sync_service_.SetTransportState( syncer::SyncService::TransportState::INITIALIZING); - sync_service_.SetAuthError( - GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); + sync_service_.SetPersistentAuthErrorOtherThanWebSignout(); EXPECT_CALL(callback_, Run(SyncStartupTracker::ServiceStartupState::kError)); tracker.OnStateChanged(&sync_service_); }
diff --git a/chrome/browser/sync/test/integration/password_manager_sync_test.cc b/chrome/browser/sync/test/integration/password_manager_sync_test.cc index bd5cf07..086ecd0 100644 --- a/chrome/browser/sync/test/integration/password_manager_sync_test.cc +++ b/chrome/browser/sync/test/integration/password_manager_sync_test.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/password_manager/password_manager_test_base.h" #include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/password_manager/passwords_navigation_observer.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/sync/test/integration/passwords_helper.h" #include "chrome/browser/sync/test/integration/secondary_account_helper.h" #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h" @@ -32,9 +33,11 @@ #include "components/password_manager/core/browser/password_manager_features_util.h" #include "components/password_manager/core/browser/password_manager_test_utils.h" #include "components/password_manager/core/browser/password_store_interface.h" +#include "components/password_manager/core/browser/password_sync_util.h" #include "components/password_manager/core/common/password_manager_features.h" #include "components/prefs/pref_service.h" #include "components/signin/public/identity_manager/account_info.h" +#include "components/sync/driver/sync_auth_util.h" #include "components/sync/driver/sync_service_impl.h" #include "components/sync/test/fake_server_nigori_helper.h" #include "content/public/browser/browser_context.h" @@ -112,6 +115,8 @@ } void SetUpCommandLine(base::CommandLine* command_line) override { + SyncTest::SetUpCommandLine(command_line); + // Make sure that fake Gaia pages served by the test server match the Gaia // URL (as specified by GaiaUrls::gaia_url()). Note that even though the // hostname is the same, it's necessary to override the port to the one used @@ -893,4 +898,40 @@ #endif // !BUILDFLAG(IS_CHROMEOS_ASH) +IN_PROC_BROWSER_TEST_F(PasswordManagerSyncTest, SyncUtilApis) { + // Username hardcoded in SyncTest. + const std::string kExpectedUsername = "user@gmail.com"; + + ASSERT_TRUE(SetupSync()); + + EXPECT_TRUE( + password_manager::sync_util::IsPasswordSyncEnabled(GetSyncService(0))); + EXPECT_TRUE( + password_manager::sync_util::IsPasswordSyncActive(GetSyncService(0))); + EXPECT_EQ(password_manager::sync_util::GetSyncUsernameIfSyncingPasswords( + GetSyncService(0), + IdentityManagerFactory::GetForProfile(GetProfile(0))), + kExpectedUsername); + + // Enter a persistent auth error state (web signout). + GetClient(0)->EnterSyncPausedStateForPrimaryAccount(); + ASSERT_TRUE(syncer::IsWebSignout(GetSyncService(0)->GetAuthError())); + + // Passwords are not sync-ing actively while sync is paused due to a web + // signout. Note that this is not the case for other persistent auth errors. + // TODO(crbug.com/1156584): Update comments when the logic gets unified for + // all persistent auth errors. + EXPECT_FALSE( + password_manager::sync_util::IsPasswordSyncActive(GetSyncService(0))); + + // In the current implementation, these predicates return true even if sync is + // paused. + EXPECT_TRUE( + password_manager::sync_util::IsPasswordSyncEnabled(GetSyncService(0))); + EXPECT_EQ(password_manager::sync_util::GetSyncUsernameIfSyncingPasswords( + GetSyncService(0), + IdentityManagerFactory::GetForProfile(GetProfile(0))), + kExpectedUsername); +} + } // namespace
diff --git a/chrome/browser/sync/test/integration/single_client_history_sync_test.cc b/chrome/browser/sync/test/integration/single_client_history_sync_test.cc index c1eb8af..74ea72a 100644 --- a/chrome/browser/sync/test/integration/single_client_history_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_history_sync_test.cc
@@ -46,6 +46,9 @@ using testing::Not; using testing::UnorderedElementsAre; +const char kRedirectFromPath[] = "/redirect.html"; +const char kRedirectToPath[] = "/sync/simple.html"; + MATCHER_P(UrlIs, url, "") { if (arg.redirect_entries_size() != 1) { return false; @@ -53,14 +56,34 @@ return arg.redirect_entries(0).url() == url; } +MATCHER_P2(UrlsAre, url1, url2, "") { + if (arg.redirect_entries_size() != 2) { + return false; + } + return arg.redirect_entries(0).url() == url1 && + arg.redirect_entries(1).url() == url2; +} + MATCHER_P(CoreTransitionIs, transition, "") { return arg.page_transition().core_transition() == transition; } +MATCHER(IsChainStart, "") { + return !arg.redirect_chain_start_incomplete(); +} + +MATCHER(IsChainEnd, "") { + return !arg.redirect_chain_end_incomplete(); +} + MATCHER(HasReferringVisit, "") { return arg.originator_referring_visit_id() != 0; } +MATCHER(HasOpenerVisit, "") { + return arg.originator_opener_visit_id() != 0; +} + MATCHER(HasReferrerURL, "") { return !arg.referrer_url().empty(); } @@ -73,13 +96,19 @@ return arg.visit_duration_micros() > 0; } +MATCHER(HasHttpResponseCode, "") { + return arg.http_response_code() > 0; +} + MATCHER(StandardFieldsArePopulated, "") { // Checks all fields that should never be empty/unset/default. Some fields can // be legitimately empty, or are set after an entity is first created. // May be legitimately empty: - // redirect_entries.title, redirect_entries.redirect_type, - // originator_referring_visit_id, originator_opener_visit_id, - // root_task_id, parent_task_id + // redirect_entries.title (may simply be empty) + // redirect_entries.redirect_type (empty if it's not a redirect) + // originator_referring_visit_id, originator_opener_visit_id (may not exist) + // root_task_id, parent_task_id (not always set) + // http_response_code (unset for replaced navigations) // Populated later: // visit_duration_micros, page_language, password_state return arg.visit_time_windows_epoch_micros() > 0 && @@ -87,8 +116,7 @@ arg.redirect_entries_size() > 0 && arg.redirect_entries(0).originator_visit_id() > 0 && !arg.redirect_entries(0).url().empty() && arg.has_browser_type() && - arg.window_id() > 0 && arg.tab_id() > 0 && arg.task_id() > 0 && - arg.http_response_code() > 0; + arg.window_id() > 0 && arg.tab_id() > 0 && arg.task_id() > 0; } std::vector<sync_pb::HistorySpecifics> SyncEntitiesToHistorySpecifics( @@ -160,6 +188,20 @@ void SetUpOnMainThread() override { host_resolver()->AddRule("*", "127.0.0.1"); + // Set up a server redirect from `kRedirectFromPath` to `kRedirectToPath`. + embedded_test_server()->RegisterDefaultHandler(base::BindRepeating( + [](const net::test_server::HttpRequest& request) + -> std::unique_ptr<net::test_server::HttpResponse> { + if (request.relative_url != kRedirectFromPath) { + return nullptr; + } + auto response = + std::make_unique<net::test_server::BasicHttpResponse>(); + response->set_code(net::HTTP_TEMPORARY_REDIRECT); + response->AddCustomHeader("Location", kRedirectToPath); + return response; + })); + ASSERT_TRUE(embedded_test_server()->Start()); SyncTest::SetUpOnMainThread(); @@ -208,7 +250,6 @@ fake_server_->GetSyncEntitiesByModelType(syncer::HISTORY)); } - private: content::WebContents* GetActiveWebContents() { #if BUILDFLAG(IS_ANDROID) return chrome_test_utils::GetActiveWebContents(this); @@ -220,6 +261,7 @@ #endif } + private: base::test::ScopedFeatureList features_; }; @@ -283,11 +325,107 @@ EXPECT_TRUE(WaitForHistory(UnorderedElementsAre( AllOf(StandardFieldsArePopulated(), UrlIs(url1.spec()), CoreTransitionIs(sync_pb::SyncEnums_PageTransition_AUTO_BOOKMARK), - Not(HasReferringVisit()), Not(HasReferrerURL()), - HasVisitDuration()), + HasHttpResponseCode(), Not(HasReferringVisit()), + Not(HasReferrerURL()), HasVisitDuration()), AllOf(StandardFieldsArePopulated(), UrlIs(url2.spec()), CoreTransitionIs(sync_pb::SyncEnums_PageTransition_LINK), - HasReferringVisit(), ReferrerURLIs(url1.spec()))))); + HasHttpResponseCode(), HasReferringVisit(), + ReferrerURLIs(url1.spec()))))); +} + +IN_PROC_BROWSER_TEST_F(SingleClientHistorySyncTest, UploadsServerRedirect) { + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + + // Navigate to a URL which will redirect to another URL via a server redirect + // i.e. an HTTP 3xx response (see SetUpOnMainThread()). + const GURL url_from = + embedded_test_server()->GetURL("www.host.com", kRedirectFromPath); + NavigateToURL(url_from, ui::PAGE_TRANSITION_AUTO_BOOKMARK); + + const GURL url_to = + embedded_test_server()->GetURL("www.host.com", kRedirectToPath); + + // The redirect chain should have been uploaded as a single entity (since + // server redirects within a chain all have the same visit_time). + EXPECT_TRUE(WaitForHistory(UnorderedElementsAre(AllOf( + StandardFieldsArePopulated(), UrlsAre(url_from.spec(), url_to.spec()), + IsChainStart(), IsChainEnd(), Not(HasReferringVisit()))))); +} + +IN_PROC_BROWSER_TEST_F(SingleClientHistorySyncTest, UploadsClientMetaRedirect) { + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + + // Navigate to a URL which will redirect to another URL via an html <meta> + // tag. + const GURL url_from = embedded_test_server()->GetURL( + "www.host.com", "/sync/meta_redirect.html"); + NavigateToURL(url_from, ui::PAGE_TRANSITION_AUTO_BOOKMARK); + + const GURL url_to = + embedded_test_server()->GetURL("www.host.com", kRedirectToPath); + + // The redirect chain should have been uploaded as two separate entities, + // since client redirects result in different visit_times. However, the + // chain_start and chain_end markers should indicate that these two entities + // belong to the same chain. + EXPECT_TRUE(WaitForHistory(UnorderedElementsAre( + AllOf(StandardFieldsArePopulated(), UrlIs(url_from.spec()), + IsChainStart(), Not(IsChainEnd()), Not(HasReferringVisit())), + AllOf(StandardFieldsArePopulated(), UrlIs(url_to.spec()), + Not(IsChainStart()), IsChainEnd(), HasReferringVisit())))); +} + +IN_PROC_BROWSER_TEST_F(SingleClientHistorySyncTest, UploadsClientJSRedirect) { + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + + // Navigate to a page. + const GURL url1 = + embedded_test_server()->GetURL("www.host1.com", "/sync/simple.html"); + NavigateToURL(url1, ui::PAGE_TRANSITION_AUTO_BOOKMARK); + + // The page sets window.location in JavaScript to redirect to a different URL. + const GURL url2 = + embedded_test_server()->GetURL("www.host2.com", "/sync/simple.html"); + ASSERT_TRUE(content::ExecJs( + GetActiveWebContents(), + base::StringPrintf("window.location = '%s';", url2.spec().c_str()))); + + // This kind of "redirect" is not actually considered a redirect by the + // history backend, so two separate sync entities should have been uploaded, + // each its own complete redirect chain. + EXPECT_TRUE(WaitForHistory(UnorderedElementsAre( + AllOf(StandardFieldsArePopulated(), UrlIs(url1.spec()), IsChainStart(), + IsChainEnd()), + AllOf(StandardFieldsArePopulated(), UrlIs(url2.spec()), IsChainStart(), + IsChainEnd())))); +} + +IN_PROC_BROWSER_TEST_F(SingleClientHistorySyncTest, + UploadsReplaceStateNavigation) { + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + + // Navigate to some page. + const GURL url1 = + embedded_test_server()->GetURL("www.host1.com", "/sync/simple.html"); + NavigateToURL(url1, ui::PAGE_TRANSITION_AUTO_BOOKMARK); + + // The page uses the JS history.replaceState API to update the URL. + const GURL url2 = + embedded_test_server()->GetURL("www.host1.com", "/replaced_history.html"); + ASSERT_TRUE(content::ExecJs( + GetActiveWebContents(), + base::StringPrintf("history.replaceState({}, 'page 2', '%s')", + url2.spec().c_str()))); + + // This results in two visits with different visit_times, which thus gets + // mapped to two separate sync entities. There's no redirection link between + // the two, but since it was a same-document navigation, the first visit + // should be the opener of the second. + EXPECT_TRUE(WaitForHistory(UnorderedElementsAre( + AllOf(StandardFieldsArePopulated(), UrlIs(url1.spec()), IsChainStart(), + IsChainEnd()), + AllOf(StandardFieldsArePopulated(), UrlIs(url2.spec()), IsChainStart(), + IsChainEnd(), HasOpenerVisit())))); } } // namespace
diff --git a/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc b/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc index 0544f38c..3e753fd 100644 --- a/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc +++ b/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc
@@ -194,8 +194,8 @@ class SingleClientSyncInvalidationsTestBase : public SyncTest { public: SingleClientSyncInvalidationsTestBase( - const std::vector<base::Feature>& enabled_features, - const std::vector<base::Feature>& disabled_features) + const std::vector<base::test::FeatureRef>& enabled_features, + const std::vector<base::test::FeatureRef>& disabled_features) : SyncTest(SINGLE_CLIENT) { override_features_.InitWithFeatures(enabled_features, disabled_features); }
diff --git a/chrome/browser/sync/test/integration/web_apps_sync_test_base.cc b/chrome/browser/sync/test/integration/web_apps_sync_test_base.cc index cc27381c..5d03b87 100644 --- a/chrome/browser/sync/test/integration/web_apps_sync_test_base.cc +++ b/chrome/browser/sync/test/integration/web_apps_sync_test_base.cc
@@ -24,7 +24,7 @@ WebAppsSyncTestBase::WebAppsSyncTestBase(TestType test_type) : SyncTest(test_type) { - std::vector<base::Feature> disabled_features; + std::vector<base::test::FeatureRef> disabled_features; #if BUILDFLAG(IS_CHROMEOS) // TODO(crbug.com/1357905): Update test driver to work with new UI.
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/res/layout/fast_checkout_autofill_profile_item.xml b/chrome/browser/ui/android/fast_checkout/internal/java/res/layout/fast_checkout_autofill_profile_item.xml index 8b0639f..f64d774 100644 --- a/chrome/browser/ui/android/fast_checkout/internal/java/res/layout/fast_checkout_autofill_profile_item.xml +++ b/chrome/browser/ui/android/fast_checkout/internal/java/res/layout/fast_checkout_autofill_profile_item.xml
@@ -49,17 +49,23 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.TextMedium.Primary" /> - <TextView - android:id="@+id/fast_checkout_autofill_profile_item_email" + <LinearLayout + android:id="@+id/fast_checkout_autofill_profile_sub_section" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/fast_checkout_address_item_email_margin_top" - android:textAppearance="@style/TextAppearance.TextMedium.Primary" /> - <TextView - android:id="@+id/fast_checkout_autofill_profile_item_phone_number" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:textAppearance="@style/TextAppearance.TextMedium.Primary" /> + android:orientation="vertical" + android:layout_marginTop="@dimen/fast_checkout_address_item_email_margin_top"> + <TextView + android:id="@+id/fast_checkout_autofill_profile_item_email" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.TextMedium.Primary" /> + <TextView + android:id="@+id/fast_checkout_autofill_profile_item_phone_number" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.TextMedium.Primary" /> + </LinearLayout> </LinearLayout> <ImageView android:id="@+id/fast_checkout_autofill_profile_item_selected_icon"
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/res/layout/fast_checkout_home_screen_sheet.xml b/chrome/browser/ui/android/fast_checkout/internal/java/res/layout/fast_checkout_home_screen_sheet.xml index 74e19633..92d5fee 100644 --- a/chrome/browser/ui/android/fast_checkout/internal/java/res/layout/fast_checkout_home_screen_sheet.xml +++ b/chrome/browser/ui/android/fast_checkout/internal/java/res/layout/fast_checkout_home_screen_sheet.xml
@@ -74,17 +74,23 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.TextMedium.Primary" /> - <TextView - android:id="@+id/fast_checkout_home_sheet_profile_email" + <LinearLayout + android:id="@+id/fast_checkout_home_sheet_profile_sub_section" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/fast_checkout_address_item_email_margin_top" - android:textAppearance="@style/TextAppearance.TextMedium.Primary" /> - <TextView - android:id="@+id/fast_checkout_home_sheet_profile_phone_number" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:textAppearance="@style/TextAppearance.TextMedium.Primary" /> + android:orientation="vertical" + android:layout_marginTop="@dimen/fast_checkout_address_item_email_margin_top"> + <TextView + android:id="@+id/fast_checkout_home_sheet_profile_email" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.TextMedium.Primary" /> + <TextView + android:id="@+id/fast_checkout_home_sheet_profile_phone_number" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.TextMedium.Primary" /> + </LinearLayout> </LinearLayout> <ImageView android:id="@+id/fast_checkout_expand_icon_autofill_profile"
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/AutofillProfileItemViewBinder.java b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/AutofillProfileItemViewBinder.java index 23ff207..b448be2 100644 --- a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/AutofillProfileItemViewBinder.java +++ b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/AutofillProfileItemViewBinder.java
@@ -30,19 +30,43 @@ static void bind(PropertyModel model, View view, PropertyKey propertyKey) { if (propertyKey == AUTOFILL_PROFILE) { FastCheckoutAutofillProfile profile = model.get(AUTOFILL_PROFILE); - ((TextView) view.findViewById(R.id.fast_checkout_autofill_profile_item_name)) - .setText(profile.getFullName()); - ((TextView) view.findViewById(R.id.fast_checkout_autofill_profile_item_street_address)) - .setText(profile.getStreetAddress()); - ((TextView) view.findViewById( - R.id.fast_checkout_autofill_profile_item_city_and_postal_code)) - .setText(getCityAndPostalCode(profile)); - ((TextView) view.findViewById(R.id.fast_checkout_autofill_profile_item_country)) - .setText(profile.getCountryName()); - ((TextView) view.findViewById(R.id.fast_checkout_autofill_profile_item_email)) - .setText(profile.getEmailAddress()); - ((TextView) view.findViewById(R.id.fast_checkout_autofill_profile_item_phone_number)) - .setText(profile.getPhoneNumber()); + TextView fullNameView = + view.findViewById(R.id.fast_checkout_autofill_profile_item_name); + fullNameView.setText(profile.getFullName()); + + TextView streetAddressView = + view.findViewById(R.id.fast_checkout_autofill_profile_item_street_address); + streetAddressView.setText(profile.getStreetAddress()); + + TextView postalCodeView = view.findViewById( + R.id.fast_checkout_autofill_profile_item_city_and_postal_code); + postalCodeView.setText(getLocalityAndPostalCode(profile)); + + TextView countryView = + view.findViewById(R.id.fast_checkout_autofill_profile_item_country); + countryView.setText(profile.getCountryName()); + + TextView emailView = view.findViewById(R.id.fast_checkout_autofill_profile_item_email); + emailView.setText(profile.getEmailAddress()); + + TextView phoneNumber = + view.findViewById(R.id.fast_checkout_autofill_profile_item_phone_number); + phoneNumber.setText(profile.getPhoneNumber()); + + hideIfEmpty(fullNameView); + hideIfEmpty(streetAddressView); + hideIfEmpty(postalCodeView); + hideIfEmpty(countryView); + hideIfEmpty(emailView); + hideIfEmpty(phoneNumber); + + // Hide address profile subsection if empty. + View profileSubSectionView = + view.findViewById(R.id.fast_checkout_autofill_profile_sub_section); + profileSubSectionView.setVisibility( + profile.getEmailAddress().isEmpty() && profile.getPhoneNumber().isEmpty() + ? View.GONE + : View.VISIBLE); } else if (propertyKey == ON_CLICK_LISTENER) { view.setOnClickListener((v) -> model.get(ON_CLICK_LISTENER).run()); } else if (propertyKey == IS_SELECTED) { @@ -55,11 +79,18 @@ * Returns the properly formatted combination of city and postal code. For now, * that means adhering to US formatting. */ - private static String getCityAndPostalCode(FastCheckoutAutofillProfile profile) { + private static String getLocalityAndPostalCode(FastCheckoutAutofillProfile profile) { StringBuilder builder = new StringBuilder(); builder.append(profile.getLocality()); - builder.append(", "); + // Add divider only if both elements exist. + if (!profile.getLocality().isEmpty() && !profile.getPostalCode().isEmpty()) { + builder.append(", "); + } builder.append(profile.getPostalCode()); return builder.toString(); } + + private static void hideIfEmpty(TextView view) { + view.setVisibility(view.length() == 0 ? View.GONE : View.VISIBLE); + } }
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/CreditCardItemViewBinder.java b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/CreditCardItemViewBinder.java index a05f98c..415be10 100644 --- a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/CreditCardItemViewBinder.java +++ b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/CreditCardItemViewBinder.java
@@ -35,22 +35,22 @@ if (propertyKey == CREDIT_CARD) { FastCheckoutCreditCard card = model.get(CREDIT_CARD); - ((TextView) view.findViewById(R.id.fast_checkout_credit_card_item_number)) - .setText(card.getObfuscatedNumber()); + TextView numberView = view.findViewById(R.id.fast_checkout_credit_card_item_number); + numberView.setText(card.getObfuscatedNumber()); - // Only show the name line if a name is set. TextView nameView = view.findViewById(R.id.fast_checkout_credit_card_item_name); - if (card.getName().isEmpty()) { - nameView.setVisibility(View.INVISIBLE); - } else { - nameView.setText(card.getName()); - nameView.setVisibility(View.VISIBLE); - } + nameView.setText(card.getName()); - ((TextView) view.findViewById(R.id.fast_checkout_credit_card_item_expiration_date)) - .setText(card.getFormattedExpirationDate(view.getContext())); + TextView expirationDateViewView = + view.findViewById(R.id.fast_checkout_credit_card_item_expiration_date); + expirationDateViewView.setText(card.getFormattedExpirationDate(view.getContext())); ImageView icon = view.findViewById(R.id.fast_checkout_credit_card_icon); + + hideIfEmpty(numberView); + hideIfEmpty(nameView); + hideIfEmpty(expirationDateViewView); + try { icon.setImageDrawable(AppCompatResources.getDrawable( icon.getContext(), card.getIssuerIconDrawableId())); @@ -64,4 +64,8 @@ .setVisibility(model.get(IS_SELECTED) ? View.VISIBLE : View.GONE); } } + + private static void hideIfEmpty(TextView view) { + view.setVisibility(view.length() == 0 ? View.GONE : View.VISIBLE); + } }
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/home_screen/HomeScreenViewBinder.java b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/home_screen/HomeScreenViewBinder.java index cdbce279..e2974db 100644 --- a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/home_screen/HomeScreenViewBinder.java +++ b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/home_screen/HomeScreenViewBinder.java
@@ -35,6 +35,7 @@ final Context mContext; final TextView mFullNameTextView; final TextView mStreetAddressTextView; + final LinearLayout mProfileSubsectionView; final TextView mEmailAddressTextView; final TextView mPhoneNumberTextView; final TextView mCreditCardHeaderTextView; @@ -49,6 +50,8 @@ contentView.findViewById(R.id.fast_checkout_home_sheet_profile_name); mStreetAddressTextView = contentView.findViewById(R.id.fast_checkout_home_sheet_profile_street); + mProfileSubsectionView = + contentView.findViewById(R.id.fast_checkout_home_sheet_profile_sub_section); mEmailAddressTextView = contentView.findViewById(R.id.fast_checkout_home_sheet_profile_email); mPhoneNumberTextView = @@ -79,7 +82,14 @@ } private static String getFullStreetAddress(FastCheckoutAutofillProfile profile) { - return profile.getStreetAddress() + ", " + profile.getPostalCode(); + StringBuilder builder = new StringBuilder(); + builder.append(profile.getStreetAddress()); + // Add divider only if both elements exist. + if (!profile.getStreetAddress().isEmpty() && !profile.getPostalCode().isEmpty()) { + builder.append(", "); + } + builder.append(profile.getPostalCode()); + return builder.toString(); } private static void updateProfile(PropertyModel model, ViewHolder view) { @@ -88,6 +98,16 @@ view.mStreetAddressTextView.setText(getFullStreetAddress(profile)); view.mEmailAddressTextView.setText(profile.getEmailAddress()); view.mPhoneNumberTextView.setText(profile.getPhoneNumber()); + hideIfEmpty(view.mFullNameTextView); + hideIfEmpty(view.mStreetAddressTextView); + hideIfEmpty(view.mEmailAddressTextView); + hideIfEmpty(view.mPhoneNumberTextView); + + // Hide address profile subsection if empty. + view.mProfileSubsectionView.setVisibility( + profile.getEmailAddress().isEmpty() && profile.getPhoneNumber().isEmpty() + ? View.GONE + : View.VISIBLE); } private static void updateCreditCard(PropertyModel model, ViewHolder view) { @@ -100,4 +120,8 @@ view.mCreditCardImageView.setImageDrawable(null); } } + + private static void hideIfEmpty(TextView view) { + view.setVisibility(view.length() == 0 ? View.GONE : View.VISIBLE); + } }
diff --git a/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutDetailScreenViewTest.java b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutDetailScreenViewTest.java index 9f63825e..791eff68 100644 --- a/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutDetailScreenViewTest.java +++ b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutDetailScreenViewTest.java
@@ -188,6 +188,12 @@ @Test @SmallTest public void testRecyclerViewBindsProfileDataToItemView() { + FastCheckoutAutofillProfile emptyFieldsProfile = + FastCheckoutTestUtils.createDetailedProfile( + /*guid=*/"111", /*name=*/"", /*streetAddress=*/"", + /*city=*/"", /*postalCode=*/"", /*email=*/"", + /*phoneNumber=*/""); + ModelList models = mModel.get(PROFILE_MODEL_LIST); models.add(new ListItem(DetailItemType.PROFILE, AutofillProfileItemProperties.create(sSampleProfile1, /*isSelected=*/false, @@ -195,23 +201,44 @@ models.add(new ListItem(DetailItemType.PROFILE, AutofillProfileItemProperties.create(sSampleProfile2, /*isSelected=*/true, /*onClickListener=*/() -> {}))); + + models.add(new ListItem(DetailItemType.PROFILE, + AutofillProfileItemProperties.create(emptyFieldsProfile, /*isSelected=*/false, + /*onClickListener=*/() -> {}))); + mModel.set(DETAIL_SCREEN_MODEL_LIST, models); // Check that the sheet is populated properly. ShadowLooper.shadowMainLooper().idle(); - assertThat(getListItems().getChildCount(), is(2)); + assertThat(getListItems().getAdapter().getItemCount(), is(3)); assertThatProfileItemLayoutIsCorrectAt(0, sSampleProfile1, /*isSelected=*/false); assertThatProfileItemLayoutIsCorrectAt(1, sSampleProfile2, /*isSelected=*/true); + assertThatProfileItemLayoutIsCorrectAt(2, emptyFieldsProfile, /*isSelected=*/false); // Update the selection. models.get(0).model.set(AutofillProfileItemProperties.IS_SELECTED, true); models.get(1).model.set(AutofillProfileItemProperties.IS_SELECTED, false); + models.get(2).model.set(AutofillProfileItemProperties.IS_SELECTED, false); ShadowLooper.shadowMainLooper().idle(); assertThatProfileItemLayoutIsCorrectAt(0, sSampleProfile1, /*isSelected=*/true); assertThatProfileItemLayoutIsCorrectAt(1, sSampleProfile2, /*isSelected=*/false); + assertThatProfileItemLayoutIsCorrectAt(2, emptyFieldsProfile, /*isSelected=*/false); + + // Update the selection. + models.get(0).model.set(AutofillProfileItemProperties.IS_SELECTED, false); + models.get(1).model.set(AutofillProfileItemProperties.IS_SELECTED, false); + models.get(2).model.set(AutofillProfileItemProperties.IS_SELECTED, true); + + ShadowLooper.shadowMainLooper().idle(); + + assertThatProfileItemLayoutIsCorrectAt(0, sSampleProfile1, /*isSelected=*/false); + assertThatProfileItemLayoutIsCorrectAt(1, sSampleProfile2, /*isSelected=*/false); + assertThatProfileItemLayoutIsCorrectAt(2, emptyFieldsProfile, /*isSelected=*/true); + + ShadowLooper.shadowMainLooper().idle(); } @Test @@ -223,35 +250,41 @@ /*origin=*/"https://example.at", /*name=*/"", /*number=*/"23423423432", /*obfuscatedNumber=*/"34326", /*month=*/"05", /*year=*/"2035", /*issuerIconString=*/"visaCC"); + FastCheckoutCreditCard sampleCardEmptyFields = + FastCheckoutTestUtils.createDetailedCreditCard(/*guid=*/"7534", + /*origin=*/"", /*name=*/"", /*number=*/"", + /*obfuscatedNumber=*/"", /*month=*/"05", /*year=*/"2035", + /*issuerIconString=*/"visaCC"); models.add(new ListItem(DetailItemType.CREDIT_CARD, - CreditCardItemProperties.create(sSampleCard1, /*isSelected=*/false, - /*onClickListener=*/() -> {}))); - models.add(new ListItem(DetailItemType.CREDIT_CARD, - CreditCardItemProperties.create(sSampleCard2, /*isSelected=*/true, + CreditCardItemProperties.create(sSampleCard1, /*isSelected=*/true, /*onClickListener=*/() -> {}))); models.add(new ListItem(DetailItemType.CREDIT_CARD, CreditCardItemProperties.create(sampleCardNoName, /*isSelected=*/false, /*onClickListener=*/() -> {}))); + models.add(new ListItem(DetailItemType.CREDIT_CARD, + CreditCardItemProperties.create(sampleCardEmptyFields, /*isSelected=*/false, + /*onClickListener=*/() -> {}))); mModel.set(DETAIL_SCREEN_MODEL_LIST, models); // Check that the sheet is populated properly. ShadowLooper.shadowMainLooper().idle(); - assertThat(getListItems().getChildCount(), is(3)); + assertThat(getListItems().getAdapter().getItemCount(), is(3)); - assertThatCreditCardItemLayoutIsCorrectAt(0, sSampleCard1, /*isSelected=*/false); - assertThatCreditCardItemLayoutIsCorrectAt(1, sSampleCard2, /*isSelected=*/true); - assertThatCreditCardItemLayoutIsCorrectAt(2, sampleCardNoName, /*isSelected=*/false); + assertThatCreditCardItemLayoutIsCorrectAt(0, sSampleCard1, /*isSelected=*/true); + assertThatCreditCardItemLayoutIsCorrectAt(1, sampleCardNoName, /*isSelected=*/false); + assertThatCreditCardItemLayoutIsCorrectAt(2, sampleCardEmptyFields, /*isSelected=*/false); // Update the selection. - models.get(0).model.set(CreditCardItemProperties.IS_SELECTED, true); - models.get(1).model.set(CreditCardItemProperties.IS_SELECTED, false); + models.get(0).model.set(CreditCardItemProperties.IS_SELECTED, false); + models.get(1).model.set(CreditCardItemProperties.IS_SELECTED, true); + models.get(2).model.set(CreditCardItemProperties.IS_SELECTED, false); ShadowLooper.shadowMainLooper().idle(); - assertThatCreditCardItemLayoutIsCorrectAt(0, sSampleCard1, /*isSelected=*/true); - assertThatCreditCardItemLayoutIsCorrectAt(1, sSampleCard2, /*isSelected=*/false); - assertThatCreditCardItemLayoutIsCorrectAt(2, sampleCardNoName, /*isSelected=*/false); + assertThatCreditCardItemLayoutIsCorrectAt(0, sSampleCard1, /*isSelected=*/false); + assertThatCreditCardItemLayoutIsCorrectAt(1, sampleCardNoName, /*isSelected=*/true); + assertThatCreditCardItemLayoutIsCorrectAt(2, sampleCardEmptyFields, /*isSelected=*/false); } @Test @@ -298,25 +331,35 @@ return textView.getText().toString(); } + /** Returns the TextView with resId inside the item at this index. */ + private TextView getTextViewFromListItemWithId(int index, int resId) { + return getListItemAt(index).findViewById(resId); + } + /** Asserts that the layout of the profile item at the given index is correct. */ private void assertThatProfileItemLayoutIsCorrectAt( int index, FastCheckoutAutofillProfile profile, boolean isSelected) { - assertThat(getTextFromListItemWithId(index, R.id.fast_checkout_autofill_profile_item_name), - equalTo(profile.getFullName())); - assertThat(getTextFromListItemWithId( - index, R.id.fast_checkout_autofill_profile_item_street_address), - equalTo(profile.getStreetAddress())); - assertThat(getTextFromListItemWithId( - index, R.id.fast_checkout_autofill_profile_item_city_and_postal_code), - equalTo(profile.getLocality() + ", " + profile.getPostalCode())); - assertThat( - getTextFromListItemWithId(index, R.id.fast_checkout_autofill_profile_item_country), - equalTo(profile.getCountryName())); - assertThat(getTextFromListItemWithId(index, R.id.fast_checkout_autofill_profile_item_email), - equalTo(profile.getEmailAddress())); - assertThat(getTextFromListItemWithId( - index, R.id.fast_checkout_autofill_profile_item_phone_number), - equalTo(profile.getPhoneNumber())); + assertViewShowsTextOrInvisible( + getTextViewFromListItemWithId(index, R.id.fast_checkout_autofill_profile_item_name), + profile.getFullName()); + assertViewShowsTextOrInvisible( + getTextViewFromListItemWithId( + index, R.id.fast_checkout_autofill_profile_item_street_address), + profile.getStreetAddress()); + assertViewShowsTextOrInvisible( + getTextViewFromListItemWithId( + index, R.id.fast_checkout_autofill_profile_item_city_and_postal_code), + getLocalityAndPostalCode(profile)); + assertViewShowsTextOrInvisible(getTextViewFromListItemWithId(index, + R.id.fast_checkout_autofill_profile_item_country), + profile.getCountryName()); + assertViewShowsTextOrInvisible(getTextViewFromListItemWithId(index, + R.id.fast_checkout_autofill_profile_item_email), + profile.getEmailAddress()); + assertViewShowsTextOrInvisible( + getTextViewFromListItemWithId( + index, R.id.fast_checkout_autofill_profile_item_phone_number), + profile.getPhoneNumber()); View icon = getListItemAt(index).findViewById( R.id.fast_checkout_autofill_profile_item_selected_icon); @@ -329,22 +372,18 @@ /** Asserts that the layout of the credit card item at the given index is correct. */ private void assertThatCreditCardItemLayoutIsCorrectAt( int index, FastCheckoutCreditCard card, boolean isSelected) { - assertThat(getTextFromListItemWithId(index, R.id.fast_checkout_credit_card_item_number), - equalTo(card.getObfuscatedNumber())); + assertViewShowsTextOrInvisible( + getTextViewFromListItemWithId(index, R.id.fast_checkout_credit_card_item_number), + card.getObfuscatedNumber()); // The name row should get hidden if the name is empty. - TextView nameView = - getListItemAt(index).findViewById(R.id.fast_checkout_credit_card_item_name); - if (card.getName().isEmpty()) { - assertThat(nameView.getVisibility(), is(View.INVISIBLE)); - } else { - assertThat(nameView.getVisibility(), is(View.VISIBLE)); - assertThat(nameView.getText().toString(), equalTo(card.getName())); - } + assertViewShowsTextOrInvisible( + getListItemAt(index).findViewById(R.id.fast_checkout_credit_card_item_name), + card.getName()); - assertThat(getTextFromListItemWithId( - index, R.id.fast_checkout_credit_card_item_expiration_date), - equalTo(card.getMonth() + "/" + card.getYear())); + assertViewShowsTextOrInvisible(getTextViewFromListItemWithId(index, + R.id.fast_checkout_credit_card_item_expiration_date), + card.getMonth() + "/" + card.getYear()); View icon = getListItemAt(index).findViewById( R.id.fast_checkout_credit_card_item_selected_icon); @@ -356,4 +395,28 @@ assertThat(shadowOf(paymentIcon.getDrawable()).getCreatedFromResId(), is(card.getIssuerIconDrawableId())); } + + private void assertViewShowsTextOrInvisible(TextView view, String text) { + if (text.isEmpty()) { + assertThat(view.getVisibility(), is(View.GONE)); + } else { + assertThat(view.getVisibility(), is(View.VISIBLE)); + assertThat(view.getText().toString(), equalTo(text)); + } + } + + /** + * Returns the properly formatted combination of city and postal code. For now, + * that means adhering to US formatting. + */ + private static String getLocalityAndPostalCode(FastCheckoutAutofillProfile profile) { + StringBuilder builder = new StringBuilder(); + builder.append(profile.getLocality()); + // Add divider only if both elements exist. + if (!profile.getLocality().isEmpty() && !profile.getPostalCode().isEmpty()) { + builder.append(", "); + } + builder.append(profile.getPostalCode()); + return builder.toString(); + } }
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc index bc23e61b..f900d654 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc
@@ -77,6 +77,17 @@ return model_->GetColorsModel(); } +void ReadAnythingController::OnLineSpacingChanged(int new_index) { + if (!model_->GetLineSpacingModel()->IsValidLineSpacingIndex(new_index)) + return; + + model_->SetSelectedLineSpacingByIndex(new_index); +} + +ui::ComboboxModel* ReadAnythingController::GetLineSpacingModel() { + return model_->GetLineSpacingModel(); +} + void ReadAnythingController::OnLetterSpacingChanged(int new_index) { if (!model_->GetLetterSpacingModel()->IsValidLetterSpacingIndex(new_index)) return;
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h index 49e35bf..c28776e 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h
@@ -60,6 +60,8 @@ void OnFontSizeChanged(bool increase) override; void OnColorsChanged(int new_index) override; ui::ComboboxModel* GetColorsModel() override; + void OnLineSpacingChanged(int new_index) override; + ui::ComboboxModel* GetLineSpacingModel() override; void OnLetterSpacingChanged(int new_index) override; ui::ComboboxModel* GetLetterSpacingModel() override;
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller_unittest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller_unittest.cc index b371f1c..e929338 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller_unittest.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller_unittest.cc
@@ -32,7 +32,7 @@ (int)read_anything::mojom::Colors::kDefaultValue); browser()->profile()->GetPrefs()->SetInteger( prefs::kAccessibilityReadAnythingLetterSpacing, - (int)read_anything::mojom::LetterSpacing::kDefaultValue); + (int)read_anything::mojom::Spacing::kDefault); } void MockOnFontChoiceChanged(int index) { @@ -45,6 +45,10 @@ void MockOnColorsChanged(int index) { controller_->OnColorsChanged(index); } + void MockOnLineSpacingChanged(int index) { + controller_->OnLineSpacingChanged(index); + } + void MockOnLetterSpacingChanged(int index) { controller_->OnLetterSpacingChanged(index); } @@ -52,8 +56,9 @@ void MockModelInit(std::string font_name, double font_scale, read_anything::mojom::Colors colors, - read_anything::mojom::LetterSpacing letter_spacing) { - model_->Init(font_name, font_scale, colors, letter_spacing); + read_anything::mojom::Spacing line_spacing, + read_anything::mojom::Spacing letter_spacing) { + model_->Init(font_name, font_scale, colors, line_spacing, letter_spacing); } std::string GetPrefFontName() { @@ -109,9 +114,9 @@ EXPECT_NEAR(GetPrefFontScale(), 1.0, 0.01); std::string font_name; - MockModelInit(font_name, 4.5, read_anything::mojom::Colors::kDefaultValue, - read_anything::mojom::LetterSpacing::kDefaultValue); + read_anything::mojom::Spacing::kDefault, + read_anything::mojom::Spacing::kDefault); MockOnFontSizeChanged(true); @@ -122,9 +127,9 @@ EXPECT_NEAR(GetPrefFontScale(), 1.0, 0.01); std::string font_name; - MockModelInit(font_name, 0.5, read_anything::mojom::Colors::kDefaultValue, - read_anything::mojom::LetterSpacing::kDefaultValue); + read_anything::mojom::Spacing::kDefault, + read_anything::mojom::Spacing::kDefault); MockOnFontSizeChanged(false); @@ -142,7 +147,7 @@ TEST_F(ReadAnythingControllerTest, OnLetterSpacingChangedUpdatesPref) { EXPECT_EQ(GetPrefsLetterSpacing(), 1); - MockOnLetterSpacingChanged((int)read_anything::mojom::LetterSpacing::kLoose); + MockOnLetterSpacingChanged((int)read_anything::mojom::Spacing::kLoose); EXPECT_EQ(GetPrefsLetterSpacing(), 2); }
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc index b476b564..b42be3e 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc
@@ -50,8 +50,12 @@ browser->profile()->GetPrefs()->GetInteger( prefs::kAccessibilityReadAnythingColorInfo)); - read_anything::mojom::LetterSpacing prefs_letter_spacing; - prefs_letter_spacing = static_cast<read_anything::mojom::LetterSpacing>( + read_anything::mojom::Spacing prefs_line_spacing; + // TODO Get pref from browser profile (future CL) + prefs_line_spacing = read_anything::mojom::Spacing::kDefault; + + read_anything::mojom::Spacing prefs_letter_spacing; + prefs_letter_spacing = static_cast<read_anything::mojom::Spacing>( browser->profile()->GetPrefs()->GetInteger( prefs::kAccessibilityReadAnythingLetterSpacing)); @@ -59,6 +63,7 @@ /* font name = */ prefs_font_name, /* font scale = */ prefs_font_scale, /* colors = */ prefs_colors, + /* line spacing = */ prefs_line_spacing, /* letter spacing = */ prefs_letter_spacing); }
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc index ca24ad79..c668853 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc
@@ -20,28 +20,29 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/image_model.h" #include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/color_palette.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/paint_vector_icon.h" using read_anything::mojom::ReadAnythingTheme; +using read_anything::mojom::Spacing; ReadAnythingModel::ReadAnythingModel() : font_name_(kReadAnythingDefaultFontName), font_scale_(kReadAnythingDefaultFontScale), font_model_(std::make_unique<ReadAnythingFontModel>()), colors_model_(std::make_unique<ReadAnythingColorsModel>()), + lines_model_(std::make_unique<ReadAnythingLineSpacingModel>()), letter_spacing_model_( std::make_unique<ReadAnythingLetterSpacingModel>()) {} ReadAnythingModel::~ReadAnythingModel() = default; -void ReadAnythingModel::Init( - std::string& font_name, - double font_scale, - read_anything::mojom::Colors colors, - read_anything::mojom::LetterSpacing letter_spacing) { +void ReadAnythingModel::Init(std::string& font_name, + double font_scale, + read_anything::mojom::Colors colors, + Spacing line_spacing, + Spacing letter_spacing) { // If this profile has previously selected choices that were saved to // prefs, check they are still a valid, and then assign if so. if (font_model_->IsValidFontName(font_name)) { @@ -49,17 +50,17 @@ font_name_ = font_name; } - size_t letter_spacing_index = static_cast<size_t>((int)letter_spacing); + size_t letter_spacing_index = static_cast<size_t>(letter_spacing); if (letter_spacing_model_->IsValidLetterSpacingIndex(letter_spacing_index)) { letter_spacing_model_->SetDefaultLetterSpacingIndexFromPref( letter_spacing_index); letter_spacing_ = - (int)(letter_spacing_model_->GetLetterSpacingAt(letter_spacing_index)); + letter_spacing_model_->GetLetterSpacingAt(letter_spacing_index); } font_scale_ = font_scale; - size_t colors_index = static_cast<size_t>((int)colors); + size_t colors_index = static_cast<size_t>(colors); if (colors_model_->IsValidColorsIndex(colors_index)) { colors_model_->SetDefaultColorsIndexFromPref(colors_index); } @@ -68,6 +69,11 @@ colors_model_->GetColorsAt(colors_model_->GetStartingStateIndex()); foreground_color_ = initial_colors.foreground; background_color_ = initial_colors.background; + + size_t line_spacing_index = static_cast<size_t>(line_spacing); + if (lines_model_->IsValidLineSpacingIndex(line_spacing_index)) { + line_spacing_ = lines_model_->GetLineSpacingAt(line_spacing_index); + } } void ReadAnythingModel::AddObserver(Observer* obs) { @@ -99,11 +105,19 @@ NotifyThemeChanged(); } +void ReadAnythingModel::SetSelectedLineSpacingByIndex(size_t new_index) { + // Check that the index is valid. + DCHECK(lines_model_->IsValidLineSpacingIndex(new_index)); + + line_spacing_ = lines_model_->GetLineSpacingAt(new_index); + NotifyThemeChanged(); +} + void ReadAnythingModel::SetSelectedLetterSpacingByIndex(size_t new_index) { // Check that the index is valid. DCHECK(letter_spacing_model_->IsValidLetterSpacingIndex(new_index)); - letter_spacing_ = (int)(letter_spacing_model_->GetLetterSpacingAt(new_index)); + letter_spacing_ = letter_spacing_model_->GetLetterSpacingAt(new_index); NotifyThemeChanged(); } @@ -143,9 +157,9 @@ void ReadAnythingModel::NotifyThemeChanged() { for (Observer& obs : observers_) { - obs.OnReadAnythingThemeChanged( - ReadAnythingTheme::New(font_name_, font_scale_, foreground_color_, - background_color_, letter_spacing_)); + obs.OnReadAnythingThemeChanged(ReadAnythingTheme::New( + font_name_, font_scale_, foreground_color_, background_color_, + line_spacing_, letter_spacing_)); } } @@ -295,18 +309,88 @@ ReadAnythingColorsModel::~ReadAnythingColorsModel() = default; /////////////////////////////////////////////////////////////////////////////// +// ReadAnythingLineSpacingModel +/////////////////////////////////////////////////////////////////////////////// + +ReadAnythingLineSpacingModel::ReadAnythingLineSpacingModel() { + // Define the line spacing options available to the user. + lines_choices_.emplace_back(Spacing::kTight); + lines_choices_.emplace_back(Spacing::kDefault); + lines_choices_.emplace_back(Spacing::kLoose); + lines_choices_.emplace_back(Spacing::kVeryLoose); + lines_choices_.shrink_to_fit(); +} + +bool ReadAnythingLineSpacingModel::IsValidLineSpacingIndex(size_t index) { + return index < GetItemCount(); +} + +void ReadAnythingLineSpacingModel::SetDefaultLineSpacingIndexFromPref( + size_t index) { + default_index_ = index; +} + +Spacing ReadAnythingLineSpacingModel::GetLineSpacingAt(size_t index) { + DCHECK_LT(index, GetItemCount()); + + return lines_choices_[index]; +} + +absl::optional<size_t> ReadAnythingLineSpacingModel::GetDefaultIndex() const { + return default_index_; +} + +size_t ReadAnythingLineSpacingModel::GetItemCount() const { + return lines_choices_.size(); +} + +ui::ImageModel ReadAnythingLineSpacingModel::GetIconAt(size_t index) const { + // The dropdown should always show the line spacing icon. + return ui::ImageModel::FromImageSkia(gfx::CreateVectorIcon( + kLineSpacingIcon, kColorsIconSize, gfx::kPlaceholderColor)); +} + +ui::ImageModel ReadAnythingLineSpacingModel::GetDropDownIconAt( + size_t index) const { + return ui::ImageModel(); +} + +std::u16string ReadAnythingLineSpacingModel::GetItemAt(size_t index) const { + // Only display the icon in the toolbar, so return empty string here. + return std::u16string(); +} + +std::u16string ReadAnythingLineSpacingModel::GetLineSpacingName( + Spacing line_spacing) const { + switch (line_spacing) { + case Spacing::kTight: + return u"Tight"; + case Spacing::kDefault: + return u"Default"; + case Spacing::kLoose: + return u"Loose"; + case Spacing::kVeryLoose: + return u"Very Loose"; + } +} + +std::u16string ReadAnythingLineSpacingModel::GetDropDownTextAt( + size_t index) const { + DCHECK_LT(index, GetItemCount()); + return GetLineSpacingName(lines_choices_[index]); +} + +ReadAnythingLineSpacingModel::~ReadAnythingLineSpacingModel() = default; + +/////////////////////////////////////////////////////////////////////////////// // ReadAnythingLetterSpacingModel /////////////////////////////////////////////////////////////////////////////// ReadAnythingLetterSpacingModel::ReadAnythingLetterSpacingModel() { - letter_spacing_choices_.emplace_back( - read_anything::mojom::LetterSpacing::kTight); - letter_spacing_choices_.emplace_back( - read_anything::mojom::LetterSpacing::kDefault); - letter_spacing_choices_.emplace_back( - read_anything::mojom::LetterSpacing::kLoose); - letter_spacing_choices_.emplace_back( - read_anything::mojom::LetterSpacing::kVeryLoose); + letter_spacing_choices_.emplace_back(Spacing::kTight); + letter_spacing_choices_.emplace_back(Spacing::kDefault); + letter_spacing_choices_.emplace_back(Spacing::kLoose); + letter_spacing_choices_.emplace_back(Spacing::kVeryLoose); letter_spacing_choices_.shrink_to_fit(); } @@ -327,26 +411,25 @@ return letter_spacing_choices_.size(); } -read_anything::mojom::LetterSpacing -ReadAnythingLetterSpacingModel::GetLetterSpacingAt(size_t index) { +Spacing ReadAnythingLetterSpacingModel::GetLetterSpacingAt(size_t index) { return letter_spacing_choices_[index]; } // TODO (crbug.com/1266555): Change to translatable messages std::u16string ReadAnythingLetterSpacingModel::GetLetterSpacingName( - read_anything::mojom::LetterSpacing letter_spacing) const { + Spacing letter_spacing) const { int label; switch (letter_spacing) { - case read_anything::mojom::LetterSpacing::kTight: + case Spacing::kTight: label = IDS_READ_ANYTHING_SPACING_COMBOBOX_TIGHT; break; - case read_anything::mojom::LetterSpacing::kDefault: + case Spacing::kDefault: label = IDS_READ_ANYTHING_SPACING_COMBOBOX_DEFAULT; break; - case read_anything::mojom::LetterSpacing::kLoose: + case Spacing::kLoose: label = IDS_READ_ANYTHING_SPACING_COMBOBOX_LOOSE; break; - case read_anything::mojom::LetterSpacing::kVeryLoose: + case Spacing::kVeryLoose: label = IDS_READ_ANYTHING_SPACING_COMBOBOX_VERY_LOOSE; } return l10n_util::GetStringUTF16(label);
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h index be3fe1a..69fafd41 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h
@@ -105,6 +105,49 @@ size_t default_index_ = 0; }; +////////////////////////////////////////////////////////////////////////////// +// ReadAnythingLineSpacingModel +// +// A class that stores the data for the colors combobox. +// This class is owned by the ReadAnythingModel and has the same lifetime as +// the browser. +// +class ReadAnythingLineSpacingModel : public ui::ComboboxModel { + public: + ReadAnythingLineSpacingModel(); + ReadAnythingLineSpacingModel(const ReadAnythingLineSpacingModel&) = delete; + ReadAnythingLineSpacingModel& operator=(const ReadAnythingLineSpacingModel&) = + delete; + ~ReadAnythingLineSpacingModel() override; + + bool IsValidLineSpacingIndex(size_t index); + void SetDefaultLineSpacingIndexFromPref(size_t index); + read_anything::mojom::Spacing GetLineSpacingAt(size_t index); + + // Simple pass-through method so Init can set the starting state. + size_t GetStartingStateIndex() { return GetDefaultIndex().value(); } + + protected: + // ui::Combobox implementation: + absl::optional<size_t> GetDefaultIndex() const override; + size_t GetItemCount() const override; + std::u16string GetItemAt(size_t index) const override; + ui::ImageModel GetIconAt(size_t index) const override; + ui::ImageModel GetDropDownIconAt(size_t index) const override; + std::u16string GetDropDownTextAt(size_t index) const override; + + private: + // Names for the drop down options in front-end. + std::vector<read_anything::mojom::Spacing> lines_choices_; + + // Default index for drop down, either one or populated from prefs. + size_t default_index_ = 1; + + // Display names for line spacing choices + std::u16string GetLineSpacingName( + read_anything::mojom::Spacing line_spacing) const; +}; + /////////////////////////////////////////////////////////////////////////////// // ReadAnythingLetterSpacingModel // @@ -123,7 +166,7 @@ bool IsValidLetterSpacingIndex(size_t index); void SetDefaultLetterSpacingIndexFromPref(size_t index); - read_anything::mojom::LetterSpacing GetLetterSpacingAt(size_t index); + read_anything::mojom::Spacing GetLetterSpacingAt(size_t index); protected: // ui::Combobox implementation: @@ -136,7 +179,7 @@ private: // Letter spacing choices for the drop down options in front-end. - std::vector<read_anything::mojom::LetterSpacing> letter_spacing_choices_; + std::vector<read_anything::mojom::Spacing> letter_spacing_choices_; // Default index for drop down, either one (normal spacing) or populated from // prefs. @@ -144,7 +187,7 @@ // Display names for each letter spacing choice std::u16string GetLetterSpacingName( - read_anything::mojom::LetterSpacing letter_spacing) const; + read_anything::mojom::Spacing letter_spacing) const; }; /////////////////////////////////////////////////////////////////////////////// // ReadAnythingModel @@ -172,7 +215,8 @@ void Init(std::string& font_name, double font_scale, read_anything::mojom::Colors colors, - read_anything::mojom::LetterSpacing letter_spacing); + read_anything::mojom::Spacing line_spacing, + read_anything::mojom::Spacing letter_spacing); void AddObserver(Observer* obs); void RemoveObserver(Observer* obs); @@ -184,11 +228,15 @@ void DecreaseTextSize(); void IncreaseTextSize(); void SetSelectedColorsByIndex(size_t new_index); + void SetSelectedLineSpacingByIndex(size_t new_index); void SetSelectedLetterSpacingByIndex(size_t new_index); ReadAnythingFontModel* GetFontModel() { return font_model_.get(); } double GetFontScale() { return font_scale_; } ReadAnythingColorsModel* GetColorsModel() { return colors_model_.get(); } + ReadAnythingLineSpacingModel* GetLineSpacingModel() { + return lines_model_.get(); + } ReadAnythingLetterSpacingModel* GetLetterSpacingModel() { return letter_spacing_model_.get(); } @@ -207,7 +255,8 @@ // A scale multiplier for font size (internal use only, not shown to user). float font_scale_; - int letter_spacing_; + read_anything::mojom::Spacing line_spacing_; + read_anything::mojom::Spacing letter_spacing_; // TODO(crbug.com/1266555): Use |snapshot_| and |content_node_ids_| to keep // scrolls in sync. @@ -217,6 +266,7 @@ base::ObserverList<Observer> observers_; const std::unique_ptr<ReadAnythingFontModel> font_model_; const std::unique_ptr<ReadAnythingColorsModel> colors_model_; + const std::unique_ptr<ReadAnythingLineSpacingModel> lines_model_; const std::unique_ptr<ReadAnythingLetterSpacingModel> letter_spacing_model_; };
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc index a39b804..d86a793 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc
@@ -135,6 +135,14 @@ model_->SetSelectedColorsByIndex(2); } +TEST_F(ReadAnythingModelTest, NotificationsOnSetSelectedLineSpacingIndex) { + model_->AddObserver(&model_observer_1_); + + EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_)).Times(1); + + model_->SetSelectedLineSpacingByIndex(2); +} + TEST_F(ReadAnythingModelTest, NotificationsOnSetSelectedLetterSpacingIndex) { model_->AddObserver(&model_observer_1_); @@ -146,7 +154,8 @@ TEST_F(ReadAnythingModelTest, MinimumFontScaleIsEnforced) { std::string font_name; model_->Init(font_name, 0.5, read_anything::mojom::Colors::kDefaultValue, - read_anything::mojom::LetterSpacing::kDefaultValue); + read_anything::mojom::Spacing::kDefault, + read_anything::mojom::Spacing::kDefault); model_->DecreaseTextSize(); EXPECT_NEAR(model_->GetFontScale(), 0.5, 0.01); } @@ -154,7 +163,8 @@ TEST_F(ReadAnythingModelTest, MaximumFontScaleIsEnforced) { std::string font_name; model_->Init(font_name, 4.5, read_anything::mojom::Colors::kDefaultValue, - read_anything::mojom::LetterSpacing::kDefaultValue); + read_anything::mojom::Spacing::kDefault, + read_anything::mojom::Spacing::kDefault); model_->IncreaseTextSize(); EXPECT_NEAR(model_->GetFontScale(), 4.5, 0.01); }
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.cc index ecb9e468..dea367d 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.cc
@@ -76,6 +76,18 @@ colors_combobox->SetShouldShowArrow(false); colors_combobox->SetBorderColorId(ui::kColorSidePanelComboboxBorder); + // Create line spacing combobox + auto lines_combobox = std::make_unique<views::Combobox>(); + lines_combobox->SetModel(delegate_->GetLineSpacingModel()); + lines_combobox->SetTooltipTextAndAccessibleName( + l10n_util::GetStringUTF16(IDS_READ_ANYTHING_LINE_SPACING_COMBOBOX_LABEL)); + lines_combobox->SetSizeToLargestLabel(true); + lines_combobox->SetCallback( + base::BindRepeating(&ReadAnythingToolbarView::ChangeLineSpacingCallback, + weak_pointer_factory_.GetWeakPtr())); + lines_combobox->SetShouldShowArrow(false); + lines_combobox->SetBorderColorId(ui::kColorSidePanelComboboxBorder); + // Create letter spacing selection combobox. auto letter_spacing_combobox = std::make_unique<views::Combobox>(); letter_spacing_combobox->SetModel(delegate_->GetLetterSpacingModel()); @@ -96,6 +108,7 @@ increase_text_size_button_ = AddChildView(std::move(increase_size_button)); AddChildView(Separator()); colors_combobox_ = AddChildView(std::move(colors_combobox)); + lines_combobox_ = AddChildView(std::move(lines_combobox)); letter_spacing_combobox_ = AddChildView(std::move(letter_spacing_combobox)); // Start observing model after views creation so initial theme is applied. @@ -118,6 +131,12 @@ colors_combobox_->GetSelectedIndex().value_or(0)); } +void ReadAnythingToolbarView::ChangeLineSpacingCallback() { + if (delegate_) + delegate_->OnLineSpacingChanged( + lines_combobox_->GetSelectedIndex().value_or(1)); +} + void ReadAnythingToolbarView::ChangeLetterSpacingCallback() { if (delegate_) delegate_->OnLetterSpacingChanged( @@ -138,6 +157,8 @@ views::CreateSolidBackground(new_theme->background_color)); colors_combobox_->SetBackground( views::CreateSolidBackground(new_theme->background_color)); + lines_combobox_->SetBackground( + views::CreateSolidBackground(new_theme->background_color)); letter_spacing_combobox_->SetBackground( views::CreateSolidBackground(new_theme->background_color));
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h index 42efb2a..c2b4520 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h
@@ -31,6 +31,8 @@ virtual void OnFontSizeChanged(bool increase) = 0; virtual void OnColorsChanged(int new_index) = 0; virtual ui::ComboboxModel* GetColorsModel() = 0; + virtual void OnLineSpacingChanged(int new_index) = 0; + virtual ui::ComboboxModel* GetLineSpacingModel() = 0; virtual void OnLetterSpacingChanged(int new_index) = 0; virtual ui::ComboboxModel* GetLetterSpacingModel() = 0; }; @@ -56,6 +58,7 @@ void DecreaseFontSizeCallback(); void IncreaseFontSizeCallback(); void ChangeColorsCallback(); + void ChangeLineSpacingCallback(); void ChangeLetterSpacingCallback(); // views::View: @@ -67,6 +70,7 @@ raw_ptr<ReadAnythingButtonView> decrease_text_size_button_; raw_ptr<ReadAnythingButtonView> increase_text_size_button_; raw_ptr<views::Combobox> colors_combobox_; + raw_ptr<views::Combobox> lines_combobox_; raw_ptr<views::Combobox> letter_spacing_combobox_; raw_ptr<ReadAnythingToolbarView::Delegate> delegate_;
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view_browsertest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view_browsertest.cc index a38a80e6..49807ac 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view_browsertest.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view_browsertest.cc
@@ -19,6 +19,8 @@ MOCK_METHOD(void, OnFontSizeChanged, (bool increase), (override)); MOCK_METHOD(void, OnColorsChanged, (int new_index), (override)); MOCK_METHOD(ui::ComboboxModel*, GetColorsModel, (), (override)); + MOCK_METHOD(void, OnLineSpacingChanged, (int new_index), (override)); + MOCK_METHOD(ui::ComboboxModel*, GetLineSpacingModel, (), (override)); MOCK_METHOD(void, OnLetterSpacingChanged, (int new_index), (override)); MOCK_METHOD(ui::ComboboxModel*, GetLetterSpacingModel, (), (override)); }; @@ -71,6 +73,10 @@ void ChangeColorsCallback() { toolbar_view_->ChangeColorsCallback(); } + void ChangeLineSpacingCallback() { + toolbar_view_->ChangeLineSpacingCallback(); + } + void ChangeLetterSpacingCallback() { toolbar_view_->ChangeLetterSpacingCallback(); } @@ -104,6 +110,12 @@ ChangeColorsCallback(); } +IN_PROC_BROWSER_TEST_F(ReadAnythingToolbarViewTest, ChangeLineSpacingCallback) { + EXPECT_CALL(toolbar_delegate_, OnLineSpacingChanged(1)).Times(1); + + ChangeLineSpacingCallback(); +} + IN_PROC_BROWSER_TEST_F(ReadAnythingToolbarViewTest, ChangeLetterSpacingCallback) { EXPECT_CALL(toolbar_delegate_, OnLetterSpacingChanged(1)).Times(1);
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc index bb545046..6aec26f 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc
@@ -158,6 +158,17 @@ helper_.CheckAppInListWindowed(Site::kScreenshots); } +IN_PROC_BROWSER_TEST_F(WebAppIntegration, CheckBrowserNavigation) { + helper_.CreateShortcut(Site::kStandalone, WindowOptions::kBrowser); + helper_.CheckBrowserNavigation(Site::kStandalone); +} + +IN_PROC_BROWSER_TEST_F(WebAppIntegration, CheckBrowserNavigationFails) { + helper_.CreateShortcut(Site::kStandaloneNestedA, WindowOptions::kBrowser); + EXPECT_NONFATAL_FAILURE(helper_.CheckBrowserNavigation(Site::kStandalone), + "webapps_integration/standalone/foo/basic.html"); +} + // Generated tests: IN_PROC_BROWSER_TEST_F(
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc index 7638e6b1..a7a70b60 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
@@ -1999,6 +1999,15 @@ AfterStateCheckAction(); } +void WebAppIntegrationTestDriver::CheckBrowserNavigation(Site site) { + if (!BeforeStateCheckAction(__FUNCTION__)) + return; + ASSERT_TRUE(browser()); + GURL url = browser()->tab_strip_model()->GetActiveWebContents()->GetURL(); + EXPECT_EQ(url, GetUrlForSite(site)); + AfterStateCheckAction(); +} + void WebAppIntegrationTestDriver::CheckBrowserNavigationIsAppSettings( Site site) { #if !BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h index 452c0b6..fd554b73 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h +++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h
@@ -277,6 +277,7 @@ void CheckAppInListTabbed(Site site); void CheckAppNavigation(Site site); void CheckAppNavigationIsStartUrl(); + void CheckBrowserNavigation(Site site); void CheckBrowserNavigationIsAppSettings(Site site); void CheckAppNotInList(Site site); void CheckAppIcon(Site site, Color color);
diff --git a/chrome/browser/ui/webui/chromeos/in_session_password_change/password_change_handler.cc b/chrome/browser/ui/webui/chromeos/in_session_password_change/password_change_handler.cc index 44d03ef..40c0d63 100644 --- a/chrome/browser/ui/webui/chromeos/in_session_password_change/password_change_handler.cc +++ b/chrome/browser/ui/webui/chromeos/in_session_password_change/password_change_handler.cc
@@ -47,19 +47,15 @@ const base::Value::List& params) { const base::Value& old_passwords = params[0]; const base::Value& new_passwords = params[1]; - VLOG(4) << "Scraped " << old_passwords.GetListDeprecated().size() - << " old passwords"; - VLOG(4) << "Scraped " << new_passwords.GetListDeprecated().size() - << " new passwords"; + VLOG(4) << "Scraped " << old_passwords.GetList().size() << " old passwords"; + VLOG(4) << "Scraped " << new_passwords.GetList().size() << " new passwords"; - const std::string old_password = - (old_passwords.GetListDeprecated().size() > 0) - ? old_passwords.GetListDeprecated()[0].GetString() - : ""; - const std::string new_password = - (new_passwords.GetListDeprecated().size() == 1) - ? new_passwords.GetListDeprecated()[0].GetString() - : ""; + const std::string old_password = (old_passwords.GetList().size() > 0) + ? old_passwords.GetList()[0].GetString() + : ""; + const std::string new_password = (new_passwords.GetList().size() == 1) + ? new_passwords.GetList()[0].GetString() + : ""; InSessionPasswordChangeManager::Get()->OnSamlPasswordChanged(old_password, new_password);
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc index 1984be4..a50fd235 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -17,6 +17,7 @@ #include "base/feature_list.h" #include "base/i18n/message_formatter.h" #include "base/i18n/number_formatting.h" +#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/strings/utf_string_conversions.h" @@ -1032,6 +1033,8 @@ void SiteSettingsHandler::HandleGetAllSites(const base::Value::List& args) { AllowJavascript(); + request_started_time_ = base::TimeTicks::Now(); + CHECK_EQ(1U, args.size()); std::string callback_id = args[0].GetString(); @@ -1223,6 +1226,12 @@ void SiteSettingsHandler::OnStorageFetched() { AllowJavascript(); + + // Record how long does it take to fetch the storage and return complete + // information to the UI. + DCHECK(!request_started_time_.is_null()); + base::UmaHistogramTimes("WebsiteSettings.GetAllSitesLoadTime", + base::TimeTicks::Now() - request_started_time_); FireWebUIListener("onStorageListFetched", PopulateCookiesAndUsageData(profile_)); } @@ -2020,6 +2029,7 @@ std::unique_ptr<CookiesTreeModel> cookies_tree_model) { cookies_tree_model_ = std::move(cookies_tree_model); tree_model_set_for_testing_ = true; + request_started_time_ = base::TimeTicks::Now(); } void SiteSettingsHandler::ClearAllSitesMapForTesting() {
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.h b/chrome/browser/ui/webui/settings/site_settings_handler.h index 9b6064a..7995117 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler.h +++ b/chrome/browser/ui/webui/settings/site_settings_handler.h
@@ -361,6 +361,10 @@ // Whether to send site detail data on cookie tree model update. bool update_site_details_ = false; + + // Time when all sites list was requested. Used to record metrics on how long + // does it take to fetch storage. + base::TimeTicks request_started_time_; }; } // namespace settings
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.cc b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.cc index 2faf723..f3db09c3 100644 --- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.cc +++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.cc
@@ -43,7 +43,7 @@ user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); registry->RegisterIntegerPref( prefs::kAccessibilityReadAnythingLetterSpacing, - (int)read_anything::mojom::LetterSpacing::kDefaultValue, + (int)read_anything::mojom::Spacing::kDefaultValue, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); }
diff --git a/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.h b/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.h index f199703b2..45720b1 100644 --- a/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.h +++ b/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.h
@@ -23,7 +23,7 @@ class WebUIMessageHandler; } -// A tab-modal dialog to ask the user to confirm his email before signing in. +// A tab-modal dialog to ask the user to confirm their email before signing in. class SigninEmailConfirmationDialog : public ui::WebDialogDelegate, public SigninViewControllerDelegate { public:
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 4eea11c..640393b 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1664857638-4c1b0a36ea397a1ae2151d06d18fc74455377550.profdata +chrome-linux-main-1664881835-5d7cd6055354b19eef48e95dfac92b65af747ae1.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index cefff89..a797ee3 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1664841456-3da53ffb56c67b1b7a8a3c50a5ec0546f638715b.profdata +chrome-mac-main-1664857638-c57aaf35f44486c9583ff1cb20b2c8d810b8acb9.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index e58ebff..321b01e5 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1664841456-6e91453cac2e734626ffc2b01a75c5cf0f56a190.profdata +chrome-win32-main-1664857638-cf9ce713fb7b36aa64a895e474ebc980474ffbbc.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 63be3125..3a3daa5 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1664841456-9235d616af2d3484228f317fc208f8f5a271db3f.profdata +chrome-win64-main-1664857638-03f4d9e49a57b4ccc243d0d256e19c6e33798b60.profdata
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index c7157a9..1b2aa02 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -583,7 +583,6 @@ ] deps = [ - ":channel_info", ":version_header", "//base", "//base/third_party/dynamic_annotations", @@ -626,6 +625,7 @@ public_deps += [ "//chromeos/crosapi/mojom" ] } else if (is_linux || is_chromeos) { sources += [ "chrome_paths_linux.cc" ] + deps += [ ":channel_info" ] } if (is_mac) { sources += [ "chrome_paths_mac.mm" ]
diff --git a/chrome/common/accessibility/read_anything.mojom b/chrome/common/accessibility/read_anything.mojom index 9888eb8..16cb97b 100644 --- a/chrome/common/accessibility/read_anything.mojom +++ b/chrome/common/accessibility/read_anything.mojom
@@ -21,8 +21,11 @@ skia.mojom.SkColor foreground_color; skia.mojom.SkColor background_color; + // The enum value of the user's line spacing choice + read_anything.mojom.Spacing line_spacing; + // The enum value of the user's letter spacing choice. - int32 letter_spacing; + read_anything.mojom.Spacing letter_spacing; }; // Used by the WebUI page to bootstrap bidirectional communication. @@ -42,8 +45,9 @@ kYellow = 3, }; -[Extensible, Stable, Uuid="2B5C793A-D81E-4C76-8CDF-695C7E0A30E2"] -enum LetterSpacing { +[Extensible, Stable, Uuid="2B5C793A-D81E-4C76-8CDF-695C7E0A30E2", + RenamedFrom="read_anything.mojom.LetterSpacing"] +enum Spacing { kTight = 0, [Default]kDefault = 1, kLoose = 2,
diff --git a/chrome/common/chromeos/extensions/api/telemetry.idl b/chrome/common/chromeos/extensions/api/telemetry.idl index 79e029f..ce42bd224 100644 --- a/chrome/common/chromeos/extensions/api/telemetry.idl +++ b/chrome/common/chromeos/extensions/api/telemetry.idl
@@ -167,6 +167,62 @@ callback StatefulPartitionInfoCallback = void (StatefulPartitionInfo statefulPartitionInfo); + enum TpmGSCVersion { + not_gsc, + cr50, + ti50 + }; + + dictionary TpmVersion { + // GSC version. + TpmGSCVersion? gscVersion; + // TPM family. We use the TPM 2.0 style encoding, e.g.: + // * TPM 1.2: "1.2" -> 0x312e3200 + // * TPM 2.0: "2.0" -> 0x322e3000 + long? family; + // TPM spec level. + double? specLevel; + // Manufacturer code. + long? manufacturer; + // TPM model number. + long? tpmModel; + // Firmware version. + double? firmwareVersion; + // Vendor specific information. + DOMString? vendorSpecific; + }; + + dictionary TpmStatus { + // Whether a TPM is enabled on the system. + boolean? enabled; + // Whether the TPM has been owned. + boolean? owned; + // Whether the owner password is still retained. + boolean? ownerPasswordIsPresent; + }; + + dictionary TpmDictionaryAttack { + // The current dictionary attack counter value. + long? counter; + // The current dictionary attack counter threshold. + long? threshold; + // Whether the TPM is in some form of dictionary attack lockout. + boolean? lockoutInEffect; + // The number of seconds remaining in the lockout. + long? lockoutSecondsRemaining; + }; + + dictionary TpmInfo { + // TPM version related information. + TpmVersion version; + // TPM status related information. + TpmStatus status; + // TPM dictionary attack (DA) related information. + TpmDictionaryAttack dictionaryAttack; + }; + + callback TpmInfoCallback = void (TpmInfo tpmInfo); + interface Functions { [supportsPromises] static void getBatteryInfo(BatteryInfoCallback callback); @@ -174,6 +230,8 @@ [supportsPromises] static void getCpuInfo(CpuInfoCallback callback); + [supportsPromises] static void getInternetConnectivityInfo(InternetConnectivityInfoCallback callback); + [supportsPromises] static void getMemoryInfo(MemoryInfoCallback callback); [supportsPromises] static void getOemData(OemDataCallback callback); @@ -184,6 +242,6 @@ [supportsPromises] static void getStatefulPartitionInfo(StatefulPartitionInfoCallback callback); - [supportsPromises] static void getInternetConnectivityInfo(InternetConnectivityInfoCallback callback); + [supportsPromises] static void getTpmInfo(TpmInfoCallback callback); }; };
diff --git a/chrome/renderer/accessibility/read_anything_app_controller.cc b/chrome/renderer/accessibility/read_anything_app_controller.cc index f60e989..e317ef5 100644 --- a/chrome/renderer/accessibility/read_anything_app_controller.cc +++ b/chrome/renderer/accessibility/read_anything_app_controller.cc
@@ -297,11 +297,12 @@ } void ReadAnythingAppController::OnThemeChanged(ReadAnythingThemePtr new_theme) { + background_color_ = new_theme->background_color; font_name_ = new_theme->font_name; font_size_ = new_theme->font_size; - letter_spacing_ = GetLetterSpacingValue(new_theme->letter_spacing); foreground_color_ = new_theme->foreground_color; - background_color_ = new_theme->background_color; + letter_spacing_ = GetLetterSpacingValue(new_theme->letter_spacing); + line_spacing_ = GetLineSpacingValue(new_theme->line_spacing); // TODO(abigailbklein): Use v8::Function rather than javascript. If possible, // replace this function call with firing an event. @@ -313,14 +314,15 @@ v8::Isolate* isolate) { return gin::Wrappable<ReadAnythingAppController>::GetObjectTemplateBuilder( isolate) + .SetProperty("backgroundColor", + &ReadAnythingAppController::BackgroundColor) .SetProperty("displayNodeIds", &ReadAnythingAppController::DisplayNodeIds) .SetProperty("fontName", &ReadAnythingAppController::FontName) .SetProperty("fontSize", &ReadAnythingAppController::FontSize) - .SetProperty("letterSpacing", &ReadAnythingAppController::LetterSpacing) .SetProperty("foregroundColor", &ReadAnythingAppController::ForegroundColor) - .SetProperty("backgroundColor", - &ReadAnythingAppController::BackgroundColor) + .SetProperty("letterSpacing", &ReadAnythingAppController::LetterSpacing) + .SetProperty("lineSpacing", &ReadAnythingAppController::LineSpacing) .SetMethod("getChildren", &ReadAnythingAppController::GetChildren) .SetMethod("getHtmlTag", &ReadAnythingAppController::GetHtmlTag) .SetMethod("getLanguage", &ReadAnythingAppController::GetLanguage) @@ -339,6 +341,10 @@ return content_node_ids_; } +SkColor ReadAnythingAppController::BackgroundColor() { + return background_color_; +} + std::string ReadAnythingAppController::FontName() { return font_name_; } @@ -347,16 +353,16 @@ return font_size_; } -float ReadAnythingAppController::LetterSpacing() { - return letter_spacing_; -} - SkColor ReadAnythingAppController::ForegroundColor() { return foreground_color_; } -SkColor ReadAnythingAppController::BackgroundColor() { - return background_color_; +float ReadAnythingAppController::LetterSpacing() { + return letter_spacing_; +} + +float ReadAnythingAppController::LineSpacing() { + return line_spacing_; } std::vector<ui::AXNodeID> ReadAnythingAppController::GetChildren( @@ -428,9 +434,15 @@ float font_size, SkColor foreground_color, SkColor background_color, + int line_spacing, int letter_spacing) { + auto line_spacing_enum = + static_cast<read_anything::mojom::Spacing>(line_spacing); + auto letter_spacing_enum = + static_cast<read_anything::mojom::Spacing>(letter_spacing); OnThemeChanged(ReadAnythingTheme::New(font_name, font_size, foreground_color, - background_color, letter_spacing)); + background_color, line_spacing_enum, + letter_spacing_enum)); } void ReadAnythingAppController::SetContentForTesting( @@ -442,20 +454,37 @@ OnAXTreeDistilled(snapshot, content_node_ids); } -double ReadAnythingAppController::GetLetterSpacingValue(int letter_spacing) { - auto ls = static_cast<read_anything::mojom::LetterSpacing>(letter_spacing); - switch (ls) { - case read_anything::mojom::LetterSpacing::kTight: +double ReadAnythingAppController::GetLetterSpacingValue( + read_anything::mojom::Spacing letter_spacing) { + // auto ls = static_cast<read_anything::mojom::Spacing>(letter_spacing); + switch (letter_spacing) { + case read_anything::mojom::Spacing::kTight: return -0.05; - case read_anything::mojom::LetterSpacing::kDefault: + case read_anything::mojom::Spacing::kDefault: return 0; - case read_anything::mojom::LetterSpacing::kLoose: + case read_anything::mojom::Spacing::kLoose: return 0.05; - case read_anything::mojom::LetterSpacing::kVeryLoose: + case read_anything::mojom::Spacing::kVeryLoose: return 0.1; } } +double ReadAnythingAppController::GetLineSpacingValue( + read_anything::mojom::Spacing line_spacing) { + // auto ls = static_cast<read_anything::mojom::Spacing>(line_spacing); + switch (line_spacing) { + case read_anything::mojom::Spacing::kTight: + return 1.0; + case read_anything::mojom::Spacing::kDefault: + default: + return 1.15; + case read_anything::mojom::Spacing::kLoose: + return 1.5; + case read_anything::mojom::Spacing::kVeryLoose: + return 2.0; + } +} + ui::AXNode* ReadAnythingAppController::GetAXNode(ui::AXNodeID ax_node_id) { if (!tree_) return nullptr;
diff --git a/chrome/renderer/accessibility/read_anything_app_controller.h b/chrome/renderer/accessibility/read_anything_app_controller.h index a667cba..a16c09d 100644 --- a/chrome/renderer/accessibility/read_anything_app_controller.h +++ b/chrome/renderer/accessibility/read_anything_app_controller.h
@@ -72,11 +72,12 @@ // gin templates: std::vector<ui::AXNodeID> DisplayNodeIds(); + SkColor BackgroundColor(); std::string FontName(); float FontSize(); - float LetterSpacing(); SkColor ForegroundColor(); - SkColor BackgroundColor(); + float LetterSpacing(); + float LineSpacing(); std::vector<ui::AXNodeID> GetChildren(ui::AXNodeID ax_node_id); std::string GetHtmlTag(ui::AXNodeID ax_node_id); std::string GetLanguage(ui::AXNodeID ax_node_id); @@ -107,8 +108,10 @@ float font_size, SkColor foreground_color, SkColor background_color, + int line_spacing, int letter_spacing); - double GetLetterSpacingValue(int letter_spacing); + double GetLetterSpacingValue(read_anything::mojom::Spacing letter_spacing); + double GetLineSpacingValue(read_anything::mojom::Spacing line_spacing); ui::AXNode* GetAXNode(ui::AXNodeID ax_node_id); @@ -132,11 +135,13 @@ ui::AXNode* end_node_ = nullptr; int32_t start_offset_ = -1; int32_t end_offset_ = -1; + + SkColor background_color_; std::string font_name_; float font_size_; - float letter_spacing_; SkColor foreground_color_; - SkColor background_color_; + float letter_spacing_; + float line_spacing_; }; #endif // CHROME_RENDERER_ACCESSIBILITY_READ_ANYTHING_APP_CONTROLLER_H_
diff --git a/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc b/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc index 38681d2..ef98d78 100644 --- a/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc +++ b/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc
@@ -44,9 +44,11 @@ float font_size, SkColor foreground_color, SkColor background_color, + int line_spacing, int letter_spacing) { controller_->SetThemeForTesting(font_name, font_size, foreground_color, - background_color, letter_spacing); + background_color, line_spacing, + letter_spacing); } void OnAXTreeDistilled(const ui::AXTreeUpdate& snapshot, const std::vector<ui::AXNodeID>& content_node_ids) { @@ -65,6 +67,8 @@ SkColor BackgroundColor() { return controller_->BackgroundColor(); } + float LineSpacing() { return controller_->LineSpacing(); } + float LetterSpacing() { return controller_->LetterSpacing(); } std::vector<ui::AXNodeID> GetChildren(ui::AXNodeID ax_node_id) { @@ -104,12 +108,15 @@ SkColor background = SkColorSetRGB(0xFD, 0xE2, 0x93); int letter_spacing = 0; // enum value, kTight float letter_spacing_value = -0.05; - SetThemeForTesting(font_name, font_size, foreground, background, + int line_spacing = 1; // enum value, kDefault + float line_spacing_value = 1.15; + SetThemeForTesting(font_name, font_size, foreground, background, line_spacing, letter_spacing); EXPECT_EQ(font_name, FontName()); EXPECT_EQ(font_size, FontSize()); EXPECT_EQ(foreground, ForegroundColor()); EXPECT_EQ(background, BackgroundColor()); + EXPECT_EQ(line_spacing_value, LineSpacing()); EXPECT_EQ(letter_spacing_value, LetterSpacing()); }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index bf81823..dbcb821 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -8915,8 +8915,8 @@ "../browser/supervised_user/child_accounts/child_account_service_unittest.cc", "../browser/supervised_user/child_accounts/family_info_fetcher_unittest.cc", "../browser/supervised_user/child_accounts/permission_request_creator_apiary_unittest.cc", + "../browser/supervised_user/kids_chrome_management/kids_access_token_fetcher_unittest.cc", "../browser/supervised_user/kids_chrome_management/kids_external_fetcher_unittest.cc", - "../browser/supervised_user/kids_chrome_management/kids_management_service_unittest.cc", "../browser/supervised_user/kids_management_url_checker_client_unittest.cc", "../browser/supervised_user/parental_control_metrics_unittest.cc", "../browser/supervised_user/supervised_user_favicon_request_handler_unittest.cc",
diff --git a/chrome/test/data/sync/meta_redirect.html b/chrome/test/data/sync/meta_redirect.html new file mode 100644 index 0000000..32827b8 --- /dev/null +++ b/chrome/test/data/sync/meta_redirect.html
@@ -0,0 +1,8 @@ +<html> + <head> + <meta http-equiv="refresh" content="0;url=simple.html"> + </head> + <body> + Redirecting... + </body> +</html>
diff --git a/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts b/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts index 93c9f3e..5781b3b 100644 --- a/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts +++ b/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts
@@ -20,7 +20,7 @@ document.body.innerHTML = ''; readAnythingApp = document.createElement('read-anything-app'); document.body.appendChild(readAnythingApp); - chrome.readAnything.setThemeForTesting('default', 18.0, 0, 0, 0); + chrome.readAnything.setThemeForTesting('default', 18.0, 0, 0, 1, 0); }); function assertFontName(fontFamily: string) { @@ -33,6 +33,11 @@ assertEquals(fontSize, getComputedStyle(container!).fontSize); } + function assertLineSpacing(lineSpacing: string) { + const container = readAnythingApp.shadowRoot!.getElementById('container'); + assertEquals(lineSpacing, getComputedStyle(container!).lineHeight); + } + function assertContainerInnerHTML(expected: string) { const actual: string = readAnythingApp.shadowRoot!.getElementById('container')!.innerHTML; @@ -40,36 +45,36 @@ } test('updateTheme fontName', () => { - chrome.readAnything.setThemeForTesting('Standard font', 18.0, 0, 0, 0); + chrome.readAnything.setThemeForTesting('Standard font', 18.0, 0, 0, 1, 0); assertFontName('"Standard font"'); - chrome.readAnything.setThemeForTesting('Sans-serif', 18.0, 0, 0, 0); + chrome.readAnything.setThemeForTesting('Sans-serif', 18.0, 0, 0, 1, 0); assertFontName('sans-serif'); - chrome.readAnything.setThemeForTesting('Serif', 18.0, 0, 0, 0); + chrome.readAnything.setThemeForTesting('Serif', 18.0, 0, 0, 1, 0); assertFontName('serif'); - chrome.readAnything.setThemeForTesting('Avenir', 18.0, 0, 0, 0); + chrome.readAnything.setThemeForTesting('Avenir', 18.0, 0, 0, 1, 0); assertFontName('avenir'); - chrome.readAnything.setThemeForTesting('Comic Neue', 18.0, 0, 0, 0); + chrome.readAnything.setThemeForTesting('Comic Neue', 18.0, 0, 0, 1, 0); assertFontName('"Comic Neue"'); - chrome.readAnything.setThemeForTesting('Comic Sans MS', 18.0, 0, 0, 0); + chrome.readAnything.setThemeForTesting('Comic Sans MS', 18.0, 0, 0, 1, 0); assertFontName('"Comic Sans MS"'); - chrome.readAnything.setThemeForTesting('Poppins', 18.0, 0, 0, 0); + chrome.readAnything.setThemeForTesting('Poppins', 18.0, 0, 0, 1, 0); assertFontName('poppins'); }); test('updateTheme fontSize', () => { - chrome.readAnything.setThemeForTesting('Standard font', 1.0, 0, 0, 0); + chrome.readAnything.setThemeForTesting('Standard font', 1.0, 0, 0, 1, 0); assertFontSize('16px'); // 1em = 16px }); test('updateTheme foregroundColor', () => { chrome.readAnything.setThemeForTesting( - 'f', 1, /* SkColorSetRGB(0x33, 0x36, 0x39) = */ 4281546297, 0, 0); + 'f', 1, /* SkColorSetRGB(0x33, 0x36, 0x39) = */ 4281546297, 0, 1, 0); const container = readAnythingApp.shadowRoot!.getElementById('container'); assertEquals( /* #333639 = */ 'rgb(51, 54, 57)', getComputedStyle(container!).color); @@ -77,15 +82,20 @@ test('updateTheme backgroundColor', () => { chrome.readAnything.setThemeForTesting( - 'f', 1, 0, /* SkColorSetRGB(0xFD, 0xE2, 0x93) = */ 4294828691, 0); + 'f', 1, 0, /* SkColorSetRGB(0xFD, 0xE2, 0x93) = */ 4294828691, 1, 0); const container = readAnythingApp.shadowRoot!.getElementById('container'); assertEquals( /* #FDE293 = */ 'rgb(253, 226, 147)', getComputedStyle(container!).backgroundColor); }); + test('updateTheme lineSpacing', () => { + chrome.readAnything.setThemeForTesting('Standard font', 1.0, 0, 0, 2, 0); + assertLineSpacing('24px'); // 1.5 times the 1em (16px) font size + }); + test('updateTheme letterSpacing', () => { - chrome.readAnything.setThemeForTesting('f', 1, 0, 0, 3); + chrome.readAnything.setThemeForTesting('f', 1, 0, 0, 1, 3); const container = readAnythingApp.shadowRoot!.getElementById('container'); // very loose letter letter spacing = 0.1em, font size = 1em = 16px assertEquals('1.6px', getComputedStyle(container!).letterSpacing);
diff --git a/chrome/test/webapps/data/actions.md b/chrome/test/webapps/data/actions.md index c9ffbe41..cc05236 100644 --- a/chrome/test/webapps/data/actions.md +++ b/chrome/test/webapps/data/actions.md
@@ -20,7 +20,7 @@ TODO(dmurph): Possibly this table up into markdown-header section. -| # Action base name | Argument Types | Output Actions | Unique Identifier (next: 133) | Status (WIP, Implemented, Not Implemented, Parameterized) | Description | Metadata, implementation bug, etc | +| # Action base name | Argument Types | Output Actions | Unique Identifier (next: 135) | Status (WIP, Implemented, Not Implemented, Parameterized) | Description | Metadata, implementation bug, etc | | --- | --- | --- | --- | --- | --- | --- | | # Badging | | check_app_badge_empty | Site | | 2 | Not Implemented | Check that the 'badge' on the app icon is empty | | @@ -90,6 +90,7 @@ | check_app_in_list_icon_correct | Site | | 75 | Implemented | Find the app in the app list (on desktop, this is chrome://apps, and on ChromeOS, this is the app drawer). Check that the icon for the given app in the app list is correct. | P2 (fetch icon using web request for chrome://app-icon/<app-id>/<icon-size>) | | check_theme_color | Site | | 76 | Not Implemented | Asserts that the theme color of the given app window is correct. | P3 | | # Misc UX | +| check_browser_navigation | Site | | 134 | Implemented | Check the current browser navigation is the given site | | | check_browser_navigation_is_app_settings | Site | | 109 | Implemented | Check the current browser navigation is chrome://app-settings/<app-id> | phillis@ | | check_create_shortcut_not_shown | | | 85 | WIP | Check that the "Create Shortcut" menu option (3-dot->"More Tools"->"Create Shortcut) is greyed out | | | check_create_shortcut_shown | | | 86 | WIP | Check that the "Create Shortcut" menu option (3-dot->"More Tools"->"Create Shortcut) is shown | |
diff --git a/chromeos/ash/components/login/auth/auth_factor_editor.cc b/chromeos/ash/components/login/auth/auth_factor_editor.cc index 2db789d..cfd7f9b 100644 --- a/chromeos/ash/components/login/auth/auth_factor_editor.cc +++ b/chromeos/ash/components/login/auth/auth_factor_editor.cc
@@ -376,6 +376,7 @@ } CHECK(reply.has_value()); LOGIN_LOG(EVENT) << "Successfully added credentials"; + context->ClearAuthFactorsConfiguration(); std::move(callback).Run(std::move(context), absl::nullopt); // TODO(crbug.com/1310312): Think if we should update SessionAuthFactors in // context after such operation. @@ -393,6 +394,7 @@ } CHECK(reply.has_value()); LOGIN_LOG(EVENT) << "Successfully added auth factor"; + context->ClearAuthFactorsConfiguration(); std::move(callback).Run(std::move(context), absl::nullopt); // TODO(crbug.com/1310312): Think if we should update SessionAuthFactors in // context after such operation. @@ -410,6 +412,7 @@ } CHECK(reply.has_value()); LOGIN_LOG(EVENT) << "Successfully updated credential"; + context->ClearAuthFactorsConfiguration(); std::move(callback).Run(std::move(context), absl::nullopt); } @@ -425,6 +428,7 @@ } CHECK(reply.has_value()); LOGIN_LOG(EVENT) << "Successfully updated auth factor"; + context->ClearAuthFactorsConfiguration(); std::move(callback).Run(std::move(context), absl::nullopt); } @@ -441,6 +445,7 @@ CHECK(reply.has_value()); LOGIN_LOG(EVENT) << "Successfully added recovery key"; + context->ClearAuthFactorsConfiguration(); std::move(callback).Run(std::move(context), absl::nullopt); } @@ -457,6 +462,7 @@ CHECK(reply.has_value()); LOGIN_LOG(EVENT) << "Successfully removed recovery key"; + context->ClearAuthFactorsConfiguration(); std::move(callback).Run(std::move(context), absl::nullopt); }
diff --git a/chromeos/ash/components/login/auth/public/user_context.cc b/chromeos/ash/components/login/auth/public/user_context.cc index d32876a..d03aae3 100644 --- a/chromeos/ash/components/login/auth/public/user_context.cc +++ b/chromeos/ash/components/login/auth/public/user_context.cc
@@ -315,6 +315,10 @@ auth_factors_configuration_ = std::move(auth_factors); } +void UserContext::ClearAuthFactorsConfiguration() { + auth_factors_configuration_ = absl::nullopt; +} + const AuthFactorsConfiguration& UserContext::GetAuthFactorsConfiguration() { DCHECK(features::IsUseAuthFactorsEnabled()); if (!auth_factors_configuration_.has_value()) {
diff --git a/chromeos/ash/components/login/auth/public/user_context.h b/chromeos/ash/components/login/auth/public/user_context.h index d1c592f..f3ecf437 100644 --- a/chromeos/ash/components/login/auth/public/user_context.h +++ b/chromeos/ash/components/login/auth/public/user_context.h
@@ -163,6 +163,7 @@ void SetCanLockManagedGuestSession(bool can_lock_managed_guest_session); void SetSessionAuthFactors(SessionAuthFactors keys); void SetAuthFactorsConfiguration(AuthFactorsConfiguration auth_factors); + void ClearAuthFactorsConfiguration(); // We need to pull input method used to log in into the user session to make // it consistent. This method will remember given input method to be used // when session starts.
diff --git a/chromeos/system/name_value_pairs_parser.cc b/chromeos/system/name_value_pairs_parser.cc index f33604429..b6518d2 100644 --- a/chromeos/system/name_value_pairs_parser.cc +++ b/chromeos/system/name_value_pairs_parser.cc
@@ -28,16 +28,13 @@ // Runs a tool and capture its standard output into |output|. Returns false // if the tool cannot be run. -bool GetToolOutput(const std::vector<std::string>& args, std::string* output) { - DCHECK_GE(args.size(), 1u); - - if (!base::PathExists(base::FilePath(args[0]))) { - LOG(WARNING) << "Tool for statistics not found: " << args[0]; +bool GetToolOutput(const base::CommandLine& command, std::string* output) { + if (!base::PathExists(command.GetProgram())) { + LOG(WARNING) << "Tool for statistics not found: " << command.GetProgram(); return false; } - - if (!base::GetAppOutput(args, output)) { - LOG(WARNING) << "Error executing " << args[0]; + if (!base::GetAppOutput(command, output)) { + LOG(WARNING) << "Error executing " << command.GetProgram(); return false; } @@ -156,15 +153,14 @@ } bool NameValuePairsParser::ParseNameValuePairsFromTool( - const std::vector<std::string>& args, + const base::CommandLine& command, NameValuePairsFormat format) { - DCHECK_GE(args.size(), 1u); - std::string output_string; - if (!GetToolOutput(args, &output_string)) + if (!GetToolOutput(command, &output_string)) return false; - return ParseNameValuePairs(output_string, format, /*debug_source=*/args[0]); + return ParseNameValuePairs(output_string, format, + /*debug_source=*/command.GetProgram().value()); } void NameValuePairsParser::DeletePairsWithValue(const std::string& value) {
diff --git a/chromeos/system/name_value_pairs_parser.h b/chromeos/system/name_value_pairs_parser.h index fa16da9b..1757aef 100644 --- a/chromeos/system/name_value_pairs_parser.h +++ b/chromeos/system/name_value_pairs_parser.h
@@ -9,6 +9,7 @@ #include <string> #include <vector> +#include "base/command_line.h" #include "base/component_export.h" #include "base/gtest_prod_util.h" @@ -57,11 +58,11 @@ NameValuePairsFormat format); // Parses name-value pairs in the specified |format| from the standard output - // of a tool invocation specified by |args|. + // of a tool invocation specified by |command|. // // Returns false if there was any error in the command invocation or when // parsing its output. Valid pairs will still be added to the map. - bool ParseNameValuePairsFromTool(const std::vector<std::string>& args, + bool ParseNameValuePairsFromTool(const base::CommandLine& command, NameValuePairsFormat format); // Delete all pairs with |value|.
diff --git a/chromeos/system/name_value_pairs_parser_unittest.cc b/chromeos/system/name_value_pairs_parser_unittest.cc index db0ae37b1..0bc714d 100644 --- a/chromeos/system/name_value_pairs_parser_unittest.cc +++ b/chromeos/system/name_value_pairs_parser_unittest.cc
@@ -4,6 +4,7 @@ #include "chromeos/system/name_value_pairs_parser.h" +#include "base/command_line.h" #include "testing/gtest/include/gtest/gtest.h" namespace chromeos { @@ -140,19 +141,20 @@ } TEST(NameValuePairsParser, TestParseNameValuePairsFromCrossystemTool) { - // Sample output is taken from the /usr/bin/crosssytem tool. - const std::vector<std::string> command = { - "/bin/echo", - "arch = x86 # Platform architecture\n" - "cros_debug = 1 # OS should allow debug\n" - "dbg_reset = (error) # Debug reset mode request\n" - "key#with_comment = some value # Multiple # comment # delims\n" - "key = # No value.\n" - "vdat_timers = " - "LFS=0,0 LF=1784220250,2971030570 LK=9064076660,9342689170 " - "# Timer values from VbSharedData\n" - "wpsw_cur = 1 # Firmware hardware WP switch " - "pos\n"}; + // Sample output is taken from the /usr/bin/crossystem tool. + const base::CommandLine command( + {"/bin/echo", + // Below is single string argument. + "arch = x86 # Platform architecture\n" + "cros_debug = 1 # OS should allow debug\n" + "dbg_reset = (error) # Debug reset mode request\n" + "key#with_comment = some value # Multiple # comment # delims\n" + "key = # No value.\n" + "vdat_timers = " + "LFS=0,0 LF=1784220250,2971030570 LK=9064076660,9342689170 " + "# Timer values from VbSharedData\n" + "wpsw_cur = 1 # Firmware hardware WP switch " + "pos\n"}); NameValuePairsParser::NameValueMap map; NameValuePairsParser parser(&map); @@ -169,6 +171,20 @@ EXPECT_EQ("1", map["wpsw_cur"]); } +TEST(NameValuePairsParser, TestParseNameValuePairsFromEmptyTool) { + // Sample output is taken from the /usr/bin/crossystem tool. + const base::CommandLine command( + {"/bin/echo", + // Use empty string argument to check that tool caller can handle it. + ""}); + + NameValuePairsParser::NameValueMap map; + NameValuePairsParser parser(&map); + parser.ParseNameValuePairsFromTool(command, + NameValuePairsFormat::kCrossystem); + EXPECT_TRUE(map.empty()); +} + TEST(NameValuePairsParser, DeletePairsWithValue) { NameValuePairsParser::NameValueMap map = { {"foo", "good"}, {"bar", "bad"}, {"baz", "good"}, {"end", "bad"},
diff --git a/chromeos/system/statistics_provider_impl.cc b/chromeos/system/statistics_provider_impl.cc index 30d08807..6d21b20 100644 --- a/chromeos/system/statistics_provider_impl.cc +++ b/chromeos/system/statistics_provider_impl.cc
@@ -152,7 +152,7 @@ StatisticsProviderImpl::StatisticsSources CreateDefaultSources() { StatisticsProviderImpl::StatisticsSources sources; - sources.crossystem_tool = {kCrosSystemTool}; + sources.crossystem_tool = base::CommandLine(base::FilePath(kCrosSystemTool)); sources.machine_info_filepath = GetFilePathIgnoreFailure(FILE_MACHINE_INFO); sources.vpd_echo_filepath = base::FilePath(kEchoCouponFile); sources.vpd_filepath = GetFilePathIgnoreFailure(FILE_VPD); @@ -199,8 +199,6 @@ oem_manifest_loaded_(false), statistics_loaded_(base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED) { - DCHECK(!sources_.crossystem_tool.empty()); - regional_data_extractors_[kInitialLocaleKey] = &GetInitialLocaleFromRegionalData; regional_data_extractors_[kKeyboardLayoutKey] = @@ -373,7 +371,7 @@ if (!parser.ParseNameValuePairsFromTool( sources_.crossystem_tool, NameValuePairsFormat::kCrossystem)) { LOG(ERROR) << "Errors parsing output from: " - << sources_.crossystem_tool[0]; + << sources_.crossystem_tool.GetProgram(); } // Drop useless "(error)" values so they don't displace valid values // supplied later by other tools: https://crbug.com/844258
diff --git a/chromeos/system/statistics_provider_impl.h b/chromeos/system/statistics_provider_impl.h index 31426f3..30d38a2 100644 --- a/chromeos/system/statistics_provider_impl.h +++ b/chromeos/system/statistics_provider_impl.h
@@ -11,6 +11,7 @@ #include <vector> #include "base/callback_forward.h" +#include "base/command_line.h" #include "base/containers/flat_map.h" #include "base/files/file_path.h" #include "base/memory/scoped_refptr.h" @@ -41,7 +42,7 @@ StatisticsSources& operator=(StatisticsSources&& other); // Binary to fake crossystem tool with arguments. E.g. echo. - std::vector<std::string> crossystem_tool; + base::CommandLine crossystem_tool{base::CommandLine::NO_PROGRAM}; base::FilePath machine_info_filepath; base::FilePath vpd_echo_filepath;
diff --git a/chromeos/system/statistics_provider_impl_unittest.cc b/chromeos/system/statistics_provider_impl_unittest.cc index c3c508e8..606a5f4 100644 --- a/chromeos/system/statistics_provider_impl_unittest.cc +++ b/chromeos/system/statistics_provider_impl_unittest.cc
@@ -5,6 +5,7 @@ #include "chromeos/system/statistics_provider_impl.h" #include "ash/constants/ash_switches.h" +#include "base/command_line.h" #include "base/files/file.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" @@ -63,10 +64,8 @@ SourcesBuilder(const SourcesBuilder&) = delete; SourcesBuilder& operator=(const SourcesBuilder&) = delete; - SourcesBuilder& set_crossystem_tool(const std::string& tool_cmd, - const std::string& tool_args) { - EXPECT_FALSE(tool_args.empty()); - sources_.crossystem_tool = {tool_cmd, tool_args}; + SourcesBuilder& set_crossystem_tool(const base::CommandLine& tool_cmd) { + sources_.crossystem_tool = tool_cmd; return *this; } @@ -96,8 +95,8 @@ } StatisticsProviderImpl::StatisticsSources Build() { - if (sources_.crossystem_tool.empty()) { - sources_.crossystem_tool = {kEchoCmd}; + if (sources_.crossystem_tool.GetProgram().empty()) { + sources_.crossystem_tool = base::CommandLine(base::FilePath(kEchoCmd)); } if (sources_.machine_info_filepath.empty()) { @@ -167,7 +166,7 @@ StatisticsProviderImpl::StatisticsSources testing_sources = SourcesBuilder(temp_dir()) - .set_crossystem_tool(kEchoCmd, kEchoArgs) + .set_crossystem_tool(base::CommandLine({kEchoCmd, kEchoArgs})) .Build(); // Load statistics. @@ -226,7 +225,7 @@ StatisticsProviderImpl::StatisticsSources testing_sources = SourcesBuilder(temp_dir()) - .set_crossystem_tool(kEchoCmd, kEchoArgs) + .set_crossystem_tool(base::CommandLine({kEchoCmd, kEchoArgs})) .set_machine_info( CreateFileInTempDir(kMachineInfoStatistics, temp_dir())) .Build(); @@ -265,7 +264,7 @@ StatisticsProviderImpl::StatisticsSources testing_sources = SourcesBuilder(temp_dir()) - .set_crossystem_tool(kEchoCmd, kEchoArgs) + .set_crossystem_tool(base::CommandLine({kEchoCmd, kEchoArgs})) .set_machine_info( CreateFileInTempDir(kMachineInfoStatistics, temp_dir())) .Build(); @@ -300,7 +299,7 @@ StatisticsProviderImpl::StatisticsSources testing_sources = SourcesBuilder(temp_dir()) - .set_crossystem_tool(kEchoCmd, kEchoArgs) + .set_crossystem_tool(base::CommandLine({kEchoCmd, kEchoArgs})) .Build(); // Load statistics.
diff --git a/components/autofill/core/browser/autofill_experiments_unittest.cc b/components/autofill/core/browser/autofill_experiments_unittest.cc index 7535f7b3..6bef837 100644 --- a/components/autofill/core/browser/autofill_experiments_unittest.cc +++ b/components/autofill/core/browser/autofill_experiments_unittest.cc
@@ -105,8 +105,7 @@ } TEST_F(AutofillExperimentsTest, IsCardUploadEnabled_AuthError) { - sync_service_.SetAuthError( - GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); + sync_service_.SetPersistentAuthErrorOtherThanWebSignout(); EXPECT_FALSE(IsCreditCardUploadEnabled(AutofillSyncSigninState::kSyncPaused)); histogram_tester.ExpectUniqueSample( "Autofill.CardUploadEnabled",
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc index fbb2b443..e794ab6 100644 --- a/components/autofill/core/browser/personal_data_manager_unittest.cc +++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -4778,14 +4778,12 @@ // Call OnSyncServiceInitialized with a sync service in auth error. syncer::TestSyncService sync_service; - sync_service.SetAuthError( - GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); + sync_service.SetPersistentAuthErrorOtherThanWebSignout(); personal_data_->OnSyncServiceInitialized(&sync_service); WaitForOnPersonalDataChanged(); // Remove the auth error to be able to get the server cards. - sync_service.SetAuthError( - GoogleServiceAuthError(GoogleServiceAuthError::NONE)); + sync_service.ClearAuthError(); // Check that cards were masked and other were untouched. EXPECT_EQ(3U, personal_data_->GetCreditCards().size());
diff --git a/components/autofill_assistant/browser/features.cc b/components/autofill_assistant/browser/features.cc index 1c2a58f..08c232a 100644 --- a/components/autofill_assistant/browser/features.cc +++ b/components/autofill_assistant/browser/features.cc
@@ -29,13 +29,13 @@ // |GetActions| calls. BASE_FEATURE(kAutofillAssistantVerifyGetActionsResponses, "AutofillAssistantVerifyGetActionsResponses", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // Controls whether RPC requests to the backend should be signed for // |GetActions| calls. BASE_FEATURE(kAutofillAssistantSignGetActionsRequests, "AutofillAssistantSignGetActionsRequests", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // Controls whether RPC requests to the backend should be signed for // |GetNoRoundTripScriptsByHash| calls.
diff --git a/components/autofill_assistant/browser/service/service_request_sender_impl_unittest.cc b/components/autofill_assistant/browser/service/service_request_sender_impl_unittest.cc index 398d392..beefd9e 100644 --- a/components/autofill_assistant/browser/service/service_request_sender_impl_unittest.cc +++ b/components/autofill_assistant/browser/service/service_request_sender_impl_unittest.cc
@@ -100,6 +100,7 @@ }; TEST_F(ServiceRequestSenderImplTest, SendUnauthenticatedRequest) { + InitCupFeatures(false, false); auto cup_factory = std::make_unique<NiceMock<autofill_assistant::cup::MockCUPFactory>>(); auto loader_factory = @@ -136,6 +137,7 @@ } TEST_F(ServiceRequestSenderImplTest, SendAuthenticatedRequest) { + InitCupFeatures(false, false); auto cup_factory = std::make_unique<NiceMock<autofill_assistant::cup::MockCUPFactory>>(); auto loader_factory = @@ -227,6 +229,7 @@ TEST_F(ServiceRequestSenderImplTest, AuthRequestFallsBackToApiKeyOnEmptyAccessToken) { + InitCupFeatures(false, false); EXPECT_CALL(mock_access_token_fetcher_, OnFetchAccessToken) .WillOnce(RunOnceCallback<0>(true, /*access_token = */ "")); @@ -268,6 +271,7 @@ TEST_F(ServiceRequestSenderImplTest, AuthRequestFallsBackToApiKeyIfFetchingAccessTokenFails) { + InitCupFeatures(false, false); EXPECT_CALL(mock_access_token_fetcher_, OnFetchAccessToken) .WillOnce( RunOnceCallback<0>(/*success = */ false, /*access_token = */ "")); @@ -387,8 +391,7 @@ RpcType::GET_ACTIONS); } -TEST_F(ServiceRequestSenderImplTest, ValidatesGetActionsResponsesWhenEnabled) { - InitCupFeatures(true, true); +TEST_F(ServiceRequestSenderImplTest, ValidatesGetActionsResponsesByDefault) { auto cup_factory = std::make_unique<NiceMock<autofill_assistant::cup::MockCUPFactory>>(); auto cup = std::make_unique<NiceMock<autofill_assistant::cup::MockCUP>>();
diff --git a/components/content_settings/core/browser/cookie_settings_unittest.cc b/components/content_settings/core/browser/cookie_settings_unittest.cc index 3d5aba9..19a1ed579 100644 --- a/components/content_settings/core/browser/cookie_settings_unittest.cc +++ b/components/content_settings/core/browser/cookie_settings_unittest.cc
@@ -90,8 +90,8 @@ kHttpsSubdomainSite("https://www.example.com"), kHttpsSite8080("https://example.com:8080"), kAllHttpsSitesPattern(ContentSettingsPattern::FromString("https://*")) { - std::vector<base::Feature> enabled_features; - std::vector<base::Feature> disabled_features; + std::vector<base::test::FeatureRef> enabled_features; + std::vector<base::test::FeatureRef> disabled_features; #if BUILDFLAG(IS_IOS) enabled_features.push_back(kImprovedCookieControls); #endif
diff --git a/components/content_settings/core/common/cookie_settings_base_unittest.cc b/components/content_settings/core/common/cookie_settings_base_unittest.cc index 5ff86f72..4bd31680 100644 --- a/components/content_settings/core/common/cookie_settings_base_unittest.cc +++ b/components/content_settings/core/common/cookie_settings_base_unittest.cc
@@ -233,7 +233,7 @@ public: CookieSettingsBaseStorageAccessAPITest() { std::vector<base::test::ScopedFeatureList::FeatureAndParams> enabled; - std::vector<base::Feature> disabled; + std::vector<base::test::FeatureRef> disabled; if (IsStorageAccessAPIEnabled()) { enabled.push_back({net::features::kStorageAccessAPI, {{"storage-access-api-grants-unpartitioned-storage",
diff --git a/components/google/core/common/google_util.cc b/components/google/core/common/google_util.cc index a80af757..51f1a81 100644 --- a/components/google/core/common/google_util.cc +++ b/components/google/core/common/google_util.cc
@@ -115,8 +115,6 @@ base::MakeFixedFlatSet<base::StringPiece>({YOUTUBE_TLD_LIST}); return IsValidHostName(canonical_host, "youtube", subdomain_permission, - youtube_tlds) || - IsValidHostName(canonical_host, "youtubekids", subdomain_permission, youtube_tlds); }
diff --git a/components/google/core/common/google_util_unittest.cc b/components/google/core/common/google_util_unittest.cc index 66bd3818..4b34a51f 100644 --- a/components/google/core/common/google_util_unittest.cc +++ b/components/google/core/common/google_util_unittest.cc
@@ -401,10 +401,13 @@ google_util::ALLOW_SUBDOMAIN, google_util::DISALLOW_NON_STANDARD_PORTS)); - // YouTube Kids - EXPECT_TRUE(IsYoutubeDomainUrl(GURL("http://www.youtubekids.com"), - google_util::ALLOW_SUBDOMAIN, - google_util::DISALLOW_NON_STANDARD_PORTS)); + // YouTube Kids is not a youtube domain as it does not use the standard Google + // auth stack. + // + // Regression test for b/247647476 + EXPECT_FALSE(IsYoutubeDomainUrl(GURL("http://www.youtubekids.com"), + google_util::ALLOW_SUBDOMAIN, + google_util::DISALLOW_NON_STANDARD_PORTS)); // TLD checks. EXPECT_TRUE(IsYoutubeDomainUrl(GURL("http://www.youtube.ca"),
diff --git a/components/history/core/browser/sync/history_sync_bridge.cc b/components/history/core/browser/sync/history_sync_bridge.cc index 285e602..7dedf70 100644 --- a/components/history/core/browser/sync/history_sync_bridge.cc +++ b/components/history/core/browser/sync/history_sync_bridge.cc
@@ -161,12 +161,15 @@ if (specifics.page_transition().home_page()) { page_transition |= ui::PAGE_TRANSITION_HOME_PAGE; } - // Then add redirect markers as appropriate - first chain start/end markers. - if (redirect_index == 0) { + // Then add redirect markers as appropriate. + // First, chain start/end markers. Note that these only apply to the + // first/last visit per entity, respectively. + if (redirect_index == 0 && !specifics.redirect_chain_start_incomplete()) { page_transition |= ui::PAGE_TRANSITION_CHAIN_START; } // No "else" - a visit can be both the start and end of a chain! - if (redirect_index == specifics.redirect_entries_size() - 1) { + if (redirect_index == specifics.redirect_entries_size() - 1 && + !specifics.redirect_chain_end_incomplete()) { page_transition |= ui::PAGE_TRANSITION_CHAIN_END; } // Finally, add the redirect type (if any). @@ -307,6 +310,17 @@ history->mutable_page_transition()->set_home_page( (first_visit.transition & ui::PAGE_TRANSITION_HOME_PAGE) != 0); + // The chain_start/end markers are inverted in the proto. + history->set_redirect_chain_start_incomplete( + (first_visit.transition & ui::PAGE_TRANSITION_CHAIN_START) == 0); + // Exception: The chain *end* marker needs to be taken from the last visit! + history->set_redirect_chain_end_incomplete( + (last_visit.transition & ui::PAGE_TRANSITION_CHAIN_END) == 0); + // Note: Typically, chain_start_incomplete and chain_end_incomplete will both + // end up being false here. However, in some cases (notably, client + // redirects), a single redirect chain may be split up over multiple entities, + // in which case one (or even both) might be true. + // Referring visit and opener visit are taken from the *first* visit in the // chain, since they only make sense for that one. history->set_originator_referring_visit_id(first_visit.referring_visit); @@ -549,9 +563,21 @@ continue; } - std::unique_ptr<syncer::EntityData> entity_data = + std::vector<std::unique_ptr<syncer::EntityData>> entity_data_list = QueryRedirectChainAndMakeEntityData(final_visit); - if (!entity_data) { + // Typically, `entity_data_list` will have exactly one entry. In some error + // cases (corrupted DB), it may be empty, and in some cases the redirect + // chain may have been split into multiple entities. In that case, the last + // entity should be the one corresponding to the `key`. + if (entity_data_list.empty()) { + continue; + } + std::unique_ptr<syncer::EntityData> entity_data = + std::move(entity_data_list.back()); + // The last entity's visit time should almost always match the desired one, + // but again, in some rare DB error cases it may not. + if (entity_data->specifics.history().visit_time_windows_epoch_micros() != + visit_time.ToDeltaSinceWindowsEpoch().InMicroseconds()) { continue; } batch->Put(key, std::move(entity_data)); @@ -644,16 +670,17 @@ return; } - std::unique_ptr<syncer::EntityData> entity_data = + std::vector<std::unique_ptr<syncer::EntityData>> entity_data_list = QueryRedirectChainAndMakeEntityData(visit_row); - if (!entity_data) { - return; - } std::unique_ptr<syncer::MetadataChangeList> metadata_change_list = CreateMetadataChangeList(); - change_processor()->Put(GetStorageKeyFromVisitRow(visit_row), - std::move(entity_data), metadata_change_list.get()); + + for (auto& entity_data : entity_data_list) { + std::string storage_key = GetStorageKey(*entity_data); + change_processor()->Put(storage_key, std::move(entity_data), + metadata_change_list.get()); + } // `metadata_change_list` must have been created via // CreateMetadataChangeList(), so downcasting is safe. @@ -740,16 +767,17 @@ return; } - std::unique_ptr<syncer::EntityData> entity_data = + std::vector<std::unique_ptr<syncer::EntityData>> entity_data_list = QueryRedirectChainAndMakeEntityData(visit_row); - if (!entity_data) { - return; - } std::unique_ptr<syncer::MetadataChangeList> metadata_change_list = CreateMetadataChangeList(); - change_processor()->Put(GetStorageKeyFromVisitRow(visit_row), - std::move(entity_data), metadata_change_list.get()); + + for (auto& entity_data : entity_data_list) { + std::string storage_key = GetStorageKey(*entity_data); + change_processor()->Put(storage_key, std::move(entity_data), + metadata_change_list.get()); + } // `metadata_change_list` must have been created via // CreateMetadataChangeList(), so downcasting is safe. @@ -807,7 +835,7 @@ change_processor()->ModelReadyToSync(std::move(batch)); } -std::unique_ptr<syncer::EntityData> +std::vector<std::unique_ptr<syncer::EntityData>> HistorySyncBridge::QueryRedirectChainAndMakeEntityData( const VisitRow& final_visit) { // Query the redirect chain that ended in this visit. @@ -816,26 +844,53 @@ if (redirect_visits.empty()) { // This can happen if there's invalid data in the DB (e.g. broken referrer // "links"). - return nullptr; + return {}; } DCHECK_EQ(redirect_visits.back().visit_id, final_visit.visit_id); - std::vector<AnnotatedVisit> annotated_visits = - history_backend_->ToAnnotatedVisits(redirect_visits); - if (annotated_visits.empty()) { - // Again, this can happen if there's invalid data in the DB. - return nullptr; + // Typically, all visits in a redirect chain have the same timestamp. However, + // in some cases, a redirect chain may be extended retroactively (with visits + // with a different timestamp). In that case, split the chain into multiple + // subchains, which will become separate Sync entities. + std::vector<std::unique_ptr<syncer::EntityData>> entities; + auto subchain_begin = redirect_visits.begin(); + while (subchain_begin != redirect_visits.end()) { + // `subchain_begin` points to the beginning of the current subchain. + base::Time chain_time = subchain_begin->visit_time; + auto subchain_end = subchain_begin + 1; + while (subchain_end != redirect_visits.end() && + subchain_end->visit_time == chain_time) { + ++subchain_end; + } + // Now `subchain_end` points just beyond the end of the current subchain + // (i.e. first entry with a different timestamp or `redirect_visits.end()`). + + // Grab the current subchain. + std::vector<VisitRow> subchain_visits( + std::make_move_iterator(subchain_begin), + std::make_move_iterator(subchain_end)); + + // Make `subchain_begin` point to the beginning of the *next* subchain, for + // the next iteration. + subchain_begin = subchain_end; + + // Convert the current subchain into a SyncEntity. + std::vector<AnnotatedVisit> annotated_visits = + history_backend_->ToAnnotatedVisits(subchain_visits); + if (annotated_visits.empty()) { + // Again, this can happen if there's invalid data in the DB. In that case, + // skip this subchain but still try to handle any others. + continue; + } + GURL referrer_url = + GetURLForVisit(annotated_visits.front().visit_row.referring_visit); + std::vector<GURL> favicon_urls = history_backend_->GetFaviconURLsForURL( + annotated_visits.back().url_row.url()); + // Note: `favicon_urls` may legitimately be empty, that's fine. + entities.push_back(MakeEntityData(GetLocalCacheGuid(), annotated_visits, + referrer_url, favicon_urls)); } - - GURL referrer_url = - GetURLForVisit(annotated_visits.front().visit_row.referring_visit); - - std::vector<GURL> favicon_urls = history_backend_->GetFaviconURLsForURL( - annotated_visits.back().url_row.url()); - // Note: `favicon_urls` may legitimately be empty, that's fine. - - return MakeEntityData(GetLocalCacheGuid(), annotated_visits, referrer_url, - favicon_urls); + return entities; } GURL HistorySyncBridge::GetURLForVisit(VisitID visit_id) {
diff --git a/components/history/core/browser/sync/history_sync_bridge.h b/components/history/core/browser/sync/history_sync_bridge.h index cb3c4dc..f156e03a 100644 --- a/components/history/core/browser/sync/history_sync_bridge.h +++ b/components/history/core/browser/sync/history_sync_bridge.h
@@ -84,10 +84,12 @@ void LoadMetadata(); // Queries the redirect chain ending in `final_visit` from the HistoryBackend, - // and creates the corresponding EntityData. May return null in case of + // and creates the corresponding EntityData(s). Typically returns a single + // EntityData, but in some cases the redirect chain may have to be split up + // into multiple entities. May return no entities at all in case of // HistoryBackend failure (e.g. corrupted DB). - std::unique_ptr<syncer::EntityData> QueryRedirectChainAndMakeEntityData( - const VisitRow& final_visit); + std::vector<std::unique_ptr<syncer::EntityData>> + QueryRedirectChainAndMakeEntityData(const VisitRow& final_visit); GURL GetURLForVisit(VisitID visit_id);
diff --git a/components/history/core/browser/sync/history_sync_bridge_unittest.cc b/components/history/core/browser/sync/history_sync_bridge_unittest.cc index 28f65f6..b99af14 100644 --- a/components/history/core/browser/sync/history_sync_bridge_unittest.cc +++ b/components/history/core/browser/sync/history_sync_bridge_unittest.cc
@@ -20,6 +20,7 @@ #include "components/sync/model/model_type_change_processor.h" #include "components/sync/protocol/entity_metadata.pb.h" #include "components/sync/protocol/history_specifics.pb.h" +#include "components/sync/protocol/proto_value_conversions.h" #include "components/sync/test/forwarding_model_type_change_processor.h" #include "sql/database.h" #include "sql/meta_table.h" @@ -250,6 +251,8 @@ FakeModelTypeChangeProcessor* processor() { return &fake_processor_; } HistorySyncBridge* bridge() { return bridge_.get(); } + void AdvanceClock() { task_environment_.FastForwardBy(base::Seconds(1)); } + std::pair<URLRow, VisitRow> AddVisitToBackendAndAdvanceClock( const GURL& url, ui::PageTransition transition, @@ -257,7 +260,7 @@ // After grabbing the visit time, advance the mock time so that the next // visit will get a unique time. base::Time visit_time = base::Time::Now(); - task_environment_.FastForwardBy(base::Seconds(1)); + AdvanceClock(); URLRow url_row; const URLRow* existing_url_row = backend()->FindURLRow(url); @@ -626,21 +629,23 @@ visit_row1.transition = ui::PageTransitionFromInt( ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CHAIN_START | ui::PAGE_TRANSITION_CLIENT_REDIRECT); - VisitID visit_id1 = backend()->AddVisit(visit_row1); + visit_row1.visit_id = backend()->AddVisit(visit_row1); + VisitRow visit_row2; - visit_row2.referring_visit = visit_id1; + visit_row2.referring_visit = visit_row1.visit_id; visit_row2.url_id = url_id2; visit_row2.visit_time = visit_time; visit_row2.transition = ui::PageTransitionFromInt( ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_SERVER_REDIRECT); - VisitID visit_id2 = backend()->AddVisit(visit_row2); + visit_row2.visit_id = backend()->AddVisit(visit_row2); + VisitRow visit_row3; - visit_row3.referring_visit = visit_id2; + visit_row3.referring_visit = visit_row2.visit_id; visit_row3.url_id = url_id3; visit_row3.visit_time = visit_time; visit_row3.transition = ui::PageTransitionFromInt( ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CHAIN_END); - backend()->AddVisit(visit_row3); + visit_row3.visit_id = backend()->AddVisit(visit_row3); // Notify the bridge about all of the visits. bridge()->OnURLVisited( @@ -650,7 +655,7 @@ bridge()->OnURLVisited( /*history_backend=*/nullptr, url_row3, visit_row3); - // The whole chain should have resulting in a single entity being Put(). + // The whole chain should have resulted in a single entity being Put(). const std::string storage_key = HistorySyncMetadataDatabase::StorageKeyFromVisitTime(visit_time); EXPECT_EQ(processor()->GetEntities().size(), 1u); @@ -674,6 +679,123 @@ ui::PAGE_TRANSITION_LINK)); } +TEST_F(HistorySyncBridgeTest, SplitsRedirectChainWithDifferentTimestamps) { + // Start syncing (with no data yet). + ApplyInitialSyncChanges({}); + + // Create a redirect chain with 2 entries. + URLRow url_row1(GURL("https://url1.com")); + URLID url_id1 = backend()->AddURL(url_row1); + url_row1.set_id(url_id1); + URLRow url_row2(GURL("https://url2.com")); + URLID url_id2 = backend()->AddURL(url_row2); + url_row2.set_id(url_id2); + + const base::Time visit_time_chain1 = base::Time::Now(); + + VisitRow visit_row1; + visit_row1.url_id = url_id1; + visit_row1.visit_time = visit_time_chain1; + visit_row1.transition = ui::PageTransitionFromInt( + ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CHAIN_START | + ui::PAGE_TRANSITION_SERVER_REDIRECT); + visit_row1.visit_id = backend()->AddVisit(visit_row1); + + VisitRow visit_row2; + visit_row2.referring_visit = visit_row1.visit_id; + visit_row2.url_id = url_id2; + visit_row2.visit_time = visit_time_chain1; + visit_row2.transition = ui::PageTransitionFromInt( + ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CHAIN_END); + visit_row2.visit_id = backend()->AddVisit(visit_row2); + + // Notify the bridge about the visits. + bridge()->OnURLVisited( + /*history_backend=*/nullptr, url_row1, visit_row1); + bridge()->OnURLVisited( + /*history_backend=*/nullptr, url_row2, visit_row2); + + // The chain should have resulted in an entity being Put(). + const std::string storage_key1 = + HistorySyncMetadataDatabase::StorageKeyFromVisitTime(visit_time_chain1); + ASSERT_EQ(processor()->GetEntities().size(), 1u); + ASSERT_EQ(processor()->GetEntities().count(storage_key1), 1u); + sync_pb::HistorySpecifics history1 = + processor()->GetEntities().at(storage_key1).specifics.history(); + ASSERT_EQ(history1.redirect_entries_size(), 2); + ASSERT_FALSE(history1.redirect_chain_start_incomplete()); + ASSERT_FALSE(history1.redirect_chain_end_incomplete()); + + // Now, the existing chain gets extended. + // First, the PAGE_TRANSITION_CHAIN_END bit gets removed from the existing + // visit. + visit_row2.transition = ui::PAGE_TRANSITION_LINK; + ASSERT_TRUE(backend()->UpdateVisit(visit_row2)); + // The bridge gets notified about the updated visit, but this should have no + // effect since it's not a chain end anymore. + bridge()->OnVisitUpdated(visit_row2); + + // Two more visits get appended to the chain. + URLRow url_row3(GURL("https://url3.com")); + URLID url_id3 = backend()->AddURL(url_row3); + url_row3.set_id(url_id3); + URLRow url_row4(GURL("https://url4.com")); + URLID url_id4 = backend()->AddURL(url_row4); + url_row4.set_id(url_id4); + + AdvanceClock(); + const base::Time visit_time_chain2 = base::Time::Now(); + + VisitRow visit_row3; + // Link to the previous chain! + visit_row3.referring_visit = visit_row2.visit_id; + visit_row3.url_id = url_id3; + visit_row3.visit_time = visit_time_chain2; + // Note: No PAGE_TRANSITION_CHAIN_START. + visit_row3.transition = ui::PageTransitionFromInt( + ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT); + visit_row3.visit_id = backend()->AddVisit(visit_row3); + + VisitRow visit_row4; + visit_row4.referring_visit = visit_row3.visit_id; + visit_row4.url_id = url_id4; + visit_row4.visit_time = visit_time_chain2; + visit_row4.transition = ui::PageTransitionFromInt( + ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CHAIN_END); + visit_row4.visit_id = backend()->AddVisit(visit_row4); + + // Notify the bridge about the new visits. + bridge()->OnURLVisited( + /*history_backend=*/nullptr, url_row3, visit_row3); + bridge()->OnURLVisited( + /*history_backend=*/nullptr, url_row4, visit_row4); + + // Now, there should be two entities: The one from the initial chain, and a + // separate one for the later addition. + const std::string storage_key2 = + HistorySyncMetadataDatabase::StorageKeyFromVisitTime(visit_time_chain2); + ASSERT_EQ(processor()->GetEntities().size(), 2u); + ASSERT_EQ(processor()->GetEntities().count(storage_key1), 1u); + ASSERT_EQ(processor()->GetEntities().count(storage_key2), 1u); + // The initial chain should not have the chain_end marker anymore, but be + // otherwise unmodified. + sync_pb::HistorySpecifics history1_expected = history1; + history1_expected.set_redirect_chain_end_incomplete(true); + sync_pb::HistorySpecifics history1_updated = + processor()->GetEntities().at(storage_key1).specifics.history(); + EXPECT_EQ(*syncer::HistorySpecificsToValue(history1_expected), + *syncer::HistorySpecificsToValue(history1_updated)); + // The second chain should contain only the last two entries. + sync_pb::HistorySpecifics history2 = + processor()->GetEntities().at(storage_key2).specifics.history(); + ASSERT_EQ(history2.redirect_entries_size(), 2); + EXPECT_EQ(history2.redirect_entries(0).url(), url_row3.url()); + EXPECT_EQ(history2.redirect_entries(1).url(), url_row4.url()); + EXPECT_EQ(history2.originator_referring_visit_id(), visit_row2.visit_id); + EXPECT_TRUE(history2.redirect_chain_start_incomplete()); + EXPECT_FALSE(history2.redirect_chain_end_incomplete()); +} + TEST_F(HistorySyncBridgeTest, UntracksEntitiesAfterCommit) { // Start syncing (with no data yet). ApplyInitialSyncChanges({});
diff --git a/components/metrics/demographics/demographic_metrics_provider_unittest.cc b/components/metrics/demographics/demographic_metrics_provider_unittest.cc index fb445e0..5bb8dfd 100644 --- a/components/metrics/demographics/demographic_metrics_provider_unittest.cc +++ b/components/metrics/demographics/demographic_metrics_provider_unittest.cc
@@ -75,12 +75,7 @@ case SYNC_FEATURE_ENABLED_BUT_PAUSED: sync_service_ = std::make_unique<syncer::TestSyncService>(); // Mimic the user signing out from content are (sync paused). - sync_service_->SetAuthError( - GoogleServiceAuthError::FromInvalidGaiaCredentialsReason( - GoogleServiceAuthError::InvalidGaiaCredentialsReason:: - CREDENTIALS_REJECTED_BY_CLIENT)); - sync_service_->SetTransportState( - syncer::SyncService::TransportState::PAUSED); + sync_service_->SetPersistentAuthErrorWithWebSignout(); CHECK(sync_service_->GetUserSettings()->IsSyncRequested()); CHECK(sync_service_->GetDisableReasons().Empty());
diff --git a/components/ownership/mock_owner_key_util.cc b/components/ownership/mock_owner_key_util.cc index 851d772c..1ac2f95 100644 --- a/components/ownership/mock_owner_key_util.cc +++ b/components/ownership/mock_owner_key_util.cc
@@ -14,13 +14,35 @@ namespace ownership { +static const uint16_t kKeySizeInBits = 2048; + MockOwnerKeyUtil::MockOwnerKeyUtil() = default; MockOwnerKeyUtil::~MockOwnerKeyUtil() = default; -bool MockOwnerKeyUtil::ImportPublicKey(std::vector<uint8_t>* output) { - *output = public_key_; - return !public_key_.empty(); +scoped_refptr<PublicKey> MockOwnerKeyUtil::ImportPublicKey() { + return public_key_.empty() ? nullptr + : base::MakeRefCounted<ownership::PublicKey>( + /*is_persisted=*/true, /*data=*/public_key_); +} + +crypto::ScopedSECKEYPrivateKey MockOwnerKeyUtil::GenerateKeyPair( + PK11SlotInfo* slot) { + if (generate_key_fail_times_ > 0) { + --generate_key_fail_times_; + return nullptr; + } + + PK11RSAGenParams param; + param.keySizeInBits = kKeySizeInBits; + param.pe = 65537L; + SECKEYPublicKey* public_key_ptr = nullptr; + + crypto::ScopedSECKEYPrivateKey key(PK11_GenerateKeyPair( + slot, CKM_RSA_PKCS_KEY_PAIR_GEN, ¶m, &public_key_ptr, + PR_TRUE /* permanent */, PR_TRUE /* sensitive */, nullptr)); + crypto::ScopedSECKEYPublicKey public_key(public_key_ptr); + return key; } crypto::ScopedSECKEYPrivateKey MockOwnerKeyUtil::FindPrivateKeyInSlot( @@ -66,4 +88,8 @@ CHECK(private_key_); } +void MockOwnerKeyUtil::SimulateGenerateKeyFailure(int fail_times) { + generate_key_fail_times_ = fail_times; +} + } // namespace ownership
diff --git a/components/ownership/mock_owner_key_util.h b/components/ownership/mock_owner_key_util.h index 360244cb..fb96799 100644 --- a/components/ownership/mock_owner_key_util.h +++ b/components/ownership/mock_owner_key_util.h
@@ -30,7 +30,8 @@ MockOwnerKeyUtil& operator=(const MockOwnerKeyUtil&) = delete; // OwnerKeyUtil implementation: - bool ImportPublicKey(std::vector<uint8_t>* output) override; + scoped_refptr<PublicKey> ImportPublicKey() override; + crypto::ScopedSECKEYPrivateKey GenerateKeyPair(PK11SlotInfo* slot) override; crypto::ScopedSECKEYPrivateKey FindPrivateKeyInSlot( const std::vector<uint8_t>& key, PK11SlotInfo* slot) override; @@ -52,9 +53,14 @@ void ImportPrivateKeyAndSetPublicKey( std::unique_ptr<crypto::RSAPrivateKey> key); + // Makes next `fail_times` number of calls to OwnerKeyUtil::GenerateKeyPair + // fail. + void SimulateGenerateKeyFailure(int fail_times); + private: ~MockOwnerKeyUtil() override; + int generate_key_fail_times_ = 0; std::vector<uint8_t> public_key_; crypto::ScopedSECKEYPrivateKey private_key_; };
diff --git a/components/ownership/owner_key_util.cc b/components/ownership/owner_key_util.cc index 5ce3513..177e233 100644 --- a/components/ownership/owner_key_util.cc +++ b/components/ownership/owner_key_util.cc
@@ -11,10 +11,13 @@ /////////////////////////////////////////////////////////////////////////// // PublicKey -PublicKey::PublicKey() { -} +PublicKey::PublicKey(bool is_persisted, std::vector<uint8_t> data) + : is_persisted_(is_persisted), data_(std::move(data)) {} -PublicKey::~PublicKey() { +PublicKey::~PublicKey() = default; + +scoped_refptr<PublicKey> PublicKey::clone() { + return base::MakeRefCounted<ownership::PublicKey>(is_persisted_, data_); } /////////////////////////////////////////////////////////////////////////// @@ -23,7 +26,6 @@ PrivateKey::PrivateKey(crypto::ScopedSECKEYPrivateKey key) : key_(std::move(key)) {} -PrivateKey::~PrivateKey() { -} +PrivateKey::~PrivateKey() = default; } // namespace ownership
diff --git a/components/ownership/owner_key_util.h b/components/ownership/owner_key_util.h index b135480..2d386686 100644 --- a/components/ownership/owner_key_util.h +++ b/components/ownership/owner_key_util.h
@@ -23,14 +23,27 @@ class OWNERSHIP_EXPORT PublicKey : public base::RefCountedThreadSafe<PublicKey> { public: - PublicKey(); + // `is_persisted` should be true for keys that are loaded from disk and false + // for newly generated ones. `data` is the binary representation of the key + // itself. + PublicKey(bool is_persisted, std::vector<uint8_t> data); PublicKey(const PublicKey&) = delete; PublicKey& operator=(const PublicKey&) = delete; + scoped_refptr<PublicKey> clone(); + std::vector<uint8_t>& data() { return data_; } - bool is_loaded() const { return !data_.empty(); } + bool is_empty() const { return data_.empty(); } + + // Returns true if the key was read from the filesystem or it was already + // saved on disk. Returns false for recently generated keys that still need + // to be sent to session_manager for saving on disk. + bool is_persisted() { return is_persisted_; } + + // Marks that the key was saved on disk. + void mark_persisted() { is_persisted_ = true; } std::string as_string() { return std::string(reinterpret_cast<const char*>(data_.data()), @@ -42,6 +55,7 @@ virtual ~PublicKey(); + bool is_persisted_ = false; std::vector<uint8_t> data_; }; @@ -70,9 +84,13 @@ class OWNERSHIP_EXPORT OwnerKeyUtil : public base::RefCountedThreadSafe<OwnerKeyUtil> { public: - // Attempts to read the public key from the file system. Upon success, - // returns true and populates |output|. False on failure. - virtual bool ImportPublicKey(std::vector<uint8_t>* output) = 0; + // Attempts to read the public key from the file system. Returns nullptr on + // failure and a populated key on success. + virtual scoped_refptr<PublicKey> ImportPublicKey() = 0; + + // Generates a new key pair in the `slot`. + virtual crypto::ScopedSECKEYPrivateKey GenerateKeyPair( + PK11SlotInfo* slot) = 0; // Looks for the private key associated with |key| in the |slot| // and returns it if it can be found. Returns NULL otherwise.
diff --git a/components/ownership/owner_key_util_impl.cc b/components/ownership/owner_key_util_impl.cc index 875c761..bb5c1dd41 100644 --- a/components/ownership/owner_key_util_impl.cc +++ b/components/ownership/owner_key_util_impl.cc
@@ -16,14 +16,14 @@ namespace ownership { +static const uint16_t kKeySizeInBits = 2048; + OwnerKeyUtilImpl::OwnerKeyUtilImpl(const base::FilePath& public_key_file) - : public_key_file_(public_key_file) { -} + : public_key_file_(public_key_file) {} -OwnerKeyUtilImpl::~OwnerKeyUtilImpl() { -} +OwnerKeyUtilImpl::~OwnerKeyUtilImpl() = default; -bool OwnerKeyUtilImpl::ImportPublicKey(std::vector<uint8_t>* output) { +scoped_refptr<PublicKey> OwnerKeyUtilImpl::ImportPublicKey() { // Get the file size (must fit in a 32 bit int for NSS). int64_t file_size; if (!base::GetFileSize(public_key_file_, &file_size)) { @@ -31,27 +31,49 @@ LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS()) << "Could not get size of " << public_key_file_.value(); #endif // BUILDFLAG(IS_CHROMEOS_ASH) - return false; + return nullptr; } if (file_size > static_cast<int64_t>(std::numeric_limits<int>::max())) { LOG(ERROR) << public_key_file_.value() << "is " << file_size << "bytes!!! Too big!"; - return false; + return nullptr; } int32_t safe_file_size = static_cast<int32_t>(file_size); - output->resize(safe_file_size); + std::vector<uint8_t> key_data; + key_data.resize(safe_file_size); if (safe_file_size == 0) { LOG(WARNING) << "Public key file is empty. This seems wrong."; - return false; + return nullptr; } // Get the key data off of disk int data_read = - base::ReadFile(public_key_file_, reinterpret_cast<char*>(output->data()), + base::ReadFile(public_key_file_, reinterpret_cast<char*>(key_data.data()), safe_file_size); - return data_read == safe_file_size; + if (data_read != safe_file_size) { + return nullptr; + } + + return base::MakeRefCounted<ownership::PublicKey>( + /*is_persisted=*/true, std::move(key_data)); +} + +crypto::ScopedSECKEYPrivateKey OwnerKeyUtilImpl::GenerateKeyPair( + PK11SlotInfo* slot) { + DCHECK(slot); + + PK11RSAGenParams param; + param.keySizeInBits = kKeySizeInBits; + param.pe = 65537L; + SECKEYPublicKey* public_key_ptr = nullptr; + + crypto::ScopedSECKEYPrivateKey key(PK11_GenerateKeyPair( + slot, CKM_RSA_PKCS_KEY_PAIR_GEN, ¶m, &public_key_ptr, + PR_TRUE /* permanent */, PR_TRUE /* sensitive */, nullptr)); + crypto::ScopedSECKEYPublicKey public_key(public_key_ptr); + return key; } crypto::ScopedSECKEYPrivateKey OwnerKeyUtilImpl::FindPrivateKeyInSlot(
diff --git a/components/ownership/owner_key_util_impl.h b/components/ownership/owner_key_util_impl.h index 7b950f7..b4f6334 100644 --- a/components/ownership/owner_key_util_impl.h +++ b/components/ownership/owner_key_util_impl.h
@@ -24,7 +24,8 @@ OwnerKeyUtilImpl& operator=(const OwnerKeyUtilImpl&) = delete; // OwnerKeyUtil implementation: - bool ImportPublicKey(std::vector<uint8_t>* output) override; + scoped_refptr<PublicKey> ImportPublicKey() override; + crypto::ScopedSECKEYPrivateKey GenerateKeyPair(PK11SlotInfo* slot) override; crypto::ScopedSECKEYPrivateKey FindPrivateKeyInSlot( const std::vector<uint8_t>& key, PK11SlotInfo* slot) override;
diff --git a/components/ownership/owner_key_util_impl_unittest.cc b/components/ownership/owner_key_util_impl_unittest.cc index 182fa47..ba72900 100644 --- a/components/ownership/owner_key_util_impl_unittest.cc +++ b/components/ownership/owner_key_util_impl_unittest.cc
@@ -76,24 +76,22 @@ public_key.size())); EXPECT_TRUE(util_->IsPublicKeyPresent()); - std::vector<uint8_t> from_disk; - EXPECT_TRUE(util_->ImportPublicKey(&from_disk)); + scoped_refptr<PublicKey> from_disk = util_->ImportPublicKey(); + EXPECT_TRUE(from_disk); - EXPECT_EQ(public_key, from_disk); + EXPECT_EQ(public_key, from_disk->data()); + EXPECT_EQ(true, from_disk->is_persisted()); } TEST_F(OwnerKeyUtilImplTest, ImportPublicKeyFailed) { // First test the case where the file is missing which should fail. EXPECT_FALSE(util_->IsPublicKeyPresent()); - std::vector<uint8_t> from_disk; - EXPECT_FALSE(util_->ImportPublicKey(&from_disk)); + EXPECT_FALSE(util_->ImportPublicKey()); - // Next try empty file. This should fail and the array should be empty. - from_disk.resize(10); + // Next try empty file. This should fail as well. ASSERT_EQ(0, base::WriteFile(key_file_, "", 0)); EXPECT_TRUE(util_->IsPublicKeyPresent()); - EXPECT_FALSE(util_->ImportPublicKey(&from_disk)); - EXPECT_FALSE(from_disk.size()); + EXPECT_FALSE(util_->ImportPublicKey()); } } // namespace ownership
diff --git a/components/ownership/owner_settings_service.cc b/components/ownership/owner_settings_service.cc index b2c4dc97..ddbd7f1 100644 --- a/components/ownership/owner_settings_service.cc +++ b/components/ownership/owner_settings_service.cc
@@ -168,7 +168,9 @@ // loading (even if unsuccessfully). Absence of the actual data inside can // indicate that the keys are unavailable. public_key_ = - public_key ? public_key : base::MakeRefCounted<ownership::PublicKey>(); + public_key ? public_key + : base::MakeRefCounted<ownership::PublicKey>( + /*is_persisted=*/false, /*data=*/std::vector<uint8_t>()); private_key_ = private_key ? private_key : base::MakeRefCounted<ownership::PrivateKey>(nullptr);
diff --git a/components/password_manager/content/browser/content_password_manager_driver_factory_unittest.cc b/components/password_manager/content/browser/content_password_manager_driver_factory_unittest.cc index 05eb2c1d..71cf094 100644 --- a/components/password_manager/content/browser/content_password_manager_driver_factory_unittest.cc +++ b/components/password_manager/content/browser/content_password_manager_driver_factory_unittest.cc
@@ -29,7 +29,7 @@ public: ContentPasswordManagerDriverFactoryFencedFramesTest() { std::vector<base::test::ScopedFeatureList::FeatureAndParams> enabled; - std::vector<base::Feature> disabled; + std::vector<base::test::FeatureRef> disabled; enabled.push_back( {blink::features::kFencedFrames, {{"implementation_type", "mparch"}}}); if (password_manager_enabled_in_fencedframe()) {
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc index 1339559..9dc0438 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -139,7 +139,7 @@ // server-predicted clear-text fields is enabled. bool IsPasswordGenerationForClearTextFieldsEnabled() { return base::FeatureList::IsEnabled( - password_manager::features::KEnablePasswordGenerationForClearTextFields); + password_manager::features::kEnablePasswordGenerationForClearTextFields); } // Returns true iff |field_type| is one of password types.
diff --git a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc index 9b8ab8f9..0fe0bce 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -1145,7 +1145,7 @@ TEST(FormParserTest, ServerPredictionsForClearTextPasswordFields) { base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature( - password_manager::features::KEnablePasswordGenerationForClearTextFields); + password_manager::features::kEnablePasswordGenerationForClearTextFields); CheckTestData({ { .description_for_logging = "Server prediction for account change "
diff --git a/components/password_manager/core/browser/leak_detection_delegate_unittest.cc b/components/password_manager/core/browser/leak_detection_delegate_unittest.cc index b380068..55319a3a 100644 --- a/components/password_manager/core/browser/leak_detection_delegate_unittest.cc +++ b/components/password_manager/core/browser/leak_detection_delegate_unittest.cc
@@ -88,7 +88,7 @@ class LeakDetectionDelegateTest : public testing::Test { public: explicit LeakDetectionDelegateTest( - const std::vector<base::Feature>& enabled_features) { + const std::vector<base::test::FeatureRef>& enabled_features) { features_.InitWithFeatures(enabled_features, {}); auto mock_factory = @@ -105,7 +105,7 @@ } LeakDetectionDelegateTest() - : LeakDetectionDelegateTest(std::vector<base::Feature>()) {} + : LeakDetectionDelegateTest(std::vector<base::test::FeatureRef>()) {} ~LeakDetectionDelegateTest() override = default;
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc index fba084e1..5746abf 100644 --- a/components/password_manager/core/browser/password_manager.cc +++ b/components/password_manager/core/browser/password_manager.cc
@@ -147,7 +147,7 @@ bool HasNewPasswordVote(const FormPredictions& form) { if (!base::FeatureList::IsEnabled( password_manager::features:: - KEnablePasswordGenerationForClearTextFields)) + kEnablePasswordGenerationForClearTextFields)) return false; for (const auto& field : form.fields) { if (field.type == ACCOUNT_CREATION_PASSWORD || field.type == NEW_PASSWORD)
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc index 0909268..f6c2495 100644 --- a/components/password_manager/core/browser/password_manager_unittest.cc +++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -3513,7 +3513,7 @@ MarkServerPredictedClearTextPasswordFieldEligibleForGeneration) { base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature( - password_manager::features::KEnablePasswordGenerationForClearTextFields); + password_manager::features::kEnablePasswordGenerationForClearTextFields); PasswordFormManager::set_wait_for_server_predictions_for_filling(true); EXPECT_CALL(client_, IsSavingAndFillingEnabled(_))
diff --git a/components/password_manager/core/browser/password_store_backend_migration_decorator_unittest.cc b/components/password_manager/core/browser/password_store_backend_migration_decorator_unittest.cc index f97ca9e..42646191 100644 --- a/components/password_manager/core/browser/password_store_backend_migration_decorator_unittest.cc +++ b/components/password_manager/core/browser/password_store_backend_migration_decorator_unittest.cc
@@ -494,8 +494,7 @@ // Set password sync to be active and have no auth errors. InitSyncService(/*is_password_sync_enabled=*/true); sync_service().SetActiveDataTypes(syncer::ModelTypeSet(syncer::PASSWORDS)); - sync_service().SetAuthError( - GoogleServiceAuthError(GoogleServiceAuthError::NONE)); + sync_service().ClearAuthError(); // Migration attemot will start and will trigger logins retrieval from the // built-in backend. @@ -530,8 +529,7 @@ // Set password sync to be enabled in settings, but inactive. InitSyncService(/*is_password_sync_enabled=*/true); sync_service().SetActiveDataTypes({}); - sync_service().SetAuthError( - GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_ERROR)); + sync_service().SetPersistentAuthErrorOtherThanWebSignout(); // Reenrolling migration attempt should not happen, logins should not be // retrieved. @@ -572,8 +570,7 @@ // Set password sync to be active and have no auth errors. InitSyncService(/*is_password_sync_enabled=*/true); sync_service().SetActiveDataTypes(syncer::ModelTypeSet(syncer::PASSWORDS)); - sync_service().SetAuthError( - GoogleServiceAuthError(GoogleServiceAuthError::NONE)); + sync_service().ClearAuthError(); // Reenrolling migration attempt should not happen, logins should not be // retrieved. @@ -614,8 +611,7 @@ // Set password sync to be active and have no auth errors. InitSyncService(/*is_password_sync_enabled=*/true); sync_service().SetActiveDataTypes(syncer::ModelTypeSet(syncer::PASSWORDS)); - sync_service().SetAuthError( - GoogleServiceAuthError(GoogleServiceAuthError::NONE)); + sync_service().ClearAuthError(); // Reenrolling migration attempt should not happen, logins should not be // retrieved.
diff --git a/components/password_manager/core/browser/password_sync_util_unittest.cc b/components/password_manager/core/browser/password_sync_util_unittest.cc index 0086f49..609bdb1 100644 --- a/components/password_manager/core/browser/password_sync_util_unittest.cc +++ b/components/password_manager/core/browser/password_sync_util_unittest.cc
@@ -139,6 +139,7 @@ sync_service.SetTransportState(syncer::SyncService::TransportState::DISABLED); sync_service.SetHasSyncConsent(false); EXPECT_FALSE(IsPasswordSyncEnabled(&sync_service)); + EXPECT_FALSE(IsPasswordSyncActive(&sync_service)); EXPECT_EQ(absl::nullopt, GetSyncingAccount(&sync_service)); } @@ -150,6 +151,7 @@ ->SetSelectedTypes(/*sync_everything=*/false, {syncer::UserSelectableType::kHistory}); EXPECT_FALSE(IsPasswordSyncEnabled(&sync_service)); + EXPECT_FALSE(IsPasswordSyncActive(&sync_service)); EXPECT_EQ(absl::nullopt, GetSyncingAccount(&sync_service)); } @@ -161,9 +163,35 @@ active_info.email = "test@email.com"; sync_service.SetAccountInfo(active_info); EXPECT_TRUE(IsPasswordSyncEnabled(&sync_service)); + EXPECT_TRUE(IsPasswordSyncActive(&sync_service)); EXPECT_TRUE(GetSyncingAccount(&sync_service).has_value()); EXPECT_EQ(active_info.email, GetSyncingAccount(&sync_service).value()); } +TEST_F(PasswordSyncUtilTest, SyncPausedDueToWebSignout) { + syncer::TestSyncService sync_service; + sync_service.SetHasSyncConsent(true); + sync_service.SetPersistentAuthErrorWithWebSignout(); + ASSERT_EQ(sync_service.GetTransportState(), + syncer::SyncService::TransportState::PAUSED); + EXPECT_TRUE(IsPasswordSyncEnabled(&sync_service)); + EXPECT_FALSE(IsPasswordSyncActive(&sync_service)); + EXPECT_NE(absl::nullopt, GetSyncingAccount(&sync_service)); +} + +TEST_F(PasswordSyncUtilTest, SyncWithPersistentAuthErrorOtherThanWebSignout) { + syncer::TestSyncService sync_service; + sync_service.SetHasSyncConsent(true); + sync_service.SetPersistentAuthErrorOtherThanWebSignout(); + ASSERT_NE(sync_service.GetTransportState(), + syncer::SyncService::TransportState::PAUSED); + EXPECT_TRUE(IsPasswordSyncEnabled(&sync_service)); + // As opposed to web signout, other persistent auth errors don't cause Sync to + // become inactive. + // TODO(crbug.com/1156584): Unify the behavior for all persistent auth errors. + EXPECT_TRUE(IsPasswordSyncActive(&sync_service)); + EXPECT_NE(absl::nullopt, GetSyncingAccount(&sync_service)); +} + } // namespace sync_util } // namespace password_manager
diff --git a/components/password_manager/core/browser/saved_passwords_capabilities_fetcher.cc b/components/password_manager/core/browser/saved_passwords_capabilities_fetcher.cc index 9186562c..957aff91 100644 --- a/components/password_manager/core/browser/saved_passwords_capabilities_fetcher.cc +++ b/components/password_manager/core/browser/saved_passwords_capabilities_fetcher.cc
@@ -8,15 +8,14 @@ #include <iterator> #include <map> #include <memory> +#include <utility> #include <vector> #include "base/containers/cxx20_erase.h" -#include "base/logging.h" #include "base/metrics/histogram_functions.h" #include "base/scoped_observation.h" #include "base/stl_util.h" #include "base/values.h" -#include "components/password_manager/core/browser/password_store_interface.h" #include "components/password_manager/core/browser/ui/saved_passwords_presenter.h" #include "components/password_manager/core/common/password_manager_features.h" #include "url/gurl.h" @@ -25,10 +24,11 @@ SavedPasswordsCapabilitiesFetcher::SavedPasswordsCapabilitiesFetcher( std::unique_ptr<CapabilitiesService> fetcher, - scoped_refptr<password_manager::PasswordStoreInterface> password_store) - : fetcher_(std::move(fetcher)), saved_passwords_presenter_(password_store) { - observed_saved_password_presenter_.Observe(&saved_passwords_presenter_); - saved_passwords_presenter_.Init(); + std::unique_ptr<SavedPasswordsPresenter> saved_passwords_presenter) + : fetcher_(std::move(fetcher)), + saved_passwords_presenter_(std::move(saved_passwords_presenter)) { + observed_saved_password_presenter_.Observe(saved_passwords_presenter_.get()); + saved_passwords_presenter_->Init(); } SavedPasswordsCapabilitiesFetcher::~SavedPasswordsCapabilitiesFetcher() = @@ -111,7 +111,7 @@ void SavedPasswordsCapabilitiesFetcher::OnEdited(const PasswordForm& form) { // OnEdited() only gets called if a the password was edited via - // |saved_passwords_presenter_|, so even if the password gets edited + // `saved_passwords_presenter_`, so even if the password gets edited // elsewhere, we wouldn't end up here. NOTREACHED(); } @@ -243,7 +243,7 @@ std::vector<url::Origin> SavedPasswordsCapabilitiesFetcher::GetOriginsOfStoredPasswords() const { std::vector<url::Origin> origins; - for (const auto& form : saved_passwords_presenter_.GetSavedPasswords()) { + for (const auto& form : saved_passwords_presenter_->GetSavedPasswords()) { if (form.url.SchemeIs(url::kHttpScheme)) { // Http schemes are not supported. continue;
diff --git a/components/password_manager/core/browser/saved_passwords_capabilities_fetcher.h b/components/password_manager/core/browser/saved_passwords_capabilities_fetcher.h index 6c02dedb1..5bd4b3c5 100644 --- a/components/password_manager/core/browser/saved_passwords_capabilities_fetcher.h +++ b/components/password_manager/core/browser/saved_passwords_capabilities_fetcher.h
@@ -32,7 +32,8 @@ SavedPasswordsCapabilitiesFetcher( std::unique_ptr<CapabilitiesService> fetcher, - scoped_refptr<password_manager::PasswordStoreInterface> password_store); + std::unique_ptr<password_manager::SavedPasswordsPresenter> + saved_passwords_presenter); SavedPasswordsCapabilitiesFetcher(const SavedPasswordsCapabilitiesFetcher&) = delete; @@ -90,7 +91,8 @@ std::unique_ptr<CapabilitiesService> fetcher_; // Manages the list of saved passwords, including updates. - password_manager::SavedPasswordsPresenter saved_passwords_presenter_; + std::unique_ptr<password_manager::SavedPasswordsPresenter> + saved_passwords_presenter_; // Stores the callbacks that are waiting for the refresh capabilities request // to finish.
diff --git a/components/password_manager/core/browser/saved_passwords_capabilities_fetcher_unittest.cc b/components/password_manager/core/browser/saved_passwords_capabilities_fetcher_unittest.cc index 74f8a1c..2dd4d57 100644 --- a/components/password_manager/core/browser/saved_passwords_capabilities_fetcher_unittest.cc +++ b/components/password_manager/core/browser/saved_passwords_capabilities_fetcher_unittest.cc
@@ -16,6 +16,7 @@ #include "components/password_manager/core/browser/capabilities_service.h" #include "components/password_manager/core/browser/password_form.h" #include "components/password_manager/core/browser/test_password_store.h" +#include "components/password_manager/core/browser/ui/saved_passwords_presenter.h" #include "components/password_manager/core/common/password_manager_features.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -111,12 +112,14 @@ public: SavedPasswordsCapabilitiesFetcherTest() { store_->Init(/*prefs=*/nullptr, /*affiliated_match_helper=*/nullptr); + FillPasswordStore(); auto capabilities_service = std::make_unique<NiceMock<MockCapabilitiesService>>(); mock_capabilities_service_ = capabilities_service.get(); fetcher_ = std::make_unique<SavedPasswordsCapabilitiesFetcher>( - std::move(capabilities_service), store_); - FillPasswordStore(); + std::move(capabilities_service), + std::make_unique<SavedPasswordsPresenter>(store_)); + RunUntilIdle(); } ~SavedPasswordsCapabilitiesFetcherTest() override {
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc index 8a80ee4..23ef8e6 100644 --- a/components/password_manager/core/common/password_manager_features.cc +++ b/components/password_manager/core/common/password_manager_features.cc
@@ -69,9 +69,9 @@ #endif ); -const base::Feature KEnablePasswordGenerationForClearTextFields = { - "EnablePasswordGenerationForClearTextFields", - base::FEATURE_ENABLED_BY_DEFAULT}; +BASE_FEATURE(kEnablePasswordGenerationForClearTextFields, + "EnablePasswordGenerationForClearTextFields", + base::FEATURE_ENABLED_BY_DEFAULT); // By default, Password Manager is disabled in fenced frames for now. // TODO(crbug.com/1294378): Remove once launched.
diff --git a/components/password_manager/core/common/password_manager_features.h b/components/password_manager/core/common/password_manager_features.h index 245da59..932926b 100644 --- a/components/password_manager/core/common/password_manager_features.h +++ b/components/password_manager/core/common/password_manager_features.h
@@ -34,7 +34,7 @@ BASE_DECLARE_FEATURE(kEnableFaviconForPasswords); BASE_DECLARE_FEATURE(kEnableOverwritingPlaceholderUsernames); BASE_DECLARE_FEATURE(kEnablePasswordsAccountStorage); -extern const base::Feature KEnablePasswordGenerationForClearTextFields; +BASE_DECLARE_FEATURE(kEnablePasswordGenerationForClearTextFields); BASE_DECLARE_FEATURE(kEnablePasswordManagerWithinFencedFrame); BASE_DECLARE_FEATURE(kFillingAcrossAffiliatedWebsites); BASE_DECLARE_FEATURE(kFillOnAccountSelect);
diff --git a/components/safe_browsing/content/browser/password_protection/password_protection_service.cc b/components/safe_browsing/content/browser/password_protection/password_protection_service.cc index 1aa3632..a38f90c 100644 --- a/components/safe_browsing/content/browser/password_protection/password_protection_service.cc +++ b/components/safe_browsing/content/browser/password_protection/password_protection_service.cc
@@ -108,22 +108,6 @@ } } -PasswordReuseInfo PasswordProtectionService::ConstructPasswordReuseInfo( - uint64_t reused_password_hash, - const std::string& username, - PasswordType password_type, - std::vector<std::string> matching_domains) { - PasswordReuseInfo pw_reuse_info; - pw_reuse_info.matches_signin_password = - password_type == PasswordType::PRIMARY_ACCOUNT_PASSWORD; - pw_reuse_info.matching_domains = matching_domains; - pw_reuse_info.reused_password_account_type = - GetPasswordProtectionReusedPasswordAccountType(password_type, username); - pw_reuse_info.count = 1; - pw_reuse_info.reused_password_hash = reused_password_hash; - return pw_reuse_info; -} - void PasswordProtectionService::StartRequest( WebContents* web_contents, const GURL& main_frame_url,
diff --git a/components/safe_browsing/content/browser/password_protection/password_protection_service.h b/components/safe_browsing/content/browser/password_protection/password_protection_service.h index 7f6dfa6..0fce0e40 100644 --- a/components/safe_browsing/content/browser/password_protection/password_protection_service.h +++ b/components/safe_browsing/content/browser/password_protection/password_protection_service.h
@@ -128,13 +128,6 @@ MaybeCreateCommitDeferringCondition( content::NavigationHandle& navigation_handle); - // Exports the password reuse event info to a struct. - PasswordReuseInfo ConstructPasswordReuseInfo( - uint64_t reused_password_hash, - const std::string& username, - PasswordType reuse_password_type, - std::vector<std::string> matching_domains); - protected: void RemoveWarningRequestsByWebContents(content::WebContents* web_contents);
diff --git a/components/safe_browsing/core/common/proto/csd.proto b/components/safe_browsing/core/common/proto/csd.proto index e24f4f3..d332f2fe 100644 --- a/components/safe_browsing/core/common/proto/csd.proto +++ b/components/safe_browsing/core/common/proto/csd.proto
@@ -1923,6 +1923,8 @@ // pages. optional uint32 count = 4; } + // The remote host(s) contacted within 1 second of at least one (but not + // all) of the password reuse event(s) listed below. repeated RemoteHostInfo remote_hosts = 1; repeated PasswordReuseInfo reused_password_infos = 2; }
diff --git a/components/signin/core/browser/signin_header_helper_unittest.cc b/components/signin/core/browser/signin_header_helper_unittest.cc index 41f1aa4..a6cf3c43 100644 --- a/components/signin/core/browser/signin_header_helper_unittest.cc +++ b/components/signin/core/browser/signin_header_helper_unittest.cc
@@ -240,6 +240,16 @@ } #endif +// Tests that no Mirror request is returned for youtubekids.com. +// +// Regression test for b/247647476 +TEST_F(SigninHeaderHelperTest, TestNoMirrorHeaderForYoutubekids) { + account_consistency_ = AccountConsistencyMethod::kMirror; + CheckMirrorHeaderRequest(GURL("https://youtubekids.com"), "0123456789", + /*is_child_account=*/Tribool::kUnknown, ""); + CheckMirrorCookieRequest(GURL("https://youtubekids.com"), "0123456789", ""); +} + // Tests that no Mirror request is returned when the cookies aren't allowed to // be set. TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestCookieSettingBlocked) {
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index d96142c..aa8ab6f 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -189,12 +189,6 @@ "//testing/gmock", ] } - - # TODO(crbug.com/1249845): Remove this dependency once - # SyncSettingsCategorization feature flag is removed. - if (is_chromeos_ash) { - deps += [ "//ash/constants" ] - } } source_set("unit_tests") {
diff --git a/components/sync/driver/data_type_controller.h b/components/sync/driver/data_type_controller.h index e7f531b..a99a520 100644 --- a/components/sync/driver/data_type_controller.h +++ b/components/sync/driver/data_type_controller.h
@@ -16,7 +16,6 @@ #include "base/values.h" #include "components/sync/base/model_type.h" #include "components/sync/engine/shutdown_reason.h" -#include "components/sync/model/data_type_error_handler.h" namespace syncer {
diff --git a/components/sync/driver/model_load_manager.cc b/components/sync/driver/model_load_manager.cc index d901f5c..39397c8 100644 --- a/components/sync/driver/model_load_manager.cc +++ b/components/sync/driver/model_load_manager.cc
@@ -11,8 +11,8 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/logging.h" -#include "base/metrics/histogram_functions.h" #include "components/sync/base/model_type.h" +#include "components/sync/model/sync_error.h" namespace syncer {
diff --git a/components/sync/driver/model_type_controller.cc b/components/sync/driver/model_type_controller.cc index fde0c7fa..3fd1bf7 100644 --- a/components/sync/driver/model_type_controller.cc +++ b/components/sync/driver/model_type_controller.cc
@@ -9,13 +9,12 @@ #include "base/bind.h" #include "base/location.h" #include "base/logging.h" +#include "base/metrics/histogram_macros.h" #include "base/threading/sequenced_task_runner_handle.h" #include "components/signin/public/identity_manager/account_info.h" -#include "components/sync/base/data_type_histogram.h" #include "components/sync/driver/configure_context.h" #include "components/sync/engine/data_type_activation_response.h" #include "components/sync/model/data_type_activation_request.h" -#include "components/sync/model/data_type_error_handler_impl.h" #include "components/sync/model/type_entities_count.h" namespace syncer {
diff --git a/components/sync/driver/sync_service_utils_unittest.cc b/components/sync/driver/sync_service_utils_unittest.cc index 92e024c..2d37f2e 100644 --- a/components/sync/driver/sync_service_utils_unittest.cc +++ b/components/sync/driver/sync_service_utils_unittest.cc
@@ -151,27 +151,21 @@ GetUploadToGoogleState(&service, syncer::BOOKMARKS)); // On a transient error, uploading goes back to INITIALIZING. - GoogleServiceAuthError transient_error( - GoogleServiceAuthError::CONNECTION_FAILED); - ASSERT_TRUE(transient_error.IsTransientError()); - service.SetAuthError(transient_error); + service.SetTransientAuthError(); EXPECT_EQ(UploadState::INITIALIZING, GetUploadToGoogleState(&service, syncer::BOOKMARKS)); // On a persistent error, uploading is not considered active anymore (even // though Sync may still be considered active). - GoogleServiceAuthError persistent_error( - GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); - ASSERT_TRUE(persistent_error.IsPersistentError()); - service.SetAuthError(persistent_error); + service.SetPersistentAuthErrorOtherThanWebSignout(); EXPECT_EQ(UploadState::NOT_ACTIVE, GetUploadToGoogleState(&service, syncer::BOOKMARKS)); // Once the auth error is resolved (e.g. user re-authenticated), uploading is // active again. - service.SetAuthError(GoogleServiceAuthError(GoogleServiceAuthError::NONE)); + service.ClearAuthError(); service.SetTransportState(syncer::SyncService::TransportState::ACTIVE); EXPECT_EQ(UploadState::ACTIVE,
diff --git a/components/sync/driver/sync_session_durations_metrics_recorder_unittest.cc b/components/sync/driver/sync_session_durations_metrics_recorder_unittest.cc index 25e4950f4..250cf51 100644 --- a/components/sync/driver/sync_session_durations_metrics_recorder_unittest.cc +++ b/components/sync/driver/sync_session_durations_metrics_recorder_unittest.cc
@@ -45,20 +45,28 @@ } void SetInvalidCredentialsAuthError() { - GoogleServiceAuthError auth_error( - GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); + sync_service_.SetPersistentAuthErrorOtherThanWebSignout(); + + const GoogleServiceAuthError auth_error = sync_service_.GetAuthError(); + CHECK_EQ(auth_error.state(), + GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); + identity_test_env_.UpdatePersistentErrorOfRefreshTokenForAccount( identity_test_env_.identity_manager()->GetPrimaryAccountId( signin::ConsentLevel::kSync), auth_error); - sync_service_.SetAuthError(auth_error); + + // TODO(crbug.com/1156584): This below seems off since + // GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS doesn't actually lead to + // the PAUSED state. sync_service_.SetTransportState(SyncService::TransportState::PAUSED); } void ClearAuthError() { identity_test_env_.SetRefreshTokenForPrimaryAccount(); - sync_service_.SetAuthError(GoogleServiceAuthError::AuthErrorNone()); - sync_service_.SetTransportState(SyncService::TransportState::ACTIVE); + sync_service_.ClearAuthError(); + ASSERT_EQ(sync_service_.GetTransportState(), + SyncService::TransportState::ACTIVE); } std::string GetSessionHistogramName(const std::string& histogram_suffix) {
diff --git a/components/sync/model/BUILD.gn b/components/sync/model/BUILD.gn index e0455d8..3344f3cf 100644 --- a/components/sync/model/BUILD.gn +++ b/components/sync/model/BUILD.gn
@@ -15,9 +15,6 @@ "data_batch.h", "data_type_activation_request.cc", "data_type_activation_request.h", - "data_type_error_handler.h", - "data_type_error_handler_impl.cc", - "data_type_error_handler_impl.h", "dummy_metadata_change_list.cc", "dummy_metadata_change_list.h", "entity_change.cc",
diff --git a/components/sync/model/data_type_error_handler.h b/components/sync/model/data_type_error_handler.h deleted file mode 100644 index df35607..0000000 --- a/components/sync/model/data_type_error_handler.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2014 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_SYNC_MODEL_DATA_TYPE_ERROR_HANDLER_H__ -#define COMPONENTS_SYNC_MODEL_DATA_TYPE_ERROR_HANDLER_H__ - -#include <memory> -#include <string> - -#include "base/location.h" -#include "components/sync/base/model_type.h" -#include "components/sync/model/sync_error.h" - -namespace syncer { - -class DataTypeErrorHandler { - public: - virtual ~DataTypeErrorHandler() {} - - // Call this to disable a datatype while it is running. This is usually - // called for a runtime failure that is specific to a datatype. - virtual void OnUnrecoverableError(const SyncError& error) = 0; - - // This will create a SyncError object. This will also upload a breakpad call - // stack to crash server. A sync error usually means that sync has to be - // disabled either for that type or completely. - virtual SyncError CreateAndUploadError(const base::Location& location, - const std::string& message, - ModelType type) = 0; - - // Create a copy of this error handler. - virtual std::unique_ptr<DataTypeErrorHandler> Copy() const = 0; -}; - -} // namespace syncer - -#endif // COMPONENTS_SYNC_MODEL_DATA_TYPE_ERROR_HANDLER_H__
diff --git a/components/sync/model/data_type_error_handler_impl.cc b/components/sync/model/data_type_error_handler_impl.cc deleted file mode 100644 index 889dc68..0000000 --- a/components/sync/model/data_type_error_handler_impl.cc +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2016 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/sync/model/data_type_error_handler_impl.h" - -#include "base/bind.h" -#include "base/metrics/histogram_macros.h" - -namespace syncer { - -DataTypeErrorHandlerImpl::DataTypeErrorHandlerImpl( - const scoped_refptr<base::SequencedTaskRunner>& ui_thread, - const base::RepeatingClosure& dump_stack, - const ErrorCallback& sync_callback) - : ui_thread_(ui_thread), - dump_stack_(dump_stack), - sync_callback_(sync_callback) {} - -DataTypeErrorHandlerImpl::~DataTypeErrorHandlerImpl() = default; - -void DataTypeErrorHandlerImpl::OnUnrecoverableError(const SyncError& error) { - if (!dump_stack_.is_null()) - dump_stack_.Run(); - UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures2", - ModelTypeHistogramValue(error.model_type())); - ui_thread_->PostTask(error.location(), base::BindOnce(sync_callback_, error)); -} - -SyncError DataTypeErrorHandlerImpl::CreateAndUploadError( - const base::Location& location, - const std::string& message, - ModelType type) { - if (!dump_stack_.is_null()) - dump_stack_.Run(); - return SyncError(location, SyncError::DATATYPE_ERROR, message, type); -} - -std::unique_ptr<DataTypeErrorHandler> DataTypeErrorHandlerImpl::Copy() const { - return std::make_unique<DataTypeErrorHandlerImpl>(ui_thread_, dump_stack_, - sync_callback_); -} - -} // namespace syncer
diff --git a/components/sync/model/data_type_error_handler_impl.h b/components/sync/model/data_type_error_handler_impl.h deleted file mode 100644 index a34f90d..0000000 --- a/components/sync/model/data_type_error_handler_impl.h +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2014 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_SYNC_MODEL_DATA_TYPE_ERROR_HANDLER_IMPL_H__ -#define COMPONENTS_SYNC_MODEL_DATA_TYPE_ERROR_HANDLER_IMPL_H__ - -#include <memory> -#include <string> - -#include "base/memory/ref_counted.h" -#include "base/task/sequenced_task_runner.h" -#include "components/sync/model/data_type_error_handler.h" - -namespace syncer { - -// The standard implementation of DataTypeErrorHandler. -class DataTypeErrorHandlerImpl : public DataTypeErrorHandler { - public: - using ErrorCallback = base::RepeatingCallback<void(const SyncError&)>; - - DataTypeErrorHandlerImpl( - const scoped_refptr<base::SequencedTaskRunner>& ui_thread, - const base::RepeatingClosure& dump_stack, - const ErrorCallback& sync_callback); - - DataTypeErrorHandlerImpl(const DataTypeErrorHandlerImpl&) = delete; - DataTypeErrorHandlerImpl& operator=(const DataTypeErrorHandlerImpl&) = delete; - - ~DataTypeErrorHandlerImpl() override; - - void OnUnrecoverableError(const SyncError& error) override; - SyncError CreateAndUploadError(const base::Location& location, - const std::string& message, - ModelType type) override; - std::unique_ptr<DataTypeErrorHandler> Copy() const override; - - private: - // The thread task runner that |sync_callback_| runs on. This is passed in - // separately instead of bound inside the callback because we want to be able - // to perform the PostTask using the error location. - scoped_refptr<base::SequencedTaskRunner> ui_thread_; - - // The callback to dump and upload the stack from the current thread. - base::RepeatingClosure dump_stack_; - - // The callback used to inform sync of the error on the |ui_thread_|. - ErrorCallback sync_callback_; -}; - -} // namespace syncer - -#endif // COMPONENTS_SYNC_MODEL_DATA_TYPE_ERROR_HANDLER_IMPL_H__
diff --git a/components/sync/protocol/entity_data.cc b/components/sync/protocol/entity_data.cc index e7d98dbb..024a7d8 100644 --- a/components/sync/protocol/entity_data.cc +++ b/components/sync/protocol/entity_data.cc
@@ -24,7 +24,7 @@ EntityData& EntityData::operator=(EntityData&& other) = default; -base::Value::Dict EntityData::ToDictionaryValue() { +base::Value::Dict EntityData::ToDictionaryValue() const { // This is used when debugging at sync-internals page. The code in // sync_node_browser.js is expecting certain fields names. e.g. CTIME, MTIME, // and IS_DIR.
diff --git a/components/sync/protocol/entity_data.h b/components/sync/protocol/entity_data.h index 768b301..829b472a 100644 --- a/components/sync/protocol/entity_data.h +++ b/components/sync/protocol/entity_data.h
@@ -91,7 +91,7 @@ bool is_deleted() const { return specifics.ByteSize() == 0; } // Dumps all info into a DictionaryValue and returns it. - base::Value::Dict ToDictionaryValue(); + base::Value::Dict ToDictionaryValue() const; // Returns the estimate of dynamically allocated memory in bytes. size_t EstimateMemoryUsage() const;
diff --git a/components/sync/protocol/history_specifics.proto b/components/sync/protocol/history_specifics.proto index d2e8b64..cc721bd 100644 --- a/components/sync/protocol/history_specifics.proto +++ b/components/sync/protocol/history_specifics.proto
@@ -46,6 +46,16 @@ // redirects, this has only one entry. repeated RedirectEntry redirect_entries = 3; + // Whether the redirect chain in this entity is the continuation of a prior + // chain, and whether a continuation of this chain exists, in other entities. + // These are effectively the inverse of the CHAIN_START/CHAIN_END page + // transition qualifiers in Chrome. They are typically both false, since the + // whole chain is included in `redirect_entries`, but in some cases (notably, + // client redirects) a redirect chain may be split up across multiple + // entities. + optional bool redirect_chain_start_incomplete = 19; + optional bool redirect_chain_end_incomplete = 20; + message PageTransition { // The core transition type. optional SyncEnums.PageTransition core_transition = 1 [default = LINK];
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h index 94e3fd5f..8e2bcc7 100644 --- a/components/sync/protocol/proto_visitors.h +++ b/components/sync/protocol/proto_visitors.h
@@ -789,6 +789,8 @@ VISIT(visit_time_windows_epoch_micros); VISIT(originator_cache_guid); VISIT_REP(redirect_entries); + VISIT(redirect_chain_start_incomplete); + VISIT(redirect_chain_end_incomplete); VISIT(page_transition); VISIT(originator_referring_visit_id); VISIT(originator_opener_visit_id);
diff --git a/components/sync/test/test_sync_service.cc b/components/sync/test/test_sync_service.cc index e84acb0..13952be6 100644 --- a/components/sync/test/test_sync_service.cc +++ b/components/sync/test/test_sync_service.cc
@@ -63,8 +63,32 @@ has_sync_consent_ = has_sync_consent; } -void TestSyncService::SetAuthError(const GoogleServiceAuthError& auth_error) { - auth_error_ = auth_error; +void TestSyncService::SetPersistentAuthErrorOtherThanWebSignout() { + auth_error_ = GoogleServiceAuthError::FromInvalidGaiaCredentialsReason( + GoogleServiceAuthError::InvalidGaiaCredentialsReason:: + CREDENTIALS_REJECTED_BY_SERVER); + CHECK(auth_error_.IsPersistentError()); +} + +void TestSyncService::SetPersistentAuthErrorWithWebSignout() { + transport_state_ = TransportState::PAUSED; + auth_error_ = GoogleServiceAuthError::FromInvalidGaiaCredentialsReason( + GoogleServiceAuthError::InvalidGaiaCredentialsReason:: + CREDENTIALS_REJECTED_BY_CLIENT); + CHECK(auth_error_.IsPersistentError()); +} + +void TestSyncService::SetTransientAuthError() { + auth_error_ = + GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED); + CHECK(auth_error_.IsTransientError()); +} + +void TestSyncService::ClearAuthError() { + auth_error_ = GoogleServiceAuthError::AuthErrorNone(); + if (transport_state_ == TransportState::PAUSED) { + transport_state_ = TransportState::ACTIVE; + } } void TestSyncService::SetFirstSetupComplete(bool first_setup_complete) { @@ -187,6 +211,9 @@ } ModelTypeSet TestSyncService::GetActiveDataTypes() const { + if (transport_state_ != TransportState::ACTIVE) { + return ModelTypeSet(); + } return active_data_types_; }
diff --git a/components/sync/test/test_sync_service.h b/components/sync/test/test_sync_service.h index fb6ab19..430c8c9 100644 --- a/components/sync/test/test_sync_service.h +++ b/components/sync/test/test_sync_service.h
@@ -37,7 +37,16 @@ void SetAccountInfo(const CoreAccountInfo& account_info); void SetHasSyncConsent(bool has_consent); void SetSetupInProgress(bool in_progress); - void SetAuthError(const GoogleServiceAuthError& auth_error); + + // Setters to mimic common auth error scenarios. Note that these functions + // may change the transport state, as returned by GetTransportState(). + // TODO(crbug.com/1156584): Unify the two below once all persistent auth + // errors are treated equally. + void SetPersistentAuthErrorOtherThanWebSignout(); + void SetPersistentAuthErrorWithWebSignout(); + void SetTransientAuthError(); + void ClearAuthError(); + void SetFirstSetupComplete(bool first_setup_complete); // TODO(crbug.com/1356216): reconsider SetActiveDataTypes() use in tests. It // should set the active types from the user selected types; did not fail.
diff --git a/components/sync/test/test_sync_user_settings.cc b/components/sync/test/test_sync_user_settings.cc index 7245b998..3644537 100644 --- a/components/sync/test/test_sync_user_settings.cc +++ b/components/sync/test/test_sync_user_settings.cc
@@ -13,10 +13,6 @@ #include "components/sync/engine/nigori/nigori.h" #include "components/sync/test/test_sync_service.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) -#include "ash/constants/ash_features.h" -#endif - namespace syncer { ModelTypeSet UserSelectableTypesToModelTypes(
diff --git a/components/sync_sessions/proxy_tabs_data_type_controller.cc b/components/sync_sessions/proxy_tabs_data_type_controller.cc index 042c36c7..7c62eb6 100644 --- a/components/sync_sessions/proxy_tabs_data_type_controller.cc +++ b/components/sync_sessions/proxy_tabs_data_type_controller.cc
@@ -11,6 +11,7 @@ #include "base/values.h" #include "components/sync/driver/configure_context.h" #include "components/sync/engine/data_type_activation_response.h" +#include "components/sync/model/sync_error.h" #include "components/sync/model/type_entities_count.h" namespace sync_sessions {
diff --git a/components/translate/ios/browser/BUILD.gn b/components/translate/ios/browser/BUILD.gn index f61c879..4f3df8e 100644 --- a/components/translate/ios/browser/BUILD.gn +++ b/components/translate/ios/browser/BUILD.gn
@@ -21,8 +21,6 @@ "string_clipping_util.h", "translate_controller.h", "translate_controller.mm", - "translate_java_script_feature.h", - "translate_java_script_feature.mm", ] deps = [ @@ -51,11 +49,6 @@ visibility = [ ":browser" ] primary_script = "resources/translate_ios.js" sources = [ "resources/translate_ios.js" ] - - deps = [ - "//ios/web/public/js_messaging:gcrweb", - "//ios/web/public/js_messaging:util_scripts", - ] } source_set("unit_tests") {
diff --git a/components/translate/ios/browser/ios_translate_driver.h b/components/translate/ios/browser/ios_translate_driver.h index 23cf1c8..4e17775f 100644 --- a/components/translate/ios/browser/ios_translate_driver.h +++ b/components/translate/ios/browser/ios_translate_driver.h
@@ -46,6 +46,9 @@ return language_detection_controller_.get(); } + TranslateController* translate_controller() { + return translate_controller_.get(); + } void OnLanguageModelFileAvailabilityChanged(bool available); // web::WebStateObserver methods. @@ -106,6 +109,7 @@ web::WebState* web_state_ = nullptr; base::WeakPtr<TranslateManager> translate_manager_; + std::unique_ptr<TranslateController> translate_controller_; std::unique_ptr<LanguageDetectionController> language_detection_controller_; LanguageDetectionModelService* language_detection_model_service_ = nullptr;
diff --git a/components/translate/ios/browser/ios_translate_driver.mm b/components/translate/ios/browser/ios_translate_driver.mm index 8b3a7e5..0799747 100644 --- a/components/translate/ios/browser/ios_translate_driver.mm +++ b/components/translate/ios/browser/ios_translate_driver.mm
@@ -75,9 +75,10 @@ web_state, language_detection_model, translate_manager_->translate_client()->GetPrefs()); - TranslateController::CreateForWebState( + translate_controller_ = std::make_unique<TranslateController>( web_state, JSTranslateWebFrameManagerFactory::GetInstance()); - TranslateController::FromWebState(web_state)->set_observer(this); + + translate_controller_->set_observer(this); } IOSTranslateDriver::~IOSTranslateDriver() { @@ -162,14 +163,13 @@ source_language_ = source_lang; target_language_ = target_lang; pending_page_seq_no_ = page_seq_no; - TranslateController::FromWebState(web_state_) - ->InjectTranslateScript(translate_script); + translate_controller_->InjectTranslateScript(translate_script); } void IOSTranslateDriver::RevertTranslation(int page_seq_no) { if (page_seq_no != page_seq_no_) return; // The user navigated away. - TranslateController::FromWebState(web_state_)->RevertTranslation(); + translate_controller_->RevertTranslation(); } bool IOSTranslateDriver::IsIncognito() { @@ -257,8 +257,7 @@ std::string source = (source_language_ != kUnknownLanguageCode) ? source_language_ : kAutoDetectionLanguage; - TranslateController::FromWebState(web_state_) - ->StartTranslation(source_language_, target_language_); + translate_controller_->StartTranslation(source_language_, target_language_); } void IOSTranslateDriver::OnTranslateComplete(TranslateErrors error_type,
diff --git a/components/translate/ios/browser/resources/translate_ios.js b/components/translate/ios/browser/resources/translate_ios.js index d83f6c2..8b075c8a 100644 --- a/components/translate/ios/browser/resources/translate_ios.js +++ b/components/translate/ios/browser/resources/translate_ios.js
@@ -6,34 +6,44 @@ * @fileoverview Translate script for iOS that is needed in addition to the * cross platform script translate.js. * + * TODO(crbug.com/659442): Enable checkTypes, checkVars errors for this file. + * @suppress {checkTypes, checkVars} */ -import {gCrWeb} from '//ios/web/public/js_messaging/resources/gcrweb.js'; -import {sendWebKitMessage} from '//ios/web/public/js_messaging/resources/utils.js'; +// Requires functions from base.js + +/** + * Namespace for this module. + */ +__gCrWeb.translate = {}; + +// Store message namespace object in a global __gCrWeb object referenced by a +// string, so it does not get renamed by closure compiler during the +// minification. +__gCrWeb['translate'] = __gCrWeb.translate; /** * Defines function to install callbacks on cr.googleTranslate. * See translate_script.cc for usage. */ -function installCallbacks() { +__gCrWeb.translate['installCallbacks'] = function() { /** * Sets a callback to inform host of the ready state of the translate element. */ cr.googleTranslate.readyCallback = function() { - sendWebKitMessage('TranslateMessage', { - 'command': 'ready', - 'errorCode': cr.googleTranslate.errorCode, - 'loadTime': cr.googleTranslate.loadTime, - 'readyTime': cr.googleTranslate.readyTime, - }); + __gCrWeb.message.invokeOnHost({ + 'command': 'translate.ready', + 'errorCode': cr.googleTranslate.errorCode, + 'loadTime': cr.googleTranslate.loadTime, + 'readyTime': cr.googleTranslate.readyTime}); }; /** * Sets a callback to inform host of the result of translation. */ cr.googleTranslate.resultCallback = function() { - sendWebKitMessage('TranslateMessage', { - 'command': 'status', + __gCrWeb.message.invokeOnHost({ + 'command': 'translate.status', 'errorCode': cr.googleTranslate.errorCode, 'pageSourceLanguage': cr.googleTranslate.sourceLang, 'translationTime': cr.googleTranslate.translationTime, @@ -44,10 +54,11 @@ * Sets a callback to inform host to download javascript. */ cr.googleTranslate.loadJavascriptCallback = function(url) { - sendWebKitMessage( - 'TranslateMessage', {'command': 'loadjavascript', 'url': url}); + __gCrWeb.message.invokeOnHost({ + 'command': 'translate.loadjavascript', + 'url': url}); }; -} +}; /** * Redefine XMLHttpRequest's open to capture request configurations. @@ -67,6 +78,12 @@ } /** + * Translate XMLHttpRequests still outstanding. + * @type {Array<XMLHttpRequest>} + */ +__gCrWeb.translate['xhrs'] = []; + +/** * Redefine XMLHttpRequest's send to call into the browser if it matches the * predefined translate security origin. * Only redefines once because this script may be injected multiple times. @@ -78,14 +95,13 @@ // the browser. Else, pass it through to the original implementation. // |securityOrigin| is predefined by translate_script.cc. if (this.savedUrl.startsWith(securityOrigin)) { - const length = gCrWeb.translate.xhrs.push(this); - sendWebKitMessage('TranslateMessage', { - 'command': 'sendrequest', - 'method': this.savedMethod, - 'url': this.savedUrl, - 'body': body, - 'requestID': length - 1, - }); + const length = __gCrWeb.translate['xhrs'].push(this); + __gCrWeb.message.invokeOnHost({ + 'command': 'translate.sendrequest', + 'method': this.savedMethod, + 'url': this.savedUrl, + 'body': body, + 'requestID': length - 1}); } else { this.realSend(body); } @@ -102,10 +118,10 @@ * @param {string} responseURL The url which the response was returned from. * @param {string} responseText The text received from the server. */ -function handleResponse( +__gCrWeb.translate['handleResponse'] = function( url, requestID, status, statusText, responseURL, responseText) { - // Retrieve xhr object that's waiting for the response. - xhr = gCrWeb.translate.xhrs[requestID]; + // Retrive xhr object that's waiting for the response. + xhr = __gCrWeb.translate['xhrs'][requestID]; // Configure xhr as it would have been if it was sent. Object.defineProperties(xhr, { @@ -120,19 +136,5 @@ xhr.onreadystatechange(); // Clean it up - delete gCrWeb.translate.xhrs[requestID]; -} - -// Mark: Public API - -/** - * Translate XMLHttpRequests still outstanding. - * @type {Array<XMLHttpRequest>} - */ -const xhrs = []; - -gCrWeb.translate = { - installCallbacks, - handleResponse, - xhrs, + delete __gCrWeb.translate['xhrs'][requestID]; };
diff --git a/components/translate/ios/browser/translate_controller.h b/components/translate/ios/browser/translate_controller.h index 7793e40..fbb4e401 100644 --- a/components/translate/ios/browser/translate_controller.h +++ b/components/translate/ios/browser/translate_controller.h
@@ -12,13 +12,12 @@ #include "base/gtest_prod_util.h" #include "base/memory/weak_ptr.h" -#include "base/values.h" #include "components/translate/core/common/translate_errors.h" #import "ios/web/public/web_state.h" #include "ios/web/public/web_state_observer.h" -#import "ios/web/public/web_state_user_data.h" #include "services/network/public/cpp/simple_url_loader.h" +class GURL; class JSTranslateWebFrameManagerFactory; namespace web { @@ -29,8 +28,7 @@ // TranslateController controls the translation of the page, by injecting the // translate scripts and monitoring the status. -class TranslateController : public web::WebStateObserver, - public web::WebStateUserData<TranslateController> { +class TranslateController : public web::WebStateObserver { public: // Observer class to monitor the progress of the translation. class Observer { @@ -48,6 +46,9 @@ double translation_time) = 0; }; + TranslateController(web::WebState* web_state, + JSTranslateWebFrameManagerFactory* js_manager_factory); + TranslateController(const TranslateController&) = delete; TranslateController& operator=(const TranslateController&) = delete; @@ -67,20 +68,12 @@ void StartTranslation(const std::string& source_language, const std::string& target_language); - // Called when a JavaScript command is received. - void OnJavascriptCommandReceived(const base::Value::Dict& payload); - // Changes the JSTranslateWebFrameManagerFactory used by this // TranslateController. Only used for testing. void SetJsTranslateWebFrameManagerFactoryForTesting( JSTranslateWebFrameManagerFactory* manager); private: - TranslateController(web::WebState* web_state, - JSTranslateWebFrameManagerFactory* js_manager_factory); - friend class web::WebStateUserData<TranslateController>; - WEB_STATE_USER_DATA_KEY_DECL(); - FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest, OnJavascriptCommandReceived); FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest, @@ -99,12 +92,17 @@ FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest, OnTranslateSendRequestWithBadMethod); + // Called when a JavaScript command is received. + bool OnJavascriptCommandReceived(const base::Value& command, + const GURL& url, + bool interacting, + web::WebFrame* sender_frame); // Methods to handle specific JavaScript commands. - // The command is ignored if `payload` format is unexpected. - void OnTranslateReady(const base::Value::Dict& payload); - void OnTranslateComplete(const base::Value::Dict& payload); - void OnTranslateLoadJavaScript(const base::Value::Dict& payload); - void OnTranslateSendRequest(const base::Value::Dict& payload); + // Return false if the command is invalid. + bool OnTranslateReady(const base::Value& command); + bool OnTranslateComplete(const base::Value& command); + bool OnTranslateLoadJavaScript(const base::Value& command); + bool OnTranslateSendRequest(const base::Value& command); // The callback when the script is fetched or a server error occurred. void OnScriptFetchComplete(std::unique_ptr<std::string> response_body); @@ -136,6 +134,9 @@ // Used to fetch additional scripts needed for translate. std::unique_ptr<network::SimpleURLLoader> script_fetcher_; + // Subscription for JS message. + base::CallbackListSubscription subscription_; + Observer* observer_; JSTranslateWebFrameManagerFactory* js_manager_factory_; base::WeakPtrFactory<TranslateController> weak_method_factory_;
diff --git a/components/translate/ios/browser/translate_controller.mm b/components/translate/ios/browser/translate_controller.mm index 04a4e3e0..3bb1605 100644 --- a/components/translate/ios/browser/translate_controller.mm +++ b/components/translate/ios/browser/translate_controller.mm
@@ -36,13 +36,16 @@ namespace { +// Prefix for the translate javascript commands. Must be kept in sync with +// translate_ios.js. +const char kCommandPrefix[] = "translate"; + // Extracts a TranslateErrors value from `value` for the given `key`. Returns // absl::nullopt if the value is missing or not convertible to TranslateErrors. -absl::optional<TranslateErrors> FindTranslateErrorsKey( - const base::Value::Dict& value, - base::StringPiece key) { +absl::optional<TranslateErrors> FindTranslateErrorsKey(const base::Value& value, + base::StringPiece key) { // Does `value` contains a double value for `key`? - const absl::optional<double> found_value = value.FindDouble(key); + const absl::optional<double> found_value = value.FindDoubleKey(key); if (!found_value.has_value()) return absl::nullopt; @@ -68,8 +71,6 @@ } // anonymous namespace -WEB_STATE_USER_DATA_KEY_IMPL(TranslateController) - TranslateController::TranslateController( web::WebState* web_state, JSTranslateWebFrameManagerFactory* js_manager_factory) @@ -79,6 +80,11 @@ weak_method_factory_(this) { DCHECK(web_state_); web_state_->AddObserver(this); + subscription_ = web_state_->AddScriptCommandCallback( + base::BindRepeating( + base::IgnoreResult(&TranslateController::OnJavascriptCommandReceived), + base::Unretained(this)), + kCommandPrefix); } TranslateController::~TranslateController() { @@ -121,59 +127,67 @@ js_manager_factory_ = manager; } -void TranslateController::OnJavascriptCommandReceived( - const base::Value::Dict& payload) { - const std::string* command = payload.FindString("command"); - if (!command) { - return; +bool TranslateController::OnJavascriptCommandReceived( + const base::Value& command, + const GURL& page_url, + bool user_is_interacting, + web::WebFrame* sender_frame) { + if (!sender_frame->IsMainFrame()) { + // Translate is only supported on main frame. + return false; + } + const std::string* command_string = command.FindStringKey("command"); + if (!command_string) { + return false; } - if (*command == "ready") { - OnTranslateReady(payload); - } else if (*command == "status") { - OnTranslateComplete(payload); - } else if (*command == "loadjavascript") { - OnTranslateLoadJavaScript(payload); - } else if (*command == "sendrequest") { - OnTranslateSendRequest(payload); - } + if (*command_string == "translate.ready") + return OnTranslateReady(command); + if (*command_string == "translate.status") + return OnTranslateComplete(command); + if (*command_string == "translate.loadjavascript") + return OnTranslateLoadJavaScript(command); + if (*command_string == "translate.sendrequest") + return OnTranslateSendRequest(command); + + return false; } -void TranslateController::OnTranslateReady(const base::Value::Dict& payload) { +bool TranslateController::OnTranslateReady(const base::Value& command) { absl::optional<TranslateErrors> error_type = - FindTranslateErrorsKey(payload, "errorCode"); + FindTranslateErrorsKey(command, "errorCode"); if (!error_type.has_value()) - return; + return false; absl::optional<double> load_time; absl::optional<double> ready_time; if (*error_type == TranslateErrors::NONE) { - load_time = payload.FindDouble("loadTime"); - ready_time = payload.FindDouble("readyTime"); + load_time = command.FindDoubleKey("loadTime"); + ready_time = command.FindDoubleKey("readyTime"); if (!load_time.has_value() || !ready_time.has_value()) { - return; + return false; } } if (observer_) { observer_->OnTranslateScriptReady(*error_type, load_time.value_or(0.), ready_time.value_or(0.)); } + return true; } -void TranslateController::OnTranslateComplete( - const base::Value::Dict& payload) { +bool TranslateController::OnTranslateComplete(const base::Value& command) { absl::optional<TranslateErrors> error_type = - FindTranslateErrorsKey(payload, "errorCode"); + FindTranslateErrorsKey(command, "errorCode"); if (!error_type.has_value()) - return; + return false; const std::string* source_language = nullptr; absl::optional<double> translation_time; if (*error_type == TranslateErrors::NONE) { - source_language = payload.FindString("pageSourceLanguage"); - translation_time = payload.FindDouble("translationTime"); + source_language = command.FindStringKey("pageSourceLanguage"); + translation_time = command.FindDoubleKey("translationTime"); if (!source_language || !translation_time.has_value()) { - return; + return false; } } @@ -182,18 +196,19 @@ *error_type, source_language ? *source_language : std::string(), translation_time.value_or(0.)); } + return true; } -void TranslateController::OnTranslateLoadJavaScript( - const base::Value::Dict& payload) { - const std::string* url = payload.FindString("url"); +bool TranslateController::OnTranslateLoadJavaScript( + const base::Value& command) { + const std::string* url = command.FindStringKey("url"); if (!url) { - return; + return false; } GURL security_origin = translate::GetTranslateSecurityOrigin(); if (url->find(security_origin.spec()) || script_fetcher_) { - return; + return false; } auto resource_request = std::make_unique<network::ResourceRequest>(); @@ -205,25 +220,31 @@ web_state_->GetBrowserState()->GetURLLoaderFactory(), base::BindOnce(&TranslateController::OnScriptFetchComplete, base::Unretained(this))); + + return true; } -void TranslateController::OnTranslateSendRequest( - const base::Value::Dict& payload) { - const std::string* method = payload.FindString("method"); - const std::string* url = payload.FindString("url"); - const std::string* body = payload.FindString("body"); - - if (!method || !url || !body) { - return; +bool TranslateController::OnTranslateSendRequest(const base::Value& command) { + const std::string* method = command.FindStringKey("method"); + if (!method) { + return false; } - absl::optional<double> request_id = payload.FindDouble("requestID"); + const std::string* url = command.FindStringKey("url"); + if (!url) { + return false; + } + const std::string* body = command.FindStringKey("body"); + if (!body) { + return false; + } + absl::optional<double> request_id = command.FindDoubleKey("requestID"); if (!request_id.has_value()) { - return; + return false; } GURL security_origin = translate::GetTranslateSecurityOrigin(); if (url->find(security_origin.spec())) { - return; + return false; } auto request = std::make_unique<network::ResourceRequest>(); @@ -240,6 +261,7 @@ base::BindOnce(&TranslateController::OnRequestFetchComplete, base::Unretained(this), pair.first, *url, static_cast<int>(*request_id))); + return true; } void TranslateController::OnScriptFetchComplete(
diff --git a/components/translate/ios/browser/translate_controller_unittest.mm b/components/translate/ios/browser/translate_controller_unittest.mm index 7ffbfdb..1618840 100644 --- a/components/translate/ios/browser/translate_controller_unittest.mm +++ b/components/translate/ios/browser/translate_controller_unittest.mm
@@ -110,12 +110,14 @@ public TranslateController::Observer { protected: TranslateControllerTest() - : task_environment_(web::WebTaskEnvironment::Options::IO_MAINLOOP), - fake_web_state_(std::make_unique<web::FakeWebState>()), + : fake_web_state_(std::make_unique<web::FakeWebState>()), fake_browser_state_(std::make_unique<web::FakeBrowserState>()), fake_main_frame_(web::FakeWebFrame::Create(/*frame_id=*/"", /*is_main_frame=*/true, GURL())), + fake_iframe_(web::FakeWebFrame::Create(/*frame_id=*/"", + /*is_main_frame=*/false, + GURL())), error_type_(TranslateErrors::NONE), ready_time_(0), load_time_(0), @@ -123,10 +125,9 @@ on_script_ready_called_(false), on_translate_complete_called_(false) { fake_web_state_->SetBrowserState(fake_browser_state_.get()); - TranslateController::CreateForWebState(fake_web_state_.get(), - &fake_translate_factory_); - TranslateController::FromWebState(fake_web_state_.get()) - ->set_observer(this); + translate_controller_ = std::make_unique<TranslateController>( + fake_web_state_.get(), &fake_translate_factory_); + translate_controller_->set_observer(this); } // TranslateController::Observer methods. @@ -148,15 +149,13 @@ translation_time_ = translation_time; } - TranslateController* translate_controller() { - return TranslateController::FromWebState(fake_web_state_.get()); - } - web::WebTaskEnvironment task_environment_; std::unique_ptr<web::FakeWebState> fake_web_state_; std::unique_ptr<web::FakeBrowserState> fake_browser_state_; std::unique_ptr<web::FakeWebFrame> fake_main_frame_; + std::unique_ptr<web::FakeWebFrame> fake_iframe_; FakeJSTranslateWebFrameManagerFactory fake_translate_factory_; + std::unique_ptr<TranslateController> translate_controller_; TranslateErrors error_type_; double ready_time_; double load_time_; @@ -166,36 +165,59 @@ bool on_translate_complete_called_; }; -// Tests that OnTranslateScriptReady() is called when a timeout message is -// received from the JS side. -TEST_F(TranslateControllerTest, OnTranslateScriptReadyTimeoutCalled) { +// Tests that OnJavascriptCommandReceived() returns false to malformed commands. +TEST_F(TranslateControllerTest, OnJavascriptCommandReceived) { + base::Value::Dict malformed_command; + EXPECT_FALSE(translate_controller_->OnJavascriptCommandReceived( + base::Value(std::move(malformed_command)), GURL("http://google.com"), + /*interacting*/ false, fake_main_frame_.get())); +} + +// Tests that OnJavascriptCommandReceived() returns false to iframe commands. +TEST_F(TranslateControllerTest, OnIFrameJavascriptCommandReceived) { base::Value::Dict command; - command.Set("command", "ready"); + command.Set("command", "translate.ready"); command.Set("errorCode", static_cast<double>(TranslateErrors::TRANSLATION_TIMEOUT)); command.Set("loadTime", .0); command.Set("readyTime", .0); - translate_controller()->OnJavascriptCommandReceived( - base::Value::Dict(std::move(command))); + EXPECT_FALSE(translate_controller_->OnJavascriptCommandReceived( + base::Value(std::move(command)), GURL("http://google.com"), + /*interacting*/ false, fake_iframe_.get())); +} + +// Tests that OnTranslateScriptReady() is called when a timeout message is +// received from the JS side. +TEST_F(TranslateControllerTest, OnTranslateScriptReadyTimeoutCalled) { + base::Value::Dict command; + command.Set("command", "translate.ready"); + command.Set("errorCode", + static_cast<double>(TranslateErrors::TRANSLATION_TIMEOUT)); + command.Set("loadTime", .0); + command.Set("readyTime", .0); + EXPECT_TRUE(translate_controller_->OnJavascriptCommandReceived( + base::Value(std::move(command)), GURL("http://google.com"), + /*interacting*/ false, fake_main_frame_.get())); EXPECT_TRUE(on_script_ready_called_); EXPECT_FALSE(on_translate_complete_called_); EXPECT_FALSE(error_type_ == TranslateErrors::NONE); } // Tests that OnTranslateScriptReady() is called with the right parameters when -// a `ready` message is received from the JS side. +// a |translate.ready| message is received from the JS side. TEST_F(TranslateControllerTest, OnTranslateScriptReadyCalled) { // Arbitrary values. double some_load_time = 23.1; double some_ready_time = 12.2; base::Value::Dict command; - command.Set("command", "ready"); + command.Set("command", "translate.ready"); command.Set("errorCode", static_cast<double>(TranslateErrors::NONE)); command.Set("loadTime", some_load_time); command.Set("readyTime", some_ready_time); - translate_controller()->OnJavascriptCommandReceived( - base::Value::Dict(std::move(command))); + EXPECT_TRUE(translate_controller_->OnJavascriptCommandReceived( + base::Value(std::move(command)), GURL("http://google.com"), + /*interacting*/ false, fake_main_frame_.get())); EXPECT_TRUE(on_script_ready_called_); EXPECT_FALSE(on_translate_complete_called_); EXPECT_TRUE(error_type_ == TranslateErrors::NONE); @@ -204,19 +226,20 @@ } // Tests that OnTranslateComplete() is called with the right parameters when a -// `status` message is received from the JS side. +// |translate.status| message is received from the JS side. TEST_F(TranslateControllerTest, TranslationSuccess) { // Arbitrary values. std::string some_source_language("en"); double some_translation_time = 12.9; base::Value::Dict command; - command.Set("command", "status"); + command.Set("command", "translate.status"); command.Set("errorCode", static_cast<double>(TranslateErrors::NONE)); command.Set("pageSourceLanguage", some_source_language); command.Set("translationTime", some_translation_time); - translate_controller()->OnJavascriptCommandReceived( - base::Value::Dict(std::move(command))); + EXPECT_TRUE(translate_controller_->OnJavascriptCommandReceived( + base::Value(std::move(command)), GURL("http://google.com"), + /*interacting*/ false, fake_main_frame_.get())); EXPECT_FALSE(on_script_ready_called_); EXPECT_TRUE(on_translate_complete_called_); EXPECT_TRUE(error_type_ == TranslateErrors::NONE); @@ -225,64 +248,57 @@ } // Tests that OnTranslateComplete() is called with the right parameters when a -// `status` message is received from the JS side. +// |translate.status| message is received from the JS side. TEST_F(TranslateControllerTest, TranslationFailure) { base::Value::Dict command; - command.Set("command", "status"); + command.Set("command", "translate.status"); command.Set("errorCode", static_cast<double>(TranslateErrors::INITIALIZATION_ERROR)); - translate_controller()->OnJavascriptCommandReceived( - base::Value::Dict(std::move(command))); + EXPECT_TRUE(translate_controller_->OnJavascriptCommandReceived( + base::Value(std::move(command)), GURL("http://google.com"), + /*interacting*/ false, fake_main_frame_.get())); EXPECT_FALSE(on_script_ready_called_); EXPECT_TRUE(on_translate_complete_called_); EXPECT_FALSE(error_type_ == TranslateErrors::NONE); } -// Tests that OnTranslateSendRequest() is called with the right parameters -// when a `sendrequest` message is received from the JS side. -TEST_F(TranslateControllerTest, OnTranslateSendRequestWithValidCommand) { - fake_web_state_->OnWebFrameDidBecomeAvailable(fake_main_frame_.get()); - +// Tests that OnTranslateLoadJavaScript() is called with the right parameters +// when a |translate.loadjavascript| message is received from the JS side. +TEST_F(TranslateControllerTest, OnTranslateLoadJavascript) { base::Value::Dict command; - command.Set("command", "sendrequest"); + command.Set("command", "translate.loadjavascript"); + command.Set("url", "https://translate.googleapis.com/javascript.js"); + EXPECT_TRUE(translate_controller_->OnJavascriptCommandReceived( + base::Value(std::move(command)), GURL("http://google.com"), + /*interacting=*/false, fake_main_frame_.get())); +} + +// Tests that OnTranslateSendRequest() is called with the right parameters +// when a |translate.sendrequest| message is received from the JS side. +TEST_F(TranslateControllerTest, OnTranslateSendRequestWithValidCommand) { + base::Value::Dict command; + command.Set("command", "translate.sendrequest"); command.Set("method", "POST"); command.Set("url", "https://translate.googleapis.com/translate?key=abcd"); command.Set("body", "helloworld"); command.Set("requestID", .0); - translate_controller()->OnJavascriptCommandReceived( - base::Value::Dict(std::move(command))); - task_environment_.RunUntilIdle(); - - HandleTranslateResponseParams* last_params = - fake_translate_factory_.FromWebFrame(fake_main_frame_.get()) - ->GetLastHandleResponseParams(); - ASSERT_TRUE(last_params); - EXPECT_EQ("https://translate.googleapis.com/translate?key=abcd", - last_params->URL); - EXPECT_EQ(0, last_params->request_ID); - EXPECT_EQ(net::HttpStatusCode::HTTP_BAD_REQUEST, last_params->response_code); - EXPECT_EQ("", last_params->status_text); - EXPECT_EQ("https://translate.googleapis.com/translate?key=abcd", - last_params->response_URL); - EXPECT_EQ("", last_params->response_text); + EXPECT_TRUE(translate_controller_->OnJavascriptCommandReceived( + base::Value(std::move(command)), GURL("http://google.com"), + /*interacting=*/false, fake_main_frame_.get())); } // Tests that OnTranslateSendRequest() rejects a bad url contained in the -// `sendrequest` message received from Javascript. +// |translate.sendrequest| message received from Javascript. TEST_F(TranslateControllerTest, OnTranslateSendRequestWithBadURL) { base::Value::Dict command; - command.Set("command", "sendrequest"); + command.Set("command", "translate.sendrequest"); command.Set("method", "POST"); command.Set("url", "https://badurl.example.com"); command.Set("body", "helloworld"); command.Set("requestID", .0); - translate_controller()->OnJavascriptCommandReceived( - base::Value::Dict(std::move(command))); - task_environment_.RunUntilIdle(); - HandleTranslateResponseParams* last_params = - fake_translate_factory_.FromWebFrame(fake_main_frame_.get()) - ->GetLastHandleResponseParams(); - ASSERT_FALSE(last_params); + EXPECT_FALSE(translate_controller_->OnJavascriptCommandReceived( + base::Value(std::move(command)), GURL("http://google.com"), + /*interacting=*/false, fake_main_frame_.get())); } // Tests that OnTranslateSendRequest() called with a bad method will eventually @@ -291,7 +307,7 @@ fake_web_state_->OnWebFrameDidBecomeAvailable(fake_main_frame_.get()); base::Value::Dict command; - command.Set("command", "sendrequest"); + command.Set("command", "translate.sendrequest"); command.Set("method", "POST\r\nHost: other.example.com"); command.Set("url", "https://translate.googleapis.com/translate?key=abcd"); command.Set("body", "helloworld"); @@ -299,8 +315,9 @@ // The command will be accepted, but a bad method should cause the request to // fail shortly thereafter. - translate_controller()->OnJavascriptCommandReceived( - base::Value::Dict(std::move(command))); + EXPECT_TRUE(translate_controller_->OnJavascriptCommandReceived( + base::Value(std::move(command)), GURL("http://google.com"), + /*interacting=*/false, fake_main_frame_.get())); task_environment_.RunUntilIdle(); HandleTranslateResponseParams* last_params =
diff --git a/components/translate/ios/browser/translate_java_script_feature.h b/components/translate/ios/browser/translate_java_script_feature.h deleted file mode 100644 index 8e9d4f8..0000000 --- a/components/translate/ios/browser/translate_java_script_feature.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_TRANSLATE_IOS_BROWSER_TRANSLATE_JAVA_SCRIPT_FEATURE_H_ -#define COMPONENTS_TRANSLATE_IOS_BROWSER_TRANSLATE_JAVA_SCRIPT_FEATURE_H_ - -#include "base/no_destructor.h" -#include "ios/web/public/js_messaging/java_script_feature.h" - -namespace web { -class WebState; -} // namespace web - -namespace translate { - -// Feature which listens for translate messages from the injected scripts. -class TranslateJavaScriptFeature : public web::JavaScriptFeature { - public: - static TranslateJavaScriptFeature* GetInstance(); - - private: - friend class base::NoDestructor<TranslateJavaScriptFeature>; - - // web::JavaScriptFeature - absl::optional<std::string> GetScriptMessageHandlerName() const override; - void ScriptMessageReceived(web::WebState* web_state, - const web::ScriptMessage& message) override; - - TranslateJavaScriptFeature(); - ~TranslateJavaScriptFeature() override; - - TranslateJavaScriptFeature(const TranslateJavaScriptFeature&) = delete; - TranslateJavaScriptFeature& operator=(const TranslateJavaScriptFeature&) = - delete; -}; - -} // namespace translate - -#endif // COMPONENTS_TRANSLATE_IOS_BROWSER_TRANSLATE_JAVA_SCRIPT_FEATURE_H_
diff --git a/components/translate/ios/browser/translate_java_script_feature.mm b/components/translate/ios/browser/translate_java_script_feature.mm deleted file mode 100644 index 0317c92..0000000 --- a/components/translate/ios/browser/translate_java_script_feature.mm +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "components/translate/ios/browser/translate_java_script_feature.h" - -#import "components/translate/ios/browser/translate_controller.h" -#import "ios/web/public/js_messaging/script_message.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { -constexpr char kScriptMessageName[] = "TranslateMessage"; -} // namespace - -namespace translate { - -// static -TranslateJavaScriptFeature* TranslateJavaScriptFeature::GetInstance() { - static base::NoDestructor<TranslateJavaScriptFeature> instance; - return instance.get(); -} - -TranslateJavaScriptFeature::TranslateJavaScriptFeature() - : web::JavaScriptFeature( - ContentWorld::kPageContentWorld, - {/* The `translate_ios` script is injected on demand */ - /* by JSTranslateWebFrameManager. */}) {} - -TranslateJavaScriptFeature::~TranslateJavaScriptFeature() = default; - -absl::optional<std::string> -TranslateJavaScriptFeature::GetScriptMessageHandlerName() const { - return kScriptMessageName; -} - -void TranslateJavaScriptFeature::ScriptMessageReceived( - web::WebState* web_state, - const web::ScriptMessage& message) { - if (!message.is_main_frame() || !message.body() || - !message.body()->is_dict()) { - return; - } - - TranslateController* translate_controller = - TranslateController::FromWebState(web_state); - translate_controller->OnJavascriptCommandReceived(message.body()->GetDict()); -} - -} // namespace translate
diff --git a/components/ukm/observers/ukm_consent_state_observer_unittest.cc b/components/ukm/observers/ukm_consent_state_observer_unittest.cc index ad2cddfa..0bcbe8b 100644 --- a/components/ukm/observers/ukm_consent_state_observer_unittest.cc +++ b/components/ukm/observers/ukm_consent_state_observer_unittest.cc
@@ -51,11 +51,6 @@ NotifyObserversOfStateChanged(); } - void SetAuthError(GoogleServiceAuthError::State error_state) { - syncer::TestSyncService::SetAuthError(GoogleServiceAuthError(error_state)); - NotifyObserversOfStateChanged(); - } - void Shutdown() override { for (auto& observer : observers_) { observer.OnSyncShutdown(this);
diff --git a/components/viz/service/display/dc_layer_overlay.h b/components/viz/service/display/dc_layer_overlay.h index 95210035..4985575 100644 --- a/components/viz/service/display/dc_layer_overlay.h +++ b/components/viz/service/display/dc_layer_overlay.h
@@ -71,7 +71,7 @@ gfx::HDRMetadata hdr_metadata; - bool is_video_fullscreen_letterboxing; + bool is_video_fullscreen_letterboxing = false; }; typedef std::vector<DCLayerOverlay> DCLayerOverlayList;
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc index 7450926..6c18485 100644 --- a/content/browser/devtools/protocol/page_handler.cc +++ b/content/browser/devtools/protocol/page_handler.cc
@@ -1521,6 +1521,8 @@ return Page::PrerenderFinalStatusEnum::InactivePageRestriction; case PrerenderHost::FinalStatus::kStartFailed: return Page::PrerenderFinalStatusEnum::StartFailed; + case PrerenderHost::FinalStatus::kTimeoutBackgrounded: + return Page::PrerenderFinalStatusEnum::TimeoutBackgrounded; } }
diff --git a/content/browser/preloading/prerender/prerender_host.cc b/content/browser/preloading/prerender/prerender_host.cc index e6ab794..af7fee2 100644 --- a/content/browser/preloading/prerender/prerender_host.cc +++ b/content/browser/preloading/prerender/prerender_host.cc
@@ -277,10 +277,30 @@ void PrerenderHost::OnVisibilityChanged(Visibility visibility) { TRACE_EVENT("navigation", "PrerenderHost::OnVisibilityChanged"); - // Keep prerenderings alive in the background when their visibility state - // changes to HIDDEN if the feature is enabled. - if (base::FeatureList::IsEnabled(blink::features::kPrerender2InBackground)) + if (base::FeatureList::IsEnabled(blink::features::kPrerender2InBackground)) { + switch (visibility) { + case Visibility::HIDDEN: + // Keep a prerendered page alive in the background when its visibility + // state changes to HIDDEN if the feature is enabled. + DCHECK(!timeout_timer_.IsRunning()); + + timeout_timer_.SetTaskRunner(GetTimerTaskRunner()); + // Cancel PrerenderHost in the background when it exceeds a certain + // amount of time defined in `kTimeToLiveInBackground`. + timeout_timer_.Start( + FROM_HERE, kTimeToLiveInBackground, + base::BindOnce(&PrerenderHost::Cancel, base::Unretained(this), + FinalStatus::kTimeoutBackgrounded)); + break; + case Visibility::OCCLUDED: + break; + case Visibility::VISIBLE: + // Stop the timer when a prerendered page gets visible to users. + timeout_timer_.Stop(); + break; + } return; + } if (visibility == Visibility::HIDDEN) { Cancel(FinalStatus::kTriggerBackgrounded); @@ -753,6 +773,7 @@ case FinalStatus::kActivatedBeforeStarted: case FinalStatus::kInactivePageRestriction: case FinalStatus::kStartFailed: + case FinalStatus::kTimeoutBackgrounded: attempt_->SetFailureReason(ToPreloadingFailureReason(status)); // We reset the attempt to ensure we don't update once we have reported it // as failure or accidentally use it for any other prerender attempts as @@ -804,4 +825,15 @@ registry->CancelHost(frame_tree_node_id_, status); } +scoped_refptr<base::SingleThreadTaskRunner> +PrerenderHost::GetTimerTaskRunner() { + return timer_task_runner_for_testing_ ? timer_task_runner_for_testing_ + : base::ThreadTaskRunnerHandle::Get(); +} + +void PrerenderHost::SetTaskRunnerForTesting( + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + timer_task_runner_for_testing_ = std::move(task_runner); +} + } // namespace content
diff --git a/content/browser/preloading/prerender/prerender_host.h b/content/browser/preloading/prerender/prerender_host.h index 37b5548c..581396f 100644 --- a/content/browser/preloading/prerender/prerender_host.h +++ b/content/browser/preloading/prerender/prerender_host.h
@@ -56,6 +56,12 @@ // is owned by PrerenderHostRegistry. class CONTENT_EXPORT PrerenderHost : public WebContentsObserver { public: + // The time to allow prerendering kept alive in the background. PrerenderHost + // will be terminated with kTimeoutBackgrounded when the timer exceeds this. + // The value was determined to align with the default value of BFCache's + // eviction timer. + static constexpr base::TimeDelta kTimeToLiveInBackground = base::Seconds(180); + // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. enum class FinalStatus { @@ -108,7 +114,8 @@ kActivatedBeforeStarted = 40, kInactivePageRestriction = 41, kStartFailed = 42, - kMaxValue = kStartFailed, + kTimeoutBackgrounded = 43, + kMaxValue = kTimeoutBackgrounded, }; // These values are persisted to logs. Entries should not be renumbered and @@ -244,6 +251,11 @@ const url::Origin& origin, blink::EnabledClientHints* client_hints) const; + // Only used for tests. + base::OneShotTimer* GetTimerForTesting() { return &timeout_timer_; } + void SetTaskRunnerForTesting( + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + // Returns absl::nullopt iff prerendering is initiated by the browser (not by // a renderer using Speculation Rules API). absl::optional<url::Origin> initiator_origin() const { @@ -304,6 +316,8 @@ AreCommonNavigationParamsCompatibleWithNavigation( const blink::mojom::CommonNavigationParams& potential_activation); + scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner(); + const PrerenderAttributes attributes_; // Indicates if `page_holder_` is ready for activation. @@ -336,6 +350,12 @@ base::flat_map<url::Origin, std::vector<network::mojom::WebClientHintsType>> client_hints_type_; + // Starts running the timer when prerendering gets hidden. + base::OneShotTimer timeout_timer_; + // Only used for tests. This task runner is used for precise injection in + // tests and for timing control. + scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner_for_testing_; + // Holds the navigation ID for the main frame initial navigation. absl::optional<int64_t> initial_navigation_id_; };
diff --git a/content/browser/preloading/prerender/prerender_host_unittest.cc b/content/browser/preloading/prerender/prerender_host_unittest.cc index f926ce88..e44178fc 100644 --- a/content/browser/preloading/prerender/prerender_host_unittest.cc +++ b/content/browser/preloading/prerender/prerender_host_unittest.cc
@@ -7,6 +7,7 @@ #include "base/functional/bind.h" #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" +#include "base/test/test_mock_time_task_runner.h" #include "build/build_config.h" #include "components/ukm/test_ukm_recorder.h" #include "content/browser/preloading/preloading.h" @@ -415,7 +416,7 @@ ASSERT_NE(prerender_host, nullptr); CommitPrerenderNavigation(*prerender_host); - // Changing the visibility state to VISIBLE will not affect prerendering. + // Changing the visibility state to VISIBLE will not stop prerendering. web_contents->WasShown(); web_contents->ActivatePrerenderedPage(kPrerenderingUrl); ExpectFinalStatus(PrerenderHost::FinalStatus::kActivated); @@ -437,7 +438,7 @@ ASSERT_NE(prerender_host, nullptr); CommitPrerenderNavigation(*prerender_host); - // Changing the visibility state to OCCLUDED will not affect prerendering. + // Changing the visibility state to OCCLUDED will not stop prerendering. web_contents->WasOccluded(); web_contents->ActivatePrerenderedPage(kPrerenderingUrl); ExpectFinalStatus(PrerenderHost::FinalStatus::kActivated); @@ -567,11 +568,74 @@ ASSERT_NE(prerender_host, nullptr); CommitPrerenderNavigation(*prerender_host); - // Changing the visibility state to HIDDEN will not affect prerendering. + // Changing the visibility state to HIDDEN will not stop prerendering. web_contents->WasHidden(); web_contents->ActivatePrerenderedPage(kPrerenderingUrl); ExpectFinalStatus(PrerenderHost::FinalStatus::kActivated); } +TEST_F(PrerenderHostInBackgroundTest, CancelPrerenderWhenTimeout) { + std::unique_ptr<TestWebContents> web_contents = + CreateWebContents(GURL("https://example.com/")); + const GURL kPrerenderingUrl = GURL("https://example.com/empty.html"); + RenderFrameHostImpl* initiator_rfh = web_contents->GetPrimaryMainFrame(); + PrerenderHostRegistry* registry = web_contents->GetPrerenderHostRegistry(); + const int prerender_frame_tree_node_id = registry->CreateAndStartHost( + GeneratePrerenderAttributes(kPrerenderingUrl, initiator_rfh), + *web_contents); + PrerenderHost* prerender_host = + registry->FindNonReservedHostById(prerender_frame_tree_node_id); + ASSERT_NE(prerender_host, nullptr); + CommitPrerenderNavigation(*prerender_host); + + // The timer should not start yet when the prerendered page is in the + // foreground. + ASSERT_FALSE(prerender_host->GetTimerForTesting()->IsRunning()); + + // Inject mock time task runner. + scoped_refptr<base::TestMockTimeTaskRunner> task_runner = + base::MakeRefCounted<base::TestMockTimeTaskRunner>(); + prerender_host->SetTaskRunnerForTesting(task_runner); + + // Changing the visibility state to HIDDEN will not stop prerendering. + web_contents->WasHidden(); + ASSERT_TRUE(prerender_host->GetTimerForTesting()->IsRunning()); + + task_runner->FastForwardBy(PrerenderHost::kTimeToLiveInBackground); + + ExpectFinalStatus(PrerenderHost::FinalStatus::kTimeoutBackgrounded); +} + +TEST_F(PrerenderHostInBackgroundTest, + TimerResetWhenHiddenPageGoBackToForeground) { + std::unique_ptr<TestWebContents> web_contents = + CreateWebContents(GURL("https://example.com/")); + const GURL kPrerenderingUrl = GURL("https://example.com/empty.html"); + RenderFrameHostImpl* initiator_rfh = web_contents->GetPrimaryMainFrame(); + PrerenderHostRegistry* registry = web_contents->GetPrerenderHostRegistry(); + const int prerender_frame_tree_node_id = registry->CreateAndStartHost( + GeneratePrerenderAttributes(kPrerenderingUrl, initiator_rfh), + *web_contents); + PrerenderHost* prerender_host = + registry->FindNonReservedHostById(prerender_frame_tree_node_id); + ASSERT_NE(prerender_host, nullptr); + CommitPrerenderNavigation(*prerender_host); + + // The timer should not start yet when the prerendered page is in the + // foreground. + ASSERT_FALSE(prerender_host->GetTimerForTesting()->IsRunning()); + + // Changing the visibility state to HIDDEN will not stop prerendering. + web_contents->WasHidden(); + ASSERT_TRUE(prerender_host->GetTimerForTesting()->IsRunning()); + + // The timer should be reset when the hidden page goes back to the foreground. + web_contents->WasShown(); + ASSERT_FALSE(prerender_host->GetTimerForTesting()->IsRunning()); + + web_contents->ActivatePrerenderedPage(kPrerenderingUrl); + ExpectFinalStatus(PrerenderHost::FinalStatus::kActivated); +} + } // namespace } // namespace content
diff --git a/content/browser/preloading/prerender/prerender_internals_handler_impl.cc b/content/browser/preloading/prerender/prerender_internals_handler_impl.cc index 17a8354..6aaf30d9 100644 --- a/content/browser/preloading/prerender/prerender_internals_handler_impl.cc +++ b/content/browser/preloading/prerender/prerender_internals_handler_impl.cc
@@ -88,6 +88,8 @@ return "InactivePageRestriction"; case PrerenderHost::FinalStatus::kStartFailed: return "StartFailed"; + case PrerenderHost::FinalStatus::kTimeoutBackgrounded: + return "TimeoutBackgrounded"; } NOTREACHED(); return "";
diff --git a/content/web_test/browser/web_test_cookie_manager.cc b/content/web_test/browser/web_test_cookie_manager.cc index 8b959b2..66f9985 100644 --- a/content/web_test/browser/web_test_cookie_manager.cc +++ b/content/web_test/browser/web_test_cookie_manager.cc
@@ -5,6 +5,7 @@ #include "content/web_test/browser/web_test_cookie_manager.h" #include "content/public/browser/storage_partition.h" +#include "net/cookies/canonical_cookie.h" #include "services/network/public/mojom/cookie_manager.mojom.h" #include "url/gurl.h" @@ -35,4 +36,44 @@ std::move(callback))); } +void WebTestCookieManager::GetAllCookies( + blink::test::mojom::CookieManagerAutomation::GetAllCookiesCallback + callback) { + cookie_manager_->GetCookieList( + url_, net::CookieOptions::MakeAllInclusive(), + net::CookiePartitionKeyCollection(), + base::BindOnce( + [](blink::test::mojom::CookieManagerAutomation::GetAllCookiesCallback + callback, + const net::CookieAccessResultList& cookies, + const net::CookieAccessResultList&) { + std::move(callback).Run(std::move(cookies)); + }, + std::move(callback))); +} + +void WebTestCookieManager::GetNamedCookie( + const std::string& name, + blink::test::mojom::CookieManagerAutomation::GetNamedCookieCallback + callback) { + cookie_manager_->GetCookieList( + url_, net::CookieOptions::MakeAllInclusive(), + net::CookiePartitionKeyCollection(), + base::BindOnce( + [](const std::string& name, + blink::test::mojom::CookieManagerAutomation::GetNamedCookieCallback + callback, + const net::CookieAccessResultList& cookies, + const net::CookieAccessResultList&) { + for (const auto& cookie : cookies) { + if (cookie.cookie.Name() == name) { + std::move(callback).Run(std::move(cookie)); + return; + } + } + std::move(callback).Run(absl::nullopt); + }, + name, std::move(callback))); +} + } // namespace content
diff --git a/content/web_test/browser/web_test_cookie_manager.h b/content/web_test/browser/web_test_cookie_manager.h index 3fcf54c..50c58ce 100644 --- a/content/web_test/browser/web_test_cookie_manager.h +++ b/content/web_test/browser/web_test_cookie_manager.h
@@ -27,6 +27,13 @@ void DeleteAllCookies( blink::test::mojom::CookieManagerAutomation::DeleteAllCookiesCallback) override; + void GetAllCookies( + blink::test::mojom::CookieManagerAutomation::GetAllCookiesCallback) + override; + void GetNamedCookie( + const std::string& name, + blink::test::mojom::CookieManagerAutomation::GetNamedCookieCallback) + override; private: const raw_ptr<network::mojom::CookieManager> cookie_manager_;
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index da261b760..5083ca0c 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1780,6 +1780,7 @@ PASSWORDSPRIVATE_SWITCHBIOMETRICAUTHBEFOREFILLINGSTATE = 1717, WMDESKSPRIVATE_GETACTIVEDESK = 1718, WMDESKSPRIVATE_SWITCHDESK = 1719, + OS_TELEMETRY_GETTPMINFO = 1720, // Last entry: Add new entries above, then run: // tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/fuchsia_web/runners/cast/cast_runner.cc b/fuchsia_web/runners/cast/cast_runner.cc index c9d8ee5..45fea1f 100644 --- a/fuchsia_web/runners/cast/cast_runner.cc +++ b/fuchsia_web/runners/cast/cast_runner.cc
@@ -97,9 +97,6 @@ // Application URL for the pseudo-component providing fuchsia.web.FrameHost. constexpr char kFrameHostComponentName[] = "cast:fuchsia.web.FrameHost"; -// Application URL for the pseudo-component providing chromium.cast.DataReset. -constexpr char kDataResetComponentName[] = "cast:chromium.cast.DataReset"; - // Subdirectory used to stage persistent directories to be deleted upon next // startup. const char kStagedForDeletionSubdirectory[] = "staged_for_deletion"; @@ -264,46 +261,6 @@ base::WeakPtrFactory<const sys::ServiceDirectory> weak_incoming_services_; }; -// TODO(crbug.com/1120914): Remove this once Component Framework v2 can be -// used to route chromium.cast.DataReset capabilities cleanly. -class DataResetComponent final : public fuchsia::sys::ComponentController { - public: - // Creates a DataResetComponent with lifetime managed by |controller_request|. - static void Start(chromium::cast::DataReset* data_reset_impl, - std::unique_ptr<base::StartupContext> startup_context, - fidl::InterfaceRequest<fuchsia::sys::ComponentController> - controller_request) { - new DataResetComponent(data_reset_impl, std::move(startup_context), - std::move(controller_request)); - } - - private: - DataResetComponent(chromium::cast::DataReset* data_reset_impl, - std::unique_ptr<base::StartupContext> startup_context, - fidl::InterfaceRequest<fuchsia::sys::ComponentController> - controller_request) - : startup_context_(std::move(startup_context)), - data_reset_handler_binding_(startup_context_->outgoing(), - data_reset_impl) { - startup_context_->ServeOutgoingDirectory(); - controller_binding_.Bind(std::move(controller_request)); - controller_binding_.set_error_handler([this](zx_status_t) { Kill(); }); - } - ~DataResetComponent() override = default; - - // fuchsia::sys::ComponentController interface. - void Kill() override { delete this; } - void Detach() override { - controller_binding_.Close(ZX_ERR_NOT_SUPPORTED); - delete this; - } - - std::unique_ptr<base::StartupContext> startup_context_; - const base::ScopedServiceBinding<chromium::cast::DataReset> - data_reset_handler_binding_; - fidl::Binding<fuchsia::sys::ComponentController> controller_binding_{this}; -}; - } // namespace CastRunner::CastRunner(WebInstanceHost* web_instance_host, bool is_headless) @@ -757,18 +714,6 @@ return; } - // TODO(crbug.com/1120914): Remove this once Component Framework v2 can be - // used to route chromium.cast.DataReset capabilities cleanly. - if (url.spec() == kDataResetComponentName) { - // DataResetComponents are self-owned, so may outlive |this|. However, - // |this| is only touched when processing DataReset protocol requests. - // Since |this| is only deleted during component shutdown, no protocol - // requests will be processed after deletion. - DataResetComponent::Start(this, std::move(startup_context), - std::move(controller_request)); - return; - } - pending_components_.emplace(std::make_unique<PendingCastComponent>( this, std::move(startup_context), std::move(controller_request), url.GetContent()));
diff --git a/fuchsia_web/runners/cast/cast_runner_integration_test.cc b/fuchsia_web/runners/cast/cast_runner_integration_test.cc index 46cae8a..166f8bcb 100644 --- a/fuchsia_web/runners/cast/cast_runner_integration_test.cc +++ b/fuchsia_web/runners/cast/cast_runner_integration_test.cc
@@ -1192,30 +1192,6 @@ component.ExpectControllerDisconnectWithStatus(ZX_ERR_PEER_CLOSED); } -// Verifies that CastRunner offers a chromium.cast.DataReset component, that -// provides the DataReset service. -TEST_F(CastRunnerIntegrationTest, DataReset_component) { - TestCastComponent component(cast_runner()); - constexpr char kDataResetComponentName[] = "cast:chromium.cast.DataReset"; - component.StartCastComponent(kDataResetComponentName); - - base::RunLoop loop; - auto data_reset = component.component_services_client() - ->Connect<chromium::cast::DataReset>(); - data_reset.set_error_handler([quit_loop = loop.QuitClosure()](zx_status_t) { - quit_loop.Run(); - ADD_FAILURE(); - }); - bool succeeded = false; - data_reset->DeletePersistentData([&succeeded, &loop](bool result) { - succeeded = result; - loop.Quit(); - }); - loop.Run(); - - EXPECT_TRUE(succeeded); -} - class CastRunnerFrameHostIntegrationTest : public CastRunnerIntegrationTest { public: CastRunnerFrameHostIntegrationTest()
diff --git a/gpu/command_buffer/service/memory_tracking.h b/gpu/command_buffer/service/memory_tracking.h index 86a6cc90..92d874f 100644 --- a/gpu/command_buffer/service/memory_tracking.h +++ b/gpu/command_buffer/service/memory_tracking.h
@@ -75,6 +75,8 @@ ~MemoryTypeTracker(); + const MemoryTracker* memory_tracker() const { return memory_tracker_; } + void TrackMemAlloc(size_t bytes); void TrackMemFree(size_t bytes); size_t GetMemRepresented() const;
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc index 7511eec..1b40d0a 100644 --- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc +++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
@@ -28,11 +28,6 @@ namespace gpu { namespace { -size_t EstimatedSize(viz::ResourceFormat format, const gfx::Size& size) { - size_t estimated_size = 0; - viz::ResourceSizes::MaybeSizeInBytes(size, format, &estimated_size); - return estimated_size; -} using ScopedRestoreTexture = GLTextureImageBackingHelper::ScopedRestoreTexture; @@ -134,15 +129,16 @@ GrSurfaceOrigin surface_origin, SkAlphaType alpha_type, uint32_t usage) - : ClearTrackingSharedImageBacking(mailbox, - format, - size, - color_space, - surface_origin, - alpha_type, - usage, - EstimatedSize(format, size), - false /* is_thread_safe */), + : ClearTrackingSharedImageBacking( + mailbox, + format, + size, + color_space, + surface_origin, + alpha_type, + usage, + viz::ResourceSizes::UncheckedSizeInBytes<size_t>(size, format), + false /* is_thread_safe */), context_state_(context_state) {} AngleVulkanImageBacking::~AngleVulkanImageBacking() {
diff --git a/gpu/command_buffer/service/shared_image/gl_image_backing.cc b/gpu/command_buffer/service/shared_image/gl_image_backing.cc index 3645edc0..90687d0 100644 --- a/gpu/command_buffer/service/shared_image/gl_image_backing.cc +++ b/gpu/command_buffer/service/shared_image/gl_image_backing.cc
@@ -30,12 +30,6 @@ namespace { -size_t EstimatedSize(viz::ResourceFormat format, const gfx::Size& size) { - size_t estimated_size = 0; - viz::ResourceSizes::MaybeSizeInBytes(size, format, &estimated_size); - return estimated_size; -} - using ScopedRestoreTexture = GLTextureImageBackingHelper::ScopedRestoreTexture; using InitializeGLTextureParams = @@ -336,15 +330,16 @@ uint32_t usage, const InitializeGLTextureParams& params, bool is_passthrough) - : SharedImageBacking(mailbox, - format, - size, - color_space, - surface_origin, - alpha_type, - usage, - EstimatedSize(format, size), - false /* is_thread_safe */), + : SharedImageBacking( + mailbox, + format, + size, + color_space, + surface_origin, + alpha_type, + usage, + viz::ResourceSizes::UncheckedSizeInBytes<size_t>(size, format), + false /* is_thread_safe */), image_(image), gl_params_(params), is_passthrough_(is_passthrough), @@ -382,7 +377,8 @@ // Set the GLImage to be initially unbound from the GL texture. image_bind_or_copy_needed_ = true; if (is_passthrough_) { - passthrough_texture_->SetEstimatedSize(EstimatedSize(format(), size())); + passthrough_texture_->SetEstimatedSize( + viz::ResourceSizes::UncheckedSizeInBytes<size_t>(size(), format())); passthrough_texture_->SetLevelImage(gl_params_.target, 0, image_.get()); passthrough_texture_->set_is_bind_pending(true); } else {
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_image_backing.cc b/gpu/command_buffer/service/shared_image/gl_texture_image_backing.cc index 2dd9e79..bacf5a2e 100644 --- a/gpu/command_buffer/service/shared_image/gl_texture_image_backing.cc +++ b/gpu/command_buffer/service/shared_image/gl_texture_image_backing.cc
@@ -69,12 +69,6 @@ using InitializeGLTextureParams = GLTextureImageBackingHelper::InitializeGLTextureParams; -size_t EstimatedSize(viz::ResourceFormat format, const gfx::Size& size) { - size_t estimated_size = 0; - viz::ResourceSizes::MaybeSizeInBytes(size, format, &estimated_size); - return estimated_size; -} - int BytesPerPixel(viz::ResourceFormat format) { int bits = viz::BitsPerPixel(format); DCHECK_GE(bits, 8); @@ -133,15 +127,16 @@ SkAlphaType alpha_type, uint32_t usage, bool is_passthrough) - : ClearTrackingSharedImageBacking(mailbox, - format, - size, - color_space, - surface_origin, - alpha_type, - usage, - EstimatedSize(format, size), - false /* is_thread_safe */), + : ClearTrackingSharedImageBacking( + mailbox, + format, + size, + color_space, + surface_origin, + alpha_type, + usage, + viz::ResourceSizes::UncheckedSizeInBytes<size_t>(size, format), + false /* is_thread_safe */), is_passthrough_(is_passthrough) {} GLTextureImageBacking::~GLTextureImageBacking() { @@ -335,7 +330,8 @@ IsPassthrough() ? nullptr : &texture_); texture_params_ = params; if (IsPassthrough()) { - passthrough_texture_->SetEstimatedSize(EstimatedSize(format(), size())); + passthrough_texture_->SetEstimatedSize( + viz::ResourceSizes::UncheckedSizeInBytes<size_t>(size(), format())); SetClearedRect(params.is_cleared ? gfx::Rect(size()) : gfx::Rect()); } else { texture_->SetLevelInfo(params.target, 0, params.internal_format,
diff --git a/gpu/command_buffer/service/shared_image/raw_draw_image_backing.cc b/gpu/command_buffer/service/shared_image/raw_draw_image_backing.cc index 337e75c..e985fa2e 100644 --- a/gpu/command_buffer/service/shared_image/raw_draw_image_backing.cc +++ b/gpu/command_buffer/service/shared_image/raw_draw_image_backing.cc
@@ -19,15 +19,6 @@ #include "ui/gl/trace_util.h" namespace gpu { -namespace { - -size_t EstimatedSize(viz::ResourceFormat format, const gfx::Size& size) { - size_t estimated_size = 0; - viz::ResourceSizes::MaybeSizeInBytes(size, format, &estimated_size); - return estimated_size; -} - -} // namespace class RawDrawImageBacking::RasterRawDrawImageRepresentation : public RasterImageRepresentation { @@ -158,7 +149,10 @@ size_t RawDrawImageBacking::EstimatedSizeForMemTracking() const { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); AutoLock auto_lock(this); - return backend_texture_.isValid() ? EstimatedSize(format(), size()) : 0u; + return backend_texture_.isValid() + ? viz::ResourceSizes::UncheckedSizeInBytes<size_t>(size(), + format()) + : 0u; } std::unique_ptr<RasterImageRepresentation> RawDrawImageBacking::ProduceRaster(
diff --git a/gpu/command_buffer/service/shared_image/shared_image_backing.cc b/gpu/command_buffer/service/shared_image/shared_image_backing.cc index 93652e2..5f7d2ad 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_backing.cc +++ b/gpu/command_buffer/service/shared_image/shared_image_backing.cc
@@ -239,6 +239,14 @@ } } +const MemoryTracker* SharedImageBacking::GetMemoryTracker() const { + AutoLock auto_lock(this); + if (refs_.empty()) + return nullptr; + + return refs_[0]->tracker()->memory_tracker(); +} + void SharedImageBacking::RegisterImageFactory(SharedImageFactory* factory) { DCHECK_CALLED_ON_VALID_THREAD(factory_thread_checker_); DCHECK(!factory_);
diff --git a/gpu/command_buffer/service/shared_image/shared_image_backing.h b/gpu/command_buffer/service/shared_image/shared_image_backing.h index 784a660..14bdbab 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_backing.h +++ b/gpu/command_buffer/service/shared_image/shared_image_backing.h
@@ -51,6 +51,7 @@ class MemoryImageRepresentation; class VaapiImageRepresentation; class RasterImageRepresentation; +class MemoryTracker; class MemoryTypeTracker; class SharedImageFactory; class VaapiDependenciesFactory; @@ -115,6 +116,9 @@ void ReleaseRef(SharedImageRepresentation* representation); bool HasAnyRefs() const; + // Returns the memory tracker this backing is registering memory with. + const MemoryTracker* GetMemoryTracker() const; + // Notify backing a read access is succeeded void OnReadSucceeded(); // Notify backing a write access is succeeded.
diff --git a/gpu/command_buffer/service/shared_image/shared_image_factory.cc b/gpu/command_buffer/service/shared_image/shared_image_factory.cc index e315de9..d0f4b96 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_factory.cc +++ b/gpu/command_buffer/service/shared_image/shared_image_factory.cc
@@ -509,20 +509,6 @@ } #endif // BUILDFLAG(IS_FUCHSIA) -// TODO(ericrk): Move this entirely to SharedImageManager. -bool SharedImageFactory::OnMemoryDump( - const base::trace_event::MemoryDumpArgs& args, - base::trace_event::ProcessMemoryDump* pmd, - const std::string& dump_base_name, - uint64_t client_tracing_id) { - for (const auto& shared_image : shared_images_) { - shared_image_manager_->OnMemoryDump(shared_image->mailbox(), pmd, - dump_base_name, client_tracing_id); - } - - return true; -} - #if BUILDFLAG(IS_WIN) bool SharedImageFactory::CopyToGpuMemoryBuffer(const Mailbox& mailbox) { auto it = shared_images_.find(mailbox);
diff --git a/gpu/command_buffer/service/shared_image/shared_image_factory.h b/gpu/command_buffer/service/shared_image/shared_image_factory.h index 73d0df0..830a4faa 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_factory.h +++ b/gpu/command_buffer/service/shared_image/shared_image_factory.h
@@ -112,10 +112,6 @@ bool ReleaseSysmemBufferCollection(gfx::SysmemBufferCollectionId id); #endif // BUILDFLAG(IS_FUCHSIA) - bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, - base::trace_event::ProcessMemoryDump* pmd, - const std::string& dump_base_name, - uint64_t client_tracing_id); bool RegisterBacking(std::unique_ptr<SharedImageBacking> backing); SharedContextState* GetSharedContextState() const {
diff --git a/gpu/command_buffer/service/shared_image/shared_image_manager.cc b/gpu/command_buffer/service/shared_image/shared_image_manager.cc index b333146c..63c05ca 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_manager.cc +++ b/gpu/command_buffer/service/shared_image/shared_image_manager.cc
@@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/process_memory_dump.h" #include "base/trace_event/trace_event.h" @@ -84,6 +85,13 @@ } #endif CALLED_ON_VALID_THREAD(); + + // In tests there might not be a SingleThreadTaskRunner for this thread. + if (base::ThreadTaskRunnerHandle::IsSet()) { + is_registered_as_memory_dump_provider_ = true; + base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( + this, "SharedImageManager", base::ThreadTaskRunnerHandle::Get()); + } } SharedImageManager::~SharedImageManager() { @@ -92,6 +100,11 @@ AutoLock auto_lock(this); #endif DCHECK(images_.empty()); + + if (is_registered_as_memory_dump_provider_) { + base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( + this); + } } std::unique_ptr<SharedImageRepresentationFactoryRef> @@ -371,36 +384,52 @@ } } -void SharedImageManager::OnMemoryDump(const Mailbox& mailbox, - base::trace_event::ProcessMemoryDump* pmd, - const std::string& dump_base_name, - uint64_t client_tracing_id) { +bool SharedImageManager::OnMemoryDump( + const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) { CALLED_ON_VALID_THREAD(); - AutoLock autolock(this); - auto found = images_.find(mailbox); - if (found == images_.end()) { - LOG(ERROR) << "SharedImageManager::OnMemoryDump: Trying to dump memory for " - "a non existent mailbox."; - return; + + const char* base_dump_name = "gpu/shared_images"; + + if (args.level_of_detail == + base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND) { + size_t total_size = 0; + for (auto& backing : images_) + total_size += backing->EstimatedSizeForMemTracking(); + + base::trace_event::MemoryAllocatorDump* dump = + pmd->CreateAllocatorDump(base_dump_name); + dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + total_size); + + // Early out, no need for more detail in a BACKGROUND dump. + return true; } - auto* backing = found->get(); - size_t estimated_size = backing->EstimatedSizeForMemTracking(); - if (estimated_size == 0) - return; + for (auto& backing : images_) { + auto* memory_tracker = backing->GetMemoryTracker(); - // Unique name in the process. - std::string dump_name = base::StringPrintf( - "%s/mailbox_%s", dump_base_name.c_str(), mailbox.ToDebugString().c_str()); + // All the backings registered here should have a memory tracker. + DCHECK(memory_tracker); - // GUID which expresses shared ownership with the client process. This must - // match the client-side GUID for mailbox. - auto client_guid = GetSharedImageGUIDForTracing(backing->mailbox()); + // Unique name in the process. + std::string dump_name = base::StringPrintf( + "%s/client_0x%" PRIX32 "/mailbox_%s", base_dump_name, + memory_tracker->ClientId(), backing->mailbox().ToDebugString().c_str()); - // Backing will produce dump with relevant information along with ownership - // edge to `client_guid`. - backing->OnMemoryDump(dump_name, client_guid, pmd, client_tracing_id); + // GUID which expresses shared ownership with the client process. This must + // match the client-side GUID for mailbox. + auto client_guid = GetSharedImageGUIDForTracing(backing->mailbox()); + + // Backing will produce dump with relevant information along with ownership + // edge to `client_guid`. + backing->OnMemoryDump(dump_name, client_guid, pmd, + memory_tracker->ClientTracingId()); + } + + return true; } scoped_refptr<gfx::NativePixmap> SharedImageManager::GetNativePixmap(
diff --git a/gpu/command_buffer/service/shared_image/shared_image_manager.h b/gpu/command_buffer/service/shared_image/shared_image_manager.h index 97d8367..7869fba 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_manager.h +++ b/gpu/command_buffer/service/shared_image/shared_image_manager.h
@@ -9,6 +9,7 @@ #include "base/memory/scoped_refptr.h" #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" +#include "base/trace_event/memory_dump_provider.h" #include "build/build_config.h" #include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/service/shared_image/shared_image_backing.h" @@ -20,7 +21,8 @@ class SharedImageRepresentationFactoryRef; class VaapiDependenciesFactory; -class GPU_GLES2_EXPORT SharedImageManager { +class GPU_GLES2_EXPORT SharedImageManager + : public base::trace_event::MemoryDumpProvider { public: // If |thread_safe| is set, the manager itself can be safely accessed from // other threads but the backings themselves may not be thread-safe so @@ -35,7 +37,11 @@ SharedImageManager(const SharedImageManager&) = delete; SharedImageManager& operator=(const SharedImageManager&) = delete; - ~SharedImageManager(); + ~SharedImageManager() override; + + // base::trace_event::MemoryDumpProvider implementation: + bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) override; // Registers a SharedImageBacking with the manager and returns a // SharedImageRepresentationFactoryRef which holds a ref on the SharedImage. @@ -95,12 +101,6 @@ void OnRepresentationDestroyed(const Mailbox& mailbox, SharedImageRepresentation* representation); - // Dump memory for the given mailbox. - void OnMemoryDump(const Mailbox& mailbox, - base::trace_event::ProcessMemoryDump* pmd, - const std::string& dump_base_name, - uint64_t client_tracing_id); - bool is_thread_safe() const { return !!lock_; } bool display_context_on_another_thread() const { @@ -130,6 +130,8 @@ const bool display_context_on_another_thread_; + bool is_registered_as_memory_dump_provider_ = false; + #if BUILDFLAG(IS_WIN) scoped_refptr<DXGISharedHandleManager> dxgi_shared_handle_manager_; #endif
diff --git a/gpu/command_buffer/service/shared_image/shared_image_manager_unittest.cc b/gpu/command_buffer/service/shared_image/shared_image_manager_unittest.cc index 49e3017..a5dca8eb 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_manager_unittest.cc +++ b/gpu/command_buffer/service/shared_image/shared_image_manager_unittest.cc
@@ -7,30 +7,33 @@ #include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "base/task/thread_pool/thread_pool_instance.h" -#include "gpu/command_buffer/common/gpu_memory_buffer_support.h" +#include "base/trace_event/process_memory_dump.h" #include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/common/shared_image_usage.h" -#include "gpu/command_buffer/service/mailbox_manager_impl.h" -#include "gpu/command_buffer/service/service_utils.h" #include "gpu/command_buffer/service/shared_image/shared_image_backing.h" #include "gpu/command_buffer/service/shared_image/shared_image_representation.h" #include "gpu/command_buffer/service/shared_image/test_image_backing.h" -#include "gpu/command_buffer/service/texture_manager.h" -#include "gpu/command_buffer/tests/texture_image_factory.h" -#include "gpu/config/gpu_driver_bug_workarounds.h" -#include "gpu/config/gpu_feature_info.h" -#include "gpu/config/gpu_preferences.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/color_space.h" -#include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_context.h" -#include "ui/gl/gl_surface.h" -#include "ui/gl/init/gl_factory.h" namespace gpu { namespace { +std::unique_ptr<TestImageBacking> CreateImageBacking(size_t size_in_bytes) { + auto mailbox = Mailbox::GenerateForSharedImage(); + auto format = viz::ResourceFormat::RGBA_8888; + gfx::Size size(256, 256); + auto color_space = gfx::ColorSpace::CreateSRGB(); + auto surface_origin = kTopLeft_GrSurfaceOrigin; + auto alpha_type = kPremul_SkAlphaType; + uint32_t usage = SHARED_IMAGE_USAGE_GLES2; + + return std::make_unique<TestImageBacking>(mailbox, format, size, color_space, + surface_origin, alpha_type, usage, + size_in_bytes); +} + TEST(SharedImageManagerTest, BasicRefCounting) { const size_t kSizeBytes = 1024; SharedImageManager manager; @@ -71,6 +74,38 @@ EXPECT_EQ(0u, tracker->GetMemRepresented()); } +TEST(SharedImageManagerTest, MemoryDumps) { + constexpr size_t kSizeBytes1 = 1000; + constexpr size_t kSizeBytes2 = 2000; + + SharedImageManager manager; + auto tracker = std::make_unique<MemoryTypeTracker>(nullptr); + + auto factory_ref1 = + manager.Register(CreateImageBacking(kSizeBytes1), tracker.get()); + auto factory_ref2 = + manager.Register(CreateImageBacking(kSizeBytes2), tracker.get()); + + base::trace_event::MemoryDumpArgs args = { + base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND}; + base::trace_event::ProcessMemoryDump pmd(args); + + manager.OnMemoryDump(args, &pmd); + + auto* dump = pmd.GetAllocatorDump("gpu/shared_images"); + ASSERT_NE(nullptr, dump); + ASSERT_EQ(dump->entries().size(), 1u); + + // There should be a single memory dump entry with total size of both + // backings. + auto& entry = dump->entries()[0]; + DCHECK_EQ(entry.name, base::trace_event::MemoryAllocatorDump::kNameSize); + DCHECK_EQ(entry.units, base::trace_event::MemoryAllocatorDump::kUnitsBytes); + DCHECK_EQ(entry.entry_type, + base::trace_event::MemoryAllocatorDump::Entry::kUint64); + DCHECK_EQ(entry.value_uint64, kSizeBytes1 + kSizeBytes2); +} + TEST(SharedImageManagerTest, TransferRefSameTracker) { const size_t kSizeBytes = 1024; SharedImageManager manager;
diff --git a/gpu/command_buffer/service/shared_image/shared_memory_image_backing.cc b/gpu/command_buffer/service/shared_image/shared_memory_image_backing.cc index 62f537b..2929a543 100644 --- a/gpu/command_buffer/service/shared_image/shared_memory_image_backing.cc +++ b/gpu/command_buffer/service/shared_image/shared_memory_image_backing.cc
@@ -30,12 +30,6 @@ namespace gpu { namespace { -size_t EstimatedSize(viz::ResourceFormat format, const gfx::Size& size) { - size_t estimated_size = 0; - viz::ResourceSizes::MaybeSizeInBytes(size, format, &estimated_size); - return estimated_size; -} - class MemoryImageRepresentationImpl : public MemoryImageRepresentation { public: MemoryImageRepresentationImpl(SharedImageManager* manager, @@ -199,14 +193,15 @@ SkAlphaType alpha_type, uint32_t usage, SharedMemoryRegionWrapper wrapper) - : SharedImageBacking(mailbox, - format, - size, - color_space, - surface_origin, - alpha_type, - usage, - EstimatedSize(format, size), - false), + : SharedImageBacking( + mailbox, + format, + size, + color_space, + surface_origin, + alpha_type, + usage, + viz::ResourceSizes::UncheckedSizeInBytes<size_t>(size, format), + false), shared_memory_wrapper_(std::move(wrapper)) {} } // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image/test_image_backing.h b/gpu/command_buffer/service/shared_image/test_image_backing.h index 1901b013..cbfde9b 100644 --- a/gpu/command_buffer/service/shared_image/test_image_backing.h +++ b/gpu/command_buffer/service/shared_image/test_image_backing.h
@@ -45,10 +45,6 @@ void Update(std::unique_ptr<gfx::GpuFence> in_fence) override {} bool UploadFromMemory(const SkPixmap& pixmap) override; bool ReadbackToMemory(SkPixmap& pixmap) override; - void OnMemoryDump(const std::string& dump_name, - base::trace_event::MemoryAllocatorDumpGuid client_guid, - base::trace_event::ProcessMemoryDump* pmd, - uint64_t client_tracing_id) override {} // Helper functions GLuint service_id() const { return service_id_; }
diff --git a/gpu/command_buffer/service/shared_image/video_surface_texture_image_backing.cc b/gpu/command_buffer/service/shared_image/video_surface_texture_image_backing.cc index d07aa93b..5d19188 100644 --- a/gpu/command_buffer/service/shared_image/video_surface_texture_image_backing.cc +++ b/gpu/command_buffer/service/shared_image/video_surface_texture_image_backing.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "base/feature_list.h" #include "base/threading/thread_task_runner_handle.h" #include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/resource_sizes.h" @@ -25,6 +26,27 @@ namespace gpu { +namespace { + +// If enabled, then nullptr is passed for the GLImage instance when invoking +// BindStreamTextureImage(). Rolling this change out is the last blocker to +// eliminating StreamTextureSharedImageInterface being a subclass of GLImage. +// TODO(crbug.com/1310020): Remove this flag once the change has rolled out +// safely. +BASE_FEATURE(kPassNullForGLImageWhenBindingTexture, + "kPassNullForGLImageWhenBindingTexture", + base::FEATURE_ENABLED_BY_DEFAULT); + +// Returns either |nullptr| or |sii|. +gl::GLImage* GetGLImageToUseWhenBindingTexture( + StreamTextureSharedImageInterface* sii) { + return (base::FeatureList::IsEnabled(kPassNullForGLImageWhenBindingTexture)) + ? nullptr + : sii; +} + +} // namespace + VideoSurfaceTextureImageBacking::VideoSurfaceTextureImageBacking( const Mailbox& mailbox, const gfx::Size& size, @@ -193,7 +215,7 @@ // texture_id in abstract texture via BindStreamTextureImage(). DCHECK(stream_texture_sii_->TextureOwnerBindsTextureOnUpdate()); texture->BindStreamTextureImage( - stream_texture_sii_.get(), + GetGLImageToUseWhenBindingTexture(stream_texture_sii_.get()), stream_texture_sii_->GetTextureBase()->service_id()); return std::make_unique<GLTextureVideoImageRepresentation>( @@ -222,7 +244,7 @@ // texture_id in abstract texture via BindStreamTextureImage(). DCHECK(stream_texture_sii_->TextureOwnerBindsTextureOnUpdate()); texture->BindStreamTextureImage( - stream_texture_sii_.get(), + GetGLImageToUseWhenBindingTexture(stream_texture_sii_.get()), stream_texture_sii_->GetTextureBase()->service_id()); return std::make_unique<GLTexturePassthroughVideoImageRepresentation>( @@ -263,7 +285,7 @@ // texture_id in abstract texture via BindStreamTextureImage(). DCHECK(stream_texture_sii_->TextureOwnerBindsTextureOnUpdate()); texture->BindStreamTextureImage( - stream_texture_sii_.get(), + GetGLImageToUseWhenBindingTexture(stream_texture_sii_.get()), stream_texture_sii_->GetTextureBase()->service_id()); std::unique_ptr<gpu::GLTextureImageRepresentationBase> gl_representation;
diff --git a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc index 6fcecd9..9feb0cbd 100644 --- a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc +++ b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc
@@ -52,12 +52,6 @@ namespace { -size_t EstimatedSize(viz::ResourceFormat format, const gfx::Size& size) { - size_t estimated_size = 0; - viz::ResourceSizes::MaybeSizeInBytes(size, format, &estimated_size); - return estimated_size; -} - class WrappedSkImage : public ClearTrackingSharedImageBacking { public: WrappedSkImage(base::PassKey<WrappedSkImageBackingFactory>, @@ -442,7 +436,8 @@ // That should be fine for now since we do not have/use any locks in backing. DCHECK(!is_thread_safe || (context_state_->GrContextIsVulkan() && is_drdc_enabled_)); - size_t estimated_size = EstimatedSize(format, size); + size_t estimated_size = + viz::ResourceSizes::UncheckedSizeInBytes<size_t>(size, format); auto texture = std::make_unique<WrappedSkImage>( base::PassKey<WrappedSkImageBackingFactory>(), mailbox, format, size, color_space, surface_origin, alpha_type, usage, estimated_size, @@ -464,7 +459,8 @@ SkAlphaType alpha_type, uint32_t usage, base::span<const uint8_t> data) { - size_t estimated_size = EstimatedSize(format, size); + size_t estimated_size = + viz::ResourceSizes::UncheckedSizeInBytes<size_t>(size, format); auto texture = std::make_unique<WrappedSkImage>( base::PassKey<WrappedSkImageBackingFactory>(), mailbox, format, size, color_space, surface_origin, alpha_type, usage, estimated_size,
diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc index 252aa1cf..94f1a37 100644 --- a/gpu/ipc/service/gpu_channel.cc +++ b/gpu/ipc/service/gpu_channel.cc
@@ -56,7 +56,6 @@ #include "ipc/ipc_channel.h" #include "mojo/public/cpp/bindings/associated_receiver.h" #include "ui/gl/gl_context.h" -#include "ui/gl/gl_image_shared_memory.h" #include "ui/gl/gl_surface.h" #include "ui/gl/gl_utils.h"
diff --git a/gpu/ipc/service/image_decode_accelerator_stub_unittest.cc b/gpu/ipc/service/image_decode_accelerator_stub_unittest.cc index 66588b1..e5e6cee 100644 --- a/gpu/ipc/service/image_decode_accelerator_stub_unittest.cc +++ b/gpu/ipc/service/image_decode_accelerator_stub_unittest.cc
@@ -77,7 +77,6 @@ #include "ui/gfx/geometry/size.h" #include "ui/gfx/gpu_memory_buffer.h" #include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_image_stub.h" #include "url/gurl.h" using testing::InSequence; @@ -226,9 +225,8 @@ pending_decodes_.pop(); if (success) { // We give out a dummy GpuMemoryBufferHandle as the result: since we mock - // the ImageFactory and the gl::GLImage in these tests, the only - // requirement is that the NativePixmapHandle has the right number of - // planes. + // the SharedImage backing in these tests, the only requirement is that + // the NativePixmapHandle has the right number of planes. auto decode_result = std::make_unique<DecodeResult>(); decode_result->handle.type = gfx::GpuMemoryBufferType::NATIVE_PIXMAP; for (size_t plane = 0; plane < gfx::NumberOfPlanesForLinearBufferFormat(
diff --git a/gpu/ipc/service/shared_image_stub.cc b/gpu/ipc/service/shared_image_stub.cc index f7e7a26..7ebc2ba 100644 --- a/gpu/ipc/service/shared_image_stub.cc +++ b/gpu/ipc/service/shared_image_stub.cc
@@ -11,7 +11,6 @@ #include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" -#include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "gpu/command_buffer/service/scheduler.h" @@ -36,10 +35,7 @@ channel->sync_point_manager()->CreateSyncPointClientState( CommandBufferNamespace::GPU_IO, command_buffer_id_, - sequence_)) { - base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( - this, "gpu::SharedImageStub", channel_->task_runner()); -} + sequence_)) {} SharedImageStub::~SharedImageStub() { channel_->scheduler()->DestroySequence(sequence_); @@ -48,8 +44,6 @@ bool have_context = MakeContextCurrent(); factory_->DestroyAllSharedImages(have_context); } - base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( - this); } std::unique_ptr<SharedImageStub> SharedImageStub::Create(GpuChannel* channel, @@ -510,29 +504,6 @@ return sync_point_client_state_->command_buffer_id().GetUnsafeValue(); } -bool SharedImageStub::OnMemoryDump( - const base::trace_event::MemoryDumpArgs& args, - base::trace_event::ProcessMemoryDump* pmd) { - if (!factory_) - return true; - - std::string dump_name = - base::StringPrintf("gpu/shared_images/client_0x%" PRIX32, ClientId()); - - if (args.level_of_detail == - base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND) { - base::trace_event::MemoryAllocatorDump* dump = - pmd->CreateAllocatorDump(dump_name); - dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, - base::trace_event::MemoryAllocatorDump::kUnitsBytes, size_); - - // Early out, no need for more detail in a BACKGROUND dump. - return true; - } - - return factory_->OnMemoryDump(args, pmd, dump_name, ClientTracingId()); -} - SharedImageStub::SharedImageDestructionCallback SharedImageStub::GetSharedImageDestructionCallback(const Mailbox& mailbox) { return base::BindOnce(&SharedImageStub::DestroySharedImage,
diff --git a/gpu/ipc/service/shared_image_stub.h b/gpu/ipc/service/shared_image_stub.h index 393becf..3d6451d 100644 --- a/gpu/ipc/service/shared_image_stub.h +++ b/gpu/ipc/service/shared_image_stub.h
@@ -7,7 +7,6 @@ #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" -#include "base/trace_event/memory_dump_provider.h" #include "build/build_config.h" #include "components/viz/common/resources/resource_format.h" #include "gpu/command_buffer/service/memory_tracking.h" @@ -23,9 +22,7 @@ class GpuChannel; class SharedImageFactory; -class GPU_IPC_SERVICE_EXPORT SharedImageStub - : public MemoryTracker, - public base::trace_event::MemoryDumpProvider { +class GPU_IPC_SERVICE_EXPORT SharedImageStub : public MemoryTracker { public: ~SharedImageStub() override; @@ -45,10 +42,6 @@ int ClientId() const override; uint64_t ContextGroupTracingId() const override; - // base::trace_event::MemoryDumpProvider implementation: - bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, - base::trace_event::ProcessMemoryDump* pmd) override; - SequenceId sequence() const { return sequence_; } SharedImageFactory* factory() const { return factory_.get(); } GpuChannel* channel() const { return channel_; }
diff --git "a/infra/config/generated/builders/ci/Dawn Android arm DEPS Release \050Pixel 4\051/properties.json" "b/infra/config/generated/builders/ci/Dawn Android arm DEPS Release \050Pixel 4\051/properties.json" index a47379d2..1d6a2db 100644 --- "a/infra/config/generated/builders/ci/Dawn Android arm DEPS Release \050Pixel 4\051/properties.json" +++ "b/infra/config/generated/builders/ci/Dawn Android arm DEPS Release \050Pixel 4\051/properties.json"
@@ -17,9 +17,6 @@ "config": "main_builder_rel_mb" }, "legacy_chromium_config": { - "apply_configs": [ - "mb" - ], "config": "android", "target_platform": "android" },
diff --git "a/infra/config/generated/builders/ci/Dawn Android arm Release \050Pixel 4\051/properties.json" "b/infra/config/generated/builders/ci/Dawn Android arm Release \050Pixel 4\051/properties.json" index f134011..6777233 100644 --- "a/infra/config/generated/builders/ci/Dawn Android arm Release \050Pixel 4\051/properties.json" +++ "b/infra/config/generated/builders/ci/Dawn Android arm Release \050Pixel 4\051/properties.json"
@@ -17,9 +17,6 @@ "config": "main_builder_rel_mb" }, "legacy_chromium_config": { - "apply_configs": [ - "mb" - ], "config": "android", "target_platform": "android" },
diff --git a/infra/config/generated/builders/try/android-dawn-arm-rel/properties.json b/infra/config/generated/builders/try/android-dawn-arm-rel/properties.json index 95aee61..f919a2d 100644 --- a/infra/config/generated/builders/try/android-dawn-arm-rel/properties.json +++ b/infra/config/generated/builders/try/android-dawn-arm-rel/properties.json
@@ -17,9 +17,6 @@ "config": "main_builder_rel_mb" }, "legacy_chromium_config": { - "apply_configs": [ - "mb" - ], "config": "android", "target_platform": "android" },
diff --git a/infra/config/generated/builders/try/dawn-android-arm-deps-rel/properties.json b/infra/config/generated/builders/try/dawn-android-arm-deps-rel/properties.json index 55588c60..fab20b3f 100644 --- a/infra/config/generated/builders/try/dawn-android-arm-deps-rel/properties.json +++ b/infra/config/generated/builders/try/dawn-android-arm-deps-rel/properties.json
@@ -17,9 +17,6 @@ "config": "main_builder_rel_mb" }, "legacy_chromium_config": { - "apply_configs": [ - "mb" - ], "config": "android", "target_platform": "android" },
diff --git a/infra/config/subprojects/chromium/ci/chromium.dawn.star b/infra/config/subprojects/chromium/ci/chromium.dawn.star index e6138e8..df901da 100644 --- a/infra/config/subprojects/chromium/ci/chromium.dawn.star +++ b/infra/config/subprojects/chromium/ci/chromium.dawn.star
@@ -111,9 +111,6 @@ ), chromium_config = builder_config.chromium_config( config = "android", - apply_configs = [ - "mb", - ], target_platform = builder_config.target_platform.ANDROID, ), android_config = builder_config.android_config( @@ -198,9 +195,6 @@ ), chromium_config = builder_config.chromium_config( config = "android", - apply_configs = [ - "mb", - ], target_platform = builder_config.target_platform.ANDROID, ), android_config = builder_config.android_config(
diff --git a/ios/build/tools/update_deps.py b/ios/build/tools/update_deps.py new file mode 100755 index 0000000..3f896ed --- /dev/null +++ b/ios/build/tools/update_deps.py
@@ -0,0 +1,246 @@ +#!/usr/bin/env python3 +# Copyright 2022 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" +Updates BUILD.gn files to add missing direct dependencies when the +transitive dependency already exists. +The script is intentionally conservative and will not work in many +scenarios (e.g it does not handle target names with variables). These +cases will require manual roll (as today). +""" + +import argparse +from collections import defaultdict +import os +import re +import subprocess +import sys + +# The output of gn check when some direct dependencies are missing is expected +# to contain these lines. +TRANSITIVE_PATTERNS = [ + (3, "The target:"), (5, "is including a file from the target:"), + (8, "It's usually best to depend directly on the destination target."), + (9, "In some cases, the destination target is considered a subcomponent"), + (10, "of an intermediate target. In this case, the intermediate target"), + (11, "should depend publicly on the destination to forward the ability"), + (12, "to include headers."), + (14, "Dependency chain (there may also be others):") +] +# The line containing the target in the error message. +TRANSITIVE_DEPENDENT_LINE_NUMBER = 4 +# The line containing the dependence in the error message. +TRANSITIVE_DEPENDEE_LINE_NUMBER = 6 + +MISSING_PATTERNS = [ + (3, "It is not in any dependency of"), + (5, "The include file is in the target(s):"), +] +MISSING_DEPENDENT_LINE_NUMBER = 4 +MISSING_DEPENDEE_LINE_NUMBER = 6 + +# Character to set colors in terminal. +TERMINAL_ERROR_COLOR = "\033[91m" +TERMINAL_WARNING_COLOR = "\033[93m" +TERMINAL_RESET_COLOR = "\033[0m" + +# Separator between GN errors. +GN_ERROR_SEPARATOR = "___________________\n" + +# The error message to be used when the include file is in multiple GN targets. +MULTIPLE_DEPENDEES_ERROR = "Cannot handle includes in multiple targets:" +# The error message to be used when several "deps" are present for the target. +MULTIPLE_DEPS_ERROR = "Multiple deps variables in:" +# Warning message when automatically removing a target ending with +# "_strings_grit". +GRIT_TARGET_MESSAGE = "Grit target found!" +GRIT_TARGET_MESSAGE_DETAILS = "Automatically replacing:\n %s\nby:\n %s\n" + +# Array to handle special cases for canonical public target. This avoids having +# dependencies on internal target when there is a canonical target with public +# deps on those internal targets. +CANONICAL_PUBLIC_TARGETS = { + "//ios/chrome/app/strings:ios_strings_grit": + "//ios/chrome/app/strings:strings", + "//ios/chrome/app/strings:ios_google_chrome_strings_grit": + "//ios/chrome/app/strings:strings", + "//ios/chrome/app/strings:ios_chromium_strings_grit": + "//ios/chrome/app/strings:strings", + "//components/strings:components_strings_grit": + "//components/strings:strings", +} + + +def gn_format(gn_files): + """Format the file |gn_files|.""" + subprocess.check_call(["gn", "format"] + gn_files) + + +def remove_redundant_target_name(dependant, target_name): + """Canonicalize target_name to be used as a dep of dependant.""" + if target_name in CANONICAL_PUBLIC_TARGETS: + target_name = CANONICAL_PUBLIC_TARGETS[target_name] + (dependant_folder, dependant_target) = dependant.split(":") + (folder, target) = target_name.split(":") + if dependant_folder == folder: + return ":%s" % target + last_folder = os.path.basename(folder) + if last_folder == target: + return folder + if target.endswith("_strings_grit"): + warning_message = GRIT_TARGET_MESSAGE_DETAILS % (target_name, folder) + print_warning(GRIT_TARGET_MESSAGE, warning_message) + return folder + return target_name + + +def extract_missing_dependency(error, prefix, patterns, dependant_line, + dependee_line): + """Parse gn error message for missing direct dependency.""" + lines = error.splitlines() + if len(lines) <= patterns[-1][0]: + return False, None + for line_number, pattern in patterns: + if lines[line_number] != pattern: + return False, None + dependant = lines[dependant_line].strip() + if prefix and not dependant.startswith(prefix): + return False, None + + dependees = [] + index = dependee_line + while lines[dependee_line].strip().startswith("//"): + dependees.append(remove_redundant_target_name( + dependant, lines[dependee_line].strip())) + dependee_line += 1 + + return True, (dependant, dependees) + + +def get_missing_deps(builddir, prefix): + """Extracts missing direct dependencies from gn.""" + missing_deps = defaultdict(set) + process = subprocess.Popen(["gn", "check", builddir], + stdout=subprocess.PIPE) + lines, errs = process.communicate() + errors = lines.decode("ascii").split(GN_ERROR_SEPARATOR) + for error in errors: + has_missing_dep, info = extract_missing_dependency( + error, prefix, TRANSITIVE_PATTERNS, + TRANSITIVE_DEPENDENT_LINE_NUMBER, TRANSITIVE_DEPENDEE_LINE_NUMBER) + if not has_missing_dep: + has_missing_dep, info = extract_missing_dependency( + error, prefix, MISSING_PATTERNS, MISSING_DEPENDENT_LINE_NUMBER, + MISSING_DEPENDEE_LINE_NUMBER) + if has_missing_dep: + dependant, dependees = info + if len(dependees) == 1: + missing_deps[dependant].add(dependees[0]) + else: + print_error(MULTIPLE_DEPENDEES_ERROR, error) + return missing_deps + + +def add_missing_deps(srcdir, target, deps): + """Adds the missing deps to the BUILD.gn file and run gn format on it.""" + (dir, target_name) = target.split(":") + build_gn_file = os.path.join(srcdir, dir[2:], "BUILD.gn") + content = [] + in_target = False + changed = False + first_deps_variable_line_index = -1 + target_name = target_name.replace("+", "\\+") + target_rule = re.compile("\s*[a-z_]*\(\"%s\"\) {" % target_name) + with open(build_gn_file, "r") as build_gn: + all_lines = build_gn.readlines() + for line_index, line in enumerate(all_lines): + content += [line] + if target_rule.search(line): + indent = len(line) - len(line.lstrip(" ")) + in_target = True + if in_target and line == (" " * indent + "}\n"): + in_target = False + if (in_target and first_deps_variable_line_index != -1 and + line.strip().startswith("deps ")): + error_detail = (f"At lines:\n" + f"* {build_gn_file}:{first_deps_variable_line_index}:\n" + f" {all_lines[first_deps_variable_line_index]}\n" + f"* {build_gn_file}:{line_index}:\n" + f" {line}\n") + error_detail = f"{target}\n{error_detail}" + print_error(MULTIPLE_DEPS_ERROR, error_detail) + # Multiple deps, abort + return False, None + if (in_target and first_deps_variable_line_index == -1 and + line.strip().startswith("deps ")): + first_deps_variable_line_index = line_index + onelinedeps = False + if "[" in line and line[-2] == "]": + onelinedeps = True + content[-1] = line.replace("]", ",") + for dep in deps: + content += ["\"%s\",\n" % dep] + changed = True + if onelinedeps: + content += ["]\n"] + if changed: + with open(build_gn_file, "w") as build_gn: + build_gn.write("".join(content)) + return True, build_gn_file + return False, None + + +def main(args): + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument("--prefix", + help="Only fix subtargets of prefix", + default="") + parser.add_argument("builddir", help="The build dir") + parser.add_argument("srcdir", help="The src dir") + args = parser.parse_args() + deps = get_missing_deps(args.builddir, args.prefix) + changed_build_gn_files = [] + for target in deps: + changed, build_gn_file = add_missing_deps(args.srcdir, target, + deps[target]) + if changed: + changed_build_gn_files.append(build_gn_file) + if changed_build_gn_files: + gn_format(changed_build_gn_files) + + +def print_error(error_message, error_info): + """ Print the `error_message` with additional `error_info` """ + color_start, color_end = adapted_color_for_output(TERMINAL_ERROR_COLOR, + TERMINAL_RESET_COLOR) + + error_message = color_start + "ERROR: " + error_message + color_end + if len(error_info) > 0: + error_message = error_message + "\n" + error_info + print(error_message + "\n" + GN_ERROR_SEPARATOR) + + +def print_warning(warning_message, warning_info): + """ Print the `warning_message` with additional `warning_info` """ + color_start, color_end = adapted_color_for_output(TERMINAL_WARNING_COLOR, + TERMINAL_RESET_COLOR) + + warning_message = color_start + "WARNING: " + warning_message + color_end + if len(warning_info) > 0: + warning_message = warning_message + "\n" + warning_info + print(warning_message + "\n" + GN_ERROR_SEPARATOR) + + +def adapted_color_for_output(color_start, color_end): + """ Returns a the `color_start`, `color_end` tuple if the output is a + terminal, or empty strings otherwise """ + if not sys.stdout.isatty(): + return "", "" + return color_start, color_end + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:]))
diff --git a/ios/chrome/browser/translate/translate_app_interface.mm b/ios/chrome/browser/translate/translate_app_interface.mm index 0253f27..b7abcaf9 100644 --- a/ios/chrome/browser/translate/translate_app_interface.mm +++ b/ios/chrome/browser/translate/translate_app_interface.mm
@@ -109,27 +109,25 @@ // used by this fake object. Instead just invoke host with 'translate.ready' // followed by 'translate.status'. base::Value translate_ready_dict(base::Value::Type::DICTIONARY); - translate_ready_dict.SetKey("command", base::Value("ready")); + translate_ready_dict.SetKey("command", base::Value("translate.ready")); translate_ready_dict.SetKey("errorCode", base::Value(0)); translate_ready_dict.SetKey("loadTime", base::Value(0)); translate_ready_dict.SetKey("readyTime", base::Value(0)); std::vector<base::Value> translate_ready_params; - translate_ready_params.push_back(base::Value("TranslateMessage")); translate_ready_params.push_back(std::move(translate_ready_dict)); - web_frame_->CallJavaScriptFunction("common.sendWebKitMessage", + web_frame_->CallJavaScriptFunction("message.invokeOnHost", translate_ready_params); base::Value translate_status_dict(base::Value::Type::DICTIONARY); - translate_status_dict.SetKey("command", base::Value("status")); + translate_status_dict.SetKey("command", base::Value("translate.status")); translate_status_dict.SetKey("errorCode", base::Value(0)); translate_status_dict.SetKey("pageSourceLanguage", base::Value("fr")); translate_status_dict.SetKey("translationTime", base::Value(0)); std::vector<base::Value> translate_status_params; - translate_status_params.push_back(base::Value("TranslateMessage")); translate_status_params.push_back(std::move(translate_status_dict)); - web_frame_->CallJavaScriptFunction("common.sendWebKitMessage", + web_frame_->CallJavaScriptFunction("message.invokeOnHost", translate_status_params); } @@ -150,6 +148,15 @@ u"myButton = document.getElementById('translated-button');" u"myButton.remove();"); } + + void HandleTranslateResponse(const std::string& url, + int request_id, + int response_code, + const std::string status_text, + const std::string& response_url, + const std::string& response_text) override { + // no-op + } }; class FakeJSTranslateWebFrameManagerFactory @@ -260,11 +267,13 @@ } + (void)setUpFakeJSTranslateManagerInCurrentTab { - translate::TranslateController* translate_controller = - translate::TranslateController::FromWebState( - chrome_test_util::GetCurrentWebState()); - translate_controller->SetJsTranslateWebFrameManagerFactoryForTesting( - FakeJSTranslateWebFrameManagerFactory::GetInstance()); + ChromeIOSTranslateClient* client = ChromeIOSTranslateClient::FromWebState( + chrome_test_util::GetCurrentWebState()); + translate::IOSTranslateDriver* driver = + static_cast<translate::IOSTranslateDriver*>(client->GetTranslateDriver()); + driver->translate_controller() + ->SetJsTranslateWebFrameManagerFactoryForTesting( + FakeJSTranslateWebFrameManagerFactory::GetInstance()); } + (BOOL)shouldAutoTranslateFromLanguage:(NSString*)source
diff --git a/ios/chrome/browser/ui/omnibox/popup/BUILD.gn b/ios/chrome/browser/ui/omnibox/popup/BUILD.gn index d5451e24..e0d66c2 100644 --- a/ios/chrome/browser/ui/omnibox/popup/BUILD.gn +++ b/ios/chrome/browser/ui/omnibox/popup/BUILD.gn
@@ -33,8 +33,15 @@ ":popup_ui_protocols", "//base", "//ios/chrome/app/strings:ios_strings_grit", + "//ios/chrome/app/theme", "//ios/chrome/browser/net:crurl", + "//ios/chrome/browser/ui/commands", + "//ios/chrome/browser/ui/omnibox/popup:popup_accessibility_identifier_constants", + "//ios/chrome/browser/ui/toolbar/buttons", + "//ios/chrome/browser/ui/toolbar/public:constants", + "//ios/chrome/browser/ui/util", "//ios/chrome/common/ui/colors:swift", + "//ui/base", ] frameworks = [
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn index 54bdfea..a290d4b 100644 --- a/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn
@@ -133,8 +133,11 @@ deps = [ "//base", "//ios/chrome/app/strings:ios_strings_grit", + "//ios/chrome/browser/ui/popup_menu:constants", "//ios/chrome/browser/ui/popup_menu:metrics_protocols", + "//ios/chrome/common:timing", "//ios/chrome/common/ui/colors:swift", + "//ui/base", ] frameworks = [
diff --git a/ios/chrome/browser/ui/settings/safety_check/BUILD.gn b/ios/chrome/browser/ui/settings/safety_check/BUILD.gn index 46b70138..b639f20 100644 --- a/ios/chrome/browser/ui/settings/safety_check/BUILD.gn +++ b/ios/chrome/browser/ui/settings/safety_check/BUILD.gn
@@ -32,7 +32,12 @@ swift_source_set("safety_check_ui_swift") { bridge_header = "safety_check_bridge.h" sources = [ "safety_check_table_view_controller.swift" ] - deps = [ ":safety_check_ui" ] + deps = [ + ":safety_check_ui", + "//ios/chrome/browser/ui/settings:settings_root", + "//ios/chrome/browser/ui/settings/cells", + "//ui/base", + ] } source_set("safety_check") {
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn index 43962db..3af5ff3 100644 --- a/ios/chrome/browser/web/BUILD.gn +++ b/ios/chrome/browser/web/BUILD.gn
@@ -242,7 +242,6 @@ "//components/signin/public/identity_manager", "//components/strings", "//components/translate/core/browser", - "//components/translate/ios/browser", "//components/variations", "//components/variations/field_trial_config", "//components/variations/service",
diff --git a/ios/chrome/browser/web/chrome_web_client.mm b/ios/chrome/browser/web/chrome_web_client.mm index 214ad237..3c72813 100644 --- a/ios/chrome/browser/web/chrome_web_client.mm +++ b/ios/chrome/browser/web/chrome_web_client.mm
@@ -22,7 +22,6 @@ #import "components/password_manager/core/common/password_manager_features.h" #import "components/password_manager/ios/password_manager_java_script_feature.h" #import "components/strings/grit/components_strings.h" -#import "components/translate/ios/browser/translate_java_script_feature.h" #import "components/version_info/version_info.h" #import "ios/chrome/browser/application_context/application_context.h" #import "ios/chrome/browser/browser_about_rewriter.h" @@ -320,7 +319,6 @@ SearchEngineJavaScriptFeature::GetInstance()->SetDelegate( SearchEngineTabHelperFactory::GetInstance()); features.push_back(SearchEngineJavaScriptFeature::GetInstance()); - features.push_back(translate::TranslateJavaScriptFeature::GetInstance()); features.push_back(WebPerformanceMetricsJavaScriptFeature::GetInstance()); features.push_back(FollowJavaScriptFeature::GetInstance()); return features;
diff --git a/ios/web_view/internal/sync/cwv_sync_controller_unittest.mm b/ios/web_view/internal/sync/cwv_sync_controller_unittest.mm index 88a9cbe..4ee3fee 100644 --- a/ios/web_view/internal/sync/cwv_sync_controller_unittest.mm +++ b/ios/web_view/internal/sync/cwv_sync_controller_unittest.mm
@@ -218,7 +218,7 @@ [error.userInfo[CWVSyncErrorIsTransientKey] boolValue]; }]]); OCMExpect([delegate syncControllerDidUpdateState:sync_controller]); - sync_service_.SetAuthError(GoogleServiceAuthError::FromConnectionError(0)); + sync_service_.SetTransientAuthError(); sync_service_.FireStateChanged(); [delegate verify];
diff --git a/ios/web_view/internal/web_view_web_client.mm b/ios/web_view/internal/web_view_web_client.mm index fbbf967..ca75a6b 100644 --- a/ios/web_view/internal/web_view_web_client.mm +++ b/ios/web_view/internal/web_view_web_client.mm
@@ -18,7 +18,6 @@ #import "components/security_interstitials/core/unsafe_resource.h" #include "components/ssl_errors/error_info.h" #include "components/strings/grit/components_strings.h" -#import "components/translate/ios/browser/translate_java_script_feature.h" #import "ios/components/security_interstitials/lookalikes/lookalike_url_container.h" #import "ios/components/security_interstitials/lookalikes/lookalike_url_error.h" #import "ios/components/security_interstitials/safe_browsing/safe_browsing_error.h" @@ -117,7 +116,6 @@ autofill::FormHandlersJavaScriptFeature::GetInstance(), autofill::SuggestionControllerJavaScriptFeature::GetInstance(), password_manager::PasswordManagerJavaScriptFeature::GetInstance(), - translate::TranslateJavaScriptFeature::GetInstance(), WebViewMessageHandlerJavaScriptFeature::GetInstance()}; }
diff --git a/media/audio/cras/audio_manager_chromeos_unittest.cc b/media/audio/cras/audio_manager_chromeos_unittest.cc index 4a27ac8..9a100bb 100644 --- a/media/audio/cras/audio_manager_chromeos_unittest.cc +++ b/media/audio/cras/audio_manager_chromeos_unittest.cc
@@ -274,8 +274,8 @@ AudioManagerChromeOS::SystemAudioProcessingInfo system_apm_info_; size_t user_buffer_size_ = kDefaultInputBufferSize; - std::vector<base::Feature> enabled_features_; - std::vector<base::Feature> disabled_features_; + std::vector<base::test::FeatureRef> enabled_features_; + std::vector<base::test::FeatureRef> disabled_features_; bool aec_on_dsp_allowed_; bool ns_on_dsp_allowed_; bool agc_on_dsp_allowed_;
diff --git a/media/gpu/test/video_encoder/video_encoder_test_environment.cc b/media/gpu/test/video_encoder/video_encoder_test_environment.cc index 3898319..ff81bfc9 100644 --- a/media/gpu/test/video_encoder/video_encoder_test_environment.cc +++ b/media/gpu/test/video_encoder/video_encoder_test_environment.cc
@@ -100,8 +100,8 @@ Bitrate::Mode bitrate_mode, bool reverse, const FrameOutputConfig& frame_output_config, - const std::vector<base::Feature>& enabled_features, - const std::vector<base::Feature>& disabled_features) { + const std::vector<base::test::FeatureRef>& enabled_features, + const std::vector<base::test::FeatureRef>& disabled_features) { if (video_path.empty()) { LOG(ERROR) << "No video specified"; return nullptr; @@ -147,8 +147,10 @@ // TODO(b/182008564) Add checks to make sure no features are duplicated, and // there is no intersection between the enabled and disabled set. - std::vector<base::Feature> combined_enabled_features(enabled_features); - std::vector<base::Feature> combined_disabled_features(disabled_features); + std::vector<base::test::FeatureRef> combined_enabled_features( + enabled_features); + std::vector<base::test::FeatureRef> combined_disabled_features( + disabled_features); combined_disabled_features.push_back(media::kFFmpegDecodeOpaqueVP8); #if BUILDFLAG(USE_VAAPI) // TODO(crbug.com/828482): remove once enabled by default. @@ -208,8 +210,8 @@ bool save_output_bitstream, bool reverse, const FrameOutputConfig& frame_output_config, - const std::vector<base::Feature>& enabled_features, - const std::vector<base::Feature>& disabled_features) + const std::vector<base::test::FeatureRef>& enabled_features, + const std::vector<base::test::FeatureRef>& disabled_features) : VideoTestEnvironment(enabled_features, disabled_features), video_(std::move(video)), enable_bitstream_validator_(enable_bitstream_validator),
diff --git a/media/gpu/test/video_encoder/video_encoder_test_environment.h b/media/gpu/test/video_encoder/video_encoder_test_environment.h index 6e91344..6c5f896 100644 --- a/media/gpu/test/video_encoder/video_encoder_test_environment.h +++ b/media/gpu/test/video_encoder/video_encoder_test_environment.h
@@ -51,8 +51,8 @@ Bitrate::Mode bitrate_mode, bool reverse, const FrameOutputConfig& frame_output_config = FrameOutputConfig(), - const std::vector<base::Feature>& enabled_features = {}, - const std::vector<base::Feature>& disabled_features = {}); + const std::vector<base::test::FeatureRef>& enabled_features = {}, + const std::vector<base::test::FeatureRef>& disabled_features = {}); ~VideoEncoderTestEnvironment() override; @@ -103,8 +103,8 @@ bool save_output_bitstream, bool reverse, const FrameOutputConfig& frame_output_config, - const std::vector<base::Feature>& enabled_features, - const std::vector<base::Feature>& disabled_features); + const std::vector<base::test::FeatureRef>& enabled_features, + const std::vector<base::test::FeatureRef>& disabled_features); // Video file to be used for testing. const std::unique_ptr<media::test::Video> video_;
diff --git a/media/gpu/test/video_player/video_player_test_environment.cc b/media/gpu/test/video_player/video_player_test_environment.cc index 9734e885..c5c9976 100644 --- a/media/gpu/test/video_player/video_player_test_environment.cc +++ b/media/gpu/test/video_player/video_player_test_environment.cc
@@ -32,8 +32,8 @@ bool linear_output, const base::FilePath& output_folder, const FrameOutputConfig& frame_output_config, - const std::vector<base::Feature>& enabled_features, - const std::vector<base::Feature>& disabled_features) { + const std::vector<base::test::FeatureRef>& enabled_features, + const std::vector<base::test::FeatureRef>& disabled_features) { auto video = std::make_unique<media::test::Video>( video_path.empty() ? base::FilePath(kDefaultTestVideoPath) : video_path, video_metadata_path); @@ -44,9 +44,11 @@ // TODO(b/182008564) Add checks to make sure no features are duplicated, and // there is no intersection between the enabled and disabled set. - std::vector<base::Feature> combined_enabled_features(enabled_features); + std::vector<base::test::FeatureRef> combined_enabled_features( + enabled_features); combined_enabled_features.push_back(media::kVp9kSVCHWDecoding); - std::vector<base::Feature> combined_disabled_features(disabled_features); + std::vector<base::test::FeatureRef> combined_disabled_features( + disabled_features); #if BUILDFLAG(USE_VAAPI) // TODO(b/172217032): remove once enabled by default. combined_enabled_features.push_back(media::kVaapiAV1Decoder); @@ -71,8 +73,8 @@ bool linear_output, const base::FilePath& output_folder, const FrameOutputConfig& frame_output_config, - const std::vector<base::Feature>& enabled_features, - const std::vector<base::Feature>& disabled_features) + const std::vector<base::test::FeatureRef>& enabled_features, + const std::vector<base::test::FeatureRef>& disabled_features) : VideoTestEnvironment(enabled_features, disabled_features), video_(std::move(video)), validator_type_(validator_type),
diff --git a/media/gpu/test/video_player/video_player_test_environment.h b/media/gpu/test/video_player/video_player_test_environment.h index d37527ee..1151422 100644 --- a/media/gpu/test/video_player/video_player_test_environment.h +++ b/media/gpu/test/video_player/video_player_test_environment.h
@@ -36,8 +36,8 @@ bool linear_output, const base::FilePath& output_folder = base::FilePath(), const FrameOutputConfig& frame_output_config = FrameOutputConfig(), - const std::vector<base::Feature>& enabled_features = {}, - const std::vector<base::Feature>& disabled_features = {}); + const std::vector<base::test::FeatureRef>& enabled_features = {}, + const std::vector<base::test::FeatureRef>& disabled_features = {}); ~VideoPlayerTestEnvironment() override; // Get the video the tests will be ran on. @@ -68,8 +68,8 @@ bool linear_output, const base::FilePath& output_folder, const FrameOutputConfig& frame_output_config, - const std::vector<base::Feature>& enabled_features, - const std::vector<base::Feature>& disabled_features); + const std::vector<base::test::FeatureRef>& enabled_features, + const std::vector<base::test::FeatureRef>& disabled_features); const std::unique_ptr<media::test::Video> video_; const ValidatorType validator_type_;
diff --git a/media/gpu/test/video_test_environment.cc b/media/gpu/test/video_test_environment.cc index 8dfe711..2ed50f2 100644 --- a/media/gpu/test/video_test_environment.cc +++ b/media/gpu/test/video_test_environment.cc
@@ -26,8 +26,8 @@ VideoTestEnvironment::VideoTestEnvironment() : VideoTestEnvironment({}, {}) {} VideoTestEnvironment::VideoTestEnvironment( - const std::vector<base::Feature>& enabled_features, - const std::vector<base::Feature>& disabled_features) { + const std::vector<base::test::FeatureRef>& enabled_features, + const std::vector<base::test::FeatureRef>& disabled_features) { // Using shared memory requires mojo to be initialized (crbug.com/849207). mojo::core::Init();
diff --git a/media/gpu/test/video_test_environment.h b/media/gpu/test/video_test_environment.h index 95670290..b8cba91a 100644 --- a/media/gpu/test/video_test_environment.h +++ b/media/gpu/test/video_test_environment.h
@@ -50,8 +50,9 @@ public: VideoTestEnvironment(); // Features are overridden by given features in this environment. - VideoTestEnvironment(const std::vector<base::Feature>& enabled_features, - const std::vector<base::Feature>& disabled_features); + VideoTestEnvironment( + const std::vector<base::test::FeatureRef>& enabled_features, + const std::vector<base::test::FeatureRef>& disabled_features); virtual ~VideoTestEnvironment(); // ::testing::Environment implementation.
diff --git a/media/gpu/video_decode_accelerator_perf_tests.cc b/media/gpu/video_decode_accelerator_perf_tests.cc index c707c63..d0fcbd9 100644 --- a/media/gpu/video_decode_accelerator_perf_tests.cc +++ b/media/gpu/video_decode_accelerator_perf_tests.cc
@@ -472,8 +472,8 @@ bool use_legacy = false; bool use_vd_vda = false; bool linear_output = false; - std::vector<base::Feature> disabled_features; - std::vector<base::Feature> enabled_features; + std::vector<base::test::FeatureRef> disabled_features; + std::vector<base::test::FeatureRef> enabled_features; #if defined(ARCH_CPU_ARM_FAMILY) enabled_features.push_back(media::kPreferLibYuvImageProcessor);
diff --git a/media/gpu/video_decode_accelerator_tests.cc b/media/gpu/video_decode_accelerator_tests.cc index 7671be5..712b8230 100644 --- a/media/gpu/video_decode_accelerator_tests.cc +++ b/media/gpu/video_decode_accelerator_tests.cc
@@ -544,8 +544,8 @@ bool use_legacy = false; bool use_vd_vda = false; bool linear_output = false; - std::vector<base::Feature> disabled_features; - std::vector<base::Feature> enabled_features; + std::vector<base::test::FeatureRef> disabled_features; + std::vector<base::test::FeatureRef> enabled_features; #if defined(ARCH_CPU_ARM_FAMILY) enabled_features.push_back(media::kPreferLibYuvImageProcessor);
diff --git a/media/gpu/video_encode_accelerator_perf_tests.cc b/media/gpu/video_encode_accelerator_perf_tests.cc index 7fcd3bc..2ed2028c 100644 --- a/media/gpu/video_encode_accelerator_perf_tests.cc +++ b/media/gpu/video_encode_accelerator_perf_tests.cc
@@ -791,7 +791,7 @@ media::Bitrate::Mode bitrate_mode = media::Bitrate::Mode::kConstant; bool reverse = false; absl::optional<uint32_t> encode_bitrate; - std::vector<base::Feature> disabled_features; + std::vector<base::test::FeatureRef> disabled_features; // Parse command line arguments. base::FilePath::StringType output_folder = media::test::kDefaultOutputFolder;
diff --git a/media/gpu/video_encode_accelerator_tests.cc b/media/gpu/video_encode_accelerator_tests.cc index 4e3a9de..2b48c65 100644 --- a/media/gpu/video_encode_accelerator_tests.cc +++ b/media/gpu/video_encode_accelerator_tests.cc
@@ -871,7 +871,7 @@ media::test::FrameOutputConfig frame_output_config; base::FilePath output_folder = base::FilePath(base::FilePath::kCurrentDirectory); - std::vector<base::Feature> disabled_features; + std::vector<base::test::FeatureRef> disabled_features; // Parse command line arguments. bool enable_bitstream_validator = true;
diff --git a/media/gpu/windows/d3d11_h264_accelerator.cc b/media/gpu/windows/d3d11_h264_accelerator.cc index 3b346d8..4f3f9014 100644 --- a/media/gpu/windows/d3d11_h264_accelerator.cc +++ b/media/gpu/windows/d3d11_h264_accelerator.cc
@@ -21,7 +21,6 @@ #include "ui/gfx/color_space.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" -#include "ui/gl/gl_image_dxgi.h" #include "ui/gl/gl_surface_egl.h" #include "ui/gl/scoped_binders.h"
diff --git a/media/gpu/windows/d3d11_h265_accelerator.cc b/media/gpu/windows/d3d11_h265_accelerator.cc index 2235519..ad15bf52 100644 --- a/media/gpu/windows/d3d11_h265_accelerator.cc +++ b/media/gpu/windows/d3d11_h265_accelerator.cc
@@ -23,7 +23,6 @@ #include "ui/gfx/color_space.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" -#include "ui/gl/gl_image_dxgi.h" #include "ui/gl/gl_surface_egl.h" #include "ui/gl/scoped_binders.h"
diff --git a/media/gpu/windows/d3d11_texture_wrapper.h b/media/gpu/windows/d3d11_texture_wrapper.h index bd82b6aa..1e0fde475 100644 --- a/media/gpu/windows/d3d11_texture_wrapper.h +++ b/media/gpu/windows/d3d11_texture_wrapper.h
@@ -24,7 +24,6 @@ #include "ui/gfx/hdr_metadata.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" -#include "ui/gl/gl_image_dxgi.h" #include "ui/gl/gl_surface_egl.h" #include "ui/gl/scoped_binders.h"
diff --git a/net/base/mock_network_change_notifier.cc b/net/base/mock_network_change_notifier.cc index f5e1a0d..c3aae7b 100644 --- a/net/base/mock_network_change_notifier.cc +++ b/net/base/mock_network_change_notifier.cc
@@ -84,6 +84,10 @@ base::RunLoop().RunUntilIdle(); } +bool MockNetworkChangeNotifier::IsDefaultNetworkActiveInternal() { + return is_default_network_active_; +} + void MockNetworkChangeNotifier::SetConnectionTypeAndNotifyObservers( ConnectionType connection_type) { SetConnectionType(connection_type);
diff --git a/net/base/mock_network_change_notifier.h b/net/base/mock_network_change_notifier.h index e3c50b0..f16fc8ee 100644 --- a/net/base/mock_network_change_notifier.h +++ b/net/base/mock_network_change_notifier.h
@@ -61,6 +61,12 @@ connection_cost_ = connection_cost; } + bool IsDefaultNetworkActiveInternal() override; + + void SetIsDefaultNetworkActiveInternalForTesting(bool is_active) { + is_default_network_active_ = is_active; + } + // Tells this class to ignore its cached connection cost value and instead // call the base class's implementation. This is intended to allow tests to // mock the product code's fallback to the default implementation in certain @@ -84,6 +90,7 @@ std::unique_ptr<SystemDnsConfigChangeNotifier> dns_config_notifier); bool force_network_handles_supported_ = false; + bool is_default_network_active_ = true; ConnectionType connection_type_ = CONNECTION_UNKNOWN; ConnectionCost connection_cost_ = CONNECTION_COST_UNKNOWN; bool use_default_connection_cost_implementation_ = false;
diff --git a/services/audio/input_sync_writer.cc b/services/audio/input_sync_writer.cc index 497031d..fcd5c00 100644 --- a/services/audio/input_sync_writer.cc +++ b/services/audio/input_sync_writer.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <utility> +#include "base/check.h" #include "base/format_macros.h" #include "base/logging.h" #include "base/metrics/histogram_functions.h" @@ -91,28 +92,32 @@ // - Percentage of data written to fifo (and not to shared memory). // - Percentage of data dropped (fifo reached max size or socket buffer full). // - Glitch yes/no (at least 1 drop). - // + + // The amount of data that has either been dropped or successfully written. + // This number does not include data that is in the fifo, which we do not know + // if it would have been dropped or successfully written. + size_t total_processed_data_count = + dropped_data_count_ + successful_write_count_; + + DCHECK_LE(trailing_shared_memory_full_count_, shared_memory_full_count_); + DCHECK_LE(trailing_shared_memory_full_count_, write_count_); + DCHECK_LE(trailing_dropped_data_count_, dropped_data_count_); + DCHECK_LE(trailing_dropped_data_count_, total_processed_data_count); + // Subtract 'trailing' counts that will happen if the renderer process was // killed or e.g. the page refreshed while the input device was open etc. // This trims off the end of both the error and write counts so that we - // preserve the proportion of counts before the teardown period. We pick - // the largest trailing count as the time we consider that the trailing errors - // begun, and subract that from the total write count. - DCHECK_LE(trailing_write_to_fifo_count_, write_to_fifo_count_); - DCHECK_LE(trailing_write_to_fifo_count_, write_count_); - DCHECK_LE(trailing_write_error_count_, write_error_count_); - DCHECK_LE(trailing_write_error_count_, write_count_); + // preserve the proportion of counts before the teardown period. + shared_memory_full_count_ -= trailing_shared_memory_full_count_; + write_count_ -= trailing_shared_memory_full_count_; + dropped_data_count_ -= trailing_dropped_data_count_; + total_processed_data_count -= trailing_dropped_data_count_; - write_to_fifo_count_ -= trailing_write_to_fifo_count_; - write_error_count_ -= trailing_write_error_count_; - write_count_ -= - std::max(trailing_write_to_fifo_count_, trailing_write_error_count_); - - if (write_count_ == 0) + if (write_count_ == 0 || total_processed_data_count == 0) return; base::UmaHistogramEnumeration("Media.AudioCapturerAudioGlitches", - write_error_count_ == 0 + dropped_data_count_ == 0 ? AudioGlitchResult::kNoGlitches : AudioGlitchResult::kGlitches); @@ -128,16 +133,16 @@ write_count_ < kShortStreamMaxCallbackCount ? "Short" : "Long"; int missed_deadline = - std::ceil(kPermilleScaling * static_cast<double>(write_to_fifo_count_) / - write_count_); + std::ceil(kPermilleScaling * + static_cast<double>(shared_memory_full_count_) / write_count_); base::UmaHistogramCustomCounts( "Media.AudioCapturerMissedReadDeadline2." + suffix, std::min(missed_deadline, kHistogramRange), 0, kHistogramRange + 1, 100); int dropped_data = - std::ceil(kPermilleScaling * static_cast<double>(write_error_count_) / - write_count_); + std::ceil(kPermilleScaling * static_cast<double>(dropped_data_count_) / + total_processed_data_count); base::UmaHistogramCustomCounts("Media.AudioCapturerDroppedData2." + suffix, std::min(dropped_data, kHistogramRange), 0, @@ -145,7 +150,7 @@ std::string log_string = base::StringPrintf( "AISW: number of detected audio glitches: %" PRIuS " out of %" PRIuS, - write_error_count_, write_count_); + dropped_data_count_, total_processed_data_count); log_callback_.Run(log_string); } @@ -213,37 +218,61 @@ } } - bool write_error = !WriteDataFromFifoToSharedMemory(); + // If there is data in the fifo, write as much of it to shared memory as + // possible. + if (!overflow_data_.empty()) { + const size_t segment_count = audio_buses_.size(); + auto data_it = overflow_data_.begin(); + + while (data_it != overflow_data_.end() && + number_of_filled_segments_ < segment_count) { + // Write parameters to shared memory. + if (WriteDataToCurrentSegment(*data_it->audio_bus_, data_it->volume_, + data_it->key_pressed_, + data_it->capture_time_)) { + ++successful_write_count_; + trailing_shared_memory_full_count_ = 0; + trailing_dropped_data_count_ = 0; + } else { + // This happens only if writing to the socket buffer fails, which should + // be rare. + ++dropped_data_count_; + ++trailing_dropped_data_count_; + } + ++data_it; + } + + // Erase all copied data from fifo. + overflow_data_.erase(overflow_data_.begin(), data_it); + + if (overflow_data_.empty()) { + static const char* message = "AISW: Fifo emptied."; + log_callback_.Run(message); + } + } // Write the current data to the shared memory if there is room, otherwise // put it in the fifo. if (number_of_filled_segments_ < audio_buses_.size()) { - WriteParametersToCurrentSegment(volume, key_pressed, capture_time); - - // Copy data into shared memory using pre-allocated audio buses. - data->CopyTo(audio_buses_[current_segment_id_].get()); - - if (!SignalDataWrittenAndUpdateCounters()) - write_error = true; - - trailing_write_to_fifo_count_ = 0; + DCHECK(overflow_data_.empty()); + if (WriteDataToCurrentSegment(*data, volume, key_pressed, capture_time)) { + ++successful_write_count_; + trailing_shared_memory_full_count_ = 0; + trailing_dropped_data_count_ = 0; + } else { + // This happens only if writing to the socket buffer fails, which should + // be rare. + ++dropped_data_count_; + ++trailing_dropped_data_count_; + } } else { - if (!PushDataToFifo(data, volume, key_pressed, capture_time)) - write_error = true; + if (!PushDataToFifo(*data, volume, key_pressed, capture_time)) { + ++dropped_data_count_; + ++trailing_dropped_data_count_; + } - ++write_to_fifo_count_; - ++trailing_write_to_fifo_count_; - } - - // Increase write error counts if error, or reset the trailing error counter - // if all write operations went well (no data dropped). - if (write_error) { - ++write_error_count_; - ++trailing_write_error_count_; - TRACE_EVENT_INSTANT0("audio", "InputSyncWriter write error", - TRACE_EVENT_SCOPE_THREAD); - } else { - trailing_write_error_count_ = 0; + ++shared_memory_full_count_; + ++trailing_shared_memory_full_count_; } } @@ -279,23 +308,24 @@ #endif } -bool InputSyncWriter::PushDataToFifo(const media::AudioBus* data, +bool InputSyncWriter::PushDataToFifo(const media::AudioBus& data, double volume, bool key_pressed, base::TimeTicks capture_time) { TRACE_EVENT1("audio", "InputSyncWriter::PushDataToFifo", "capture time (ms)", (capture_time - base::TimeTicks()).InMillisecondsF()); if (overflow_data_.size() == kMaxOverflowBusesSize) { - // We use |write_error_count_| for capping number of log messages. - // |write_error_count_| also includes socket Send() errors, but those should - // be rare. - TRACE_EVENT_INSTANT0("audio", "InputSyncWriter::PushDataToFifo - overflow", - TRACE_EVENT_SCOPE_THREAD); - if (write_error_count_ <= 50 && write_error_count_ % 10 == 0) { + // We use |dropped_data_count_| for capping number of log messages. + // |dropped_data_count_| also includes socket Send() errors, but those + // should be rare. + TRACE_EVENT_INSTANT0( + "audio", "InputSyncWriter::PushDataToFifo - overflow - dropped data", + TRACE_EVENT_SCOPE_THREAD); + if (dropped_data_count_ <= 50 && dropped_data_count_ % 10 == 0) { static const char* error_message = "AISW: No room in fifo."; LOG(WARNING) << error_message; log_callback_.Run(error_message); - if (write_error_count_ == 50) { + if (dropped_data_count_ == 50) { static const char* cap_error_message = "AISW: Log cap reached, suppressing further fifo overflow logs."; LOG(WARNING) << cap_error_message; @@ -312,56 +342,20 @@ // Push data to fifo. std::unique_ptr<media::AudioBus> audio_bus = - media::AudioBus::Create(data->channels(), data->frames()); - data->CopyTo(audio_bus.get()); + media::AudioBus::Create(data.channels(), data.frames()); + data.CopyTo(audio_bus.get()); overflow_data_.emplace_back(volume, key_pressed, capture_time, std::move(audio_bus)); DCHECK_LE(overflow_data_.size(), static_cast<size_t>(kMaxOverflowBusesSize)); - return true; } -bool InputSyncWriter::WriteDataFromFifoToSharedMemory() { - TRACE_EVENT0("audio", "InputSyncWriter::WriteDataFromFifoToSharedMemory"); - if (overflow_data_.empty()) - return true; - - const size_t segment_count = audio_buses_.size(); - bool write_error = false; - auto data_it = overflow_data_.begin(); - - while (data_it != overflow_data_.end() && - number_of_filled_segments_ < segment_count) { - // Write parameters to shared memory. - WriteParametersToCurrentSegment(data_it->volume_, data_it->key_pressed_, - data_it->capture_time_); - - // Copy data from the fifo into shared memory using pre-allocated audio - // buses. - data_it->audio_bus_->CopyTo(audio_buses_[current_segment_id_].get()); - - if (!SignalDataWrittenAndUpdateCounters()) - write_error = true; - - ++data_it; - } - - // Erase all copied data from fifo. - overflow_data_.erase(overflow_data_.begin(), data_it); - - if (overflow_data_.empty()) { - static const char* message = "AISW: Fifo emptied."; - log_callback_.Run(message); - } - - return !write_error; -} - -void InputSyncWriter::WriteParametersToCurrentSegment( - double volume, - bool key_pressed, - base::TimeTicks capture_time) { - TRACE_EVENT1("audio", "WriteParametersToCurrentSegment", "capture time (ms)", +bool InputSyncWriter::WriteDataToCurrentSegment(const media::AudioBus& data, + double volume, + bool key_pressed, + base::TimeTicks capture_time) { + CHECK(number_of_filled_segments_ < audio_buses_.size()); + TRACE_EVENT1("audio", "WriteDataToCurrentSegment", "capture time (ms)", (capture_time - base::TimeTicks()).InMillisecondsF()); uint8_t* ptr = static_cast<uint8_t*>(shared_memory_mapping_.memory()); CHECK_LT(current_segment_id_, audio_buses_.size()); @@ -373,6 +367,11 @@ buffer->params.capture_time_us = (capture_time - base::TimeTicks()).InMicroseconds(); buffer->params.id = next_buffer_id_; + + // Copy data into shared memory using pre-allocated audio buses. + data.CopyTo(audio_buses_[current_segment_id_].get()); + + return SignalDataWrittenAndUpdateCounters(); } bool InputSyncWriter::SignalDataWrittenAndUpdateCounters() { @@ -385,13 +384,13 @@ static const char* error_message = "AISW: No room in socket buffer."; PLOG(WARNING) << error_message; log_callback_.Run(error_message); - TRACE_EVENT_INSTANT0("audio", "InputSyncWriter: No room in socket buffer", - TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_INSTANT0( + "audio", "InputSyncWriter: No room in socket buffer - dropped data", + TRACE_EVENT_SCOPE_THREAD); } return false; - } else { - had_socket_error_ = false; } + had_socket_error_ = false; if (++current_segment_id_ >= audio_buses_.size()) current_segment_id_ = 0;
diff --git a/services/audio/input_sync_writer.h b/services/audio/input_sync_writer.h index 4b4f061a..7758f2d 100644 --- a/services/audio/input_sync_writer.h +++ b/services/audio/input_sync_writer.h
@@ -79,20 +79,18 @@ // Push |data| and metadata to |audio_buffer_fifo_|. Returns true if // successful. Logs error and returns false if the fifo already reached the // maximum size. - bool PushDataToFifo(const media::AudioBus* data, + bool PushDataToFifo(const media::AudioBus& data, double volume, bool key_pressed, base::TimeTicks capture_time); - // Writes as much data as possible from the fifo (|overflow_buses_|) to the - // shared memory ring buffer. Returns true if all operations were successful, - // otherwise false. - bool WriteDataFromFifoToSharedMemory(); - - // Write audio parameters to current segment in shared memory. - void WriteParametersToCurrentSegment(double volume, - bool key_pressed, - base::TimeTicks capture_time); + // Write data and audio parameters to current segment in shared memory. + // Returns true if the data was successfully written, returns false if it was + // dropped. + bool WriteDataToCurrentSegment(const media::AudioBus& data, + double volume, + bool key_pressed, + base::TimeTicks capture_time); // Signals over the socket that data has been written to the current segment. // Updates counters and returns true if successful. Logs error and returns @@ -136,25 +134,30 @@ // ensure the we don't overwrite data that hasn't been read yet. size_t number_of_filled_segments_ = 0; - // Counts the total number of calls to Write(). + // Counts the total number of calls to InputSyncWriter::Write(). size_t write_count_ = 0; - // Counts the number of writes to the fifo instead of to the shared memory. - size_t write_to_fifo_count_ = 0; + // Counts the number of calls to InputSyncWriter::Write() when the shared + // memory is full and we instead have to attempt to write to the fifo. + size_t shared_memory_full_count_ = 0; - // Counts the number of errors that causes data to be dropped, due to either - // the fifo or the socket buffer being full. - size_t write_error_count_ = 0; + // Counts the number of times that data is dropped, due to either the fifo or + // the socket buffer being full. + size_t dropped_data_count_ = 0; + + // Counts the number of times we have written data to the shared memory and + // successfully communicated the write over the socket. + size_t successful_write_count_ = 0; // Denotes that the most recent socket error has been logged. Used to avoid // log spam. bool had_socket_error_ = false; - // Counts the fifo writes and errors we get during renderer process teardown - // so that we can account for that (subtract) when we calculate the overall - // counts. - size_t trailing_write_to_fifo_count_ = 0; - size_t trailing_write_error_count_ = 0; + // Counts the missed deadlines and drops we get during renderer process + // teardown so that we can account for that (subtract) when we calculate the + // overall counts. + size_t trailing_shared_memory_full_count_ = 0; + size_t trailing_dropped_data_count_ = 0; // Vector of audio buses allocated during construction and deleted in the // destructor.
diff --git a/services/network/public/cpp/simple_url_loader_throttle.cc b/services/network/public/cpp/simple_url_loader_throttle.cc index 093b6e6..5528eb7 100644 --- a/services/network/public/cpp/simple_url_loader_throttle.cc +++ b/services/network/public/cpp/simple_url_loader_throttle.cc
@@ -43,7 +43,7 @@ return false; if (base::PowerMonitor::IsInitialized() && - base::PowerMonitor::IsOnBatteryPower()) { + !base::PowerMonitor::IsOnBatteryPower()) { return false; }
diff --git a/services/network/public/cpp/simple_url_loader_throttle.h b/services/network/public/cpp/simple_url_loader_throttle.h index 55f6b08..acae642 100644 --- a/services/network/public/cpp/simple_url_loader_throttle.h +++ b/services/network/public/cpp/simple_url_loader_throttle.h
@@ -65,6 +65,7 @@ void SetDelegateForTesting(std::unique_ptr<Delegate> delegate); void SetTimeoutForTesting(base::TimeDelta timeout); + Delegate& GetDelegateForTesting() { return *delegate_; } private: void OnTimeout();
diff --git a/services/network/public/cpp/simple_url_loader_unittest.cc b/services/network/public/cpp/simple_url_loader_unittest.cc index 27e5a06..d9885ba5 100644 --- a/services/network/public/cpp/simple_url_loader_unittest.cc +++ b/services/network/public/cpp/simple_url_loader_unittest.cc
@@ -29,6 +29,7 @@ #include "base/strings/stringprintf.h" #include "base/task/sequenced_task_runner.h" #include "base/test/bind.h" +#include "base/test/power_monitor_test.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/test/test_timeouts.h" @@ -40,6 +41,8 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/system/data_pipe.h" +#include "net/base/mock_network_change_notifier.h" +#include "net/base/network_change_notifier.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" #include "net/http/http_util.h" @@ -66,6 +69,10 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/gurl.h" +#if BUILDFLAG(IS_ANDROID) +#include "base/android/radio_utils.h" +#endif // BUILDFLAG(IS_ANDROID) + namespace network { namespace { @@ -3845,6 +3852,49 @@ } } +TEST(SimpleURLLoaderThrottleTest, ShouldThrottle) { + base::test::TaskEnvironment task_environment( + base::test::TaskEnvironment::MainThreadType::IO); + base::test::ScopedPowerMonitorTestSource power_monitor_source; + auto notifier = net::test::MockNetworkChangeNotifier::Create(); + SimpleURLLoaderThrottle throttle = SimpleURLLoaderThrottle(); + + // Device NOT on battery power + power_monitor_source.SetOnBatteryPower(false); + + // Device's DefaultNetwork NOT Active + notifier.get()->ForceNetworkHandlesSupported(); + notifier.get()->SetIsDefaultNetworkActiveInternalForTesting(false); + +// Device's RadioConnectionType is kCell +#if BUILDFLAG(IS_ANDROID) + base::android::RadioUtils::OverrideForTesting radio_utils_test; + radio_utils_test.SetConnectionTypeForTesting( + base::android::RadioConnectionType::kCell); +#endif // BUILDFLAG(IS_ANDROID) + + EXPECT_FALSE(throttle.GetDelegateForTesting().ShouldThrottle()); + power_monitor_source.SetOnBatteryPower(true); + + // Device's DefaultNetwork is active + notifier.get()->SetIsDefaultNetworkActiveInternalForTesting(true); + + EXPECT_FALSE(throttle.GetDelegateForTesting().ShouldThrottle()); + notifier.get()->SetIsDefaultNetworkActiveInternalForTesting(false); + +// Device's connection type is != kCell +#if BUILDFLAG(IS_ANDROID) + radio_utils_test.SetConnectionTypeForTesting( + base::android::RadioConnectionType::kWifi); + + EXPECT_FALSE(throttle.GetDelegateForTesting().ShouldThrottle()); + radio_utils_test.SetConnectionTypeForTesting( + base::android::RadioConnectionType::kCell); +#endif // BUILDFLAG(IS_ANDROID) + + EXPECT_TRUE(throttle.GetDelegateForTesting().ShouldThrottle()); +} + TEST(SimpleURLLoaderThrottleTest, BatchingDisabled_FeatureDisabled) { SimpleURLLoaderThrottle::ResetConfigForTesting(); net::NetworkTrafficAnnotationTag traffic_annotation =
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 02a1921..2e5f636 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1189,25 +1189,6 @@ ] } ], - "AutofillIgnoreAutocompleteForImport": [ - { - "platforms": [ - "chromeos", - "chromeos_lacros", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "AutofillIgnoreAutocompleteForImport" - ] - } - ] - } - ], "AutofillKeyboardAccessory": [ { "platforms": [ @@ -6440,7 +6421,7 @@ ], "experiments": [ { - "name": "Enabled_20220926", + "name": "Enabled_20221013", "params": { "minPhotosVersionForImage": "6.8", "minPhotosVersionForVideo": "6.8"
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index fe3b316..87d9381 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -8495,6 +8495,7 @@ ActivatedBeforeStarted InactivePageRestriction StartFailed + TimeoutBackgrounded # Fired when a prerender attempt is completed. experimental event prerenderAttemptCompleted
diff --git a/third_party/blink/public/mojom/cookie_manager/cookie_manager_automation.mojom b/third_party/blink/public/mojom/cookie_manager/cookie_manager_automation.mojom index d9ded7b..20856a8 100644 --- a/third_party/blink/public/mojom/cookie_manager/cookie_manager_automation.mojom +++ b/third_party/blink/public/mojom/cookie_manager/cookie_manager_automation.mojom
@@ -4,9 +4,17 @@ module blink.test.mojom; -// Provides a way for tests to modify all cookies where needed. +import "services/network/public/mojom/cookie_manager.mojom"; + +// Provides a way for tests to modify cookies for the calling frame within +// the content_shell test environment. This should be used/expanded in cases +// where the RestrictedCookieManager provides insufficient power or detail. +// This interface is bound per RenderFrameHost. interface CookieManagerAutomation { - // Delete all cookies for the url of the calling frame. // See https://w3c.github.io/webdriver/#delete-all-cookies DeleteAllCookies() => (); + // See https://w3c.github.io/webdriver/#get-all-cookies + GetAllCookies() => (array<network.mojom.CookieWithAccessResult> cookies); + // See https://w3c.github.io/webdriver/#get-named-cookie + GetNamedCookie(string name) => (network.mojom.CookieWithAccessResult? cookie); };
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni index f6a194d..548516f 100644 --- a/third_party/blink/renderer/bindings/generated_in_core.gni +++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -1774,6 +1774,10 @@ ] generated_dictionary_sources_for_testing_in_core = [ + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internal_cookie.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internal_cookie.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internal_cookie_same_site.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internal_cookie_same_site.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internal_dictionary.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internal_dictionary.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internal_dictionary_derived.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_core.gni b/third_party/blink/renderer/bindings/idl_in_core.gni index 87307d91..d1dcb60 100644 --- a/third_party/blink/renderer/bindings/idl_in_core.gni +++ b/third_party/blink/renderer/bindings/idl_in_core.gni
@@ -762,7 +762,10 @@ "//third_party/blink/renderer/core/testing/internal_dictionary_derived_derived.idl", "//third_party/blink/renderer/core/testing/internal_settings.idl", "//third_party/blink/renderer/core/testing/internals.idl", + "//third_party/blink/renderer/core/testing/internals_cookie.idl", "//third_party/blink/renderer/core/testing/internals_delete_all_cookies.idl", + "//third_party/blink/renderer/core/testing/internals_get_all_cookies.idl", + "//third_party/blink/renderer/core/testing/internals_get_named_cookie.idl", "//third_party/blink/renderer/core/testing/attribution_reporting_automation.idl", "//third_party/blink/renderer/core/testing/origin_trials_test.idl", "//third_party/blink/renderer/core/testing/origin_trials_test_dictionary.idl",
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index 8e91527..c886cff 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -467,8 +467,14 @@ "testing/internal_settings.h", "testing/internals.cc", "testing/internals.h", + "testing/internals_cookies.cc", + "testing/internals_cookies.h", "testing/internals_delete_all_cookies.cc", "testing/internals_delete_all_cookies.h", + "testing/internals_get_all_cookies.cc", + "testing/internals_get_all_cookies.h", + "testing/internals_get_named_cookie.cc", + "testing/internals_get_named_cookie.h", "testing/intersection_observer_test_helper.h", "testing/mock_clipboard_host.cc", "testing/mock_clipboard_host.h", @@ -1681,7 +1687,8 @@ "//third_party/blink/renderer/platform:blink_fuzzer_test_support", "//third_party/libprotobuf-mutator", ] - seed_corpus = "//testing/libfuzzer/fuzzers/attribution_source_registration_corpus" + seed_corpus = + "//testing/libfuzzer/fuzzers/attribution_source_registration_corpus" } fuzzer_test("attribution_trigger_registration_fuzzer") {
diff --git a/third_party/blink/renderer/core/content_capture/content_capture_test.cc b/third_party/blink/renderer/core/content_capture/content_capture_test.cc index f37e51ed..c2aa985 100644 --- a/third_party/blink/renderer/core/content_capture/content_capture_test.cc +++ b/third_party/blink/renderer/core/content_capture/content_capture_test.cc
@@ -152,14 +152,15 @@ WebContentCaptureClient& client_; }; -class ContentCaptureTest - : public PageTestBase, - public ::testing::WithParamInterface<std::vector<base::Feature>> { +class ContentCaptureTest : public PageTestBase, + public ::testing::WithParamInterface< + std::vector<base::test::FeatureRef>> { public: ContentCaptureTest() { EnablePlatform(); feature_list_.InitWithFeatures( - GetParam(), /*disabled_features=*/std::vector<base::Feature>()); + GetParam(), + /*disabled_features=*/std::vector<base::test::FeatureRef>()); } void SetUp() override { @@ -366,8 +367,8 @@ INSTANTIATE_TEST_SUITE_P( , ContentCaptureTest, - testing::Values(std::vector<base::Feature>{}, - std::vector<base::Feature>{ + testing::Values(std::vector<base::test::FeatureRef>{}, + std::vector<base::test::FeatureRef>{ features::kContentCaptureConstantStreaming})); TEST_P(ContentCaptureTest, Basic) {
diff --git a/third_party/blink/renderer/core/css/perftest_data/.gitignore b/third_party/blink/renderer/core/css/perftest_data/.gitignore new file mode 100644 index 0000000..a6c57f5 --- /dev/null +++ b/third_party/blink/renderer/core/css/perftest_data/.gitignore
@@ -0,0 +1 @@ +*.json
diff --git a/third_party/blink/renderer/core/layout/ng/ng_anchor_query.cc b/third_party/blink/renderer/core/layout/ng/ng_anchor_query.cc index 093089b..b093dd9 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_anchor_query.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_anchor_query.cc
@@ -89,6 +89,13 @@ return anchor_query; } + enum class Conflict { + // The first entry wins. The calls must be in the tree order. + kFirstInCallOrder, + // Overwrite existing entry if the new one is before the existing one. + kOverwriteIfBefore, + }; + void AddChild(const NGPhysicalFragment& fragment, const PhysicalOffset& offset_from_fragmentainer, const FragmentainerContext& fragmentainer) { @@ -99,14 +106,15 @@ DCHECK(it.value->fragment); AddAnchorReference(it.key, *it.value->fragment, it.value->rect + offset_from_fragmentainer, - fragmentainer); + fragmentainer, Conflict::kFirstInCallOrder); } } void AddAnchorReference(const AtomicString& anchor_name, const NGPhysicalFragment& fragment, const PhysicalRect& physical_rect_in_fragmentainer, - const FragmentainerContext& fragmentainer) { + const FragmentainerContext& fragmentainer, + Conflict conflict) { const LogicalRect rect_in_fragmentainer = fragmentainer.converter.ToLogical(physical_rect_in_fragmentainer); auto* new_value = MakeGarbageCollected<NGStitchedAnchorReference>( @@ -115,16 +123,30 @@ if (result.is_new_entry) return; - // If this is the same anchor-name on a different box, ignore it. The - // first one in the pre-order wins. + // If this is a fragment of the existing box, unite it with other fragments. NGStitchedAnchorReference* existing = result.stored_value->value; - if (existing->fragment->GetLayoutObject() != - new_value->fragment->GetLayoutObject()) { + const LayoutObject* existing_object = existing->fragment->GetLayoutObject(); + DCHECK(existing_object); + const LayoutObject* new_object = new_value->fragment->GetLayoutObject(); + DCHECK(new_object); + if (existing_object == new_object) { + existing->Unite(rect_in_fragmentainer, fragmentainer.offset); return; } - // If this is a fragment of the same box, unite it. - existing->Unite(rect_in_fragmentainer, fragmentainer.offset); + // If this is the same anchor-name on a different box, the first one in the + // pre-order wins. Normally, the call order is in the layout-order, which is + // pre-order of the box tree. But OOFs may be laid out later, check the tree + // order in such case. + switch (conflict) { + case Conflict::kFirstInCallOrder: + DCHECK(existing_object->IsBeforeInPreOrder(*new_object)); + break; + case Conflict::kOverwriteIfBefore: + if (new_object->IsBeforeInPreOrder(*existing_object)) + *existing = *new_value; + break; + } } void Trace(Visitor* visitor) const { visitor->Trace(references); } @@ -269,18 +291,24 @@ DCHECK(containing_block); DCHECK_NE(containing_block, &root_); DCHECK(!skip_info.AncestorSkipped()); - do { + // Skip the first containing block, because the spec defines "If el has the + // same containing block as query el, el is not absolutely positioned." That + // said, for absolutely positioned anchors should be invalid for the first + // containing block. + // https://tabatkins.github.io/specs/css-anchor-position/#determining + containing_block = containing_block->Container(&skip_info); + while (containing_block && containing_block != root_ && + !skip_info.AncestorSkipped()) { NGStitchedAnchorQuery& query = EnsureStitchedAnchorQuery(*containing_block); if (!anchor_name.IsNull()) { - query.AddAnchorReference(anchor_name, fragment, - {offset_from_fragmentainer, fragment.Size()}, - fragmentainer); + query.AddAnchorReference( + anchor_name, fragment, {offset_from_fragmentainer, fragment.Size()}, + fragmentainer, NGStitchedAnchorQuery::Conflict::kOverwriteIfBefore); } query.AddChild(fragment, offset_from_fragmentainer, fragmentainer); containing_block = containing_block->Container(&skip_info); - } while (containing_block && containing_block != root_ && - !skip_info.AncestorSkipped()); + } } NGStitchedAnchorQuery& EnsureStitchedAnchorQuery( @@ -407,27 +435,28 @@ if (result.is_new_entry) return; + // If this is a fragment of the existing |LayoutObject|, unite the rect. DCHECK(result.stored_value->value); NGLogicalAnchorReference& existing = *result.stored_value->value; const LayoutObject* existing_object = existing.fragment->GetLayoutObject(); DCHECK(existing_object); const LayoutObject* new_object = reference->fragment->GetLayoutObject(); DCHECK(new_object); - if (existing_object != new_object) { - if (!reference->is_invalid && !existing.is_invalid) { - // If both new and existing values are valid, ignore the new value. This - // logic assumes the callers call this function in the correct order. - DCHECK(existing_object->IsBeforeInPreOrder(*new_object)); - return; - } - // When out-of-flow objects are involved, callers can't guarantee the call - // order. Insert into the list in the tree order. - reference->InsertInPreOrderInto(&result.stored_value->value); + if (existing_object == new_object) { + existing.rect.Unite(reference->rect); return; } - // If this is a fragment from the same |LayoutObject|, unite the rect. - existing.rect.Unite(reference->rect); + // Ignore the new value if both new and existing values are valid. This logic + // assumes the callers call this function in the correct order. + if (!reference->is_invalid && !existing.is_invalid) { + DCHECK(existing_object->IsBeforeInPreOrder(*new_object)); + return; + } + + // When out-of-flow objects are involved, callers can't guarantee the call + // order. Insert into the list in the tree order. + reference->InsertInPreOrderInto(&result.stored_value->value); } void NGPhysicalAnchorQuery::SetFromLogical(
diff --git a/third_party/blink/renderer/core/loader/link_loader_test.cc b/third_party/blink/renderer/core/loader/link_loader_test.cc index 25c8a505..438aa2a 100644 --- a/third_party/blink/renderer/core/loader/link_loader_test.cc +++ b/third_party/blink/renderer/core/loader/link_loader_test.cc
@@ -545,8 +545,8 @@ LinkLoaderTestPrefetchPrivacyChanges() : privacy_changes_enabled_(GetParam()) {} void SetUp() override { - std::vector<base::Feature> enable_features; - std::vector<base::Feature> disabled_features; + std::vector<base::test::FeatureRef> enable_features; + std::vector<base::test::FeatureRef> disabled_features; if (GetParam()) { enable_features.push_back(features::kPrefetchPrivacyChanges); } else {
diff --git a/third_party/blink/renderer/core/testing/internals_cookie.idl b/third_party/blink/renderer/core/testing/internals_cookie.idl new file mode 100644 index 0000000..7a24972b --- /dev/null +++ b/third_party/blink/renderer/core/testing/internals_cookie.idl
@@ -0,0 +1,17 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +enum InternalCookieSameSite { "None", "Lax", "Strict" }; + +// This matches the spec in https://w3c.github.io/webdriver/#cookies. +dictionary InternalCookie { + DOMString name; + DOMString value; + DOMString path; + DOMString domain; + boolean secure; + boolean httpOnly; + long long expiry; + InternalCookieSameSite sameSite; +};
diff --git a/third_party/blink/renderer/core/testing/internals_cookies.cc b/third_party/blink/renderer/core/testing/internals_cookies.cc new file mode 100644 index 0000000..b43fc4b --- /dev/null +++ b/third_party/blink/renderer/core/testing/internals_cookies.cc
@@ -0,0 +1,42 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/testing/internals_cookies.h" +#include "base/time/time.h" + +namespace blink { + +InternalCookie* CookieMojomToInternalCookie( + const network::mojom::blink::CookieWithAccessResultPtr& cookie, + v8::Isolate* isolate) { + InternalCookie* result = InternalCookie::Create(isolate); + result->setName(cookie->cookie.Name().c_str()); + result->setValue(cookie->cookie.Value().c_str()); + result->setPath(cookie->cookie.Path().c_str()); + result->setDomain(cookie->cookie.Domain().c_str()); + result->setSecure(cookie->cookie.IsSecure()); + result->setHttpOnly(cookie->cookie.IsHttpOnly()); + if (!cookie->cookie.ExpiryDate().is_null()) { + // Expiry is omitted if unspecified. + result->setExpiry( + (cookie->cookie.ExpiryDate() - base::Time::UnixEpoch()).InSeconds()); + } + switch (cookie->cookie.SameSite()) { + case net::CookieSameSite::NO_RESTRICTION: + result->setSameSite(V8InternalCookieSameSite::Enum::kNone); + break; + case net::CookieSameSite::LAX_MODE: + result->setSameSite(V8InternalCookieSameSite::Enum::kLax); + break; + case net::CookieSameSite::STRICT_MODE: + result->setSameSite(V8InternalCookieSameSite::Enum::kStrict); + break; + case net::CookieSameSite::UNSPECIFIED: + // SameSite is omitted if unspecified. + break; + } + return result; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/testing/internals_cookies.h b/third_party/blink/renderer/core/testing/internals_cookies.h new file mode 100644 index 0000000..2077ee9 --- /dev/null +++ b/third_party/blink/renderer/core/testing/internals_cookies.h
@@ -0,0 +1,25 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_INTERNALS_COOKIES_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_INTERNALS_COOKIES_H_ + +#include "services/network/public/mojom/cookie_manager.mojom-blink.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_internal_cookie.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_internal_cookie_same_site.h" +#include "v8/include/v8-isolate.h" + +namespace v8 { +class Isolate; +} // namespace v8 + +namespace blink { + +InternalCookie* CookieMojomToInternalCookie( + const network::mojom::blink::CookieWithAccessResultPtr& cookie, + v8::Isolate* isolate); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_INTERNALS_COOKIES_H_
diff --git a/third_party/blink/renderer/core/testing/internals_get_all_cookies.cc b/third_party/blink/renderer/core/testing/internals_get_all_cookies.cc new file mode 100644 index 0000000..8d7020fbe3 --- /dev/null +++ b/third_party/blink/renderer/core/testing/internals_get_all_cookies.cc
@@ -0,0 +1,52 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/testing/internals_get_all_cookies.h" + +#include "mojo/public/cpp/bindings/remote.h" +#include "services/network/public/mojom/cookie_manager.mojom-blink.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/mojom/cookie_manager/cookie_manager_automation.mojom-blink.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_internal_cookie.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_internal_cookie_same_site.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/testing/internals_cookies.h" + +namespace blink { + +// static +ScriptPromise InternalsGetAllCookies::getAllCookies(ScriptState* script_state, + Internals&) { + LocalDOMWindow* window = LocalDOMWindow::From(script_state); + mojo::Remote<test::mojom::blink::CookieManagerAutomation> cookie_manager; + window->GetBrowserInterfaceBroker().GetInterface( + cookie_manager.BindNewPipeAndPassReceiver()); + + ScriptPromiseResolver* resolver = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + // Get the interface so `cookie_manager` can be moved below. + test::mojom::blink::CookieManagerAutomation* raw_cookie_manager = + cookie_manager.get(); + raw_cookie_manager->GetAllCookies(WTF::BindOnce( + [](ScriptPromiseResolver* resolver, ScriptState* script_state, + mojo::Remote<test::mojom::blink::CookieManagerAutomation>, + WTF::Vector<network::mojom::blink::CookieWithAccessResultPtr> + cookies) { + HeapVector<Member<InternalCookie>> cookie_results; + for (const auto& cookie : cookies) { + cookie_results.push_back( + CookieMojomToInternalCookie(cookie, script_state->GetIsolate())); + } + resolver->Resolve(cookie_results); + }, + WrapPersistent(resolver), WrapPersistent(script_state), + // Keep `cookie_manager` alive to wait for callback. + std::move(cookie_manager))); + return promise; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/testing/internals_get_all_cookies.h b/third_party/blink/renderer/core/testing/internals_get_all_cookies.h new file mode 100644 index 0000000..8d8d034d --- /dev/null +++ b/third_party/blink/renderer/core/testing/internals_get_all_cookies.h
@@ -0,0 +1,27 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_INTERNALS_GET_ALL_COOKIES_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_INTERNALS_GET_ALL_COOKIES_H_ + +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" +#include "third_party/blink/renderer/platform/wtf/forward.h" + +namespace blink { + +class Internals; +class ScriptPromise; +class ScriptState; + +class InternalsGetAllCookies { + STATIC_ONLY(InternalsGetAllCookies); + + public: + static ScriptPromise getAllCookies(ScriptState* script_state, + Internals& internals); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_INTERNALS_GET_ALL_COOKIES_H_
diff --git a/third_party/blink/renderer/core/testing/internals_get_all_cookies.idl b/third_party/blink/renderer/core/testing/internals_get_all_cookies.idl new file mode 100644 index 0000000..912e0b22 --- /dev/null +++ b/third_party/blink/renderer/core/testing/internals_get_all_cookies.idl
@@ -0,0 +1,11 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + ImplementedAs=InternalsGetAllCookies +] partial interface Internals { + // Get details for all cookies in the current context. + // See https://w3c.github.io/webdriver/#get-all-cookies + [CallWith=ScriptState] Promise<sequence<InternalCookie>> getAllCookies(); +};
diff --git a/third_party/blink/renderer/core/testing/internals_get_named_cookie.cc b/third_party/blink/renderer/core/testing/internals_get_named_cookie.cc new file mode 100644 index 0000000..f4aeb40 --- /dev/null +++ b/third_party/blink/renderer/core/testing/internals_get_named_cookie.cc
@@ -0,0 +1,53 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/testing/internals_get_named_cookie.h" + +#include "mojo/public/cpp/bindings/remote.h" +#include "services/network/public/mojom/cookie_manager.mojom-blink.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/mojom/cookie_manager/cookie_manager_automation.mojom-blink.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_internal_cookie.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_internal_cookie_same_site.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/testing/internals_cookies.h" + +namespace blink { + +// static +ScriptPromise InternalsGetNamedCookie::getNamedCookie(ScriptState* script_state, + Internals&, + const String& name) { + LocalDOMWindow* window = LocalDOMWindow::From(script_state); + mojo::Remote<test::mojom::blink::CookieManagerAutomation> cookie_manager; + window->GetBrowserInterfaceBroker().GetInterface( + cookie_manager.BindNewPipeAndPassReceiver()); + + ScriptPromiseResolver* resolver = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + // Get the interface so `cookie_manager` can be moved below. + test::mojom::blink::CookieManagerAutomation* raw_cookie_manager = + cookie_manager.get(); + raw_cookie_manager->GetNamedCookie( + name, WTF::BindOnce( + [](ScriptPromiseResolver* resolver, ScriptState* script_state, + mojo::Remote<test::mojom::blink::CookieManagerAutomation>, + network::mojom::blink::CookieWithAccessResultPtr cookie) { + InternalCookie* result = nullptr; + if (cookie) { + result = CookieMojomToInternalCookie( + cookie, script_state->GetIsolate()); + } + resolver->Resolve(result); + }, + WrapPersistent(resolver), WrapPersistent(script_state), + // Keep `cookie_manager` alive to wait for callback. + std::move(cookie_manager))); + return promise; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/testing/internals_get_named_cookie.h b/third_party/blink/renderer/core/testing/internals_get_named_cookie.h new file mode 100644 index 0000000..3928a8d --- /dev/null +++ b/third_party/blink/renderer/core/testing/internals_get_named_cookie.h
@@ -0,0 +1,28 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_INTERNALS_GET_NAMED_COOKIE_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_INTERNALS_GET_NAMED_COOKIE_H_ + +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" +#include "third_party/blink/renderer/platform/wtf/forward.h" + +namespace blink { + +class Internals; +class ScriptPromise; +class ScriptState; + +class InternalsGetNamedCookie { + STATIC_ONLY(InternalsGetNamedCookie); + + public: + static ScriptPromise getNamedCookie(ScriptState* script_state, + Internals& internals, + const String& name); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_INTERNALS_GET_NAMED_COOKIE_H_
diff --git a/third_party/blink/renderer/core/testing/internals_get_named_cookie.idl b/third_party/blink/renderer/core/testing/internals_get_named_cookie.idl new file mode 100644 index 0000000..5fa0ec0 --- /dev/null +++ b/third_party/blink/renderer/core/testing/internals_get_named_cookie.idl
@@ -0,0 +1,11 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + ImplementedAs=InternalsGetNamedCookie +] partial interface Internals { + // Get details for a cookie in the current context by name if it exists. + // See https://w3c.github.io/webdriver/#get-named-cookie + [CallWith=ScriptState] Promise<InternalCookie?> getNamedCookie(DOMString name); +};
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc b/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc index e008672d..6c0bbe08 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc +++ b/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc
@@ -15,6 +15,7 @@ #include "third_party/blink/renderer/modules/clipboard/clipboard.h" #include "third_party/blink/renderer/modules/clipboard/clipboard_promise.h" #include "third_party/blink/renderer/modules/clipboard/clipboard_writer.h" +#include "third_party/blink/renderer/platform/heap/cross_thread_handle.h" #include "third_party/blink/renderer/platform/image-encoders/image_encoder.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" @@ -83,15 +84,15 @@ } worker_pool::PostTask( - FROM_HERE, CrossThreadBindOnce( - &ClipboardTextReader::EncodeOnBackgroundThread, - std::move(plain_text), WrapCrossThreadPersistent(this), - std::move(clipboard_task_runner_))); + FROM_HERE, + CrossThreadBindOnce(&ClipboardTextReader::EncodeOnBackgroundThread, + std::move(plain_text), MakeCrossThreadHandle(this), + std::move(clipboard_task_runner_))); } static void EncodeOnBackgroundThread( String plain_text, - ClipboardTextReader* reader, + CrossThreadHandle<ClipboardTextReader> reader, scoped_refptr<base::SingleThreadTaskRunner> clipboard_task_runner) { DCHECK(!IsMainThread()); @@ -101,10 +102,13 @@ utf8_bytes.ReserveInitialCapacity(utf8_text.size()); utf8_bytes.Append(utf8_text.data(), utf8_text.size()); - PostCrossThreadTask(*clipboard_task_runner, FROM_HERE, - CrossThreadBindOnce(&ClipboardTextReader::NextRead, - WrapCrossThreadPersistent(reader), - std::move(utf8_bytes))); + PostCrossThreadTask( + *clipboard_task_runner, FROM_HERE, + CrossThreadBindOnce( + &ClipboardTextReader::NextRead, + MakeUnwrappingCrossThreadHandle<ClipboardTextReader>( + std::move(reader)), + std::move(utf8_bytes))); } void NextRead(Vector<uint8_t> utf8_bytes) override { @@ -160,16 +164,15 @@ return; } worker_pool::PostTask( - FROM_HERE, - CrossThreadBindOnce(&ClipboardHtmlReader::EncodeOnBackgroundThread, - std::move(sanitized_html), - WrapCrossThreadPersistent(this), - std::move(clipboard_task_runner_))); + FROM_HERE, CrossThreadBindOnce( + &ClipboardHtmlReader::EncodeOnBackgroundThread, + std::move(sanitized_html), MakeCrossThreadHandle(this), + std::move(clipboard_task_runner_))); } static void EncodeOnBackgroundThread( String plain_text, - ClipboardHtmlReader* reader, + CrossThreadHandle<ClipboardHtmlReader> reader, scoped_refptr<base::SingleThreadTaskRunner> clipboard_task_runner) { DCHECK(!IsMainThread()); @@ -179,10 +182,11 @@ utf8_bytes.ReserveInitialCapacity(utf8_text.size()); utf8_bytes.Append(utf8_text.data(), utf8_text.size()); - PostCrossThreadTask(*clipboard_task_runner, FROM_HERE, - CrossThreadBindOnce(&ClipboardHtmlReader::NextRead, - WrapCrossThreadPersistent(reader), - std::move(utf8_bytes))); + PostCrossThreadTask( + *clipboard_task_runner, FROM_HERE, + CrossThreadBindOnce(&ClipboardHtmlReader::NextRead, + MakeUnwrappingCrossThreadHandle(std::move(reader)), + std::move(utf8_bytes))); } void NextRead(Vector<uint8_t> utf8_bytes) override { @@ -234,16 +238,15 @@ return; } worker_pool::PostTask( - FROM_HERE, - CrossThreadBindOnce(&ClipboardSvgReader::EncodeOnBackgroundThread, - std::move(sanitized_svg), - WrapCrossThreadPersistent(this), - std::move(clipboard_task_runner_))); + FROM_HERE, CrossThreadBindOnce( + &ClipboardSvgReader::EncodeOnBackgroundThread, + std::move(sanitized_svg), MakeCrossThreadHandle(this), + std::move(clipboard_task_runner_))); } static void EncodeOnBackgroundThread( String plain_text, - ClipboardSvgReader* reader, + CrossThreadHandle<ClipboardSvgReader> reader, scoped_refptr<base::SingleThreadTaskRunner> clipboard_task_runner) { DCHECK(!IsMainThread()); @@ -253,10 +256,11 @@ utf8_bytes.ReserveInitialCapacity(utf8_text.size()); utf8_bytes.Append(utf8_text.data(), utf8_text.size()); - PostCrossThreadTask(*clipboard_task_runner, FROM_HERE, - CrossThreadBindOnce(&ClipboardSvgReader::NextRead, - WrapCrossThreadPersistent(reader), - std::move(utf8_bytes))); + PostCrossThreadTask( + *clipboard_task_runner, FROM_HERE, + CrossThreadBindOnce(&ClipboardSvgReader::NextRead, + MakeUnwrappingCrossThreadHandle(std::move(reader)), + std::move(utf8_bytes))); } void NextRead(Vector<uint8_t> utf8_bytes) override {
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc index 0b6abf2..1a94aa2 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc +++ b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
@@ -15,7 +15,9 @@ #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" +#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h" #include "third_party/blink/renderer/modules/clipboard/clipboard.h" +#include "third_party/blink/renderer/platform/heap/cross_thread_handle.h" #include "third_party/blink/renderer/platform/image-decoders/image_decoder.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" @@ -44,20 +46,23 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner) override { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // ArrayBufferContents is a thread-safe smart pointer around the backing + // store. + ArrayBufferContents contents = *raw_data->Content(); worker_pool::PostTask( FROM_HERE, CrossThreadBindOnce(&ClipboardImageWriter::DecodeOnBackgroundThread, - WrapCrossThreadPersistent(raw_data), - WrapCrossThreadPersistent(this), task_runner)); + std::move(contents), MakeCrossThreadHandle(this), + task_runner)); } static void DecodeOnBackgroundThread( - DOMArrayBuffer* png_data, - ClipboardImageWriter* writer, + ArrayBufferContents png_data, + CrossThreadHandle<ClipboardImageWriter> writer, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { DCHECK(!IsMainThread()); std::unique_ptr<ImageDecoder> decoder = ImageDecoder::Create( SegmentReader::CreateFromSkData( - SkData::MakeWithoutCopy(png_data->Data(), png_data->ByteLength())), + SkData::MakeWithoutCopy(png_data.Data(), png_data.DataLength())), true, ImageDecoder::kAlphaPremultiplied, ImageDecoder::kDefaultBitDepth, ColorBehavior::Tag()); sk_sp<SkImage> image = nullptr; @@ -65,10 +70,11 @@ if (decoder) image = ImageBitmap::GetSkImageFromDecoder(std::move(decoder)); - PostCrossThreadTask(*task_runner, FROM_HERE, - CrossThreadBindOnce(&ClipboardImageWriter::Write, - WrapCrossThreadPersistent(writer), - std::move(image))); + PostCrossThreadTask( + *task_runner, FROM_HERE, + CrossThreadBindOnce(&ClipboardImageWriter::Write, + MakeUnwrappingCrossThreadHandle(std::move(writer)), + std::move(image))); } void Write(sk_sp<SkImage> image) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -99,25 +105,28 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner) override { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // ArrayBufferContents is a thread-safe smart pointer around the backing + // store. + ArrayBufferContents contents = *raw_data->Content(); worker_pool::PostTask( FROM_HERE, CrossThreadBindOnce(&ClipboardTextWriter::DecodeOnBackgroundThread, - WrapCrossThreadPersistent(raw_data), - WrapCrossThreadPersistent(this), task_runner)); + std::move(contents), MakeCrossThreadHandle(this), + task_runner)); } static void DecodeOnBackgroundThread( - DOMArrayBuffer* raw_data, - ClipboardTextWriter* writer, + ArrayBufferContents raw_data, + CrossThreadHandle<ClipboardTextWriter> writer, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { DCHECK(!IsMainThread()); - String wtf_string = - String::FromUTF8(reinterpret_cast<const LChar*>(raw_data->Data()), - raw_data->ByteLength()); - PostCrossThreadTask(*task_runner, FROM_HERE, - CrossThreadBindOnce(&ClipboardTextWriter::Write, - WrapCrossThreadPersistent(writer), - std::move(wtf_string))); + String wtf_string = String::FromUTF8( + reinterpret_cast<const LChar*>(raw_data.Data()), raw_data.DataLength()); + PostCrossThreadTask( + *task_runner, FROM_HERE, + CrossThreadBindOnce(&ClipboardTextWriter::Write, + MakeUnwrappingCrossThreadHandle(std::move(writer)), + std::move(wtf_string))); } void Write(const String& text) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc index 47a2d37..35fc84fe 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc
@@ -336,8 +336,8 @@ public testing::WithParamInterface<ThreadPriorityTestParam> { public: void InitWithRealtimePrioritySettings(bool is_enabled_by_finch) { - std::vector<base::Feature> enabled; - std::vector<base::Feature> disabled; + std::vector<base::test::FeatureRef> enabled; + std::vector<base::test::FeatureRef> disabled; if (is_enabled_by_finch) { enabled.push_back(features::kAudioWorkletThreadRealtimePriority); } else {
diff --git a/third_party/blink/renderer/modules/webcodecs/reclaimable_codec_test.cc b/third_party/blink/renderer/modules/webcodecs/reclaimable_codec_test.cc index c19b899..cb34139 100644 --- a/third_party/blink/renderer/modules/webcodecs/reclaimable_codec_test.cc +++ b/third_party/blink/renderer/modules/webcodecs/reclaimable_codec_test.cc
@@ -89,9 +89,9 @@ class ReclaimBackgroundOnlyTest : public BaseReclaimableCodecTest { public: ReclaimBackgroundOnlyTest() { - std::vector<base::Feature> enabled_features{ + std::vector<base::test::FeatureRef> enabled_features{ kReclaimInactiveWebCodecs, kOnlyReclaimBackgroundWebCodecs}; - std::vector<base::Feature> disabled_features{}; + std::vector<base::test::FeatureRef> disabled_features{}; feature_list_.InitWithFeatures(enabled_features, disabled_features); } @@ -104,8 +104,9 @@ class ReclaimForegroundSameAsBackgroundTest : public BaseReclaimableCodecTest { public: ReclaimForegroundSameAsBackgroundTest() { - std::vector<base::Feature> enabled_features{kReclaimInactiveWebCodecs}; - std::vector<base::Feature> disabled_features{ + std::vector<base::test::FeatureRef> enabled_features{ + kReclaimInactiveWebCodecs}; + std::vector<base::test::FeatureRef> disabled_features{ kOnlyReclaimBackgroundWebCodecs}; feature_list_.InitWithFeatures(enabled_features, disabled_features); } @@ -118,8 +119,8 @@ class ReclaimDisabledTest : public BaseReclaimableCodecTest { public: ReclaimDisabledTest() { - std::vector<base::Feature> enabled_features{}; - std::vector<base::Feature> disabled_features{ + std::vector<base::test::FeatureRef> enabled_features{}; + std::vector<base::test::FeatureRef> disabled_features{ kReclaimInactiveWebCodecs, kOnlyReclaimBackgroundWebCodecs}; feature_list_.InitWithFeatures(enabled_features, disabled_features); }
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder_broker_test.cc b/third_party/blink/renderer/modules/webcodecs/video_decoder_broker_test.cc index 58e9419..ac933c8 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_decoder_broker_test.cc +++ b/third_party/blink/renderer/modules/webcodecs/video_decoder_broker_test.cc
@@ -179,12 +179,12 @@ public: VideoDecoderBrokerTest() { // Make sure we have the option of creating HW or SW decoders. - std::vector<base::Feature> disabled_features{ + std::vector<base::test::FeatureRef> disabled_features{ media::kForceHardwareVideoDecoders}; // Make it easier to switch between HW and SW decoders, by initializing with // configs with a small height. - std::vector<base::Feature> enabled_features{ + std::vector<base::test::FeatureRef> enabled_features{ media::kResolutionBasedDecoderPriority}; feature_list_.InitWithFeatures(enabled_features, disabled_features);
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc index 9636aa1..0117953 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
@@ -1863,6 +1863,7 @@ size, buffer_format, buffer_usage, gpu::kNullSurfaceHandle, nullptr); if (gpu_memory_buffer) { + gpu_memory_buffer->SetColorSpace(color_space_); back_buffer_mailbox = sii->CreateSharedImage( gpu_memory_buffer.get(), gpu_memory_buffer_manager, color_space_, origin, kPremul_SkAlphaType, usage | additional_usage_flags);
diff --git a/third_party/blink/renderer/platform/heap/BUILD.gn b/third_party/blink/renderer/platform/heap/BUILD.gn index cb0902c..46d2565e 100644 --- a/third_party/blink/renderer/platform/heap/BUILD.gn +++ b/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -31,6 +31,8 @@ "collection_support/heap_linked_stack.h", "collection_support/heap_vector.h", "collection_support/heap_vector_backing.h", + "cross_thread_handle.h", + "cross_thread_handle_internal.h", "custom_spaces.cc", "custom_spaces.h", "disallow_new_wrapper.h", @@ -140,6 +142,7 @@ "../testing/run_all_tests.cc", "test/blink_gc_memory_dump_provider_test.cc", "test/concurrent_marking_test.cc", + "test/cross_thread_handle_test.cc", "test/heap_compact_test.cc", "test/heap_linked_stack_test.cc", "test/heap_test.cc",
diff --git a/third_party/blink/renderer/platform/heap/cross_thread_handle.h b/third_party/blink/renderer/platform/heap/cross_thread_handle.h new file mode 100644 index 0000000..d3f9280 --- /dev/null +++ b/third_party/blink/renderer/platform/heap/cross_thread_handle.h
@@ -0,0 +1,128 @@ +// Copyright 2022 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_PLATFORM_HEAP_CROSS_THREAD_HANDLE_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_CROSS_THREAD_HANDLE_H_ + +#include "third_party/blink/renderer/platform/heap/cross_thread_handle_internal.h" + +namespace blink { + +// A handle object that may be used to hold a garbage collection object from a +// different thread than the object was created on. The handle supports +// thread-safe copy/move/destruction. The underlying object may only be used +// from the creation thread. +// +// Example posting to a static method that forwards back to an instance method +// on the main thread: +// ``` +// class PingPong final : public GarbageCollected<PingPong> { +// public: +// void Ping() { +// DCHECK(IsMainThread()); +// worker_pool::PostTask(FROM_HERE, +// CrossThreadBindOnce(&PingPong::PongOnBackground, +// MakeCrossThreadHandle(this), +// std::move(task_runner_))); +// } +// +// private: +// const scoped_refptr<base::SingleThreadTaskRunner> task_runner_ = +// GetTaskRunner(); +// +// void DoneOnMainThread() { DCHECK(IsMainThread()); } +// +// static void PongOnBackground( +// CrossThreadHandle<PingPong> ping_pong, +// scoped_refptr<base::SingleThreadTaskRunner> task_runner) { +// DCHECK(!IsMainThread()); +// PostCrossThreadTask( +// *task_runner, FROM_HERE, +// CrossThreadBindOnce(&PingPong::DoneOnMainThread, +// MakeUnwrappingCrossThreadWeakHandle( +// std::move(ping_pong)))); +// } +// }; +// ``` +template <typename T> +using CrossThreadHandle = internal:: + BasicCrossThreadHandle<T, internal::StrongCrossThreadHandleWeaknessPolicy>; + +// Utility function creating a `CrossThreadHandle` tracking the current source +// location position in debugging configurations. +template <typename T> +CrossThreadHandle<T> MakeCrossThreadHandle( + T* value, + const CrossThreadHandleLocation& loc = + CROSS_THREAD_HANDLE_LOCATION_FROM_HERE) { + return CrossThreadHandle<T>(value); +} + +// A weak handle object with similar restrictions as `CrossThreadHandle`. +// The object is only held alive weakly, meaning that the object may be +// reclaimed by the garbage collector. As a consequence, any value retrieved +// from this handle must be checked against nullptr. +template <typename T> +using CrossThreadWeakHandle = internal:: + BasicCrossThreadHandle<T, internal::WeakCrossThreadHandleWeaknessPolicy>; + +// Utility function creating a `CrossThreadWeakHandle` tracking the current +// source location position in debugging configurations. +template <typename T> +CrossThreadWeakHandle<T> MakeCrossThreadWeakHandle( + T* value, + const CrossThreadHandleLocation& loc = + CROSS_THREAD_HANDLE_LOCATION_FROM_HERE) { + return CrossThreadWeakHandle<T>(value); +} + +// A version of `CrossThreadHandle` that automatically unwraps into `T*` on +// invocation of a bound function. This is useful for binding against regular +// instance methods of a type. +template <typename T> +using UnwrappingCrossThreadHandle = internal::BasicUnwrappingCrossThreadHandle< + T, + internal::StrongCrossThreadHandleWeaknessPolicy>; + +// Utility function creating a `UnwrappingCrossThreadHandle`. +template <typename T> +UnwrappingCrossThreadHandle<T> MakeUnwrappingCrossThreadHandle( + const CrossThreadHandle<T>& handle) { + return UnwrappingCrossThreadHandle<T>(handle); +} + +// Utility function creating a `UnwrappingCrossThreadHandle`. +template <typename T> +UnwrappingCrossThreadHandle<T> MakeUnwrappingCrossThreadHandle( + CrossThreadHandle<T>&& handle) { + return UnwrappingCrossThreadHandle<T>(std::move(handle)); +} + +// A version of `CrossThreadWeakHandle` that automatically unwraps into `T*` +// on invocation of a bound function. This is useful for binding against regular +// instance methods of a type. +template <typename T> +using UnwrappingCrossThreadWeakHandle = + internal::BasicUnwrappingCrossThreadHandle< + T, + internal::WeakCrossThreadHandleWeaknessPolicy>; + +// Utility function creating a `UnwrappingCrossThreadHandle`. +template <typename T> +UnwrappingCrossThreadWeakHandle<T> MakeUnwrappingCrossThreadWeakHandle( + const CrossThreadWeakHandle<T>& handle) { + return UnwrappingCrossThreadWeakHandle<T>(handle); +} + +// Utility function creating a `UnwrappingCrossThreadHandle`. + +template <typename T> +UnwrappingCrossThreadWeakHandle<T> MakeUnwrappingCrossThreadWeakHandle( + CrossThreadWeakHandle<T>&& handle) { + return UnwrappingCrossThreadWeakHandle<T>(std::move(handle)); +} + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_CROSS_THREAD_HANDLE_H_
diff --git a/third_party/blink/renderer/platform/heap/cross_thread_handle_internal.h b/third_party/blink/renderer/platform/heap/cross_thread_handle_internal.h new file mode 100644 index 0000000..a88ee222 --- /dev/null +++ b/third_party/blink/renderer/platform/heap/cross_thread_handle_internal.h
@@ -0,0 +1,178 @@ +// Copyright 2022 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_PLATFORM_HEAP_CROSS_THREAD_HANDLE_INTERNAL_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_CROSS_THREAD_HANDLE_INTERNAL_H_ + +#include "base/bind.h" +#include "base/threading/platform_thread.h" +#include "third_party/blink/renderer/platform/heap/heap_buildflags.h" +#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h" +#include "v8/include/cppgc/cross-thread-persistent.h" +#include "v8/include/cppgc/source-location.h" + +// Required to optimize away locations for builds that do not need them to avoid +// binary size blowup. +// Same as in `platform/heap/persistent.h`. Avoiding the include to avoid +// exposing other types that are harder to use in concurrent contexts. +#if BUILDFLAG(VERBOSE_PERSISTENT) +#define CROSS_THREAD_HANDLE_LOCATION_FROM_HERE \ + blink::CrossThreadHandleLocation::Current() +#else // !BUILDFLAG(VERBOSE_PERSISTENT) +#define CROSS_THREAD_HANDLE_LOCATION_FROM_HERE \ + blink::CrossThreadHandleLocation() +#endif // !BUILDFLAG(VERBOSE_PERSISTENT) + +namespace blink { + +template <typename T, typename WeaknessPolicy> +class BasicUnwrappingCrossThreadHandle; + +// A source location that is used for tracking creation of +// `CrossThreadHandle` and `CrossThreadWeakHandle` in debugging +// configurations. +using CrossThreadHandleLocation = cppgc::SourceLocation; + +namespace internal { + +struct StrongCrossThreadHandleWeaknessPolicy { + template <typename T> + using InternalRefType = cppgc::subtle::CrossThreadPersistent<T>; +}; + +struct WeakCrossThreadHandleWeaknessPolicy { + template <typename T> + using InternalRefType = cppgc::subtle::WeakCrossThreadPersistent<T>; +}; + +template <typename T, typename WeaknessPolicy> +class BasicCrossThreadHandle { + public: + explicit BasicCrossThreadHandle(T* raw, + const CrossThreadHandleLocation& loc = + CROSS_THREAD_HANDLE_LOCATION_FROM_HERE) + : ref_(raw, loc) {} + + ~BasicCrossThreadHandle() = default; + BasicCrossThreadHandle(BasicCrossThreadHandle&&) = default; + // Required by CrossThreadCopier. + BasicCrossThreadHandle(const BasicCrossThreadHandle&) = default; + + BasicCrossThreadHandle& operator=(BasicCrossThreadHandle&&) = delete; + BasicCrossThreadHandle* operator=(const BasicCrossThreadHandle&) = delete; + + protected: + // Returns a pointer to the garbage collected object. Must only be used from + // the creation thread and will crash if invoked on any other thread. + T* GetOnCreationThread() const { + CHECK_EQ(creation_thread_id_, base::PlatformThread::CurrentId()); + return ref_.Get(); + } + + private: + template <typename U, typename V> + friend class blink::BasicUnwrappingCrossThreadHandle; + + typename WeaknessPolicy::template InternalRefType<T> ref_; + const base::PlatformThreadId creation_thread_id_ = + base::PlatformThread::CurrentId(); +}; + +template <typename T, typename WeaknessPolicy> +class BasicUnwrappingCrossThreadHandle final + : public BasicCrossThreadHandle<T, WeaknessPolicy> { + using Base = BasicCrossThreadHandle<T, WeaknessPolicy>; + + public: + explicit BasicUnwrappingCrossThreadHandle( + BasicCrossThreadHandle<T, WeaknessPolicy>&& handle) + : Base(std::move(handle)) {} + explicit BasicUnwrappingCrossThreadHandle( + const BasicCrossThreadHandle<T, WeaknessPolicy>& handle) + : Base(handle) {} + + ~BasicUnwrappingCrossThreadHandle() = default; + BasicUnwrappingCrossThreadHandle(BasicUnwrappingCrossThreadHandle&&) = + default; + // Required by CrossThreadCopier. + BasicUnwrappingCrossThreadHandle(const BasicUnwrappingCrossThreadHandle&) = + default; + + // Re-expose the actual getter for the underlying object. + using Base::GetOnCreationThread; + + // Returns whether a value is set. May only be accessed on the thread the + // original CrossThreadHandle object was created. + // + // Exposed so the callback implementation can test if weak handles are still + // live before trying to run the callback. + explicit operator bool() const { return Base::GetOnCreationThread(); } + + BasicUnwrappingCrossThreadHandle& operator=( + BasicUnwrappingCrossThreadHandle&&) = delete; + BasicUnwrappingCrossThreadHandle* operator=( + const BasicUnwrappingCrossThreadHandle&) = delete; +}; + +} // namespace internal +} // namespace blink + +namespace WTF { + +template <typename T, typename WeaknessPolicy> +struct CrossThreadCopier< + blink::internal::BasicCrossThreadHandle<T, WeaknessPolicy>> + : public CrossThreadCopierPassThrough< + blink::internal::BasicCrossThreadHandle<T, WeaknessPolicy>> {}; + +template <typename T, typename WeaknessPolicy> +struct CrossThreadCopier< + blink::internal::BasicUnwrappingCrossThreadHandle<T, WeaknessPolicy>> + : public CrossThreadCopierPassThrough< + blink::internal::BasicUnwrappingCrossThreadHandle<T, + WeaknessPolicy>> {}; + +} // namespace WTF + +namespace base { + +template <typename T> +struct IsWeakReceiver<blink::internal::BasicUnwrappingCrossThreadHandle< + T, + blink::internal::WeakCrossThreadHandleWeaknessPolicy>> : std::true_type {}; + +template <typename T, typename WeaknessPolicy> +struct BindUnwrapTraits< + blink::internal::BasicUnwrappingCrossThreadHandle<T, WeaknessPolicy>> { + static T* Unwrap( + const blink::internal::BasicUnwrappingCrossThreadHandle<T, + WeaknessPolicy>& + wrapped) { + return wrapped.GetOnCreationThread(); + } +}; + +template <typename T, typename WeaknessPolicy> +struct MaybeValidTraits< + blink::internal::BasicCrossThreadHandle<T, WeaknessPolicy>> { + static bool MaybeValid( + const blink::internal::BasicCrossThreadHandle<T, WeaknessPolicy>& p) { + return true; + } +}; + +template <typename T, typename WeaknessPolicy> +struct MaybeValidTraits< + blink::internal::BasicUnwrappingCrossThreadHandle<T, WeaknessPolicy>> { + static bool MaybeValid( + const blink::internal::BasicUnwrappingCrossThreadHandle<T, + WeaknessPolicy>& + p) { + return true; + } +}; + +} // namespace base + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_CROSS_THREAD_HANDLE_INTERNAL_H_
diff --git a/third_party/blink/renderer/platform/heap/persistent.h b/third_party/blink/renderer/platform/heap/persistent.h index de77a8a..1992c0f8 100644 --- a/third_party/blink/renderer/platform/heap/persistent.h +++ b/third_party/blink/renderer/platform/heap/persistent.h
@@ -35,6 +35,8 @@ // CrossThreadPersistent allows retaining objects from threads other than the // thread that owns the heap of the corresponding object. // +// Strongly prefer using `CrossThreadHandle` if the use case allows. +// // Caveats: // - Does not protect the heap owning an object from terminating. E.g., posting // a task with a CrossThreadPersistent for `this` will result in a @@ -48,6 +50,8 @@ // CrossThreadWeakPersistent allows weakly retaining objects from threads other // than the thread that owns the heap of the corresponding object. // +// Strongly prefer using `CrossThreadWeakHandle` if the use case allows. +// // Caveats: // - Does not protect the heap owning an object from termination, as the // reference is weak.
diff --git a/third_party/blink/renderer/platform/heap/test/cross_thread_handle_test.cc b/third_party/blink/renderer/platform/heap/test/cross_thread_handle_test.cc new file mode 100644 index 0000000..0ae6909 --- /dev/null +++ b/third_party/blink/renderer/platform/heap/test/cross_thread_handle_test.cc
@@ -0,0 +1,253 @@ +// Copyright 2022 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/platform/heap/cross_thread_handle.h" +#include "base/memory/scoped_refptr.h" +#include "base/task/thread_pool.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" +#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h" +#include "third_party/blink/renderer/platform/heap/persistent.h" +#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" +#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_base.h" +#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" +#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" + +namespace WTF { + +template <> +struct CrossThreadCopier<base::internal::UnretainedWrapper<void>> + : public CrossThreadCopierPassThrough< + base::internal::UnretainedWrapper<void>> { + STATIC_ONLY(CrossThreadCopier); +}; + +} // namespace WTF + +namespace blink { +namespace { + +class CrossThreadHandleTest : public TestSupportingGC {}; + +class PingPongBase; +class GCed final : public GarbageCollected<GCed> { + public: + void Trace(Visitor*) const {} + + void SetReceivedPong(scoped_refptr<PingPongBase>); +}; + +TEST_F(CrossThreadHandleTest, GetOnCreationThread) { + auto* gced = MakeGarbageCollected<GCed>(); + auto handle = MakeCrossThreadHandle(gced); + PreciselyCollectGarbage(); + EXPECT_EQ( + gced, + MakeUnwrappingCrossThreadHandle(std::move(handle)).GetOnCreationThread()); +} + +TEST_F(CrossThreadHandleTest, UnwrapperGetOnCreationThread) { + auto* gced = MakeGarbageCollected<GCed>(); + auto handle = MakeCrossThreadHandle(gced); + PreciselyCollectGarbage(); + auto unwrapping_handle = MakeUnwrappingCrossThreadHandle(std::move(handle)); + PreciselyCollectGarbage(); + EXPECT_EQ(gced, unwrapping_handle.GetOnCreationThread()); +} + +class PingPongBase : public WTF::ThreadSafeRefCounted<PingPongBase> { + public: + PingPongBase(scoped_refptr<base::SingleThreadTaskRunner> main_runner, + scoped_refptr<base::SequencedTaskRunner> thread_runner) + : main_runner_(std::move(main_runner)), + thread_runner_(std::move(thread_runner)), + needle_(MakeGarbageCollected<GCed>()) {} + + bool ReceivedPong() const { return received_pong_; } + + void SetReceivedPong() { received_pong_ = true; } + + protected: + scoped_refptr<base::SingleThreadTaskRunner> main_runner_; + scoped_refptr<base::SequencedTaskRunner> thread_runner_; + WeakPersistent<GCed> needle_; + bool received_pong_ = false; +}; + +void GCed::SetReceivedPong(scoped_refptr<PingPongBase> ping_pong) { + ping_pong->SetReceivedPong(); +} + +class PassThroughPingPong final : public PingPongBase { + public: + PassThroughPingPong(scoped_refptr<base::SingleThreadTaskRunner> main_runner, + scoped_refptr<base::SequencedTaskRunner> thread_runner) + : PingPongBase(std::move(main_runner), std::move(thread_runner)) {} + + void Ping() { + PostCrossThreadTask( + *thread_runner_, FROM_HERE, + WTF::CrossThreadBindOnce(&PassThroughPingPong::PingOnOtherThread, + scoped_refptr(this), + MakeCrossThreadHandle(needle_.Get()))); + TestSupportingGC::PreciselyCollectGarbage(); + } + + private: + static void PingOnOtherThread(scoped_refptr<PassThroughPingPong> ping_pong, + CrossThreadHandle<GCed> handle) { + auto main_runner = ping_pong->main_runner_; + PostCrossThreadTask( + *main_runner, FROM_HERE, + WTF::CrossThreadBindOnce(&PassThroughPingPong::PongOnMainThread, + std::move(ping_pong), std::move(handle))); + } + + static void PongOnMainThread(scoped_refptr<PassThroughPingPong> ping_pong, + CrossThreadHandle<GCed> handle) { + TestSupportingGC::PreciselyCollectGarbage(); + EXPECT_EQ(ping_pong->needle_.Get(), + MakeUnwrappingCrossThreadHandle(std::move(handle)) + .GetOnCreationThread()); + ping_pong->SetReceivedPong(); + } +}; + +TEST_F(CrossThreadHandleTest, PassThroughPingPong) { + auto thread_runner = base::ThreadPool::CreateSequencedTaskRunner({}); + auto main_runner = task_environment_.GetMainThreadTaskRunner(); + auto ping_pong = + base::MakeRefCounted<PassThroughPingPong>(main_runner, thread_runner); + ping_pong->Ping(); + task_environment_.RunUntilIdle(); + EXPECT_TRUE(ping_pong->ReceivedPong()); +} + +class UnwrappingPingPong final : public PingPongBase { + public: + UnwrappingPingPong(scoped_refptr<base::SingleThreadTaskRunner> main_runner, + scoped_refptr<base::SequencedTaskRunner> thread_runner) + : PingPongBase(std::move(main_runner), std::move(thread_runner)) {} + + void Ping() { + PostCrossThreadTask( + *thread_runner_, FROM_HERE, + WTF::CrossThreadBindOnce(&UnwrappingPingPong::PingOnOtherThread, + scoped_refptr(this), + MakeCrossThreadHandle(needle_.Get()))); + TestSupportingGC::PreciselyCollectGarbage(); + } + + private: + static void PingOnOtherThread(scoped_refptr<UnwrappingPingPong> ping_pong, + CrossThreadHandle<GCed> handle) { + auto main_runner = ping_pong->main_runner_; + PostCrossThreadTask( + *main_runner, FROM_HERE, + WTF::CrossThreadBindOnce( + &UnwrappingPingPong::PongOnMainThread, std::move(ping_pong), + MakeUnwrappingCrossThreadHandle(std::move(handle)))); + } + + static void PongOnMainThread(scoped_refptr<UnwrappingPingPong> ping_pong, + GCed* gced) { + // Unwrapping keeps the handle in scope during the call, so even a GC + // without stack cannot reclaim the object here. + TestSupportingGC::PreciselyCollectGarbage(); + EXPECT_EQ(ping_pong->needle_.Get(), gced); + ping_pong->SetReceivedPong(); + } +}; + +TEST_F(CrossThreadHandleTest, UnwrappingPingPong) { + auto thread_runner = base::ThreadPool::CreateSequencedTaskRunner({}); + auto main_runner = task_environment_.GetMainThreadTaskRunner(); + auto ping_pong = + base::MakeRefCounted<UnwrappingPingPong>(main_runner, thread_runner); + ping_pong->Ping(); + task_environment_.RunUntilIdle(); + EXPECT_TRUE(ping_pong->ReceivedPong()); +} + +class BindToMethodPingPong final : public PingPongBase { + public: + BindToMethodPingPong(scoped_refptr<base::SingleThreadTaskRunner> main_runner, + scoped_refptr<base::SequencedTaskRunner> thread_runner) + : PingPongBase(std::move(main_runner), std::move(thread_runner)) {} + + void Ping() { + PostCrossThreadTask( + *thread_runner_, FROM_HERE, + WTF::CrossThreadBindOnce(&BindToMethodPingPong::PingOnOtherThread, + scoped_refptr(this), + MakeCrossThreadHandle(needle_.Get()))); + TestSupportingGC::PreciselyCollectGarbage(); + ASSERT_TRUE(needle_); + } + + private: + static void PingOnOtherThread(scoped_refptr<BindToMethodPingPong> ping_pong, + CrossThreadHandle<GCed> handle) { + auto main_runner = ping_pong->main_runner_; + PostCrossThreadTask(*main_runner, FROM_HERE, + WTF::CrossThreadBindOnce( + &GCed::SetReceivedPong, + MakeUnwrappingCrossThreadHandle(std::move(handle)), + std::move(ping_pong))); + } +}; + +TEST_F(CrossThreadHandleTest, BindToMethodPingPong) { + auto thread_runner = base::ThreadPool::CreateSequencedTaskRunner({}); + auto main_runner = task_environment_.GetMainThreadTaskRunner(); + auto ping_pong = + base::MakeRefCounted<BindToMethodPingPong>(main_runner, thread_runner); + ping_pong->Ping(); + task_environment_.RunUntilIdle(); + EXPECT_TRUE(ping_pong->ReceivedPong()); +} + +class BindToMethodDiscardingPingPong final : public PingPongBase { + public: + BindToMethodDiscardingPingPong( + scoped_refptr<base::SingleThreadTaskRunner> main_runner, + scoped_refptr<base::SequencedTaskRunner> thread_runner) + : PingPongBase(std::move(main_runner), std::move(thread_runner)) {} + + void Ping() { + PostCrossThreadTask( + *thread_runner_, FROM_HERE, + WTF::CrossThreadBindOnce( + &BindToMethodDiscardingPingPong::PingOnOtherThread, + scoped_refptr(this), MakeCrossThreadWeakHandle(needle_.Get()))); + TestSupportingGC::PreciselyCollectGarbage(); + ASSERT_FALSE(needle_); + } + + private: + static void PingOnOtherThread( + scoped_refptr<BindToMethodDiscardingPingPong> ping_pong, + CrossThreadWeakHandle<GCed> handle) { + auto main_runner = ping_pong->main_runner_; + PostCrossThreadTask( + *main_runner, FROM_HERE, + WTF::CrossThreadBindOnce( + &GCed::SetReceivedPong, + MakeUnwrappingCrossThreadWeakHandle(std::move(handle)), + std::move(ping_pong))); + } +}; + +TEST_F(CrossThreadHandleTest, BindToMethodDiscardingPingPong) { + auto thread_runner = base::ThreadPool::CreateSequencedTaskRunner({}); + auto main_runner = task_environment_.GetMainThreadTaskRunner(); + auto ping_pong = base::MakeRefCounted<BindToMethodDiscardingPingPong>( + main_runner, thread_runner); + ping_pong->Ping(); + task_environment_.RunUntilIdle(); + EXPECT_FALSE(ping_pong->ReceivedPong()); +} + +} // namespace +} // namespace blink
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter_test.cc b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter_test.cc index 91ae8663..2fe9684 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter_test.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter_test.cc
@@ -200,8 +200,8 @@ sdp_format_(webrtc::SdpVideoFormat( webrtc::CodecTypeToPayloadString(webrtc::kVideoCodecVP9))), spatial_index_(0) { - std::vector<base::Feature> enabled_features; - std::vector<base::Feature> disabled_features; + std::vector<base::test::FeatureRef> enabled_features; + std::vector<base::test::FeatureRef> disabled_features; #if BUILDFLAG(IS_WIN) enabled_features.push_back(::media::kD3D11Vp9kSVCHWDecoding); #endif
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc index e6b940b3..8d6b04d 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -198,17 +198,19 @@ // Constructs a FrameSchedulerImplTest with a list of features to enable and a // list of features to disable. - FrameSchedulerImplTest(std::vector<base::Feature> features_to_enable, - std::vector<base::Feature> features_to_disable) + FrameSchedulerImplTest( + std::vector<base::test::FeatureRef> features_to_enable, + std::vector<base::test::FeatureRef> features_to_disable) : FrameSchedulerImplTest() { feature_list_.InitWithFeatures(features_to_enable, features_to_disable); } // Constructs a FrameSchedulerImplTest with a feature to enable, associated // params, and a list of features to disable. - FrameSchedulerImplTest(const base::Feature& feature_to_enable, - const base::FieldTrialParams& feature_to_enable_params, - const std::vector<base::Feature>& features_to_disable) + FrameSchedulerImplTest( + const base::Feature& feature_to_enable, + const base::FieldTrialParams& feature_to_enable_params, + const std::vector<base::test::FeatureRef>& features_to_disable) : FrameSchedulerImplTest() { feature_list_.InitWithFeaturesAndParameters( {{feature_to_enable, feature_to_enable_params}}, features_to_disable);
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc index 49a1318..b2c549d 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
@@ -395,8 +395,9 @@ class MainThreadSchedulerImplTest : public testing::Test { public: - MainThreadSchedulerImplTest(std::vector<Feature> features_to_enable, - std::vector<Feature> features_to_disable) { + MainThreadSchedulerImplTest( + const std::vector<base::test::FeatureRef>& features_to_enable, + const std::vector<base::test::FeatureRef>& features_to_disable) { feature_list_.InitWithFeatures(features_to_enable, features_to_disable); }
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc index 74b0d39f..b73ecaf5 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
@@ -94,8 +94,8 @@ feature_list_.InitAndEnableFeature(blink::features::kStopInBackground); } - PageSchedulerImplTest(std::vector<base::Feature> enabled_features, - std::vector<base::Feature> disabled_features) { + PageSchedulerImplTest(std::vector<base::test::FeatureRef> enabled_features, + std::vector<base::test::FeatureRef> disabled_features) { feature_list_.InitWithFeatures(enabled_features, disabled_features); }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-name-multicol-003.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-name-multicol-003.tentative.html new file mode 100644 index 0000000..21425112 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-name-multicol-003.tentative.html
@@ -0,0 +1,59 @@ +<!DOCTYPE html> +<title>Anchor name resolution of OOF anchors in multicol</title> +<link rel="help" href="https://tabatkins.github.io/specs/css-anchor-position/#propdef-anchor-name"> +<link rel="help" href="https://tabatkins.github.io/specs/css-anchor-position/#anchor-size"> +<link rel="author" href="mailto:kojii@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<style> +.relpos { + position: relative; +} +.abspos { + position: absolute; +} +.columns { + column-count: 6; + column-fill: auto; + column-gap: 10px; + column-width: 20px; + width: 170px; + height: 50px; +} +.spacer { + height: 10px; + background: pink; +} +.anchor { + anchor-name: --a1; + margin-left: 5px; + width: 10px; + background: orange; +} +.target { + position: absolute; + background: lime; + opacity: .3; + left: anchor(--a1 left); + top: anchor(--a1 top); + width: anchor-size(--a1 width); + height: anchor-size(--a1 height); +} +</style> +<body onload="checkLayout('.target')"> + <div class="spacer"></div> + <div class="columns"> + <div class="relpos"> + <div class="relpos"> + <div class="spacer"></div> + <div class="anchor abspos" style="top: 120px; height: 100px"></div> + <div class="anchor" style="height: 60px"></div> + <div class="target" + data-expected-width=40 data-expected-height=50></div> + </div> + <div class="target" + data-expected-width=70 data-expected-height=50></div> + </div> + </div> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/docs/writing-tests/testdriver.md b/third_party/blink/web_tests/external/wpt/docs/writing-tests/testdriver.md index 8c694fac..cc280084 100644 --- a/third_party/blink/web_tests/external/wpt/docs/writing-tests/testdriver.md +++ b/third_party/blink/web_tests/external/wpt/docs/writing-tests/testdriver.md
@@ -50,6 +50,8 @@ ### Cookies ### ```eval_rst .. js:autofunction:: test_driver.delete_all_cookies +.. js:autofunction:: test_driver.get_all_cookies +.. js:autofunction:: test_driver.get_named_cookie ``` ### Permissions ###
diff --git a/third_party/blink/web_tests/external/wpt/dom/nodes/aria-element-reflection.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/dom/nodes/aria-element-reflection.tentative-expected.txt deleted file mode 100644 index a4b34447..0000000 --- a/third_party/blink/web_tests/external/wpt/dom/nodes/aria-element-reflection.tentative-expected.txt +++ /dev/null
@@ -1,26 +0,0 @@ -This is a testharness.js-based test. -PASS aria-activedescendant element reflection -PASS If the content attribute is set directly, the IDL attribute getter always returns the first element whose ID matches the content attribute. -PASS Setting the IDL attribute to an element which is not the first element in DOM order with its ID causes the content attribute to be an empty string -PASS Setting an element reference that crosses into a shadow tree is disallowed, but setting one that is in a shadow inclusive ancestor is allowed. -PASS aria-errormessage -PASS aria-details -PASS Deleting a reflected element should return null for the IDL attribute and cause the content attribute to become stale. -PASS Changing the ID of an element causes the content attribute to become out of sync. -PASS Reparenting an element into a descendant shadow scope hides the element reference. -PASS Reparenting referenced element cannot cause retargeting of reference. -PASS Element reference set in invalid scope remains intact throughout move to valid scope. -FAIL aria-labelledby. assert_equals: check idl attribute caching after parsing expected [Element node <div id="billingElement">Billing</div>, Element node <div id="nameElement">Name</div>] but got [Element node <div id="billingElement">Billing</div>, Element node <div id="nameElement">Name</div>] -PASS aria-controls. -PASS aria-describedby. -PASS aria-flowto. -PASS aria-owns. -PASS shadow DOM behaviour for FrozenArray element reflection. -PASS Moving explicitly set elements across shadow DOM boundaries. -PASS Moving explicitly set elements around within the same scope, and removing from the DOM. -PASS Reparenting. -PASS Attaching element reference before it's inserted into the DOM. -PASS Cross-document references and moves. -PASS Adopting element keeps references. -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/aria-element-reflection.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/html/dom/aria-element-reflection.tentative-expected.txt deleted file mode 100644 index e5b83c9..0000000 --- a/third_party/blink/web_tests/external/wpt/html/dom/aria-element-reflection.tentative-expected.txt +++ /dev/null
@@ -1,28 +0,0 @@ -This is a testharness.js-based test. -PASS aria-activedescendant element reflection -PASS If the content attribute is set directly, the IDL attribute getter always returns the first element whose ID matches the content attribute. -PASS Setting the IDL attribute to an element which is not the first element in DOM order with its ID causes the content attribute to be an empty string -PASS Setting an element reference that crosses into a shadow tree is disallowed, but setting one that is in a shadow inclusive ancestor is allowed. -PASS aria-errormessage -PASS aria-details -PASS Deleting a reflected element should return null for the IDL attribute and cause the content attribute to become stale. -PASS Changing the ID of an element causes the content attribute to become out of sync. -PASS Reparenting an element into a descendant shadow scope hides the element reference. -PASS Reparenting referenced element cannot cause retargeting of reference. -PASS Element reference set in invalid scope remains intact throughout move to valid scope. -FAIL aria-labelledby. assert_equals: check idl attribute caching after parsing expected [Element node <div id="billingElement">Billing</div>, Element node <div id="nameElement">Name</div>] but got [Element node <div id="billingElement">Billing</div>, Element node <div id="nameElement">Name</div>] -PASS aria-controls. -PASS aria-describedby. -PASS aria-flowto. -PASS aria-owns. -PASS shadow DOM behaviour for FrozenArray element reflection. -PASS Moving explicitly set elements across shadow DOM boundaries. -PASS Moving explicitly set elements around within the same scope, and removing from the DOM. -PASS Reparenting. -PASS Attaching element reference before it's inserted into the DOM. -PASS Cross-document references and moves. -PASS Adopting element keeps references. -FAIL Caching invariant different attributes. assert_equals: Caching invariant for ariaControlsElements expected [Element node <div id="cachingInvariantElement1"></div>, Element node <div id="cachingInvariantElement2"></div>] but got [Element node <div id="cachingInvariantElement1"></div>, Element node <div id="cachingInvariantElement2"></div>] -FAIL Caching invariant different elements. assert_equals: Caching invariant for ariaDescribedByElements in one elemnt expected [Element node <div id="cachingInvariantElement1"></div>, Element node <div id="cachingInvariantElement2"></div>] but got [Element node <div id="cachingInvariantElement1"></div>, Element node <div id="cachingInvariantElement2"></div>] -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_all_cookies.sub.html b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_all_cookies.sub.html new file mode 100644 index 0000000..ab9ac07 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_all_cookies.sub.html
@@ -0,0 +1,90 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>TestDriver get_all_cookies method in HTTP</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script> +promise_test(async t => { + const kTenDaysFromNow = new Date(Date.now() + 10 * 24 * 60 * 60 * 1000); + document.cookie = "test0=0"; + document.cookie = `test1=1; Expires=${kTenDaysFromNow.toUTCString()}`; + document.cookie = "test2=2; Path=/"; + // document.cookie = "test3=3; HttpOnly"; This is set in the headers file. + document.cookie = "test4=4; Secure"; + document.cookie = "test5=5; SameSite=Strict"; + document.cookie = "test6=6; SameSite=None; Secure"; + document.cookie = "test7=7; SameSite=Lax"; + const cookies = await test_driver.get_all_cookies(); + assert_equals(cookies.length, 6); + let cookieMap = new Map(); + for (const cookie of cookies) { + cookieMap.set(cookie["name"], cookie); + } + + // test0 + assert_equals(cookieMap.get("test0")["name"], "test0"); + assert_equals(cookieMap.get("test0")["value"], "0"); + assert_equals(cookieMap.get("test0")["path"], "/infrastructure/testdriver"); + assert_equals(cookieMap.get("test0")["domain"], "{{host}}"); + assert_equals(cookieMap.get("test0")["secure"], false); + assert_equals(cookieMap.get("test0")["httpOnly"], false); + assert_equals(cookieMap.get("test0")["expiry"], undefined); + assert_equals(cookieMap.get("test0")["sameSite"], undefined); + + // test1 [Expires in 10 days] + assert_equals(cookieMap.get("test1")["name"], "test1"); + assert_equals(cookieMap.get("test1")["value"], "1"); + assert_equals(cookieMap.get("test1")["path"], "/infrastructure/testdriver"); + assert_equals(cookieMap.get("test1")["domain"], "{{host}}"); + assert_equals(cookieMap.get("test1")["secure"], false); + assert_equals(cookieMap.get("test1")["httpOnly"], false); + assert_equals(cookieMap.get("test1")["expiry"], Math.floor(kTenDaysFromNow.getTime()/1000)); + assert_equals(cookieMap.get("test1")["sameSite"], undefined); + + // test2 [Path /] + assert_equals(cookieMap.get("test2")["name"], "test2"); + assert_equals(cookieMap.get("test2")["value"], "2"); + assert_equals(cookieMap.get("test2")["path"], "/"); + assert_equals(cookieMap.get("test2")["domain"], "{{host}}"); + assert_equals(cookieMap.get("test2")["secure"], false); + assert_equals(cookieMap.get("test2")["httpOnly"], false); + assert_equals(cookieMap.get("test2")["expiry"], undefined); + assert_equals(cookieMap.get("test2")["sameSite"], undefined); + + // test3 [HttpOnly] + assert_equals(cookieMap.get("test3")["name"], "test3"); + assert_equals(cookieMap.get("test3")["value"], "3"); + assert_equals(cookieMap.get("test3")["path"], "/infrastructure/testdriver"); + assert_equals(cookieMap.get("test3")["domain"], "{{host}}"); + assert_equals(cookieMap.get("test3")["secure"], false); + assert_equals(cookieMap.get("test3")["httpOnly"], true); + assert_equals(cookieMap.get("test3")["expiry"], undefined); + assert_equals(cookieMap.get("test3")["sameSite"], undefined); + + // test4 [Secure] Omitted + + // test5 [SameSite Strict] + assert_equals(cookieMap.get("test5")["name"], "test5"); + assert_equals(cookieMap.get("test5")["value"], "5"); + assert_equals(cookieMap.get("test5")["path"], "/infrastructure/testdriver"); + assert_equals(cookieMap.get("test5")["domain"], "{{host}}"); + assert_equals(cookieMap.get("test5")["secure"], false); + assert_equals(cookieMap.get("test5")["httpOnly"], false); + assert_equals(cookieMap.get("test5")["expiry"], undefined); + assert_equals(cookieMap.get("test5")["sameSite"], "Strict"); + + // test6 [SameSite None] Omitted + + // test7 [SameSite Lax] + assert_equals(cookieMap.get("test7")["name"], "test7"); + assert_equals(cookieMap.get("test7")["value"], "7"); + assert_equals(cookieMap.get("test7")["path"], "/infrastructure/testdriver"); + assert_equals(cookieMap.get("test7")["domain"], "{{host}}"); + assert_equals(cookieMap.get("test7")["secure"], false); + assert_equals(cookieMap.get("test7")["httpOnly"], false); + assert_equals(cookieMap.get("test7")["expiry"], undefined); + assert_equals(cookieMap.get("test7")["sameSite"], "Lax"); +}, "Get all HTTP cookies"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_all_cookies.sub.html.headers b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_all_cookies.sub.html.headers new file mode 100644 index 0000000..3dc39a5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_all_cookies.sub.html.headers
@@ -0,0 +1 @@ +Set-Cookie: test3=3; HttpOnly
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_all_cookies.sub.https.html b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_all_cookies.sub.https.html new file mode 100644 index 0000000..1359a75 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_all_cookies.sub.https.html
@@ -0,0 +1,106 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>TestDriver get_all_cookies method in HTTPS</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script> +promise_test(async t => { + const kTenDaysFromNow = new Date(Date.now() + 10 * 24 * 60 * 60 * 1000); + document.cookie = "test0=0"; + document.cookie = `test1=1; Expires=${kTenDaysFromNow.toUTCString()}`; + document.cookie = "test2=2; Path=/"; + // document.cookie = "test3=3; HttpOnly"; This is set in the headers file. + document.cookie = "test4=4; Secure"; + document.cookie = "test5=5; SameSite=Strict"; + document.cookie = "test6=6; SameSite=None; Secure"; + document.cookie = "test7=7; SameSite=Lax"; + const cookies = await test_driver.get_all_cookies(); + assert_equals(cookies.length, 8); + let cookieMap = new Map(); + for (const cookie of cookies) { + cookieMap.set(cookie["name"], cookie); + } + + // test0 + assert_equals(cookieMap.get("test0")["name"], "test0"); + assert_equals(cookieMap.get("test0")["value"], "0"); + assert_equals(cookieMap.get("test0")["path"], "/infrastructure/testdriver"); + assert_equals(cookieMap.get("test0")["domain"], "{{host}}"); + assert_equals(cookieMap.get("test0")["secure"], false); + assert_equals(cookieMap.get("test0")["httpOnly"], false); + assert_equals(cookieMap.get("test0")["expiry"], undefined); + assert_equals(cookieMap.get("test0")["sameSite"], undefined); + + // test1 [Expires in 10 days] + assert_equals(cookieMap.get("test1")["name"], "test1"); + assert_equals(cookieMap.get("test1")["value"], "1"); + assert_equals(cookieMap.get("test1")["path"], "/infrastructure/testdriver"); + assert_equals(cookieMap.get("test1")["domain"], "{{host}}"); + assert_equals(cookieMap.get("test1")["secure"], false); + assert_equals(cookieMap.get("test1")["httpOnly"], false); + assert_equals(cookieMap.get("test1")["expiry"], Math.floor(kTenDaysFromNow.getTime()/1000)); + assert_equals(cookieMap.get("test1")["sameSite"], undefined); + + // test2 [Path /] + assert_equals(cookieMap.get("test2")["name"], "test2"); + assert_equals(cookieMap.get("test2")["value"], "2"); + assert_equals(cookieMap.get("test2")["path"], "/"); + assert_equals(cookieMap.get("test2")["domain"], "{{host}}"); + assert_equals(cookieMap.get("test2")["secure"], false); + assert_equals(cookieMap.get("test2")["httpOnly"], false); + assert_equals(cookieMap.get("test2")["expiry"], undefined); + assert_equals(cookieMap.get("test2")["sameSite"], undefined); + + // test3 [HttpOnly] + assert_equals(cookieMap.get("test3")["name"], "test3"); + assert_equals(cookieMap.get("test3")["value"], "3"); + assert_equals(cookieMap.get("test3")["path"], "/infrastructure/testdriver"); + assert_equals(cookieMap.get("test3")["domain"], "{{host}}"); + assert_equals(cookieMap.get("test3")["secure"], false); + assert_equals(cookieMap.get("test3")["httpOnly"], true); + assert_equals(cookieMap.get("test3")["expiry"], undefined); + assert_equals(cookieMap.get("test3")["sameSite"], undefined); + + // test4 [Secure] + assert_equals(cookieMap.get("test4")["name"], "test4"); + assert_equals(cookieMap.get("test4")["value"], "4"); + assert_equals(cookieMap.get("test4")["path"], "/infrastructure/testdriver"); + assert_equals(cookieMap.get("test4")["domain"], "{{host}}"); + assert_equals(cookieMap.get("test4")["secure"], true); + assert_equals(cookieMap.get("test4")["httpOnly"], false); + assert_equals(cookieMap.get("test4")["expiry"], undefined); + assert_equals(cookieMap.get("test4")["sameSite"], undefined); + + // test5 [SameSite Strict] + assert_equals(cookieMap.get("test5")["name"], "test5"); + assert_equals(cookieMap.get("test5")["value"], "5"); + assert_equals(cookieMap.get("test5")["path"], "/infrastructure/testdriver"); + assert_equals(cookieMap.get("test5")["domain"], "{{host}}"); + assert_equals(cookieMap.get("test5")["secure"], false); + assert_equals(cookieMap.get("test5")["httpOnly"], false); + assert_equals(cookieMap.get("test5")["expiry"], undefined); + assert_equals(cookieMap.get("test5")["sameSite"], "Strict"); + + // test6 [SameSite None] + assert_equals(cookieMap.get("test6")["name"], "test6"); + assert_equals(cookieMap.get("test6")["value"], "6"); + assert_equals(cookieMap.get("test6")["path"], "/infrastructure/testdriver"); + assert_equals(cookieMap.get("test6")["domain"], "{{host}}"); + assert_equals(cookieMap.get("test6")["secure"], true); + assert_equals(cookieMap.get("test6")["httpOnly"], false); + assert_equals(cookieMap.get("test6")["expiry"], undefined); + assert_equals(cookieMap.get("test6")["sameSite"], "None"); + + // test7 [SameSite Lax] + assert_equals(cookieMap.get("test7")["name"], "test7"); + assert_equals(cookieMap.get("test7")["value"], "7"); + assert_equals(cookieMap.get("test7")["path"], "/infrastructure/testdriver"); + assert_equals(cookieMap.get("test7")["domain"], "{{host}}"); + assert_equals(cookieMap.get("test7")["secure"], false); + assert_equals(cookieMap.get("test7")["httpOnly"], false); + assert_equals(cookieMap.get("test7")["expiry"], undefined); + assert_equals(cookieMap.get("test7")["sameSite"], "Lax"); +}, "Get all HTTPS cookies"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_all_cookies.sub.https.html.headers b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_all_cookies.sub.https.html.headers new file mode 100644 index 0000000..3dc39a5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_all_cookies.sub.https.html.headers
@@ -0,0 +1 @@ +Set-Cookie: test3=3; HttpOnly
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_named_cookie.sub.html b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_named_cookie.sub.html new file mode 100644 index 0000000..2a6fb57 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_named_cookie.sub.html
@@ -0,0 +1,94 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>TestDriver get_named_cookie method HTTP</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script> +promise_test(async t => { + const kTenDaysFromNow = new Date(Date.now() + 10 * 24 * 60 * 60 * 1000); + document.cookie = "test0=0"; + document.cookie = `test1=1; Expires=${kTenDaysFromNow.toUTCString()}`; + document.cookie = "test2=2; Path=/"; + // document.cookie = "test3=3; HttpOnly"; This is set in the headers file. + document.cookie = "test4=4; Secure"; + document.cookie = "test5=5; SameSite=Strict"; + document.cookie = "test6=6; SameSite=None; Secure"; + document.cookie = "test7=7; SameSite=Lax"; + + // test0 + let cookie = await test_driver.get_named_cookie("test0"); + assert_equals(cookie["name"], "test0"); + assert_equals(cookie["value"], "0"); + assert_equals(cookie["path"], "/infrastructure/testdriver"); + assert_equals(cookie["domain"], "{{host}}"); + assert_equals(cookie["secure"], false); + assert_equals(cookie["httpOnly"], false); + assert_equals(cookie["expiry"], undefined); + assert_equals(cookie["sameSite"], undefined); + + // test1 [Expires in 10 days] + cookie = await test_driver.get_named_cookie("test1"); + assert_equals(cookie["name"], "test1"); + assert_equals(cookie["value"], "1"); + assert_equals(cookie["path"], "/infrastructure/testdriver"); + assert_equals(cookie["domain"], "{{host}}"); + assert_equals(cookie["secure"], false); + assert_equals(cookie["httpOnly"], false); + assert_equals(cookie["expiry"], Math.floor(kTenDaysFromNow.getTime()/1000)); + assert_equals(cookie["sameSite"], undefined); + + // test2 [Path /] + cookie = await test_driver.get_named_cookie("test2"); + assert_equals(cookie["name"], "test2"); + assert_equals(cookie["value"], "2"); + assert_equals(cookie["path"], "/"); + assert_equals(cookie["domain"], "{{host}}"); + assert_equals(cookie["secure"], false); + assert_equals(cookie["httpOnly"], false); + assert_equals(cookie["expiry"], undefined); + assert_equals(cookie["sameSite"], undefined); + + // test3 [HttpOnly] + cookie = await test_driver.get_named_cookie("test3"); + assert_equals(cookie["name"], "test3"); + assert_equals(cookie["value"], "3"); + assert_equals(cookie["path"], "/infrastructure/testdriver"); + assert_equals(cookie["domain"], "{{host}}"); + assert_equals(cookie["secure"], false); + assert_equals(cookie["httpOnly"], true); + assert_equals(cookie["expiry"], undefined); + assert_equals(cookie["sameSite"], undefined); + + // test4 [Secure] Omitted + cookie = await test_driver.get_named_cookie("test4"); + assert_equals(cookie, null); + + // test5 [SameSite Strict] + cookie = await test_driver.get_named_cookie("test5"); + assert_equals(cookie["name"], "test5"); + assert_equals(cookie["value"], "5"); + assert_equals(cookie["path"], "/infrastructure/testdriver"); + assert_equals(cookie["domain"], "{{host}}"); + assert_equals(cookie["secure"], false); + assert_equals(cookie["httpOnly"], false); + assert_equals(cookie["expiry"], undefined); + assert_equals(cookie["sameSite"], "Strict"); + + // test6 [SameSite None] Omitted + cookie = await test_driver.get_named_cookie("test6"); + assert_equals(cookie, null); + + // test7 [SameSite Strict] + cookie = await test_driver.get_named_cookie("test7"); + assert_equals(cookie["name"], "test7"); + assert_equals(cookie["value"], "7"); + assert_equals(cookie["path"], "/infrastructure/testdriver"); + assert_equals(cookie["domain"], "{{host}}"); + assert_equals(cookie["secure"], false); + assert_equals(cookie["httpOnly"], false); + assert_equals(cookie["expiry"], undefined); + assert_equals(cookie["sameSite"], "Lax"); +}, "Get Named HTTP cookie"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_named_cookie.sub.html.headers b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_named_cookie.sub.html.headers new file mode 100644 index 0000000..3dc39a5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_named_cookie.sub.html.headers
@@ -0,0 +1 @@ +Set-Cookie: test3=3; HttpOnly
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_named_cookie.sub.https.html b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_named_cookie.sub.https.html new file mode 100644 index 0000000..0a995901 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_named_cookie.sub.https.html
@@ -0,0 +1,108 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>TestDriver get_named_cookie method HTTPS</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script> +promise_test(async t => { + const kTenDaysFromNow = new Date(Date.now() + 10 * 24 * 60 * 60 * 1000); + document.cookie = "test0=0"; + document.cookie = `test1=1; Expires=${kTenDaysFromNow.toUTCString()}`; + document.cookie = "test2=2; Path=/"; + // document.cookie = "test3=3; HttpOnly"; This is set in the headers file. + document.cookie = "test4=4; Secure"; + document.cookie = "test5=5; SameSite=Strict"; + document.cookie = "test6=6; SameSite=None; Secure"; + document.cookie = "test7=7; SameSite=Lax"; + + // test0 + let cookie = await test_driver.get_named_cookie("test0"); + assert_equals(cookie["name"], "test0"); + assert_equals(cookie["value"], "0"); + assert_equals(cookie["path"], "/infrastructure/testdriver"); + assert_equals(cookie["domain"], "{{host}}"); + assert_equals(cookie["secure"], false); + assert_equals(cookie["httpOnly"], false); + assert_equals(cookie["expiry"], undefined); + assert_equals(cookie["sameSite"], undefined); + + // test1 [Expires in 10 days] + cookie = await test_driver.get_named_cookie("test1"); + assert_equals(cookie["name"], "test1"); + assert_equals(cookie["value"], "1"); + assert_equals(cookie["path"], "/infrastructure/testdriver"); + assert_equals(cookie["domain"], "{{host}}"); + assert_equals(cookie["secure"], false); + assert_equals(cookie["httpOnly"], false); + assert_equals(cookie["expiry"], Math.floor(kTenDaysFromNow.getTime()/1000)); + assert_equals(cookie["sameSite"], undefined); + + // test2 [Path /] + cookie = await test_driver.get_named_cookie("test2"); + assert_equals(cookie["name"], "test2"); + assert_equals(cookie["value"], "2"); + assert_equals(cookie["path"], "/"); + assert_equals(cookie["domain"], "{{host}}"); + assert_equals(cookie["secure"], false); + assert_equals(cookie["httpOnly"], false); + assert_equals(cookie["expiry"], undefined); + assert_equals(cookie["sameSite"], undefined); + + // test3 [HttpOnly] + cookie = await test_driver.get_named_cookie("test3"); + assert_equals(cookie["name"], "test3"); + assert_equals(cookie["value"], "3"); + assert_equals(cookie["path"], "/infrastructure/testdriver"); + assert_equals(cookie["domain"], "{{host}}"); + assert_equals(cookie["secure"], false); + assert_equals(cookie["httpOnly"], true); + assert_equals(cookie["expiry"], undefined); + assert_equals(cookie["sameSite"], undefined); + + // test4 [Secure] + cookie = await test_driver.get_named_cookie("test4"); + assert_equals(cookie["name"], "test4"); + assert_equals(cookie["value"], "4"); + assert_equals(cookie["path"], "/infrastructure/testdriver"); + assert_equals(cookie["domain"], "{{host}}"); + assert_equals(cookie["secure"], true); + assert_equals(cookie["httpOnly"], false); + assert_equals(cookie["expiry"], undefined); + assert_equals(cookie["sameSite"], undefined); + + // test5 [SameSite Strict] + cookie = await test_driver.get_named_cookie("test5"); + assert_equals(cookie["name"], "test5"); + assert_equals(cookie["value"], "5"); + assert_equals(cookie["path"], "/infrastructure/testdriver"); + assert_equals(cookie["domain"], "{{host}}"); + assert_equals(cookie["secure"], false); + assert_equals(cookie["httpOnly"], false); + assert_equals(cookie["expiry"], undefined); + assert_equals(cookie["sameSite"], "Strict"); + + // test6 [SameSite None] + cookie = await test_driver.get_named_cookie("test6"); + assert_equals(cookie["name"], "test6"); + assert_equals(cookie["value"], "6"); + assert_equals(cookie["path"], "/infrastructure/testdriver"); + assert_equals(cookie["domain"], "{{host}}"); + assert_equals(cookie["secure"], true); + assert_equals(cookie["httpOnly"], false); + assert_equals(cookie["expiry"], undefined); + assert_equals(cookie["sameSite"], "None"); + + // test7 [SameSite Strict] + cookie = await test_driver.get_named_cookie("test7"); + assert_equals(cookie["name"], "test7"); + assert_equals(cookie["value"], "7"); + assert_equals(cookie["path"], "/infrastructure/testdriver"); + assert_equals(cookie["domain"], "{{host}}"); + assert_equals(cookie["secure"], false); + assert_equals(cookie["httpOnly"], false); + assert_equals(cookie["expiry"], undefined); + assert_equals(cookie["sameSite"], "Lax"); +}, "Get Named HTTPS cookie"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_named_cookie.sub.https.html.headers b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_named_cookie.sub.https.html.headers new file mode 100644 index 0000000..3dc39a5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/get_named_cookie.sub.https.html.headers
@@ -0,0 +1 @@ +Set-Cookie: test3=3; HttpOnly
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/mock-pressure-service.js b/third_party/blink/web_tests/external/wpt/resources/chromium/mock-pressure-service.js index b6b1f2715..27a684e1 100644 --- a/third_party/blink/web_tests/external/wpt/resources/chromium/mock-pressure-service.js +++ b/third_party/blink/web_tests/external/wpt/resources/chromium/mock-pressure-service.js
@@ -19,11 +19,6 @@ ['power-supply', PressureFactor.kPowerSupply] ]); this.pressureServiceReadingTimerId_ = null; - // Sets a timestamp by creating a DOMHighResTimeStamp from a given - // platform timestamp. In this mock implementation we use a starting value - // and an increment step value that resemble a platform timestamp - // reasonably enough. - this.timestamp_ = window.performance.timeOrigin; } start() { @@ -64,11 +59,28 @@ if (this.pressureServiceReadingTimerId_ != null) stopPlatformCollector(); + // The following code for calculating the timestamp was taken from + // https://source.chromium.org/chromium/chromium/src/+/main:third_party/ + // blink/web_tests/http/tests/resources/ + // geolocation-mock.js;l=131;drc=37a9b6c03b9bda9fcd62fc0e5e8016c278abd31f + + // The new Date().getTime() returns the number of milliseconds since the + // UNIX epoch (1970-01-01 00::00:00 UTC), while |internalValue| of the + // device.mojom.PressureUpdate represents the value of microseconds since + // the Windows FILETIME epoch (1601-01-01 00:00:00 UTC). So add the delta + // when sets the |internalValue|. See more info in //base/time/time.h. + const windowsEpoch = Date.UTC(1601, 0, 1, 0, 0, 0, 0); + const unixEpoch = Date.UTC(1970, 0, 1, 0, 0, 0, 0); + // |epochDeltaInMs| equals to base::Time::kTimeTToMicrosecondsOffset. + const epochDeltaInMs = unixEpoch - windowsEpoch; + const timeout = (1 / sampleRate) * 1000; this.pressureServiceReadingTimerId_ = window.setInterval(() => { if (this.pressureUpdate_ === null || this.observer_ === null) return; - this.pressureUpdate_.timestamp = this.timestamp_++; + this.pressureUpdate_.timestamp = { + internalValue: BigInt((new Date().getTime() + epochDeltaInMs) * 1000) + }; this.observer_.onUpdate(this.pressureUpdate_); this.updatesDelivered_++; }, timeout); @@ -102,7 +114,6 @@ this.pressureUpdate_ = { state: this.mojomStateType_.get(state), factors: pressureFactors, - timestamp: window.performance.timeOrigin }; } }
diff --git a/third_party/blink/web_tests/external/wpt/resources/testdriver.js b/third_party/blink/web_tests/external/wpt/resources/testdriver.js index 0737e64..5a59c724 100644 --- a/third_party/blink/web_tests/external/wpt/resources/testdriver.js +++ b/third_party/blink/web_tests/external/wpt/resources/testdriver.js
@@ -185,6 +185,38 @@ }, /** + * Get details for all cookies in the current context. + * See https://w3c.github.io/webdriver/#get-all-cookies + * + * @param {WindowProxy} context - Browsing context in which + * to run the call, or null for the current + * browsing context. + * + * @returns {Promise} Returns an array of cookies objects as defined in the spec: + * https://w3c.github.io/webdriver/#cookies + */ + get_all_cookies: function(context=null) { + return window.test_driver_internal.get_all_cookies(context); + }, + + /** + * Get details for a cookie in the current context by name if it exists. + * See https://w3c.github.io/webdriver/#get-named-cookie + * + * @param {String} name - The name of the cookie to get. + * @param {WindowProxy} context - Browsing context in which + * to run the call, or null for the current + * browsing context. + * + * @returns {Promise} Returns null if no such cookie exists or + * the matching cookie object as defined in the spec: + * https://w3c.github.io/webdriver/#cookies + */ + get_named_cookie: function(name, context=null) { + return window.test_driver_internal.get_named_cookie(name, context); + }, + + /** * Send keys to an element. * * If ``element`` isn't inside the @@ -637,6 +669,14 @@ return Promise.reject(new Error("unimplemented")); }, + get_all_cookies: function(context=null) { + return Promise.reject(new Error("unimplemented")); + }, + + delete_named_cookie: function(name, context=null) { + return Promise.reject(new Error("unimplemented")); + }, + send_keys: function(element, keys) { if (this.in_automation) { return Promise.reject(new Error('Not implemented'));
diff --git a/third_party/blink/web_tests/resources/testdriver-vendor.js b/third_party/blink/web_tests/resources/testdriver-vendor.js index e66c5ad..5530677 100644 --- a/third_party/blink/web_tests/resources/testdriver-vendor.js +++ b/third_party/blink/web_tests/resources/testdriver-vendor.js
@@ -445,6 +445,14 @@ return internals.deleteAllCookies(); } + window.test_driver_internal.get_all_cookies = function() { + return internals.getAllCookies(); + } + + window.test_driver_internal.get_named_cookie = function(name) { + return internals.getNamedCookie(name); + } + window.test_driver_internal.minimize_window = async () => { window.testRunner.setMainWindowHidden(true); // Wait until the new state is reflected in the document
diff --git a/third_party/blink/web_tests/resources/testdriver.js b/third_party/blink/web_tests/resources/testdriver.js index 0737e64..6aef79b 100644 --- a/third_party/blink/web_tests/resources/testdriver.js +++ b/third_party/blink/web_tests/resources/testdriver.js
@@ -185,6 +185,38 @@ }, /** + * Get details for all cookies in the current context. + * See https://w3c.github.io/webdriver/#get-all-cookies + * + * @param {WindowProxy} context - Browsing context in which + * to run the call, or null for the current + * browsing context. + * + * @returns {Promise} Returns an array of cookies objects as defined in the spec: + * https://w3c.github.io/webdriver/#cookies + */ + get_all_cookies: function(context=null) { + return window.test_driver_internal.get_all_cookies(context); + }, + + /** + * Get details for a cookie in the current context by name if it exists. + * See https://w3c.github.io/webdriver/#get-named-cookie + * + * @param {String} name - The name of the cookie to get. + * @param {WindowProxy} context - Browsing context in which + * to run the call, or null for the current + * browsing context. + * + * @returns {Promise} Returns null if no such cookie exists or + * the matching cookie object as defined in the spec: + * https://w3c.github.io/webdriver/#cookies + */ + get_named_cookie: function(name, context=null) { + return window.test_driver_internal.get_named_cookie(name, context); + }, + + /** * Send keys to an element. * * If ``element`` isn't inside the @@ -637,6 +669,14 @@ return Promise.reject(new Error("unimplemented")); }, + get_all_cookies: function(context=null) { + return Promise.reject(new Error("unimplemented")); + }, + + get_named_cookie: function(name, context=null) { + return Promise.reject(new Error("unimplemented")); + }, + send_keys: function(element, keys) { if (this.in_automation) { return Promise.reject(new Error('Not implemented'));
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index d2741b8..507e8ed2 100644 --- a/third_party/freetype/README.chromium +++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@ Name: FreeType URL: http://www.freetype.org/ -Version: VER-2-12-1-99-g8faf57dd1 -Revision: 8faf57dd17088c37fa947fd565870648bbdbad18 +Version: VER-2-12-1-101-g0417527d5 +Revision: 0417527d5b5abc3ee9426f31bd95209ca97502a5 CPEPrefix: cpe:/a:freetype:freetype:2.11.1 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses"
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index 16d62b6..ebda0d38 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -35,7 +35,7 @@ # https://chromium.googlesource.com/chromium/src/+/main/docs/updating_clang.md # Reverting problematic clang rolls is safe, though. # This is the output of `git describe` and is usable as a commit-ish. -CLANG_REVISION = 'llvmorg-16-init-6084-g2f3d7c2c' +CLANG_REVISION = 'llvmorg-16-init-6457-g20a269cf' CLANG_SUB_REVISION = 1 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION)
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index c49e28c3..3c816de 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -2474,11 +2474,11 @@ ], 'dawn_tests_android_release_trybot': [ - 'dawn_tests', 'android', 'release_trybot_minimal_symbols', + 'dawn_no_gl', 'android', 'release_trybot_minimal_symbols', ], 'dawn_tests_android_release_trybot_reclient': [ - 'dawn_tests', 'android', 'release_trybot_minimal_symbols_reclient', + 'dawn_no_gl', 'android', 'release_trybot_minimal_symbols_reclient', ], 'dawn_tests_asan_release_bot_dcheck_always_on_reclient': [ @@ -4117,6 +4117,10 @@ 'gn_args': 'dawn_enable_desktop_gl=true', }, + 'dawn_no_gl': { + 'gn_args': 'use_dawn=true', + }, + 'dawn_tests': { 'gn_args': 'use_dawn=true dawn_enable_opengles=true', },
diff --git a/tools/mb/mb_config_expectations/chromium.dawn.json b/tools/mb/mb_config_expectations/chromium.dawn.json index 953a0fc..036b446 100644 --- a/tools/mb/mb_config_expectations/chromium.dawn.json +++ b/tools/mb/mb_config_expectations/chromium.dawn.json
@@ -1,7 +1,6 @@ { "Dawn Android arm DEPS Release (Pixel 4)": { "gn_args": { - "dawn_enable_opengles": true, "dcheck_always_on": true, "debuggable_apks": false, "ffmpeg_branding": "Chrome", @@ -16,7 +15,6 @@ }, "Dawn Android arm Release (Pixel 4)": { "gn_args": { - "dawn_enable_opengles": true, "dcheck_always_on": true, "debuggable_apks": false, "ffmpeg_branding": "Chrome",
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.dawn.json b/tools/mb/mb_config_expectations/tryserver.chromium.dawn.json index b5cdacd3..4dc12ed 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.dawn.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.dawn.json
@@ -1,7 +1,6 @@ { "android-dawn-arm-rel": { "gn_args": { - "dawn_enable_opengles": true, "dcheck_always_on": true, "debuggable_apks": false, "ffmpeg_branding": "Chrome", @@ -16,7 +15,6 @@ }, "dawn-android-arm-deps-rel": { "gn_args": { - "dawn_enable_opengles": true, "dcheck_always_on": true, "debuggable_apks": false, "ffmpeg_branding": "Chrome",
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index f21f536c..5eb6cf14 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -35687,6 +35687,7 @@ label="PASSWORDSPRIVATE_SWITCHBIOMETRICAUTHBEFOREFILLINGSTATE"/> <int value="1718" label="WMDESKSPRIVATE_GETACTIVEDESK"/> <int value="1719" label="WMDESKSPRIVATE_SWITCHDESK"/> + <int value="1720" label="OS_TELEMETRY_GETTPMINFO"/> </enum> <enum name="ExtensionIconState"> @@ -80400,6 +80401,7 @@ <int value="40" label="kActivatedBeforeStarted"/> <int value="41" label="kInactivePageRestriction"/> <int value="42" label="kStartFailed"/> + <int value="43" label="kTimeoutBackgrounded"/> </enum> <enum name="PrerenderHoverEvent">
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index ad0cb8f..eabd7d7 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -1167,7 +1167,7 @@ </histogram> <histogram name="Android.DirectAction.Perform" enum="DirectActionId" - expires_after="2022-10-10"> + expires_after="2023-10-10"> <owner>arbesser@google.com</owner> <owner>autofill_assistant@google.com</owner> <summary> @@ -1443,7 +1443,7 @@ </histogram> <histogram name="Android.DragDrop.FromWebContent.Duration{DropResult}" - units="ms" expires_after="2022-11-13"> + units="ms" expires_after="2023-03-19"> <owner>wenyufu@chromium.org</owner> <owner>clank-large-form-factors@google.com</owner> <summary> @@ -1475,7 +1475,7 @@ </histogram> <histogram name="Android.DragDrop.Image.OpenFileTime.AllExpired" units="ms" - expires_after="2022-11-13"> + expires_after="2023-03-19"> <owner>shuyng@google.com</owner> <owner>clank-large-form-factors@google.com</owner> <summary> @@ -1495,7 +1495,7 @@ </histogram> <histogram name="Android.DragDrop.Image.OpenFileTime.FirstAttempt" units="ms" - expires_after="2023-02-19"> + expires_after="2023-03-19"> <owner>shuyng@google.com</owner> <owner>clank-large-form-factors@google.com</owner> <summary> @@ -1509,7 +1509,7 @@ </histogram> <histogram name="Android.DragDrop.Image.OpenFileTime.FirstExpired" units="ms" - expires_after="2022-11-13"> + expires_after="2023-03-19"> <owner>shuyng@google.com</owner> <owner>clank-large-form-factors@google.com</owner> <summary> @@ -1528,7 +1528,7 @@ </histogram> <histogram name="Android.DragDrop.Image.OpenFileTime.LastAttempt" units="ms" - expires_after="2023-02-19"> + expires_after="2023-03-19"> <owner>shuyng@google.com</owner> <owner>clank-large-form-factors@google.com</owner> <summary> @@ -1893,7 +1893,7 @@ </histogram> <histogram name="Android.InstantApps.ApiCallDurationWithoutApp" units="ms" - expires_after="2023-01-31"> + expires_after="2023-04-02"> <owner>sbirch@google.com</owner> <owner>tedchoc@chromium.org</owner> <summary> @@ -2862,7 +2862,7 @@ </histogram> <histogram name="Android.Omnibox.SuggestionView.Reused" enum="BooleanReused" - expires_after="2023-01-31"> + expires_after="2023-04-02"> <owner>ender@chromium.org</owner> <owner>mpearson@chromium.org</owner> <owner>jdonnelly@chromium.org</owner> @@ -2937,7 +2937,7 @@ </histogram> <histogram name="Android.OmniboxFocusReason" enum="OmniboxFocusReason" - expires_after="2023-01-31"> + expires_after="2023-04-02"> <owner>mdjones@chromium.org</owner> <owner>twellington@chromium.org</owner> <owner>amaralp@chromium.org</owner> @@ -3906,7 +3906,7 @@ </histogram> <histogram name="Android.WebView.ComponentUpdater.GetFilesDuration" units="ms" - expires_after="2023-02-01"> + expires_after="2023-04-02"> <owner>hazems@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3939,7 +3939,7 @@ </histogram> <histogram name="Android.WebView.ComponentUpdater.UnexpectedExit" - enum="Boolean" expires_after="2023-02-01"> + enum="Boolean" expires_after="2023-04-02"> <owner>hazems@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3950,7 +3950,7 @@ </histogram> <histogram name="Android.WebView.ComponentUpdater.UpdateJobDuration" units="ms" - expires_after="2023-02-01"> + expires_after="2023-04-02"> <owner>hazems@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/apps/histograms.xml b/tools/metrics/histograms/metadata/apps/histograms.xml index 9f3c4c0..84eb841 100644 --- a/tools/metrics/histograms/metadata/apps/histograms.xml +++ b/tools/metrics/histograms/metadata/apps/histograms.xml
@@ -1647,7 +1647,7 @@ </histogram> <histogram name="Apps.AppListSearchResultOpenTypeV2" enum="AppListSearchResult" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <!-- Name completed by histogram_suffixes name="TabletOrClamshellMode" --> <owner>tbarzic@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/chromeos/histograms.xml b/tools/metrics/histograms/metadata/chromeos/histograms.xml index a1df29ec..bddd54d 100644 --- a/tools/metrics/histograms/metadata/chromeos/histograms.xml +++ b/tools/metrics/histograms/metadata/chromeos/histograms.xml
@@ -1183,7 +1183,7 @@ </histogram> <histogram name="ChromeOS.Intents.LinkCapturingEvent2" - enum="LinkCapturingEvent" expires_after="2023-03-26"> + enum="LinkCapturingEvent" expires_after="2023-04-02"> <owner>vpao@google.com</owner> <owner>chromeos-apps-foundation-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml index 851a73c..565aadb 100644 --- a/tools/metrics/histograms/metadata/compositing/histograms.xml +++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -354,7 +354,7 @@ </histogram> <histogram name="Compositing.Display.OverlayCombinationCache.NumIdsEvicted" - units="units" expires_after="2023-01-29"> + units="units" expires_after="2023-04-02"> <owner>khaslett@chromium.org</owner> <owner>kylechar@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/cros_ml/histograms.xml b/tools/metrics/histograms/metadata/cros_ml/histograms.xml index c99fdd42..c0f2977 100644 --- a/tools/metrics/histograms/metadata/cros_ml/histograms.xml +++ b/tools/metrics/histograms/metadata/cros_ml/histograms.xml
@@ -34,7 +34,7 @@ </histogram> <histogram name="MachineLearningService.CpuUsageMilliPercent" - units="1/1000ths of %" expires_after="2023-01-29"> + units="1/1000ths of %" expires_after="2023-04-02"> <owner>alanlxl@chromium.org</owner> <owner>amoylan@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/cross_device/histograms.xml b/tools/metrics/histograms/metadata/cross_device/histograms.xml index 4e936a4..23a3ac98 100644 --- a/tools/metrics/histograms/metadata/cross_device/histograms.xml +++ b/tools/metrics/histograms/metadata/cross_device/histograms.xml
@@ -263,7 +263,7 @@ <histogram name="CryptAuth.DeviceSyncV2.DeviceActivityGetter.ApiCallResult.GetDevicesActivityStatus" - enum="CryptAuthApiCallResult" expires_after="2023-02-01"> + enum="CryptAuthApiCallResult" expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -311,7 +311,7 @@ <histogram name="CryptAuth.DeviceSyncV2.DeviceSyncer.AsyncTaskResult.DeviceMetadataDecryption" - enum="CryptAuthAsyncTaskResult" expires_after="2023-02-01"> + enum="CryptAuthAsyncTaskResult" expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -326,7 +326,7 @@ <histogram name="CryptAuth.DeviceSyncV2.DeviceSyncer.AsyncTaskResult.GroupPrivateKeyDecryption" - enum="CryptAuthAsyncTaskResult" expires_after="2023-02-01"> + enum="CryptAuthAsyncTaskResult" expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -385,7 +385,7 @@ </histogram> <histogram name="CryptAuth.DeviceSyncV2.DeviceSyncer.MetadataDecryptionSuccess" - enum="BooleanSuccess" expires_after="2023-02-01"> + enum="BooleanSuccess" expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -496,7 +496,7 @@ <histogram name="CryptAuth.DeviceSyncV2.FeatureStatusSetter.ApiCallResult.SetFeatureStatuses" - enum="CryptAuthApiCallResult" expires_after="2023-02-01"> + enum="CryptAuthApiCallResult" expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -520,7 +520,7 @@ <histogram name="CryptAuth.DeviceSyncV2.GroupPrivateKeySharer.ApiCallResult.ShareGroupPrivateKey" - enum="CryptAuthApiCallResult" expires_after="2023-02-01"> + enum="CryptAuthApiCallResult" expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -547,7 +547,7 @@ <histogram name="CryptAuth.DeviceSyncV2.GroupPrivateKeySharer.EncryptionSuccess" - enum="BooleanSuccess" expires_after="2023-02-01"> + enum="BooleanSuccess" expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -608,7 +608,7 @@ <histogram name="CryptAuth.DeviceSyncV2.MetadataSyncer.ApiCallResult.FirstSyncMetadata" - enum="CryptAuthApiCallResult" expires_after="2023-02-01"> + enum="CryptAuthApiCallResult" expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -620,7 +620,7 @@ <histogram name="CryptAuth.DeviceSyncV2.MetadataSyncer.ApiCallResult.SecondSyncMetadata" - enum="CryptAuthApiCallResult" expires_after="2023-02-01"> + enum="CryptAuthApiCallResult" expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -632,7 +632,7 @@ <histogram name="CryptAuth.DeviceSyncV2.MetadataSyncer.AsyncTaskResult.GroupKeyCreation" - enum="CryptAuthAsyncTaskResult" expires_after="2023-02-01"> + enum="CryptAuthAsyncTaskResult" expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -644,7 +644,7 @@ <histogram name="CryptAuth.DeviceSyncV2.MetadataSyncer.AsyncTaskResult.LocalDeviceMetadataEncryption" - enum="CryptAuthAsyncTaskResult" expires_after="2023-02-01"> + enum="CryptAuthAsyncTaskResult" expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -809,7 +809,7 @@ </histogram> <histogram name="CryptAuth.DeviceSyncV2.Result.ResultCode" - enum="CryptAuthV2DeviceSyncResultCode" expires_after="2023-02-01"> + enum="CryptAuthV2DeviceSyncResultCode" expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -860,7 +860,7 @@ </histogram> <histogram name="CryptAuth.EnrollmentV2.AsyncTaskResult.KeyCreation" - enum="CryptAuthAsyncTaskResult" expires_after="2023-02-01"> + enum="CryptAuthAsyncTaskResult" expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -914,7 +914,7 @@ </histogram> <histogram name="CryptAuth.EnrollmentV2.Result.ResultCode" - enum="CryptAuthV2EnrollmentResult" expires_after="2023-02-01"> + enum="CryptAuthV2EnrollmentResult" expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -1437,7 +1437,7 @@ </histogram> <histogram name="InstantTethering.KeepAliveTickle.Result" enum="BooleanSuccess" - expires_after="2023-02-01"> + expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -1567,7 +1567,7 @@ </histogram> <histogram name="MultiDevice.BetterTogetherSuite.MultiDeviceFeatureState" - enum="MultiDevice_FeatureState" expires_after="2023-02-01"> + enum="MultiDevice_FeatureState" expires_after="2023-04-02"> <owner>danlee@google.com</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -1619,7 +1619,7 @@ <histogram name="MultiDevice.DeviceSyncService.ForceSyncNow.Result" enum="MultiDevice_DeviceSyncService_ForceCryptAuthOperationResult" - expires_after="2023-02-01"> + expires_after="2023-04-02"> <owner>danlee@google.com</owner> <owner>better-together-dev@google.com</owner> <summary>Result for when ForceSyncNow is called.</summary> @@ -1735,7 +1735,7 @@ <histogram name="MultiDevice.SecureChannel.BLE.Performance.StartScanToAuthenticationDuration.Background" - units="ms" expires_after="2023-02-01"> + units="ms" expires_after="2023-04-02"> <owner>danlee@google.com</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -1768,7 +1768,7 @@ <histogram name="MultiDevice.SecureChannel.BLE.Performance.StartScanToReceiveAdvertisementDuration.Background" - units="ms" expires_after="2023-02-01"> + units="ms" expires_after="2023-04-02"> <owner>danlee@google.com</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -1784,7 +1784,7 @@ <histogram name="MultiDevice.SecureChannel.BLE.ReceiveAdvertisementToAuthentication.EffectiveSuccessRateWithRetries" - enum="BooleanSuccess" expires_after="2023-02-01"> + enum="BooleanSuccess" expires_after="2023-04-02"> <owner>danlee@google.com</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -1807,7 +1807,7 @@ </histogram> <histogram name="MultiDevice.SecureChannel.Nearby.ConnectionMedium" - enum="SecureChannelNearbyConnectionMedium" expires_after="2023-02-01"> + enum="SecureChannelNearbyConnectionMedium" expires_after="2023-04-02"> <owner>hansenmichael@google.com</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -1822,7 +1822,7 @@ <histogram name="MultiDevice.SecureChannel.Nearby.ConnectionResult" enum="MultiDeviceNearbyConnectionsInitiatorResult" - expires_after="2023-02-01"> + expires_after="2023-04-02"> <owner>hansenmichael@google.com</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -1850,7 +1850,7 @@ </histogram> <histogram name="MultiDevice.SecureChannel.Nearby.EffectiveConnectionResult" - enum="BooleanSuccess" expires_after="2023-02-01"> + enum="BooleanSuccess" expires_after="2023-04-02"> <owner>hansenmichael@google.com</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -1888,7 +1888,7 @@ </histogram> <histogram name="MultiDevice.SecureChannel.Nearby.MessageAction" - enum="MultiDeviceNearbyMessageAction" expires_after="2023-02-01"> + enum="MultiDeviceNearbyMessageAction" expires_after="2023-04-02"> <owner>hansenmichael@google.com</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -1958,7 +1958,7 @@ </histogram> <histogram name="MultiDevice.Setup.HostStatus" - enum="MultiDevice_Setup_HostStatus" expires_after="2023-02-01"> + enum="MultiDevice_Setup_HostStatus" expires_after="2023-04-02"> <owner>danlee@google.com</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -2177,7 +2177,7 @@ </histogram> <histogram name="SmartLock.AuthResult.Unlock" enum="BooleanSuccess" - expires_after="2023-02-01"> + expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -2234,7 +2234,7 @@ </histogram> <histogram name="SmartLock.FindAndConnectToHostResult.Unlock" - enum="SmartLockFindAndConnectToHostResult" expires_after="2023-02-01"> + enum="SmartLockFindAndConnectToHostResult" expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -2282,7 +2282,7 @@ </histogram> <histogram name="SmartLock.GetRemoteStatus.Unlock" enum="BooleanSuccess" - expires_after="2023-02-01"> + expires_after="2023-04-02"> <owner>hansberry@chromium.org</owner> <owner>better-together-dev@google.com</owner> <summary> @@ -2338,7 +2338,7 @@ <histogram name="SmartLock.Performance.ShowLockScreenToShowFirstStatusToUserDuration.Unlock" - units="ms" expires_after="2023-02-01"> + units="ms" expires_after="2023-04-02"> <!-- Name completed by histogram_suffixes name="SmartLockStatusTypes" --> <owner>hansberry@chromium.org</owner> @@ -2361,7 +2361,7 @@ <histogram name="SmartLock.Performance.StartScanToReceiveFirstRemoteStatusDuration.Unlock" - units="ms" expires_after="2023-02-01"> + units="ms" expires_after="2023-04-02"> <!-- Name completed by histogram_suffixes name="SmartLockStatusTypes" --> <owner>hansberry@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/cryptohome/histograms.xml b/tools/metrics/histograms/metadata/cryptohome/histograms.xml index d725140..db5d7fe 100644 --- a/tools/metrics/histograms/metadata/cryptohome/histograms.xml +++ b/tools/metrics/histograms/metadata/cryptohome/histograms.xml
@@ -368,7 +368,7 @@ </histogram> <histogram name="Cryptohome.Errors" enum="CryptohomeError" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>apronin@chromium.org</owner> <owner>cros-hwsec+uma@chromium.org</owner> <summary>Cryptohome errors.</summary> @@ -417,7 +417,7 @@ </histogram> <histogram name="Cryptohome.FreeDiskSpaceTotalTime2" units="ms" - expires_after="2023-02-01"> + expires_after="2023-04-02"> <owner>vsavu@google.com</owner> <owner>dlunev@chromium.org</owner> <owner>sarthakkukreti@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml index 33458fe..efd48bd9 100644 --- a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml +++ b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
@@ -110,7 +110,7 @@ </histogram> <histogram name="CustomTabs.ClientAppId" enum="ClientAppId" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>yusufo@chromium.org</owner> <summary> Android: AppId declared by the launching application in EXTRA_APPLICATION_ID
diff --git a/tools/metrics/histograms/metadata/event/histograms.xml b/tools/metrics/histograms/metadata/event/histograms.xml index 4eb40ca..0d413e0 100644 --- a/tools/metrics/histograms/metadata/event/histograms.xml +++ b/tools/metrics/histograms/metadata/event/histograms.xml
@@ -990,7 +990,7 @@ </histogram> <histogram name="Event.Latency.ScrollUpdate.JankyDuration" units="ms" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>ddrone@google.com</owner> <owner>chrometto-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/gcm/histograms.xml b/tools/metrics/histograms/metadata/gcm/histograms.xml index 7245dd3..0152c6b 100644 --- a/tools/metrics/histograms/metadata/gcm/histograms.xml +++ b/tools/metrics/histograms/metadata/gcm/histograms.xml
@@ -306,7 +306,7 @@ </histogram> <histogram name="GCM.RegistrationRequestStatus" - enum="GCMRegistrationRequestStatus" expires_after="2023-01-29"> + enum="GCMRegistrationRequestStatus" expires_after="2023-04-02"> <owner>peter@chromium.org</owner> <summary> Status code of the outcome of a GCM registration request. The Unknown error
diff --git a/tools/metrics/histograms/metadata/memory/histograms.xml b/tools/metrics/histograms/metadata/memory/histograms.xml index b37485a..c1891d1 100644 --- a/tools/metrics/histograms/metadata/memory/histograms.xml +++ b/tools/metrics/histograms/metadata/memory/histograms.xml
@@ -608,7 +608,7 @@ </histogram> <histogram base="true" name="Memory.Experimental.Browser2.Tiny" units="bytes" - expires_after="2023-03-26"> + expires_after="2023-04-02"> <!-- Name completed by histogram_suffixes name="ProcessMemoryAllocatorTiny2" --> <owner>sashamcintosh@chromium.org</owner> @@ -1896,7 +1896,7 @@ </histogram> <histogram name="Memory.ParkableString.Compression.SizeKb" units="KB" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>lizeb@chromium.org</owner> <owner>thiabaud@google.com</owner> <summary> @@ -1969,7 +1969,7 @@ </histogram> <histogram name="Memory.ParkableString.DiskReadTime.5min" units="ms" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>lizeb@chromium.org</owner> <owner>pasko@chromium.org</owner> <summary> @@ -2113,7 +2113,7 @@ </histogram> <histogram name="Memory.ParkableString.TotalSizeKb.5min" units="KB" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>lizeb@chromium.org</owner> <owner>pasko@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/nearby/histograms.xml b/tools/metrics/histograms/metadata/nearby/histograms.xml index 9f6af6bc..d03f0a2 100644 --- a/tools/metrics/histograms/metadata/nearby/histograms.xml +++ b/tools/metrics/histograms/metadata/nearby/histograms.xml
@@ -23,7 +23,7 @@ <histograms> <histogram name="Nearby.Connections.Bluetooth.Adapter.SetName.Result" - enum="BooleanSuccess" expires_after="2023-02-01"> + enum="BooleanSuccess" expires_after="2023-04-02"> <owner>hansenmichael@google.com</owner> <owner>nearby-share-chromeos-eng@google.com</owner> <summary> @@ -33,7 +33,7 @@ </histogram> <histogram name="Nearby.Connections.Bluetooth.Adapter.SetScanMode.Result" - enum="BooleanSuccess" expires_after="2023-02-01"> + enum="BooleanSuccess" expires_after="2023-04-02"> <owner>hansenmichael@google.com</owner> <owner>nearby-share-chromeos-eng@google.com</owner> <summary> @@ -44,7 +44,7 @@ <histogram name="Nearby.Connections.Bluetooth.ClassicMedium.ConnectToService.Duration" - units="ms" expires_after="2023-02-01"> + units="ms" expires_after="2023-04-02"> <owner>hansenmichael@google.com</owner> <owner>nearby-share-chromeos-eng@google.com</owner> <summary> @@ -67,7 +67,7 @@ </histogram> <histogram name="Nearby.Connections.Bluetooth.LEMedium.StartAdvertising.Result" - enum="BooleanSuccess" expires_after="2023-02-01"> + enum="BooleanSuccess" expires_after="2023-04-02"> <owner>hansenmichael@google.com</owner> <owner>nearby-share-chromeos-eng@google.com</owner> <summary> @@ -76,7 +76,7 @@ </histogram> <histogram name="Nearby.Connections.Bluetooth.LEMedium.StartScanning.Result" - enum="BooleanSuccess" expires_after="2023-02-01"> + enum="BooleanSuccess" expires_after="2023-04-02"> <owner>hansenmichael@google.com</owner> <owner>nearby-share-chromeos-eng@google.com</owner> <summary> @@ -206,7 +206,7 @@ <histogram name="Nearby.Connections.UtilityProcessShutdownReason" enum="NearbyConnectionsUtilityProcessShutdownReason" - expires_after="2023-02-01"> + expires_after="2023-04-02"> <owner>hansenmichael@google.com</owner> <owner>nearby-share-chromeos-eng@google.com</owner> <summary> @@ -393,7 +393,7 @@ <histogram name="Nearby.Share.Certificates.Manager.BluetoothMacAddressPresentForPrivateCertificateCreation" - enum="BooleanPresent" expires_after="2023-02-01"> + enum="BooleanPresent" expires_after="2023-04-02"> <owner>pushi@google.com</owner> <owner>nearby-share-chromeos-eng@google.com</owner> <summary> @@ -456,7 +456,7 @@ <histogram name="Nearby.Share.Certificates.Manager.DownloadPublicCertificatesSuccessRate" - enum="BooleanSuccess" expires_after="2023-02-01"> + enum="BooleanSuccess" expires_after="2023-04-02"> <owner>cclem@chromium.org</owner> <owner>nearby-share-chromeos-eng@google.com</owner> <summary> @@ -607,7 +607,7 @@ </histogram> <histogram name="Nearby.Share.Contacts.DownloadResult" enum="BooleanSuccess" - expires_after="2023-02-01"> + expires_after="2023-04-02"> <owner>crisrael@google.com</owner> <owner>nearby-share-chromeos-eng@google.com</owner> <summary> @@ -621,7 +621,7 @@ </histogram> <histogram name="Nearby.Share.Contacts.HttpResult" enum="NearbyShareHttpResult" - expires_after="2023-02-01"> + expires_after="2023-04-02"> <owner>pushi@google.com</owner> <owner>nearby-share-chromeos-eng@google.com</owner> <summary> @@ -822,7 +822,7 @@ </histogram> <histogram name="Nearby.Share.LocalDeviceData.DeviceDataUpdater.HttpResult" - enum="NearbyShareHttpResult" expires_after="2023-02-01"> + enum="NearbyShareHttpResult" expires_after="2023-04-02"> <owner>cclem@chromium.org</owner> <owner>nearby-share-chromeos-eng@google.com</owner> <summary> @@ -869,7 +869,7 @@ </histogram> <histogram name="Nearby.Share.Onboarding.Duration" units="ms" - expires_after="2023-02-01"> + expires_after="2023-04-02"> <owner>pushi@google.com</owner> <owner>nearby-share-chromeos-eng@google.com</owner> <summary> @@ -901,7 +901,7 @@ </histogram> <histogram name="Nearby.Share.Onboarding.Result" - enum="NearbyShareOnboardingFinalState" expires_after="2023-02-01"> + enum="NearbyShareOnboardingFinalState" expires_after="2023-04-02"> <owner>pushi@google.com</owner> <owner>nearby-share-chromeos-eng@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index 3e4b08f0..b46e1eee8 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -7333,7 +7333,7 @@ </histogram> <histogram name="InstanceID.GetToken.RequestStatus" - enum="GCMRegistrationRequestStatus" expires_after="2023-01-29"> + enum="GCMRegistrationRequestStatus" expires_after="2023-04-02"> <owner>peter@chromium.org</owner> <summary>Status code of the outcome of GetToken request.</summary> </histogram> @@ -11617,7 +11617,7 @@ </histogram> <histogram name="SB2.RemoteCall.CanCheckUrl" enum="BooleanCanCheckUrl" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>vakh@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary> @@ -15151,7 +15151,7 @@ </histogram> <histogram name="WebFont.DownloadTime.LoadError" units="ms" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>kenjibaheux@chromium.org</owner> <owner>ksakamoto@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/permissions/histograms.xml b/tools/metrics/histograms/metadata/permissions/histograms.xml index 34643848..8a05987 100644 --- a/tools/metrics/histograms/metadata/permissions/histograms.xml +++ b/tools/metrics/histograms/metadata/permissions/histograms.xml
@@ -282,7 +282,7 @@ </histogram> <histogram name="Permissions.CrowdDeny.PreloadData.VersionAtAbuseCheckTime" - units="date" expires_after="2023-01-29"> + units="date" expires_after="2023-04-02"> <owner>elklm@chromium.org</owner> <owner>src/components/permissions/PERMISSIONS_OWNERS</owner> <summary> @@ -1046,7 +1046,7 @@ </histogram> <histogram name="SiteEngagementService.EngagementType" - enum="SiteEngagementServiceEngagementType" expires_after="2023-01-29"> + enum="SiteEngagementServiceEngagementType" expires_after="2023-04-02"> <owner>calamity@chromium.org</owner> <owner>dominickn@chromium.org</owner> <summary> @@ -1208,6 +1208,19 @@ </summary> </histogram> +<histogram name="WebsiteSettings.GetAllSitesLoadTime" units="ms" + expires_after="M111"> + <owner>olesiamarukhno@google.com</owner> + <owner>sauski@google.com</owner> + <owner>chrome-friendly-settings@google.com</owner> + <summary> + Records the load time of the "All sites" settings page. The load + time is the time between the "GetAllSites" request start and the + time when the storage is fetched and the full information is returned to the + UI. + </summary> +</histogram> + <histogram name="WebsiteSettings.Menu.PermissionChanged" enum="ContentType" expires_after="M81"> <obsolete>
diff --git a/tools/metrics/histograms/metadata/phonehub/histograms.xml b/tools/metrics/histograms/metadata/phonehub/histograms.xml index 635bd44..9b2d80b 100644 --- a/tools/metrics/histograms/metadata/phonehub/histograms.xml +++ b/tools/metrics/histograms/metadata/phonehub/histograms.xml
@@ -199,7 +199,7 @@ </histogram> <histogram name="PhoneHub.Connection.Duration" units="ms" - expires_after="2023-02-01"> + expires_after="2023-04-02"> <owner>jonmann@chromium.org</owner> <owner>chromeos-cross-device-eng@google.com</owner> <summary> @@ -219,7 +219,7 @@ </histogram> <histogram name="PhoneHub.Connection.Result" enum="BooleanSuccess" - expires_after="2023-02-01"> + expires_after="2023-04-02"> <owner>jonmann@chromium.org</owner> <owner>chromeos-cross-device-eng@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/platform/histograms.xml b/tools/metrics/histograms/metadata/platform/histograms.xml index 87e0cdb..6e4d015e 100644 --- a/tools/metrics/histograms/metadata/platform/histograms.xml +++ b/tools/metrics/histograms/metadata/platform/histograms.xml
@@ -1555,7 +1555,7 @@ </histogram> <histogram name="Platform.Trunks.TpmErrorCode" enum="TPMResponseCode" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>yich@google.com</owner> <owner>cros-hwsec+uma@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/power/histograms.xml b/tools/metrics/histograms/metadata/power/histograms.xml index b20fc25..7fe51be3 100644 --- a/tools/metrics/histograms/metadata/power/histograms.xml +++ b/tools/metrics/histograms/metadata/power/histograms.xml
@@ -754,7 +754,7 @@ </histogram> <histogram name="Power.BatteryDischargeRate" units="mW" - expires_after="2023-03-26"> + expires_after="2023-04-02"> <owner>puthik@chromium.org</owner> <owner>chromeos-platform-power@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index c35adbe..db48159 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -1214,7 +1214,10 @@ <owner>chrome-counter-abuse-alerts@google.com</owner> <summary> Records the extension telemetry signal type. Logged each time a signal is - triggered (eg. a tabs.executeScript API call is invoked). + triggered (eg. a tabs.executeScript API call is invoked). The signal can be + a raw signal that is created externally and passed to extension service or a + combined signal that is created internally and derived from other raw + signals. </summary> </histogram> @@ -1757,7 +1760,7 @@ </histogram> <histogram name="SafeBrowsing.RT.IsLookupServiceAvailable" - enum="BooleanAvailable" expires_after="2023-01-29"> + enum="BooleanAvailable" expires_after="2023-04-02"> <owner>xinghuilu@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary> @@ -1769,7 +1772,7 @@ </histogram> <histogram name="SafeBrowsing.RT.IsLookupSuccessful" enum="BooleanSuccess" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>xinghuilu@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary> @@ -1810,7 +1813,7 @@ </histogram> <histogram name="SafeBrowsing.RT.LocalMatch.Result" - enum="SafeBrowsingAllowlistAsyncMatch" expires_after="2023-01-29"> + enum="SafeBrowsingAllowlistAsyncMatch" expires_after="2023-04-02"> <owner>vakh@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/security/histograms.xml b/tools/metrics/histograms/metadata/security/histograms.xml index a0a13b4..02e6a2fe 100644 --- a/tools/metrics/histograms/metadata/security/histograms.xml +++ b/tools/metrics/histograms/metadata/security/histograms.xml
@@ -241,7 +241,7 @@ </histogram> <histogram name="Security.PageInfo.AdPersonalizationRowShown" enum="Boolean" - expires_after="M109"> + expires_after="M112"> <owner>dullweber@chromium.org</owner> <owner>sauski@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/startup/histograms.xml b/tools/metrics/histograms/metadata/startup/histograms.xml index ce71c57..5bc4dbe97 100644 --- a/tools/metrics/histograms/metadata/startup/histograms.xml +++ b/tools/metrics/histograms/metadata/startup/histograms.xml
@@ -90,7 +90,7 @@ </histogram> <histogram name="Startup.Android.Cold.FirstSafeBrowsingResponseTime.Tabbed" - units="ms" expires_after="2023-01-29"> + units="ms" expires_after="2023-04-02"> <owner>pasko@chromium.org</owner> <owner>xinghuilu@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> @@ -102,7 +102,7 @@ </histogram> <histogram base="true" name="Startup.Android.Cold.TimeToFirstContentfulPaint" - units="ms" expires_after="2023-01-29"> + units="ms" expires_after="2023-04-02"> <owner>pasko@chromium.org</owner> <owner>alexilin@chromium.org</owner> <summary> @@ -115,7 +115,7 @@ </histogram> <histogram base="true" name="Startup.Android.Cold.TimeToFirstNavigationCommit" - units="ms" expires_after="2023-01-29"> + units="ms" expires_after="2023-04-02"> <owner>pasko@chromium.org</owner> <owner>alexilin@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/subresource/histograms.xml b/tools/metrics/histograms/metadata/subresource/histograms.xml index de5d851..ab776e4 100644 --- a/tools/metrics/histograms/metadata/subresource/histograms.xml +++ b/tools/metrics/histograms/metadata/subresource/histograms.xml
@@ -413,7 +413,7 @@ </histogram> <histogram name="SubresourceFilter.PageLoad.ActivationList" - enum="ActivationList" expires_after="2023-01-29"> + enum="ActivationList" expires_after="2023-04-02"> <owner>alexmt@chromium.org</owner> <owner>chrome-ads-histograms@google.com</owner> <summary> @@ -423,7 +423,7 @@ </histogram> <histogram name="SubresourceFilter.PageLoad.ActivationState" - enum="SubresourceFilterActivationState" expires_after="2023-01-29"> + enum="SubresourceFilterActivationState" expires_after="2023-04-02"> <owner>alexmt@chromium.org</owner> <owner>chrome-ads-histograms@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/sync/histograms.xml b/tools/metrics/histograms/metadata/sync/histograms.xml index 4d66bd8..4df4aee 100644 --- a/tools/metrics/histograms/metadata/sync/histograms.xml +++ b/tools/metrics/histograms/metadata/sync/histograms.xml
@@ -634,7 +634,7 @@ </histogram> <histogram name="Sync.Local.ReadPlatformFileError" enum="PlatformFileError" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>igorruvinov@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <component>Services>Sync</component> @@ -990,7 +990,7 @@ </histogram> <histogram name="Sync.PasswordNotesStateInUpdate" - enum="SyncPasswordNotesStateInUpdate" expires_after="2023-02-01"> + enum="SyncPasswordNotesStateInUpdate" expires_after="2023-04-02"> <owner>mamir@chromium.org</owner> <owner>mastiz@chromium.org</owner> <component>Services>Sync</component> @@ -1046,7 +1046,7 @@ </histogram> <histogram name="Sync.PostedDataTypeCommitRequest" enum="SyncModelTypes" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>mastiz@chromium.org</owner> <owner>rushans@google.com</owner> <component>Services>Sync</component> @@ -1060,7 +1060,7 @@ </histogram> <histogram name="Sync.PostedDataTypeGetUpdatesRequest" enum="SyncModelTypes" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>mastiz@chromium.org</owner> <owner>rushans@google.com</owner> <component>Services>Sync</component>
diff --git a/tools/metrics/histograms/metadata/tab/histograms.xml b/tools/metrics/histograms/metadata/tab/histograms.xml index a2dbe4d..b314cd7 100644 --- a/tools/metrics/histograms/metadata/tab/histograms.xml +++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -457,7 +457,7 @@ </histogram> <histogram name="Tab.Preview.TimeToFirstUsableFrameAfterStartCapture" - units="ms" expires_after="2023-01-29"> + units="ms" expires_after="2023-04-02"> <owner>dfried@chromium.org</owner> <owner>collinbaker@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/v8/histograms.xml b/tools/metrics/histograms/metadata/v8/histograms.xml index dbc4979..6d74583ce 100644 --- a/tools/metrics/histograms/metadata/v8/histograms.xml +++ b/tools/metrics/histograms/metadata/v8/histograms.xml
@@ -2266,7 +2266,7 @@ </histogram> <histogram name="V8.WasmTierUpModuleMicroSeconds" units="microseconds" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>ecmziegler@chromium.org</owner> <owner>adamk@chromium.org</owner> <owner>clemensb@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/web_apk/histograms.xml b/tools/metrics/histograms/metadata/web_apk/histograms.xml index 3373f59..b5e237c 100644 --- a/tools/metrics/histograms/metadata/web_apk/histograms.xml +++ b/tools/metrics/histograms/metadata/web_apk/histograms.xml
@@ -76,7 +76,7 @@ </histogram> <histogram name="WebApk.Install.GooglePlayInstallResult" - enum="WebApkGooglePlayInstallResult" expires_after="2023-01-29"> + enum="WebApkGooglePlayInstallResult" expires_after="2023-04-02"> <owner>hartmanng@chromium.org</owner> <owner> src/chrome/android/java/src/org/chromium/chrome/browser/webapps/OWNERS
diff --git a/tools/metrics/histograms/metadata/web_rtc/histograms.xml b/tools/metrics/histograms/metadata/web_rtc/histograms.xml index 468e0cf..2e8f5ee 100644 --- a/tools/metrics/histograms/metadata/web_rtc/histograms.xml +++ b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
@@ -534,7 +534,7 @@ </histogram> <histogram name="WebRTC.Audio.DelayedPacketOutageEventMs" units="ms" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>hlundin@chromium.org</owner> <summary> Measures the duration of each packet loss concealment (a.k.a. expand) event @@ -799,7 +799,7 @@ </histogram> <histogram name="WebRTC.Audio.ExpandRatePercent" units="%" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>hlundin@chromium.org</owner> <summary> Measures the expand rate for an incoming WebRTC audio stream. The expand @@ -1561,6 +1561,10 @@ <histogram name="WebRTC.PeerConnection.KeyProtocol" enum="PeerConnectionKeyProtocol" expires_after="2022-10-30"> + <obsolete> + The SDES protocol is no longer available in Chrome as of M98. DTLS is the + only possible value. + </obsolete> <owner>hta@chromium.org</owner> <owner>webrtc-dev@chromium.org</owner> <summary> @@ -1965,7 +1969,7 @@ </histogram> <histogram name="WebRTC.ReceivedAudioTrackDuration" units="ms" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>perkj@chromium.org</owner> <summary> Durations of audio tracks received over a PeerConnection. The stopwatch
diff --git a/tools/metrics/histograms/metadata/webapps/histograms.xml b/tools/metrics/histograms/metadata/webapps/histograms.xml index 5f7f2e2..6dd43e4 100644 --- a/tools/metrics/histograms/metadata/webapps/histograms.xml +++ b/tools/metrics/histograms/metadata/webapps/histograms.xml
@@ -38,7 +38,7 @@ </histogram> <histogram name="AppBanners.DismissEvent" enum="AppBannersDismissEvent" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>pjmclachlan@google.com</owner> <owner>pcovell@google.com</owner> <summary> @@ -50,7 +50,7 @@ </histogram> <histogram name="AppBanners.DisplayEvent" enum="AppBannersDisplayEvent" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>pjmclachlan@google.com</owner> <owner>pcovell@google.com</owner> <summary> @@ -975,7 +975,7 @@ </histogram> <histogram name="Webapp.SystemApps.FreshInstallDuration" units="ms" - expires_after="2023-01-29"> + expires_after="2023-04-02"> <owner>ortuno@chromium.org</owner> <owner>qjw@chromium.org</owner> <summary> @@ -1078,7 +1078,7 @@ </histogram> <histogram name="Webapp.WebAppUrlLoaderPrepareForLoadResult" - enum="WebAppUrlLoaderResult" expires_after="2023-01-29"> + enum="WebAppUrlLoaderResult" expires_after="2023-04-02"> <owner>qjw@chromium.org</owner> <owner>ortuno@chromium.org</owner> <owner>desktop-pwas-team@google.com</owner>
diff --git a/tools/perf/benchmarks/benchmark_smoke_unittest.py b/tools/perf/benchmarks/benchmark_smoke_unittest.py index 7628455..b7f75a89 100644 --- a/tools/perf/benchmarks/benchmark_smoke_unittest.py +++ b/tools/perf/benchmarks/benchmark_smoke_unittest.py
@@ -119,6 +119,8 @@ 'v8.runtime_stats.top_25', # Fails in Windows, crbug.com/1043048 'wasmpspdfkit', # Fails in Chrome OS, crbug.com/1191938 'memory.desktop' if sys.platform == 'darwin' else None, # crbug.com/1277277 + 'desktop_ui' if sys.platform == 'darwin' else None, # crbug.com/1370958 + 'power.desktop' if sys.platform == 'darwin' else None, # crbug.com/1370958 ]
diff --git a/tools/perf/core/benchmark_runner_test.py b/tools/perf/core/benchmark_runner_test.py index efb7c85..412e91e 100644 --- a/tools/perf/core/benchmark_runner_test.py +++ b/tools/perf/core/benchmark_runner_test.py
@@ -100,7 +100,8 @@ @decorators.Disabled( 'chromeos', # TODO(https://crbug.com/1098412): Fix the test. - 'android-nougat') # Flaky: https://crbug.com/1342706 + 'android-nougat', # Flaky: https://crbug.com/1342706 + 'mac') # Failing: https://crbug.com/1370958 def testTimelineBasedEndToEnd(self): class TestTimelineBasedBenchmark(perf_benchmark.PerfBenchmark): """A dummy benchmark that records a trace and runs sampleMetric on it."""
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 224283c..04e0f87 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,16 +5,16 @@ "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell" }, "win": { - "hash": "61d0dbe93ee69ed61e5b397ecb71680e7bccc7d0", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/6b54769fde8e593a5ad7142596935d8198b511f1/trace_processor_shell.exe" + "hash": "91a42a523f0546aec9aca55dd0d8d5160b6c66c9", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/73436050f398f0197bed1279f92ae87a6b7ec8ca/trace_processor_shell.exe" }, "linux_arm": { "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893", "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell" }, "mac": { - "hash": "482fe6e201c0309c90dd65cccc479b8b31658b20", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/6b54769fde8e593a5ad7142596935d8198b511f1/trace_processor_shell" + "hash": "52d287934ab7750cc91b878dcb9eac92642d4b57", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/cfd7aed8ea3518c78eb91ef185961be0ab784447/trace_processor_shell" }, "mac_arm64": { "hash": "e1ad4861384b06d911a65f035317914b8cc975c6",
diff --git a/ui/gfx/color_conversions.cc b/ui/gfx/color_conversions.cc index 4f96c2e..409f366 100644 --- a/ui/gfx/color_conversions.cc +++ b/ui/gfx/color_conversions.cc
@@ -9,6 +9,7 @@ #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/modules/skcms/skcms.h" #include "ui/gfx/color_space.h" +#include "ui/gfx/geometry/angle_conversions.h" namespace gfx { @@ -126,8 +127,12 @@ if (!h.has_value()) return std::make_tuple(l, 0, 0); - return std::make_tuple(l, c * std::cos(h.value() * 3.141592f / 180.0f), - c * std::sin(h.value() * 3.141592f / 180.0f)); + return std::make_tuple(l, c * std::cos(gfx::DegToRad(h.value())), + c * std::sin(gfx::DegToRad(h.value()))); +} +std::tuple<float, float, float> LabToLCH(float l, float a, float b) { + return std::make_tuple(l, std::sqrt(a * a + b * b), + gfx::RadToDeg(std::atan2f(b, a))); } std::tuple<float, float, float> LabToXYZD50(float l, float a, float b) {
diff --git a/ui/gfx/color_conversions.h b/ui/gfx/color_conversions.h index 99c538d3..8e88f2f 100644 --- a/ui/gfx/color_conversions.h +++ b/ui/gfx/color_conversions.h
@@ -64,6 +64,9 @@ absl::optional<float> h); // Method exposed for testing purposes. +GFX_EXPORT std::tuple<float, float, float> LabToLCH(float l, float a, float b); + +// Method exposed for testing purposes. GFX_EXPORT std::tuple<float, float, float> OKLchToLab(float l, float c, absl::optional<float> h);
diff --git a/ui/gfx/color_conversions_unittest.cc b/ui/gfx/color_conversions_unittest.cc index 7d5c6548..07f751e7 100644 --- a/ui/gfx/color_conversions_unittest.cc +++ b/ui/gfx/color_conversions_unittest.cc
@@ -171,47 +171,83 @@ 48.586294664234586f}}}; // green for (auto& color_pair : colors_tests) { - auto [input_l, input_a, input_b] = color_pair.input; + auto [input_l, input_c, input_h] = color_pair.input; auto [expected_l, expected_a, expected_b] = color_pair.expected; auto [output_l, output_a, output_b] = - LchToLab(input_l, input_a, absl::optional<float>(input_b)); + LchToLab(input_l, input_c, absl::optional<float>(input_h)); EXPECT_NEAR(output_l, expected_l, 0.001f) - << input_l << ' ' << input_a << ' ' << input_b << " to " << expected_l + << input_l << ' ' << input_c << ' ' << input_h << " to " << expected_l << ' ' << expected_a << ' ' << expected_b << " produced " << output_l << ' ' << output_a << ' ' << output_b; EXPECT_NEAR(output_a, expected_a, 0.001f) - << input_l << ' ' << input_a << ' ' << input_b << " to " << expected_l + << input_l << ' ' << input_c << ' ' << input_h << " to " << expected_l << ' ' << expected_a << ' ' << expected_b << " produced " << output_l << ' ' << output_a << ' ' << output_b; EXPECT_NEAR(output_b, expected_b, 0.001f) - << input_l << ' ' << input_a << ' ' << input_b << " to " << expected_l + << input_l << ' ' << input_c << ' ' << input_h << " to " << expected_l << ' ' << expected_a << ' ' << expected_b << " produced " << output_l << ' ' << output_a << ' ' << output_b; } // Try with a none hue value (white). float input_l = 100.0f; - float input_a = 0.000010331815288315629f; + float input_c = 0.000010331815288315629f; absl::optional<float> input_h = absl::nullopt; float expected_l = 100.0f; float expected_a = -0.000007807961277528364f; float expected_b = 0.000006766250648659877f; auto [output_l, output_a, output_b] = - LchToLab(input_l, input_a, absl::optional<float>(input_h)); + LchToLab(input_l, input_c, absl::optional<float>(input_h)); EXPECT_NEAR(output_l, expected_l, 0.001f) - << input_l << ' ' << input_a << ' ' << "none" + << input_l << ' ' << input_c << ' ' << "none" << " to " << expected_l << ' ' << expected_a << ' ' << expected_b << " produced " << output_l << ' ' << output_a << ' ' << output_b; EXPECT_NEAR(output_a, expected_a, 0.001f) - << input_l << ' ' << input_a << ' ' << "none" + << input_l << ' ' << input_c << ' ' << "none" << " to " << expected_l << ' ' << expected_a << ' ' << expected_b << " produced " << output_l << ' ' << output_a << ' ' << output_b; EXPECT_NEAR(output_b, expected_b, 0.001f) - << input_l << ' ' << input_a << ' ' << "none" + << input_l << ' ' << input_c << ' ' << "none" << " to " << expected_l << ' ' << expected_a << ' ' << expected_b << " produced " << output_l << ' ' << output_a << ' ' << output_b; } +TEST(ColorConversions, LabToLCH) { + // Color conversions obtained from + // https://colorjs.io/apps/convert/?color=purple&precision=4 + ColorTest colors_tests[] = { + {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}, // black + {{100.0f, 0.0f, 0.0f}, {100.0f, 0.0f, 0.0f}}, + {{89.11f, -65.472265155436f, 21.906713478207564f}, + {89.11f, 69.04f, 161.5f}}, + {{29.6915239933531f, 56.11167248735513f, -36.292665028011974f}, + {29.6915239933531f, 66.82572352143814f, + -32.894523620605469f}}, // purple + {{38.14895894517021f, 50.38364171345111f, 31.834803335164764f}, + {38.14895894517021f, 59.598372928277406f, + 32.286662896162966f}}, // brown + {{46.27770902748027f, -47.55240796497723f, 48.586294664234586f}, + {46.27770902748027f, 67.9842594463414f, 134.3838583288382f}}}; // green + + for (auto& color_pair : colors_tests) { + auto [input_l, input_a, input_b] = color_pair.input; + auto [expected_l, expected_c, expected_h] = color_pair.expected; + auto [output_l, output_c, output_h] = LabToLCH(input_l, input_a, input_b); + EXPECT_NEAR(output_l, expected_l, 0.001f) + << input_l << ' ' << input_a << ' ' << input_b << " to " << expected_l + << ' ' << expected_c << ' ' << expected_h << " produced " << output_l + << ' ' << output_c << ' ' << output_h; + EXPECT_NEAR(output_c, expected_c, 0.001f) + << input_l << ' ' << input_a << ' ' << input_b << " to " << expected_l + << ' ' << expected_c << ' ' << expected_h << " produced " << output_l + << ' ' << output_c << ' ' << output_h; + EXPECT_NEAR(output_h, expected_h, 0.001f) + << input_l << ' ' << input_a << ' ' << input_b << " to " << expected_l + << ' ' << expected_c << ' ' << expected_h << " produced " << output_l + << ' ' << output_c << ' ' << output_h; + } +} + TEST(ColorConversions, LchToSkColor4f) { // Color conversions obtained from // https://colorjs.io/apps/convert/?color=purple&precision=4
diff --git a/ui/gl/dc_renderer_layer_params.h b/ui/gl/dc_renderer_layer_params.h index aad14f5..344ea33 100644 --- a/ui/gl/dc_renderer_layer_params.h +++ b/ui/gl/dc_renderer_layer_params.h
@@ -66,7 +66,7 @@ gfx::HDRMetadata hdr_metadata; - bool is_video_fullscreen_letterboxing; + bool is_video_fullscreen_letterboxing = false; }; } // namespace ui
diff --git a/ui/gl/gl_surface_egl_surface_control.cc b/ui/gl/gl_surface_egl_surface_control.cc index 01027a2..f06e2e4 100644 --- a/ui/gl/gl_surface_egl_surface_control.cc +++ b/ui/gl/gl_surface_egl_surface_control.cc
@@ -21,7 +21,6 @@ #include "ui/gl/gl_context.h" #include "ui/gl/gl_features.h" #include "ui/gl/gl_fence_android_native_fence_sync.h" -#include "ui/gl/gl_image_ahardwarebuffer.h" #include "ui/gl/gl_utils.h" namespace gl {
diff --git a/ui/ozone/platform/x11/gl_ozone_glx.cc b/ui/ozone/platform/x11/gl_ozone_glx.cc index 626d75a..f8de6c9 100644 --- a/ui/ozone/platform/x11/gl_ozone_glx.cc +++ b/ui/ozone/platform/x11/gl_ozone_glx.cc
@@ -10,7 +10,6 @@ #include "ui/gl/gl_context_glx.h" #include "ui/gl/gl_gl_api_implementation.h" #include "ui/gl/gl_glx_api_implementation.h" -#include "ui/gl/gl_image_glx_native_pixmap.h" #include "ui/gl/gl_surface_glx_x11.h" #include "ui/gl/gl_utils.h" #include "ui/ozone/platform/x11/native_pixmap_glx_binding.h"