diff --git a/DEPS b/DEPS index 243c2e37..5870648 100644 --- a/DEPS +++ b/DEPS
@@ -308,7 +308,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'src_internal_revision': 'cac0eda4f931b94c714acd417202a318f49cc1cd', + 'src_internal_revision': '96d567763cde6fce93437285efeffbe518734435', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. @@ -316,11 +316,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '54df9a2e6ec0f28a218491cf15a4d6841779b4cc', + 'v8_revision': '6e0661d6b0f95270c198d690bb2c4f54ba2acf4d', # 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': '0c0d10c4914aa427d1fe969508ca327fbeece913', + 'angle_revision': '1724ab3641c825d2ed6fc76e20c3d20301e73696', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -400,7 +400,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': '60b8977eb329282198e284c76f6ac002f5320b45', + 'devtools_frontend_revision': '9d9a7262df8a7db685524e449c0c08fc3f5f0e8c', # 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. @@ -424,7 +424,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': '23f08c798e68e28242fe3cd6990ec049695a930b', + 'dawn_revision': 'd07825efa003125c46a2819c37081dbde0528277', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -1115,10 +1115,10 @@ 'condition': 'non_git_source', 'objects': [ { - 'object_name': 'meet-gpu-tests/840346920.tar.gz', - 'sha256sum': '6b8fd087ccff4a3a71f025eab8dbaacf0c2aafa333094ab88d6d9c34f7df5acd', - 'size_bytes': 279899236, - 'generation': 1764923229945265, + 'object_name': 'meet-gpu-tests/841497707.tar.gz', + 'sha256sum': 'c69f9f23e86b431b890fa3260c91a48aeb404a3c118078ce9c940093b724dbbe', + 'size_bytes': 279899387, + 'generation': 1765182513274195, }, ], }, @@ -1195,7 +1195,7 @@ 'packages': [ { 'package': 'chromium/chrome/android/orderfiles/arm', - 'version': 'dZYQu3DP9aaWlHq0Fa9e5E08WuCGbTsZ8uoJSlg_nkoC', + 'version': 'dmVPO_W27wruNBXShqIBgtUGdKz8XMw2BvT9NIlorw0C', }, ], 'condition': 'checkout_android and non_git_source', @@ -1206,7 +1206,7 @@ 'packages': [ { 'package': 'chromium/chrome/android/orderfiles/arm64', - 'version': 'qWD78zCgbRcktfbDN-NVmhHl4Nezm3StTjRgRpyCKaoC', + 'version': 'IhWwwYw-VCiROoqjoUgb7gl8tB4cR7gBZz_HHd7OxxsC', }, ], 'condition': 'checkout_android and non_git_source', @@ -1217,7 +1217,7 @@ 'packages': [ { 'package': 'chromium/android_webview/tools/orderfiles/arm', - 'version': 'Z7dxpqy_1i64GDrZgQmTk42oIsd0RC-thZ2veKuGIfQC', + 'version': 'UeP3VMzc6YVY-2zU4l1AzC23_zu9TwS7wFHLMV3YxZkC', }, ], 'condition': 'checkout_android and non_git_source', @@ -1613,7 +1613,7 @@ 'packages': [ { 'package': 'chromium/chrome/test/data/variations/cipd', - 'version': 'SXedGGUJh-QzWbgR9gl1wLbi-NDG8kgAPBkm4rBk3icC', + 'version': 'mDYe4CwlW_ojJ4hA2-gTz4U6t5J8Hfx9r9EXNxHoFdEC', }, ], 'dep_type': 'cipd', @@ -1624,12 +1624,12 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '78c4f1290f499ca246f0c7763f32c0c44a41a00d', + 'fe18f1532fab7fddfaac4b6fb1b53dd222e0a532', 'condition': 'checkout_android and checkout_src_internal', }, 'src/docs/website': { - 'url': Var('chromium_git') + '/website.git' + '@' + '105a46915f47f94998e4a3084520835f24ea5a6c', + 'url': Var('chromium_git') + '/website.git' + '@' + '1e6b9080b485c33e823208661cebb5e1f470960c', }, 'src/ios/third_party/earl_grey2/src': { @@ -2109,7 +2109,7 @@ Var('chromium_git') + '/external/github.com/google/flatbuffers.git' + '@' + '187240970746d00bbd26b0f5873ed54d2477f9f3', 'src/third_party/fontconfig/src': { - 'url': Var('chromium_git') + '/external/fontconfig.git' + '@' + '23b3fc6e58a13d126b9c30fafc9a16f8bd7143e9', + 'url': Var('chromium_git') + '/external/fontconfig.git' + '@' + 'd62c2ab268d1679335daa8fb0ea6970f35224a76', 'condition': 'checkout_linux', }, @@ -2610,7 +2610,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('chromium_git') + '/external/github.com/google/perfetto.git' + '@' + '8ab293da46a370dc17283a4d413242385e2033b1', + Var('chromium_git') + '/external/github.com/google/perfetto.git' + '@' + 'ec42dd387c2ab14c7369136e86898be936248315', 'src/base/tracing/test/data': { 'bucket': 'perfetto', @@ -2794,7 +2794,7 @@ 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'Fq2es0-0bCkqirMbdSj2rJpzrvuypdDva8j20lrg3wUC', + 'version': 'aQiRizhSSPFGfHGuoC-0t2O4lFR5OY2qySLXtBS_vtIC', }, ], 'condition': 'checkout_android and non_git_source', @@ -2929,7 +2929,7 @@ 'packages': [ { 'package': 'chromium/third_party/turbine', - 'version': 'DV_E8eKAtXx3kTD4avzQC_CWVnH_yOQrf80YkYt77PAC', + 'version': 'Fr97aXogWofWM2OLPzzlPsz6pDtCWNeOCpshlUq7nHMC', }, ], 'condition': 'checkout_android and non_git_source', @@ -2988,7 +2988,7 @@ Var('chromium_git') + '/webpagereplay.git' + '@' + Var('webpagereplay_revision'), 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'd80cfa2a3d24618558f150bcca616a56cdca234a', + Var('webrtc_git') + '/src.git' + '@' + 'bfe531707560d16644de452e51e2c4fe40c46b91', # 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. @@ -3176,7 +3176,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/projector_app/app', - 'version': 'gs2z8aUF2clQ-2deJ8WTj--ByyAnJP2o_JRY5l0ROf0C', + 'version': 'nLAi6FBQrimREDydiJC9KBDAKrrbCLNBjusC-RUmudcC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -3759,7 +3759,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - 'b751aaeca79d1952ef7631a2e83fbb5b00c133b8', + 'fd52a146a6011abcc1c9c18a07f113fa192a9161', 'condition': 'checkout_ios and checkout_src_internal', },
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_root.cc b/base/allocator/partition_allocator/src/partition_alloc/partition_root.cc index feaa750..55d30b537 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/partition_root.cc +++ b/base/allocator/partition_allocator/src/partition_alloc/partition_root.cc
@@ -1759,8 +1759,12 @@ void PartitionRoot::ResetBookkeepingForTesting() { ::partition_alloc::internal::ScopedGuard guard{ internal::PartitionRootLock(this)}; - max_size_of_allocated_bytes = total_size_of_allocated_bytes; - max_size_of_committed_pages.store(total_size_of_committed_pages); + max_size_of_allocated_bytes.store( + total_size_of_allocated_bytes.load(std::memory_order_relaxed), + std::memory_order_relaxed); + max_size_of_committed_pages.store( + total_size_of_committed_pages.load(std::memory_order_relaxed), + std::memory_order_relaxed); } void PartitionRoot::SetGlobalEmptySlotSpanRingIndexForTesting(int16_t index) {
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_root.h b/base/allocator/partition_allocator/src/partition_alloc/partition_root.h index c2b2c62..befbb5b4 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/partition_root.h +++ b/base/allocator/partition_allocator/src/partition_alloc/partition_root.h
@@ -334,10 +334,8 @@ std::atomic<size_t> max_size_of_committed_pages{0}; std::atomic<size_t> total_size_of_super_pages{0}; std::atomic<size_t> total_size_of_direct_mapped_pages{0}; - size_t total_size_of_allocated_bytes - PA_GUARDED_BY(internal::PartitionRootLock(this)) = 0; - size_t max_size_of_allocated_bytes - PA_GUARDED_BY(internal::PartitionRootLock(this)) = 0; + std::atomic<size_t> total_size_of_allocated_bytes{0}; + std::atomic<size_t> max_size_of_allocated_bytes{0}; // Atomic, because system calls can be made without the lock held. std::atomic<uint64_t> syscall_count{}; std::atomic<uint64_t> syscall_total_time_ns{}; @@ -450,12 +448,10 @@ uintptr_t address); PA_ALWAYS_INLINE void DecreaseTotalSizeOfAllocatedBytes(uintptr_t slot_start, - size_t len) - PA_EXCLUSIVE_LOCKS_REQUIRED(internal::PartitionRootLock(this)); + size_t len); PA_ALWAYS_INLINE void IncreaseTotalSizeOfAllocatedBytes(uintptr_t addr, size_t len, - size_t raw_size) - PA_EXCLUSIVE_LOCKS_REQUIRED(internal::PartitionRootLock(this)); + size_t raw_size); PA_ALWAYS_INLINE void IncreaseCommittedPages(size_t len); PA_ALWAYS_INLINE void DecreaseCommittedPages(size_t len); PA_ALWAYS_INLINE void DecommitSystemPagesForData( @@ -744,13 +740,13 @@ size_t get_total_size_of_allocated_bytes() const { // Since this is only used for bookkeeping, we don't care if the value is // stale, so no need to get a lock here. - return PA_TS_UNCHECKED_READ(total_size_of_allocated_bytes); + return total_size_of_allocated_bytes.load(std::memory_order_relaxed); } size_t get_max_size_of_allocated_bytes() const { // Since this is only used for bookkeeping, we don't care if the value is // stale, so no need to get a lock here. - return PA_TS_UNCHECKED_READ(max_size_of_allocated_bytes); + return max_size_of_allocated_bytes.load(std::memory_order_relaxed); } internal::pool_handle ChoosePool() const { return settings.pool_handle; } @@ -1304,9 +1300,6 @@ slot_start.Check(this); - IncreaseTotalSizeOfAllocatedBytes( - slot_start.value(), slot_span->GetSlotSizeForBookkeeping(), raw_size); - *slot_size = slot_span->bucket->slot_size; return slot_start; } @@ -1707,9 +1700,6 @@ PA_ALWAYS_INLINE void PartitionRoot::FreeInSlotSpan( internal::UntaggedSlotStart slot_start, SlotSpanMetadata* slot_span) { - DecreaseTotalSizeOfAllocatedBytes(slot_start.value(), - slot_span->GetSlotSizeForBookkeeping()); - return slot_span->Free(slot_start.value(), this); } @@ -1773,6 +1763,9 @@ internal::SecureMemset(ptr, 0, GetSlotUsableSize(slot_span)); } + DecreaseTotalSizeOfAllocatedBytes(slot_start.value(), + slot_span->GetSlotSizeForBookkeeping()); + ::partition_alloc::internal::ScopedGuard guard{ internal::PartitionRootLock(this)}; FreeInSlotSpan(slot_start.Untag(), slot_span); @@ -1862,6 +1855,8 @@ // may not expect that, but we never call this function on direct-mapped // allocations. PA_DCHECK(!IsDirectMappedBucket(slot_span->bucket)); + DecreaseTotalSizeOfAllocatedBytes(slot_start.value(), + slot_span->GetSlotSizeForBookkeeping()); FreeInSlotSpan(slot_start, slot_span); } @@ -1901,9 +1896,20 @@ uintptr_t addr, size_t len, size_t raw_size) { - total_size_of_allocated_bytes += len; - max_size_of_allocated_bytes = - std::max(max_size_of_allocated_bytes, total_size_of_allocated_bytes); + // |total_size_of_allocated_bytes| is only for debugging/stats, so relaxed + // memory order is sufficient. + size_t previous_total_size_of_allocated_bytes = + total_size_of_allocated_bytes.fetch_add(len, std::memory_order_relaxed); + size_t new_total_size_of_allocated_bytes = + previous_total_size_of_allocated_bytes + len; + + size_t expected, desired; + do { + expected = max_size_of_allocated_bytes.load(std::memory_order_relaxed); + desired = std::max(expected, new_total_size_of_allocated_bytes); + } while (!max_size_of_allocated_bytes.compare_exchange_weak( + expected, desired, std::memory_order_relaxed, std::memory_order_relaxed)); + #if PA_BUILDFLAG(RECORD_ALLOC_INFO) partition_alloc::internal::RecordAllocOrFree(addr | 0x01, raw_size); #endif // PA_BUILDFLAG(RECORD_ALLOC_INFO) @@ -1914,8 +1920,11 @@ size_t len) { // An underflow here means we've miscounted |total_size_of_allocated_bytes| // somewhere. - PA_DCHECK(total_size_of_allocated_bytes >= len); - total_size_of_allocated_bytes -= len; + // |total_size_of_allocated_bytes| is only for debugging/stats, so relaxed + // memory order is sufficient. + size_t previous_total_size_of_allocated_bytes = + total_size_of_allocated_bytes.fetch_sub(len, std::memory_order_relaxed); + PA_DCHECK(previous_total_size_of_allocated_bytes >= len); #if PA_BUILDFLAG(RECORD_ALLOC_INFO) partition_alloc::internal::RecordAllocOrFree(addr | 0x00, len); #endif // PA_BUILDFLAG(RECORD_ALLOC_INFO) @@ -2402,10 +2411,20 @@ size_t* usable_size, size_t* slot_size, bool* is_already_zeroed) { - ::partition_alloc::internal::ScopedGuard guard{ - internal::PartitionRootLock(this)}; - return AllocFromBucket<flags>(bucket, raw_size, slot_span_alignment, - usable_size, slot_size, is_already_zeroed); + internal::UntaggedSlotStart slot_start; + { + ::partition_alloc::internal::ScopedGuard guard{ + internal::PartitionRootLock(this)}; + slot_start = + AllocFromBucket<flags>(bucket, raw_size, slot_span_alignment, + usable_size, slot_size, is_already_zeroed); + } + + if (slot_start.value()) [[likely]] { + IncreaseTotalSizeOfAllocatedBytes(slot_start.value(), *slot_size, raw_size); + } + + return slot_start; } template <AllocFlags flags>
diff --git a/base/allocator/partition_allocator/src/partition_alloc/thread_cache.cc b/base/allocator/partition_allocator/src/partition_alloc/thread_cache.cc index d8393eb..eb4dee2f 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/thread_cache.cc +++ b/base/allocator/partition_allocator/src/partition_alloc/thread_cache.cc
@@ -621,38 +621,54 @@ PA_UNSAFE_TODO(PA_DCHECK(!root_->buckets[bucket_index].is_direct_mapped())); size_t allocated_slots = 0; - // Same as calling RawAlloc() |count| times, but acquires the lock only once. - internal::ScopedGuard guard(internal::PartitionRootLock(root_)); - for (int i = 0; i < count; i++) { - // Thread cache fill should not trigger expensive operations, to not grab - // the lock for a long time needlessly, but also to not inflate memory - // usage. Indeed, without AllocFlags::kFastPathOrReturnNull, cache - // fill may activate a new PartitionPage, or even a new SuperPage, which is - // clearly not desirable. - // - // |raw_size| is set to the slot size, as we don't know it. However, it is - // only used for direct-mapped allocations and single-slot ones anyway, - // which are not handled here. - size_t ret_slot_size; - internal::UntaggedSlotStart slot_start = root_->AllocFromBucket< - AllocFlags::kFastPathOrReturnNull | AllocFlags::kReturnNull>( - &PA_UNSAFE_TODO(root_->buckets[bucket_index]), - PA_UNSAFE_TODO(root_->buckets[bucket_index]).slot_size /* raw_size */, - internal::PartitionPageSize(), &usable_size, &ret_slot_size, - &is_already_zeroed); - // Either the previous allocation would require a slow path allocation, or - // the central allocator is out of memory. If the bucket was filled with - // some objects, then the allocation will be handled normally. Otherwise, - // this goes to the central allocator, which will service the allocation, - // return nullptr or crash. - if (!slot_start) { - break; - } - PA_UNSAFE_TODO( - PA_DCHECK(ret_slot_size == root_->buckets[bucket_index].slot_size)); - allocated_slots++; - PutInBucket(bucket, slot_start); + // limit is uint8_t, so max 255. count <= 255/8 = 31. + // Use a slightly larger buffer to be safe. + constexpr size_t kMaxBatchSize = 64; + count = std::min(count, static_cast<int>(kMaxBatchSize)); + internal::UntaggedSlotStart slot_starts[kMaxBatchSize]; + + { + // Same as calling RawAlloc() |count| times, but acquires the lock only + // once. + internal::ScopedGuard guard(internal::PartitionRootLock(root_)); + for (int i = 0; i < count; i++) { + // Thread cache fill should not trigger expensive operations, to not grab + // the lock for a long time needlessly, but also to not inflate memory + // usage. Indeed, without AllocFlags::kFastPathOrReturnNull, cache + // fill may activate a new PartitionPage, or even a new SuperPage, which + // is clearly not desirable. + // + // |raw_size| is set to the slot size, as we don't know it. However, it is + // only used for direct-mapped allocations and single-slot ones anyway, + // which are not handled here. + size_t ret_slot_size; + internal::UntaggedSlotStart slot_start = root_->AllocFromBucket< + AllocFlags::kFastPathOrReturnNull | AllocFlags::kReturnNull>( + &PA_UNSAFE_TODO(root_->buckets[bucket_index]), + PA_UNSAFE_TODO(root_->buckets[bucket_index]).slot_size /* raw_size */, + internal::PartitionPageSize(), &usable_size, &ret_slot_size, + &is_already_zeroed); + // Either the previous allocation would require a slow path allocation, or + // the central allocator is out of memory. If the bucket was filled with + // some objects, then the allocation will be handled normally. Otherwise, + // this goes to the central allocator, which will service the allocation, + // return nullptr or crash. + if (!slot_start) { + break; + } + PA_UNSAFE_TODO( + PA_DCHECK(ret_slot_size == root_->buckets[bucket_index].slot_size)); + + PA_UNSAFE_TODO(slot_starts[allocated_slots++]) = slot_start; + } + } + + for (size_t i = 0; i < allocated_slots; ++i) { + root_->IncreaseTotalSizeOfAllocatedBytes( + PA_UNSAFE_TODO(slot_starts[i]).value(), bucket.slot_size, + bucket.slot_size); + PutInBucket(bucket, PA_UNSAFE_TODO(slot_starts[i])); } cached_memory_ += allocated_slots * bucket.slot_size;
diff --git a/base/trace_event/builtin_categories.h b/base/trace_event/builtin_categories.h index af3c4d2..8649b24 100644 --- a/base/trace_event/builtin_categories.h +++ b/base/trace_event/builtin_categories.h
@@ -303,11 +303,6 @@ .SetTags("slow"), perfetto::Category(TRACE_DISABLED_BY_DEFAULT("blink.invalidation")) .SetTags("slow"), - perfetto::Category(TRACE_DISABLED_BY_DEFAULT("identifiability")) - .SetTags("slow"), - perfetto::Category( - TRACE_DISABLED_BY_DEFAULT("identifiability.high_entropy_api")) - .SetTags("slow"), perfetto::Category(TRACE_DISABLED_BY_DEFAULT("cc")) .SetTags("slow"), perfetto::Category(TRACE_DISABLED_BY_DEFAULT("cc.debug")).SetTags("debug"),
diff --git a/base/tracing/protos/chrome_track_event.proto b/base/tracing/protos/chrome_track_event.proto index 84cb96e..4c5ce3ad 100644 --- a/base/tracing/protos/chrome_track_event.proto +++ b/base/tracing/protos/chrome_track_event.proto
@@ -1340,122 +1340,6 @@ optional double first_contentful_paint_ms = 5; } -// A serialisation of v8StackFrame class. -message V8StackFrame { - // Code location (path to the script and line/column number) - message ScriptLocation { - optional string source_url = 1; - optional int64 line_number = 2; - optional int64 column_number = 3; - } - - // The name of the function that was called - optional string function_name = 1; - - // If the function was defined in a script, contains the location within the - // script. - optional ScriptLocation script_location = 2; -} - -// Serializes the blink::ExecutionContext object. -message BlinkExecutionContext { - // Definition of different context types. - enum ContextType { - UNKNOWN_CONTEXT = 0; - WINDOW = 1; - WORKLET = 2; - DEDICATED_WORKER = 3; - SHARED_WORKER = 4; - SERVICE_WORKER = 5; - } - - // Definition of world type. - enum WorldType { - WORLD_UNKNOWN = 0; - WORLD_MAIN = 1; - WORLD_ISOLATED = 2; - WORLD_INSPECTOR_ISOLATED = 3; - WORLD_REG_EXP = 4; - WORLD_FOR_V8_CONTEXT_SNAPSHOT_NON_MAIN = 5; - WORLD_WORKER = 6; - WORLD_SHADOW_REALM = 7; - } - - optional ContextType type = 1; - // Contains url of frame or worker. - optional string url = 2; - // The origin of the execution context. - optional string origin = 3; - // The world type of the execution context. - optional WorldType world_type = 4; -} - -// Serializes the blink::SourceLocation object. -message BlinkSourceLocation { - optional string function_name = 1; - optional int32 script_id = 2; - optional string url = 3; - optional int32 line_number = 4; - optional int32 column_number = 5; - optional string stack_trace = 6; - repeated V8StackFrame stack_frames = 7; -} - -// Contains the meta information for high entropy events (like api calls) -// that are to be traced for debugging in the context of identifiability study. -message BlinkHighEntropyAPI { - // Serialization of a parameter passed to a javascript function. - // Contains the stringified type of the object and some string representation - // of its value. - message JSFunctionArgument { - // Definition of different types of function parameters. - enum ArgumentType { - UNKNOWN_TYPE = 0; - NULL_TYPE = 1; - UNDEFINED = 2; - BIGINT = 3; - BOOLEAN = 4; - FUNCTION = 5; - NUMBER = 6; - STRING = 7; - SYMBOL = 8; - OBJECT = 9; - } - optional ArgumentType type = 1; - optional string value = 2; - } - - // Describes a Javascript API call. - message CalledJsApi { - // Contains class and function name of api called - // similar to "Navigator.languages.get". - optional string identifier = 1; - repeated JSFunctionArgument func_arguments = 2; - - // Deprecated in favour of outer source_location. Not filled anymore in - // newer versions of chrome. - optional BlinkSourceLocation source_location = 3 [deprecated = true]; - } - optional BlinkExecutionContext execution_context = 1; - optional CalledJsApi called_api = 2; - optional BlinkSourceLocation source_location = 3; - - // Describes lookup of a font. - message FontLookup { - enum FontLookupType { - FONT_LOOKUP_UNKNOWN_TYPE = 0; - FONT_LOOKUP_UNIQUE_OR_FAMILY_NAME = 1; - FONT_LOOKUP_UNIQUE_NAME_ONLY = 2; - } - optional FontLookupType type = 1; - optional string name = 2; - optional uint64 weight = 3; - optional uint64 width = 4; - optional uint64 slope = 5; - } - optional FontLookup font_lookup = 4; -} - // Contains information about a tab switch measurement. message TabSwitchMeasurement { // Possible outcomes of a tab switch. Maps to @@ -2875,6 +2759,8 @@ }; message ChromeTrackEvent { + reserved 1045; + // Extension range for Chrome: 1000-1999 // Next ID: 1079 extend TrackEvent { @@ -2973,8 +2859,6 @@ optional UkmPageLoadTimingUpdate ukm_page_load_timing_update = 1044; - optional BlinkHighEntropyAPI high_entropy_api = 1045; - optional TabSwitchMeasurement tab_switch_measurement = 1046; optional ScrollDeltas scroll_deltas = 1047;
diff --git a/build/config/freetype/BUILD.gn b/build/config/freetype/BUILD.gn index 4b80753..a5d5ec6 100644 --- a/build/config/freetype/BUILD.gn +++ b/build/config/freetype/BUILD.gn
@@ -20,8 +20,6 @@ visibility = [ "//chrome/test:*", "//content/test:*", - "//skia", - "//third_party/fontconfig", # The path/label of the PDFium target that depends on `freetype` is # different when building PDFium during Chromium build and during @@ -29,7 +27,8 @@ "//:freetype_common", # Building standalone PDFium "//third_party/pdfium:freetype_common", # Building Chromium - # Other dependencies that we think are PDFium-related: + # Other dependencies that are PDFium-related: "//components/services/font:font_service_unittests", + "//skia", ] }
diff --git a/build/config/freetype/freetype.gni b/build/config/freetype/freetype.gni index 7ad6862d..dd89ad0 100644 --- a/build/config/freetype/freetype.gni +++ b/build/config/freetype/freetype.gni
@@ -21,13 +21,8 @@ # FreeType is completely replaced with the Rust-based Fontations set of # libraries plus Skia path rendering. # - # Ideally, this should be set with the same value as `enable_pdf` in - # //pdf/features.gni, but: - # - # - Cast on Linux depends on Fontconfig, and Fontconfig depends on FreeType: - # https://crbug.com/370816215 - # - # Note: //build should not import directly from //pdf for layering reasons. - enable_freetype = - !is_android && !is_ios && (is_linux || !is_castos) && !is_fuchsia + # This should be kept in sync with the value of `enable_pdf` in + # //pdf/features.gni, but for layering reasons, + # we can't import pdf's features.gni here. + enable_freetype = !is_android && !is_ios && !is_castos && !is_fuchsia }
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc index b278bb8..59dd7da1 100644 --- a/cc/test/layer_tree_pixel_test.cc +++ b/cc/test/layer_tree_pixel_test.cc
@@ -149,14 +149,9 @@ void LayerTreePixelTest::DrawLayersOnThread(LayerTreeHostImpl* host_impl) { // Verify that we're using Gpu rasterization or not as requested. if (!use_software_renderer()) { - viz::RasterContextProvider* worker_context_provider = - host_impl->layer_tree_frame_sink()->worker_context_provider(); - viz::RasterContextProvider::ScopedRasterContextLock lock( - worker_context_provider); - EXPECT_EQ(use_accelerated_raster(), - worker_context_provider->ContextCapabilities().gpu_rasterization); + EXPECT_EQ(use_accelerated_raster(), host_impl->use_gpu_rasterization()); EXPECT_EQ(raster_type() == TestRasterType::kGpu, - worker_context_provider->ContextCapabilities().gpu_rasterization); + host_impl->use_gpu_rasterization()); } else { EXPECT_EQ(TestRasterType::kBitmap, raster_type()); }
diff --git a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java index e75a4664..4ca93cf 100644 --- a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java +++ b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java
@@ -11,7 +11,9 @@ import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; @@ -50,6 +52,7 @@ import org.chromium.base.task.test.CustomShadowAsyncTask; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.Features; +import org.chromium.base.test.util.Features.DisableFeatures; import org.chromium.chrome.browser.autofill.PersonalDataManager; import org.chromium.chrome.browser.autofill.PersonalDataManagerFactory; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -97,6 +100,7 @@ shadows = {CustomShadowAsyncTask.class}) @Features.EnableFeatures({ ChromeFeatureList.AUTOFILL_ANDROID_DESKTOP_KEYBOARD_ACCESSORY_REVAMP, + ChromeFeatureList.AUTOFILL_ANDROID_KEYBOARD_ACCESSORY_DYNAMIC_POSITIONING, ChromeFeatureList.AUTOFILL_ENABLE_KEYBOARD_ACCESSORY_CHIP_REDESIGN, ChromeFeatureList.AUTOFILL_ENABLE_KEYBOARD_ACCESSORY_CHIP_WIDTH_ADJUSTMENT, }) @@ -658,6 +662,7 @@ } @Test + @DisableFeatures(ChromeFeatureList.AUTOFILL_ANDROID_KEYBOARD_ACCESSORY_DYNAMIC_POSITIONING) public void testLargeFormFactorHasDismissButton() { when(mMockIsLargeFormFactorSupplier.get()).thenReturn(true); @@ -670,6 +675,19 @@ } @Test + public void testLargeFormFactorDynamicPositioningHasNoDismissButton() { + when(mMockIsLargeFormFactorSupplier.get()).thenReturn(true); + + mCoordinator.setSuggestions(List.of(mock(AutofillSuggestion.class)), mMockAutofillDelegate); + + assertThat(mModel.get(BAR_ITEMS), contains(instanceOf(AutofillBarItem.class))); + + assertThat(mModel.get(BAR_ITEMS_FIXED), not(hasItem(instanceOf(DismissBarItem.class)))); + assertThat(mModel.get(BAR_ITEMS_FIXED), contains(instanceOf(SheetOpenerBarItem.class))); + } + + @Test + @DisableFeatures(ChromeFeatureList.AUTOFILL_ANDROID_KEYBOARD_ACCESSORY_DYNAMIC_POSITIONING) public void testLargeFormFactorHasFixedItems() { when(mMockIsLargeFormFactorSupplier.get()).thenReturn(true); Provider<Action[]> generationProvider = new Provider<>(GENERATE_PASSWORD_AUTOMATIC);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/BatchUploadCardPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/BatchUploadCardPreference.java index 1fcc0398..eb1e8f7a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/BatchUploadCardPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/BatchUploadCardPreference.java
@@ -55,9 +55,7 @@ mBatchUploadCardCoordinator.immediatelyHideBatchUploadCardAndUpdateItsVisibility(); } - @Override - public void onDetached() { - super.onDetached(); + void destroy() { mBatchUploadCardCoordinator.destroy(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java index be26093d..61302fb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java
@@ -305,6 +305,10 @@ if (!mShouldReplaceSyncSettingsWithAccountSettings) { mSyncSetupInProgressHandle.close(); } + if (mBatchUploadCardPreference != null) { + mBatchUploadCardPreference.destroy(); + mBatchUploadCardPreference = null; + } } @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/chrome_item_picker/ChromeItemPickerActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/chrome_item_picker/ChromeItemPickerActivityTest.java index ae4d01f6..0ac5c74 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/chrome_item_picker/ChromeItemPickerActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/chrome_item_picker/ChromeItemPickerActivityTest.java
@@ -22,6 +22,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.test.BaseActivityTestRule; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.DoNotBatch; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.omnibox.fusebox.FuseboxMediator; @@ -79,6 +80,7 @@ @Test @MediumTest + @DisabledTest(message = "https://crbug.com/463427787") public void testActivityThemeColorIsDefault() { doTestActivityThemeColor(false); }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index c1056f4..76651ae 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -485,8 +485,6 @@ "enterprise/reporting/profile_report_generator_delegate_base.h", "enterprise/signals/profile_signals_collector.cc", "enterprise/signals/profile_signals_collector.h", - "enterprise/signin/enterprise_identity_service_factory.cc", - "enterprise/signin/enterprise_identity_service_factory.h", "enterprise/signin/interstitials/managed_profile_required_controller_client.cc", "enterprise/signin/interstitials/managed_profile_required_controller_client.h", "enterprise/signin/interstitials/managed_profile_required_page.cc", @@ -2183,7 +2181,6 @@ "//components/enterprise/device_trust", "//components/enterprise/encryption/cache", "//components/enterprise/obfuscation/core:enterprise_obfuscation", - "//components/enterprise/signin", "//components/error_page/common", "//components/error_page/content/browser", "//components/facilitated_payments/core/features",
diff --git a/chrome/browser/devtools/aida_service_handler.cc b/chrome/browser/devtools/aida_service_handler.cc index 3bc00a2f..6ab2b3af 100644 --- a/chrome/browser/devtools/aida_service_handler.cc +++ b/chrome/browser/devtools/aida_service_handler.cc
@@ -75,8 +75,8 @@ return GURL("https://aida.googleapis.com"); } -signin::ScopeSet AidaServiceHandler::OAuthScopes() const { - return {GaiaConstants::kAidaOAuth2Scope}; +signin::OAuthConsumerId AidaServiceHandler::OAuthConsumerId() const { + return signin::OAuthConsumerId::kDevtoolsAida; } net::NetworkTrafficAnnotationTag
diff --git a/chrome/browser/devtools/aida_service_handler.h b/chrome/browser/devtools/aida_service_handler.h index 31b9ac2..e9d178d 100644 --- a/chrome/browser/devtools/aida_service_handler.h +++ b/chrome/browser/devtools/aida_service_handler.h
@@ -19,7 +19,7 @@ void CanMakeRequest(Profile* profile, base::OnceCallback<void(bool success)> callback) override; GURL BaseURL() const override; - signin::ScopeSet OAuthScopes() const override; + signin::OAuthConsumerId OAuthConsumerId() const override; net::NetworkTrafficAnnotationTag NetworkTrafficAnnotationTag() const override; };
diff --git a/chrome/browser/devtools/devtools_http_service_handler.cc b/chrome/browser/devtools/devtools_http_service_handler.cc index 79251dc1..c647f69 100644 --- a/chrome/browser/devtools/devtools_http_service_handler.cc +++ b/chrome/browser/devtools/devtools_http_service_handler.cc
@@ -59,7 +59,7 @@ auto access_token_fetcher = identity_manager->CreateAccessTokenFetcherForAccount( identity_manager->GetPrimaryAccountId(signin::ConsentLevel::kSignin), - "DevTools_dispatchHttpRequest", OAuthScopes(), + OAuthConsumerId(), base::BindOnce(&DevToolsHttpServiceHandler::OnTokenFetched, weak_factory_.GetWeakPtr(), std::move(callback), profile, params, fetcher_id),
diff --git a/chrome/browser/devtools/devtools_http_service_handler.h b/chrome/browser/devtools/devtools_http_service_handler.h index e357951..7661088 100644 --- a/chrome/browser/devtools/devtools_http_service_handler.h +++ b/chrome/browser/devtools/devtools_http_service_handler.h
@@ -13,7 +13,6 @@ #include "base/unguessable_token.h" #include "chrome/browser/devtools/devtools_dispatch_http_request_params.h" #include "components/signin/public/identity_manager/access_token_fetcher.h" -#include "components/signin/public/identity_manager/scope_set.h" #include "google_apis/gaia/google_service_auth_error.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "services/network/public/cpp/simple_url_loader.h" @@ -69,8 +68,8 @@ // Returns the base URL for the service's API. virtual GURL BaseURL() const = 0; - // Returns the OAuth scopes required for authenticating with the service. - virtual signin::ScopeSet OAuthScopes() const = 0; + // Returns the OAuth consumer id required for authenticating with the service. + virtual signin::OAuthConsumerId OAuthConsumerId() const = 0; // Returns the traffic annotation for the request. virtual net::NetworkTrafficAnnotationTag NetworkTrafficAnnotationTag()
diff --git a/chrome/browser/devtools/devtools_ui_bindings_unittest.cc b/chrome/browser/devtools/devtools_ui_bindings_unittest.cc index fd59a68..c1bffff 100644 --- a/chrome/browser/devtools/devtools_ui_bindings_unittest.cc +++ b/chrome/browser/devtools/devtools_ui_bindings_unittest.cc
@@ -207,7 +207,9 @@ ~TestServiceHandler() override = default; GURL BaseURL() const override { return GURL("http://localhost:8000"); } - signin::ScopeSet OAuthScopes() const override { return {}; } + signin::OAuthConsumerId OAuthConsumerId() const override { + return signin::OAuthConsumerId::kDevtoolsAida; + } net::NetworkTrafficAnnotationTag NetworkTrafficAnnotationTag() const override { return TRAFFIC_ANNOTATION_FOR_TESTS; @@ -268,7 +270,9 @@ ~MockServiceHandler() override = default; GURL BaseURL() const override { return GURL("http://localhost:8000"); } - signin::ScopeSet OAuthScopes() const override { return {}; } + signin::OAuthConsumerId OAuthConsumerId() const override { + return signin::OAuthConsumerId::kDevtoolsAida; + } net::NetworkTrafficAnnotationTag NetworkTrafficAnnotationTag() const override { return TRAFFIC_ANNOTATION_FOR_TESTS;
diff --git a/chrome/browser/devtools/features.cc b/chrome/browser/devtools/features.cc index 468e82b9..48a79dd 100644 --- a/chrome/browser/devtools/features.cc +++ b/chrome/browser/devtools/features.cc
@@ -210,7 +210,7 @@ // If enabled, allows starting remote debugging in a running Chrome instance. BASE_FEATURE(kDevToolsAcceptDebuggingConnections, - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // Whether the policy dialog should be shown instead of greying out the // Developer Tools toggle.
diff --git a/chrome/browser/devtools/gdp_service_handler.cc b/chrome/browser/devtools/gdp_service_handler.cc index ed93f4e..0790711 100644 --- a/chrome/browser/devtools/gdp_service_handler.cc +++ b/chrome/browser/devtools/gdp_service_handler.cc
@@ -51,8 +51,8 @@ return GURL("https://developers.googleapis.com"); } -signin::ScopeSet GdpServiceHandler::OAuthScopes() const { - return {GaiaConstants::kGdpOAuth2Scope}; +signin::OAuthConsumerId GdpServiceHandler::OAuthConsumerId() const { + return signin::OAuthConsumerId::kDevtoolsGdp; } net::NetworkTrafficAnnotationTag
diff --git a/chrome/browser/devtools/gdp_service_handler.h b/chrome/browser/devtools/gdp_service_handler.h index 266cd11..248c1d1 100644 --- a/chrome/browser/devtools/gdp_service_handler.h +++ b/chrome/browser/devtools/gdp_service_handler.h
@@ -15,7 +15,7 @@ private: // DevToolsHttpServiceHandler overrides: GURL BaseURL() const override; - signin::ScopeSet OAuthScopes() const override; + signin::OAuthConsumerId OAuthConsumerId() const override; net::NetworkTrafficAnnotationTag NetworkTrafficAnnotationTag() const override; };
diff --git a/chrome/browser/devtools/protocol/devtools_pwa_browsertest.cc b/chrome/browser/devtools/protocol/devtools_pwa_browsertest.cc index ad61604..341583d7d34 100644 --- a/chrome/browser/devtools/protocol/devtools_pwa_browsertest.cc +++ b/chrome/browser/devtools/protocol/devtools_pwa_browsertest.cc
@@ -607,7 +607,7 @@ ASSERT_FALSE(AppExists(NotInstallableWebAppManifestId())); } -// TODO(crbug.com/331214986): May want a test to trigger the installation +// TODO(crbug.com/466316822): May want a test to trigger the installation // failure when installing from the url. IN_PROC_BROWSER_TEST_F(PWAProtocolTest, @@ -904,7 +904,7 @@ ASSERT_TRUE(result()->FindList("targetIds")->size() == 3); } -// TODO(crbug.com/331214986): May want a test to trigger the LaunchFilesInApp +// TODO(crbug.com/466313171): May want a test to trigger the LaunchFilesInApp // failure in LaunchApp callback. IN_PROC_BROWSER_TEST_F(PWAProtocolTest, LaunchFilesInApp_PartiallyFailed) {
diff --git a/chrome/browser/enterprise/signin/enterprise_identity_service_factory.cc b/chrome/browser/enterprise/signin/enterprise_identity_service_factory.cc deleted file mode 100644 index 9c172a2..0000000 --- a/chrome/browser/enterprise/signin/enterprise_identity_service_factory.cc +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2025 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/enterprise/signin/enterprise_identity_service_factory.h" - -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/identity_manager_factory.h" -#include "components/enterprise/signin/enterprise_identity_service.h" - -namespace enterprise { - -// static -EnterpriseIdentityServiceFactory* -EnterpriseIdentityServiceFactory::GetInstance() { - static base::NoDestructor<EnterpriseIdentityServiceFactory> instance; - return instance.get(); -} - -// static -EnterpriseIdentityService* -EnterpriseIdentityServiceFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<EnterpriseIdentityService*>( - GetInstance()->GetServiceForBrowserContext(browser_context, true)); -} - -EnterpriseIdentityServiceFactory::EnterpriseIdentityServiceFactory() - : ProfileKeyedServiceFactory("EnterpriseIdentityService", - // Only create EnterpriseIdentityService for - // regular, non-Incognito profiles. - ProfileSelections::BuildForRegularProfile()) { - DependsOn(IdentityManagerFactory::GetInstance()); -} - -EnterpriseIdentityServiceFactory::~EnterpriseIdentityServiceFactory() = default; - -std::unique_ptr<KeyedService> -EnterpriseIdentityServiceFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - auto* profile = Profile::FromBrowserContext(context); - if (!profile) { - return nullptr; - } - - return EnterpriseIdentityService::Create( - IdentityManagerFactory::GetForProfile(profile)); -} - -} // namespace enterprise
diff --git a/chrome/browser/enterprise/signin/enterprise_identity_service_factory.h b/chrome/browser/enterprise/signin/enterprise_identity_service_factory.h deleted file mode 100644 index 2934c01..0000000 --- a/chrome/browser/enterprise/signin/enterprise_identity_service_factory.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2025 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_ENTERPRISE_SIGNIN_ENTERPRISE_IDENTITY_SERVICE_FACTORY_H_ -#define CHROME_BROWSER_ENTERPRISE_SIGNIN_ENTERPRISE_IDENTITY_SERVICE_FACTORY_H_ - -#include <memory> - -#include "base/no_destructor.h" -#include "chrome/browser/profiles/profile_keyed_service_factory.h" - -namespace enterprise { - -class EnterpriseIdentityService; - -class EnterpriseIdentityServiceFactory : public ProfileKeyedServiceFactory { - public: - static EnterpriseIdentityServiceFactory* GetInstance(); - static EnterpriseIdentityService* GetForBrowserContext( - content::BrowserContext* browser_context); - - EnterpriseIdentityServiceFactory(const EnterpriseIdentityServiceFactory&) = - delete; - EnterpriseIdentityServiceFactory& operator=( - const EnterpriseIdentityServiceFactory&) = delete; - - private: - friend base::NoDestructor<EnterpriseIdentityServiceFactory>; - - EnterpriseIdentityServiceFactory(); - ~EnterpriseIdentityServiceFactory() override; - - // BrowserContextKeyedServiceFactory: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; -}; - -} // namespace enterprise - -#endif // CHROME_BROWSER_ENTERPRISE_SIGNIN_ENTERPRISE_IDENTITY_SERVICE_FACTORY_H_
diff --git a/chrome/browser/extensions/api/tabs/windows_event_router.cc b/chrome/browser/extensions/api/tabs/windows_event_router.cc index 37dc701..4e127c2 100644 --- a/chrome/browser/extensions/api/tabs/windows_event_router.cc +++ b/chrome/browser/extensions/api/tabs/windows_event_router.cc
@@ -54,7 +54,6 @@ filter_value = listener_filter->FindList(kWindowTypesKey); } - // TODO(crbug.com/41367902): Remove this. bool allow_dev_tools_windows = !!filter_value; if (!window_controller->IsVisibleToTabsAPIForExtension( extension, allow_dev_tools_windows)) { @@ -77,7 +76,6 @@ bool* dispatch_separate_event_out) { bool has_filter = listener_filter && listener_filter->contains(kWindowTypesKey); - // TODO(crbug.com/41367902): Remove this. bool allow_dev_tools_windows = has_filter; if (!window_controller->IsVisibleToTabsAPIForExtension( extension, allow_dev_tools_windows)) {
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 4d7f7e7..26cad25 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -9899,16 +9899,6 @@ "expiry_milestone": 150 }, { - "name": "tab-resumption", - "owners": [ "olivierrobin@chromium.org", "gambard@chromium.org", "bling-flags@google.com" ], - "expiry_milestone": 142 - }, - { - "name": "tab-resumption-images", - "owners": [ "gambard@chromium.org", "olivierrobin@chromium.org", "bling-flags@google.com" ], - "expiry_milestone": 140 - }, - { "name": "tab-search-position-setting", "owners": [ "top-chrome-desktop-ui@google.com", "dpenning@chromium.org" ], "expiry_milestone": 137
diff --git a/chrome/browser/glic/glic_user_status_fetcher.cc b/chrome/browser/glic/glic_user_status_fetcher.cc index 318566c..fd1cc37b 100644 --- a/chrome/browser/glic/glic_user_status_fetcher.cc +++ b/chrome/browser/glic/glic_user_status_fetcher.cc
@@ -85,7 +85,6 @@ base::RepeatingClosure callback) : profile_(profile), callback_(std::move(callback)) { endpoint_ = GURL(features::kGlicUserStatusUrl.Get()); - oauth2_scope_ = features::kGeminiOAuth2Scope.Get(); signin::IdentityManager* identity_manager = IdentityManagerFactory::GetForProfile(profile_); @@ -290,7 +289,7 @@ identity_manager, identity_manager->GetPrimaryAccountId(signin::ConsentLevel::kSignin), profile_->GetURLLoaderFactory(), - std::vector<std::string>{oauth2_scope_}), + signin::OAuthConsumerId::kGlicUserStatus), profile_->GetURLLoaderFactory(), base::ThreadPool::CreateSequencedTaskRunner( {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
diff --git a/chrome/browser/glic/glic_user_status_fetcher.h b/chrome/browser/glic/glic_user_status_fetcher.h index 036212d..ee78094 100644 --- a/chrome/browser/glic/glic_user_status_fetcher.h +++ b/chrome/browser/glic/glic_user_status_fetcher.h
@@ -142,7 +142,6 @@ raw_ptr<Profile> profile_; const base::RepeatingClosure callback_; GURL endpoint_; - std::string oauth2_scope_; // Ensures we run a request at least as often as // `features::kGlicUserStatusRequestDelay`. Reset on browser start, when a
diff --git a/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java b/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java index d1ab2ef0..c814146 100644 --- a/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java +++ b/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java
@@ -178,7 +178,13 @@ List<BarItem> fixedBarItems = new ArrayList<BarItem>(); if (showFloatingKeyboardAccessory()) { fixedBarItems.add(mModel.get(SHEET_OPENER_ITEM)); - fixedBarItems.add(mModel.get(DISMISS_ITEM)); + // Dismiss button shouldn't be added when dynamic positioning is used. + // TODO(crbug.com/458610269): Delete the the dismiss button after dynamic positioning is + // launched. + if (!ChromeFeatureList.isEnabled( + ChromeFeatureList.AUTOFILL_ANDROID_KEYBOARD_ACCESSORY_DYNAMIC_POSITIONING)) { + fixedBarItems.add(mModel.get(DISMISS_ITEM)); + } } else { scrollableItems.add(mModel.get(SHEET_OPENER_ITEM)); }
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index b37b77d7..5473ecbc 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -553,39 +553,6 @@ // Please keep the list of deprecated prefs in chronological order. i.e. Add to // the bottom of the list, not here at the top. -// Deprecated 12/2024. -inline constexpr char kDeleteTimePeriodV2[] = - "browser.clear_data.time_period_v2"; -inline constexpr char kDeleteTimePeriodV2Basic[] = - "browser.clear_data.time_period_v2_basic"; - -#if BUILDFLAG(IS_CHROMEOS) -// Deprecated 12/2024 -inline const char kCryptAuthDeviceSyncIsRecoveringFromFailure[] = - "cryptauth.device_sync.is_recovering_from_failure"; -inline const char kCryptAuthDeviceSyncLastSyncTimeSeconds[] = - "cryptauth.device_sync.last_device_sync_time_seconds"; -inline const char kCryptAuthDeviceSyncReason[] = "cryptauth.device_sync.reason"; -inline const char kCryptAuthDeviceSyncUnlockKeys[] = - "cryptauth.device_sync.unlock_keys"; -inline const char kCryptAuthEnrollmentIsRecoveringFromFailure[] = - "cryptauth.enrollment.is_recovering_from_failure"; -inline const char kCryptAuthEnrollmentLastEnrollmentTimeSeconds[] = - "cryptauth.enrollment.last_enrollment_time_seconds"; -inline const char kCryptAuthEnrollmentReason[] = "cryptauth.enrollment.reason"; -inline const char kCryptAuthEnrollmentUserPublicKey[] = - "cryptauth.enrollment.user_public_key"; -inline const char kCryptAuthEnrollmentUserPrivateKey[] = - "cryptauth.enrollment.user_private_key"; -inline const char kLacrosLaunchOnLogin[] = "lacros.launch_on_login"; -inline const char kLacrosLaunchSwitch[] = "lacros_launch_switch"; -inline const char kLacrosSelection[] = "lacros_selection"; -#endif - -// Deprecated 12/2024. -inline constexpr char kPageContentCollectionEnabled[] = - "page_content_collection.enabled"; - // Deprecated 01/2025. inline constexpr char kCompactModeEnabled[] = "compact_mode"; @@ -941,11 +908,6 @@ // Register local state used only for migration (clearing or moving to a new // key). void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) { -#if BUILDFLAG(IS_CHROMEOS) - // Deprecated 12/2024. - registry->RegisterIntegerPref(kLacrosLaunchSwitch, 0); - registry->RegisterIntegerPref(kLacrosSelection, 0); -#endif // Deprecated 02/2025. registry->RegisterBooleanPref(kUserAgentClientHintsGREASEUpdateEnabled, true); @@ -1043,34 +1005,6 @@ user_prefs::PrefRegistrySyncable* registry) { chrome_browser_net::secure_dns::RegisterProbesSettingBackupPref(registry); - // Deprecated 12/2024. - registry->RegisterIntegerPref(kDeleteTimePeriodV2, -1); - registry->RegisterIntegerPref(kDeleteTimePeriodV2Basic, -1); - -#if BUILDFLAG(IS_CHROMEOS) - // Deprecated 12/2024 - registry->RegisterDoublePref(kCryptAuthDeviceSyncLastSyncTimeSeconds, 0.0); - registry->RegisterBooleanPref(kCryptAuthDeviceSyncIsRecoveringFromFailure, - false); - registry->RegisterIntegerPref(kCryptAuthDeviceSyncReason, - cryptauth::INVOCATION_REASON_UNKNOWN); - registry->RegisterListPref(kCryptAuthDeviceSyncUnlockKeys); - registry->RegisterBooleanPref(kCryptAuthEnrollmentIsRecoveringFromFailure, - false); - registry->RegisterDoublePref(kCryptAuthEnrollmentLastEnrollmentTimeSeconds, - 0.0); - registry->RegisterIntegerPref(kCryptAuthEnrollmentReason, - cryptauth::INVOCATION_REASON_UNKNOWN); - registry->RegisterStringPref(kCryptAuthEnrollmentUserPublicKey, - std::string()); - registry->RegisterStringPref(kCryptAuthEnrollmentUserPrivateKey, - std::string()); - registry->RegisterBooleanPref(kLacrosLaunchOnLogin, false); -#endif - - // Deprecated 12/2024. - registry->RegisterBooleanPref(kPageContentCollectionEnabled, false); - // Deprecated 01/2025. registry->RegisterBooleanPref(kCompactModeEnabled, false); @@ -2139,12 +2073,6 @@ // BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS // Please don't delete the preceding line. It is used by PRESUBMIT.py. - // Added 12/2024 -#if BUILDFLAG(IS_CHROMEOS) - local_state->ClearPref(kLacrosLaunchSwitch); - local_state->ClearPref(kLacrosSelection); -#endif - // Added 02/2025. local_state->ClearPref(kUserAgentClientHintsGREASEUpdateEnabled); @@ -2298,27 +2226,6 @@ MigrateDefaultBrowserLastDeclinedPref(profile_prefs); #endif - // Added 12/2024. - profile_prefs->ClearPref(kDeleteTimePeriodV2); - profile_prefs->ClearPref(kDeleteTimePeriodV2Basic); - -#if BUILDFLAG(IS_CHROMEOS) - // Deprecated 12/2024 - profile_prefs->ClearPref(kCryptAuthDeviceSyncLastSyncTimeSeconds); - profile_prefs->ClearPref(kCryptAuthDeviceSyncIsRecoveringFromFailure); - profile_prefs->ClearPref(kCryptAuthDeviceSyncReason); - profile_prefs->ClearPref(kCryptAuthDeviceSyncUnlockKeys); - profile_prefs->ClearPref(kCryptAuthEnrollmentIsRecoveringFromFailure); - profile_prefs->ClearPref(kCryptAuthEnrollmentLastEnrollmentTimeSeconds); - profile_prefs->ClearPref(kCryptAuthEnrollmentReason); - profile_prefs->ClearPref(kCryptAuthEnrollmentUserPublicKey); - profile_prefs->ClearPref(kCryptAuthEnrollmentUserPrivateKey); - profile_prefs->ClearPref(kLacrosLaunchOnLogin); -#endif - - // Added 12/2024. - profile_prefs->ClearPref(kPageContentCollectionEnabled); - #if !BUILDFLAG(IS_ANDROID) // Added 01/2025. password_manager::features_util::MigrateDefaultProfileStorePref(
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 122081c..1617afa57 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -80,7 +80,6 @@ #include "chrome/browser/enterprise/reporting/cloud_profile_reporting_service_factory.h" #include "chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service.h" #include "chrome/browser/enterprise/signals/user_permission_service_factory.h" -#include "chrome/browser/enterprise/signin/enterprise_identity_service_factory.h" #include "chrome/browser/enterprise/signin/profile_management_disclaimer_service_factory.h" #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/favicon/history_ui_favicon_request_handler_factory.h" @@ -880,7 +879,6 @@ DriveServiceFactory::GetInstance(); EnclaveManagerFactory::GetInstance(); #endif - enterprise::EnterpriseIdentityServiceFactory::GetInstance(); enterprise::ProfileIdServiceFactory::GetInstance(); #if !BUILDFLAG(IS_CHROMEOS) enterprise_commands::UserRemoteCommandsServiceFactory::GetInstance();
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/mv2/background/phonetic_data_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/mv2/background/phonetic_data_test.js index 16155b5ef..2e26cda 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/mv2/background/phonetic_data_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/mv2/background/phonetic_data_test.js
@@ -47,8 +47,6 @@ ['働', 'ロウドウノドウ'], ]); -// TODO(crbug.com/40758998): Polish phonetic readings so that users can disambiguate -// more precisely. AX_TEST_F('ChromeVoxMV2PhoneticDataTest', 'forCharacterJa', function() { assertEquals('ヒラガナ アサヒ ノ ア', PhoneticData.forCharacter('あ', 'ja')); assertEquals('カタカナ アサヒ ノ ア', PhoneticData.forCharacter('ア', 'ja'));
diff --git a/chrome/browser/resources/side_panel/read_anything/app/app.ts b/chrome/browser/resources/side_panel/read_anything/app/app.ts index a8539ed..2aaee9a 100644 --- a/chrome/browser/resources/side_panel/read_anything/app/app.ts +++ b/chrome/browser/resources/side_panel/read_anything/app/app.ts
@@ -263,6 +263,10 @@ this.speechController_.onLockScreen(); }; + chrome.readingMode.readingModeWillClose = () => { + this.speechController_.onReadingModeWillClose(); + }; + chrome.readingMode.onTtsEngineInstalled = () => { this.voiceLanguageController_.onTtsEngineInstalled(); };
diff --git a/chrome/browser/resources/side_panel/read_anything/app/read_anything.d.ts b/chrome/browser/resources/side_panel/read_anything/app/read_anything.d.ts index d1ba137..6837d41 100644 --- a/chrome/browser/resources/side_panel/read_anything/app/read_anything.d.ts +++ b/chrome/browser/resources/side_panel/read_anything/app/read_anything.d.ts
@@ -215,6 +215,9 @@ // Called when the font is changed via the webui toolbar. function onFontChange(font: string): void; + // Called when reading mode is closed. + function readingModeWillClose(): void; + // Called when the speech rate is changed via the webui toolbar. function onSpeechRateChange(rate: number): void;
diff --git a/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_controller.ts b/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_controller.ts index b7d164f8..38c5cb1 100644 --- a/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_controller.ts +++ b/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_controller.ts
@@ -176,6 +176,16 @@ } } + // When the view is hidden with Immersive Reading Mode enabled, we should + // stop speaking. + onReadingModeWillClose() { + // TODO: crbug.com/466967616 - Ensure Read Aloud resume honors word + // boundaries after ReadingModeWillClose is called + if (this.isSpeechActive()) { + this.stopSpeech_(PauseActionSource.DEFAULT); + } + } + onTabMuteStateChange(muted: boolean) { this.model_.setVolume(muted ? 0.0 : 1.0); this.onSpeechSettingsChange();
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/file_analysis_request.cc b/chrome/browser/safe_browsing/cloud_content_scanning/file_analysis_request.cc index d586018f..d93e167d 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/file_analysis_request.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/file_analysis_request.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h" #include "components/enterprise/connectors/core/features.h" #include "components/enterprise/obfuscation/core/download_obfuscator.h" +#include "components/enterprise/obfuscation/core/utils.h" #include "components/file_access/scoped_file_access.h" #include "components/file_access/scoped_file_access_delegate.h" #include "content/public/browser/browser_thread.h" @@ -261,13 +262,22 @@ base::FilePath::StringType ext(file_name_.FinalExtension()); std::ranges::transform(ext, ext.begin(), tolower); if (IsZipFile(ext, mime_type)) { - zip_analyzer_ = SandboxedZipAnalyzer::CreateAnalyzer( - path_, - /*password=*/password(), - base::BindOnce(&FileAnalysisRequest::OnCheckedForEncryption, - weakptr_factory_.GetWeakPtr(), - std::move(result_and_data.second)), - LaunchFileUtilService()); + auto callback = base::BindOnce(&FileAnalysisRequest::OnCheckedForEncryption, + weakptr_factory_.GetWeakPtr(), + std::move(result_and_data.second)); + if (is_obfuscated_ && base::FeatureList::IsEnabled( + enterprise_obfuscation:: + kEnterpriseFileObfuscationArchiveAnalyzer)) { + zip_analyzer_ = SandboxedZipAnalyzer::CreateObfuscatedAnalyzer( + path_, + /*password=*/password(), std::move(callback), + LaunchFileUtilService()); + } else { + zip_analyzer_ = SandboxedZipAnalyzer::CreateAnalyzer( + path_, + /*password=*/password(), std::move(callback), + LaunchFileUtilService()); + } zip_analyzer_->Start(); } else if (IsRarFile(ext, mime_type)) { rar_analyzer_ = SandboxedRarAnalyzer::CreateAnalyzer(
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/file_analysis_request_unittest.cc b/chrome/browser/safe_browsing/cloud_content_scanning/file_analysis_request_unittest.cc index fc93a6e..590655c3 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/file_analysis_request_unittest.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/file_analysis_request_unittest.cc
@@ -594,4 +594,56 @@ EXPECT_EQ(data.size, original_contents.size()); } +TEST_F(FileAnalysisRequestTest, ObfuscatedEncryptedZipFile) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {enterprise_obfuscation::kEnterpriseFileObfuscation, + enterprise_obfuscation::kEnterpriseFileObfuscationArchiveAnalyzer}, + {}); + + content::BrowserTaskEnvironment browser_task_environment; + content::InProcessUtilityThreadHelper in_process_utility_thread_helper; + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + + base::FilePath test_zip; + EXPECT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_zip)); + test_zip = test_zip.AppendASCII("safe_browsing") + .AppendASCII("download_protection") + .AppendASCII("encrypted.zip"); + + std::string original_contents; + ASSERT_TRUE(base::ReadFileToString(test_zip, &original_contents)); + + // Obfuscate the file contents and write to file. + enterprise_obfuscation::DownloadObfuscator obfuscator; + auto obfuscation_result = + obfuscator.ObfuscateChunk(base::as_byte_span(original_contents), true); + + ASSERT_TRUE(obfuscation_result.has_value()); + base::FilePath obfuscated_path = + temp_dir.GetPath().AppendASCII("obfuscated.zip"); + ASSERT_TRUE(base::WriteFile(obfuscated_path, obfuscation_result.value())); + + auto obfuscated_request = + MakeRequest(obfuscated_path, obfuscated_path.BaseName(), + /*delay_opening_file=*/false, + /*mime_type=*/"application/zip", + /*is_obfuscated=*/true); + obfuscated_request->set_password("67890"); // Incorrect password + + base::test::TestFuture<enterprise_connectors::ScanRequestUploadResult, + BinaryUploadService::Request::Data> + future; + obfuscated_request->GetRequestData(future.GetCallback()); + auto [result, data] = future.Take(); + + // Should detect encryption and fail because of incorrect password. + EXPECT_EQ(result, + enterprise_connectors::ScanRequestUploadResult::kFileEncrypted); + // Check if size has been updated to use the calculated unobfuscated content + // size. + EXPECT_EQ(data.size, original_contents.size()); +} + } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/download_protection/download_item_metadata.cc b/chrome/browser/safe_browsing/download_protection/download_item_metadata.cc index 6c592f8f..3a669216 100644 --- a/chrome/browser/safe_browsing/download_protection/download_item_metadata.cc +++ b/chrome/browser/safe_browsing/download_protection/download_item_metadata.cc
@@ -141,8 +141,8 @@ std::unique_ptr<DownloadRequestMaker> DownloadItemMetadata::CreateDownloadRequestFromMetadata( scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor) const { - return DownloadRequestMaker::CreateFromDownloadItem(binary_feature_extractor, - item_); + return DownloadRequestMaker::CreateFromDownloadItem( + binary_feature_extractor, item_, std::nullopt, IsObfuscated()); } std::unique_ptr<DeepScanningMetadata::DownloadScopedObservation>
diff --git a/chrome/browser/safe_browsing/download_protection/download_request_maker.cc b/chrome/browser/safe_browsing/download_protection/download_request_maker.cc index deef8da..062b951 100644 --- a/chrome/browser/safe_browsing/download_protection/download_request_maker.cc +++ b/chrome/browser/safe_browsing/download_protection/download_request_maker.cc
@@ -82,7 +82,8 @@ DownloadRequestMaker::CreateFromDownloadItem( scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor, download::DownloadItem* item, - base::optional_ref<const std::string> password) { + base::optional_ref<const std::string> password, + bool is_obfuscated) { std::vector<ClientDownloadRequest::Resource> resources; for (size_t i = 0; i < item->GetUrlChain().size(); ++i) { ClientDownloadRequest::Resource resource; @@ -123,14 +124,16 @@ // owned by the CheckClientDownloadRequest, which observes for `item` // being destroyed, and deletes this if it is. base::BindOnce(&SetDownloadItemWarningData, item, - password.CopyAsOptional())); + password.CopyAsOptional()), + is_obfuscated); } // static std::unique_ptr<DownloadRequestMaker> DownloadRequestMaker::CreateFromFileSystemAccess( scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor, - const content::FileSystemAccessWriteItem& item) { + const content::FileSystemAccessWriteItem& item, + bool is_obfuscated) { ClientDownloadRequest::Resource resource; resource.set_url( ShortURLForReporting(GetFileSystemAccessDownloadUrl(item.frame_url))); @@ -150,7 +153,7 @@ item.sha256_hash, item.size, std::vector<ClientDownloadRequest::Resource>{resource}, item.has_user_gesture, referrer_chain_data.get(), std::nullopt, - /*previous_token=*/"", base::DoNothing()); + /*previous_token=*/"", base::DoNothing(), is_obfuscated); } DownloadRequestMaker::DownloadRequestMaker( @@ -167,10 +170,13 @@ ReferrerChainData* referrer_chain_data, base::optional_ref<const std::string> password, const std::string& previous_token, - base::OnceCallback<void(const FileAnalyzer::Results&)> on_results_callback) + base::OnceCallback<void(const FileAnalyzer::Results&)> on_results_callback, + bool is_obfuscated) : browser_context_(browser_context), request_(std::make_unique<ClientDownloadRequest>()), binary_feature_extractor_(binary_feature_extractor), + file_analyzer_(std::make_unique<FileAnalyzer>(binary_feature_extractor_, + is_obfuscated)), tab_urls_(tab_urls), target_file_name_(target_file_name), full_path_(full_path),
diff --git a/chrome/browser/safe_browsing/download_protection/download_request_maker.h b/chrome/browser/safe_browsing/download_protection/download_request_maker.h index 2f323d9..4078ef829 100644 --- a/chrome/browser/safe_browsing/download_protection/download_request_maker.h +++ b/chrome/browser/safe_browsing/download_protection/download_request_maker.h
@@ -44,11 +44,13 @@ static std::unique_ptr<DownloadRequestMaker> CreateFromDownloadItem( scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor, download::DownloadItem* item, - base::optional_ref<const std::string> password = std::nullopt); + base::optional_ref<const std::string> password = std::nullopt, + bool is_obfuscated = false); static std::unique_ptr<DownloadRequestMaker> CreateFromFileSystemAccess( scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor, - const content::FileSystemAccessWriteItem& item); + const content::FileSystemAccessWriteItem& item, + bool is_obfuscated = false); DownloadRequestMaker( scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor, @@ -65,7 +67,8 @@ base::optional_ref<const std::string> password, const std::string& previous_token, base::OnceCallback<void(const FileAnalyzer::Results&)> - on_results_callback); + on_results_callback, + bool is_obfuscated = false); DownloadRequestMaker(const DownloadRequestMaker&) = delete; DownloadRequestMaker& operator=(const DownloadRequestMaker&) = delete; @@ -95,8 +98,7 @@ raw_ptr<content::BrowserContext> browser_context_; std::unique_ptr<ClientDownloadRequest> request_; const scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor_; - const std::unique_ptr<FileAnalyzer> file_analyzer_ = - std::make_unique<FileAnalyzer>(binary_feature_extractor_); + const std::unique_ptr<FileAnalyzer> file_analyzer_; base::CancelableTaskTracker request_tracker_; // For HistoryService lookup. // The current URL for the WebContents that initiated the download, and its
diff --git a/chrome/browser/safe_browsing/download_protection/file_analyzer.cc b/chrome/browser/safe_browsing/download_protection/file_analyzer.cc index d277ead..4442bea 100644 --- a/chrome/browser/safe_browsing/download_protection/file_analyzer.cc +++ b/chrome/browser/safe_browsing/download_protection/file_analyzer.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/safe_browsing/download_protection/download_protection_util.h" #include "chrome/common/safe_browsing/archive_analyzer_results.h" #include "chrome/common/safe_browsing/download_type_util.h" +#include "components/enterprise/obfuscation/core/utils.h" #include "components/safe_browsing/content/common/file_type_policies.h" #include "components/safe_browsing/content/common/proto/download_file_types.pb.h" #include "components/safe_browsing/core/common/features.h" @@ -49,8 +50,12 @@ FileAnalyzer::Results::Results(const FileAnalyzer::Results& other) = default; FileAnalyzer::FileAnalyzer( - scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor) + scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor, + bool is_obfuscated) : binary_feature_extractor_(binary_feature_extractor) { +#if !BUILDFLAG(IS_ANDROID) + is_obfuscated_ = is_obfuscated; +#endif DCHECK_CURRENTLY_ON(BrowserThread::UI); } @@ -136,11 +141,21 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); // We give the zip analyzer a weak pointer to this object. - zip_analyzer_ = SandboxedZipAnalyzer::CreateAnalyzer( - tmp_path_, password_, - base::BindOnce(&FileAnalyzer::OnZipAnalysisFinished, - weakptr_factory_.GetWeakPtr()), - LaunchFileUtilService()); + if (is_obfuscated_ && + base::FeatureList::IsEnabled( + enterprise_obfuscation::kEnterpriseFileObfuscationArchiveAnalyzer)) { + zip_analyzer_ = SandboxedZipAnalyzer::CreateObfuscatedAnalyzer( + tmp_path_, password_, + base::BindOnce(&FileAnalyzer::OnZipAnalysisFinished, + weakptr_factory_.GetWeakPtr()), + LaunchFileUtilService()); + } else { + zip_analyzer_ = SandboxedZipAnalyzer::CreateAnalyzer( + tmp_path_, password_, + base::BindOnce(&FileAnalyzer::OnZipAnalysisFinished, + weakptr_factory_.GetWeakPtr()), + LaunchFileUtilService()); + } zip_analyzer_->Start(); }
diff --git a/chrome/browser/safe_browsing/download_protection/file_analyzer.h b/chrome/browser/safe_browsing/download_protection/file_analyzer.h index 678a98d..03b8293 100644 --- a/chrome/browser/safe_browsing/download_protection/file_analyzer.h +++ b/chrome/browser/safe_browsing/download_protection/file_analyzer.h
@@ -88,7 +88,8 @@ }; explicit FileAnalyzer( - scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor); + scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor, + bool is_obfuscated = false); ~FileAnalyzer(); void Start(const base::FilePath& target_file_name, const base::FilePath& tmp_path, @@ -142,6 +143,8 @@ std::unique_ptr<SandboxedRarAnalyzer, base::OnTaskRunnerDeleter> rar_analyzer_{nullptr, base::OnTaskRunnerDeleter(nullptr)}; + + bool is_obfuscated_ = false; #endif #if BUILDFLAG(IS_MAC)
diff --git a/chrome/browser/safe_browsing/download_protection/file_analyzer_unittest.cc b/chrome/browser/safe_browsing/download_protection/file_analyzer_unittest.cc index 2da2ec60..59d7cbda 100644 --- a/chrome/browser/safe_browsing/download_protection/file_analyzer_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection/file_analyzer_unittest.cc
@@ -16,6 +16,8 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/safe_browsing/archive_analyzer_results.h" #include "chrome/common/safe_browsing/mock_binary_feature_extractor.h" +#include "components/enterprise/obfuscation/core/download_obfuscator.h" +#include "components/enterprise/obfuscation/core/utils.h" #include "components/safe_browsing/content/common/file_type_policies_test_util.h" #include "components/safe_browsing/content/common/proto/download_file_types.pb.h" #include "components/safe_browsing/core/common/features.h" @@ -1092,6 +1094,55 @@ EXPECT_EQ(result_.archived_binaries[1].length(), 0); EXPECT_EQ(result_.inspection_performed, DownloadFileType::SEVEN_ZIP); } + +TEST_F(FileAnalyzerTest, ObfuscatedZipAnalysis) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {enterprise_obfuscation::kEnterpriseFileObfuscation, + enterprise_obfuscation::kEnterpriseFileObfuscationArchiveAnalyzer}, + {}); + + scoped_refptr<MockBinaryFeatureExtractor> extractor = + new testing::StrictMock<MockBinaryFeatureExtractor>(); + FileAnalyzer analyzer(extractor, /*is_obfuscated=*/true); + base::RunLoop run_loop; + + base::FilePath target_file_name(FILE_PATH_LITERAL("target.zip")); + base::FilePath tmp_path = + temp_dir_.GetPath().Append(FILE_PATH_LITERAL("tmp.crdownload")); + + base::ScopedTempDir zip_source_dir; + ASSERT_TRUE(zip_source_dir.CreateUniqueTempDir()); + std::string file_contents = "dummy file"; + ASSERT_TRUE(base::WriteFile( + zip_source_dir.GetPath().Append(FILE_PATH_LITERAL("file.exe")), + file_contents)); + base::FilePath zip_path = temp_dir_.GetPath().AppendASCII("original.zip"); + ASSERT_TRUE(zip::Zip(zip_source_dir.GetPath(), zip_path, + /* include_hidden_files= */ false)); + + // Obfuscate + std::string original_zip_content; + ASSERT_TRUE(base::ReadFileToString(zip_path, &original_zip_content)); + enterprise_obfuscation::DownloadObfuscator obfuscator; + auto obfuscation_result = + obfuscator.ObfuscateChunk(base::as_byte_span(original_zip_content), true); + ASSERT_TRUE(obfuscation_result.has_value()); + ASSERT_TRUE(base::WriteFile(tmp_path, obfuscation_result.value())); + + analyzer.Start( + target_file_name, tmp_path, /*password=*/std::nullopt, + base::BindOnce(&FileAnalyzerTest::DoneCallback, base::Unretained(this), + run_loop.QuitClosure())); + run_loop.Run(); + + ASSERT_TRUE(has_result_); + // It should be successfully analyzed as a zip + EXPECT_EQ(result_.inspection_performed, DownloadFileType::ZIP); + EXPECT_TRUE(result_.archived_executable); + EXPECT_EQ(result_.archive_summary.parser_status(), + ClientDownloadRequest::ArchiveSummary::VALID); +} #endif // !BUILDFLAG(IS_ANDROID) } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/download_protection/file_system_access_metadata.cc b/chrome/browser/safe_browsing/download_protection/file_system_access_metadata.cc index 26a09503b..dcf6045 100644 --- a/chrome/browser/safe_browsing/download_protection/file_system_access_metadata.cc +++ b/chrome/browser/safe_browsing/download_protection/file_system_access_metadata.cc
@@ -95,6 +95,7 @@ bool FileSystemAccessMetadata::IsObfuscated() const { // No support for enterprise obfuscation for filesystem access API. + // TODO(crbug.com/378490429): Add support for obfuscated files. return false; } @@ -130,7 +131,7 @@ FileSystemAccessMetadata::CreateDownloadRequestFromMetadata( scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor) const { return DownloadRequestMaker::CreateFromFileSystemAccess( - binary_feature_extractor, *item_); + binary_feature_extractor, *item_, IsObfuscated()); } std::unique_ptr<DeepScanningMetadata::DownloadScopedObservation>
diff --git a/chrome/browser/signin/chrome_signin_client.cc b/chrome/browser/signin/chrome_signin_client.cc index 9fdb57e3..22e337b 100644 --- a/chrome/browser/signin/chrome_signin_client.cc +++ b/chrome/browser/signin/chrome_signin_client.cc
@@ -38,6 +38,7 @@ #include "chrome/browser/ui/hats/survey_config.h" #include "chrome/common/buildflags.h" #include "chrome/common/channel_info.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/metrics/metrics_service.h" @@ -197,6 +198,17 @@ signin::oauth_consumer_name::kEnterprisePlusAddressName, {plus_addresses::features::kEnterprisePlusAddressOAuthScope.Get()}); } + + signin::OAuthConsumer GetOAuthConsumerForGlicUserStatus() const override { +#if BUILDFLAG(ENABLE_GLIC) + CHECK(base::FeatureList::IsEnabled(features::kGlicUserStatusCheck)); + return signin::OAuthConsumer( + signin::oauth_consumer_name::kGlicUserStatusName, + {features::kGeminiOAuth2Scope.Get()}); +#else + NOTREACHED(); +#endif + } }; } // namespace
diff --git a/chrome/browser/ui/autofill/BUILD.gn b/chrome/browser/ui/autofill/BUILD.gn index abee0df..656b6ef 100644 --- a/chrome/browser/ui/autofill/BUILD.gn +++ b/chrome/browser/ui/autofill/BUILD.gn
@@ -60,6 +60,7 @@ "autofill_keyboard_accessory_controller_impl.h", "autofill_keyboard_accessory_view.h", "autofill_message_controller.h", + "autofill_message_controller_impl.h", "autofill_message_model.h", "autofill_snackbar_controller.h", "autofill_snackbar_controller_impl.h", @@ -184,7 +185,7 @@ sources += [ "autofill_keyboard_accessory_controller.cc", "autofill_keyboard_accessory_controller_impl.cc", - "autofill_message_controller.cc", + "autofill_message_controller_impl.cc", "autofill_message_model.cc", "autofill_snackbar_controller_impl.cc", ] @@ -316,7 +317,7 @@ if (is_android) { sources += [ "autofill_keyboard_accessory_controller_impl_unittest.cc", - "autofill_message_controller_unittest.cc", + "autofill_message_controller_impl_unittest.cc", "autofill_message_model_unittest.cc", "autofill_snackbar_controller_impl_unittest.cc", ] @@ -355,12 +356,17 @@ "test/test_autofill_bubble_handler.h", ] - public_deps = [ ":autofill" ] + public_deps = [ + ":autofill", + "//testing/gmock", + ] if (is_android) { sources += [ "autofill_keyboard_accessory_controller_impl_test_api.h", "autofill_message_controller_test_api.h", + "mock_autofill_message_controller.cc", + "mock_autofill_message_controller.h", ] } else { sources += [ @@ -370,10 +376,7 @@ "mock_autofill_popup_controller.cc", "mock_autofill_popup_controller.h", ] - public_deps += [ - "//testing/gmock", - "//ui/gfx:test_support", - ] + public_deps += [ "//ui/gfx:test_support" ] } }
diff --git a/chrome/browser/ui/autofill/autofill_message_controller.h b/chrome/browser/ui/autofill/autofill_message_controller.h index df2a2ff..bede856d 100644 --- a/chrome/browser/ui/autofill/autofill_message_controller.h +++ b/chrome/browser/ui/autofill/autofill_message_controller.h
@@ -1,4 +1,4 @@ -// Copyright 2024 The Chromium Authors +// Copyright 2025 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -13,37 +13,13 @@ namespace autofill { -// AutofillMessageController is used to control the lifecycle of autofill -// Messages on Android. This includes handling the show, dismiss and callbacks -// of the messages. class AutofillMessageController { public: - explicit AutofillMessageController(content::WebContents* web_contents); - AutofillMessageController(const AutofillMessageController&) = delete; - AutofillMessageController& operator=(const AutofillMessageController&) = - delete; - virtual ~AutofillMessageController(); + virtual ~AutofillMessageController() = default; // Show a new message. If an existing message is already showing, dismiss that // message and show the new one. - virtual void Show(std::unique_ptr<AutofillMessageModel> message_model); - - private: - friend class AutofillMessageControllerTestApi; - - // Callback for when the action button on the message is clicked. - void OnActionClicked(AutofillMessageModel* message_model_ptr); - - // Callback for when the message is dismissed. - void OnDismissed(AutofillMessageModel* message_model_ptr, - messages::DismissReason reason); - - void Dismiss(); - - const raw_ref<content::WebContents> web_contents_; - std::set<std::unique_ptr<AutofillMessageModel>, base::UniquePtrComparator> - message_models_; - base::WeakPtrFactory<AutofillMessageController> weak_ptr_factory_{this}; + virtual void Show(std::unique_ptr<AutofillMessageModel> message_model) = 0; }; } // namespace autofill
diff --git a/chrome/browser/ui/autofill/autofill_message_controller.cc b/chrome/browser/ui/autofill/autofill_message_controller_impl.cc similarity index 83% rename from chrome/browser/ui/autofill/autofill_message_controller.cc rename to chrome/browser/ui/autofill/autofill_message_controller_impl.cc index a8bd196..c62b289 100644 --- a/chrome/browser/ui/autofill/autofill_message_controller.cc +++ b/chrome/browser/ui/autofill/autofill_message_controller_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/autofill/autofill_message_controller.h" +#include "chrome/browser/ui/autofill/autofill_message_controller_impl.h" #include <memory> @@ -14,26 +14,26 @@ namespace autofill { -AutofillMessageController::AutofillMessageController( +AutofillMessageControllerImpl::AutofillMessageControllerImpl( content::WebContents* web_contents) : web_contents_(*web_contents) {} -AutofillMessageController::~AutofillMessageController() { +AutofillMessageControllerImpl::~AutofillMessageControllerImpl() { Dismiss(); } -void AutofillMessageController::Show( +void AutofillMessageControllerImpl::Show( std::unique_ptr<AutofillMessageModel> message_model) { AutofillMessageModel* message_model_ptr = message_model.get(); message_models_.insert(std::move(message_model)); message_model_ptr->GetMessage(/*pass_key=*/{}) .SetActionClick( - base::BindOnce(&AutofillMessageController::OnActionClicked, + base::BindOnce(&AutofillMessageControllerImpl::OnActionClicked, weak_ptr_factory_.GetWeakPtr(), message_model_ptr)); message_model_ptr->GetMessage(/*pass_key=*/{}) .SetDismissCallback( - base::BindOnce(&AutofillMessageController::OnDismissed, + base::BindOnce(&AutofillMessageControllerImpl::OnDismissed, weak_ptr_factory_.GetWeakPtr(), message_model_ptr)); messages::MessageDispatcherBridge::Get()->EnqueueMessage( @@ -47,7 +47,7 @@ true); } -void AutofillMessageController::OnActionClicked( +void AutofillMessageControllerImpl::OnActionClicked( AutofillMessageModel* message_model_ptr) { auto message_model_it = message_models_.find(message_model_ptr); CHECK(message_model_it != message_models_.end()); @@ -58,7 +58,7 @@ true); } -void AutofillMessageController::OnDismissed( +void AutofillMessageControllerImpl::OnDismissed( AutofillMessageModel* message_model_ptr, messages::DismissReason reason) { auto message_model_it = message_models_.find(message_model_ptr); @@ -72,7 +72,7 @@ message_models_.erase(message_model_it); } -void AutofillMessageController::Dismiss() { +void AutofillMessageControllerImpl::Dismiss() { for (auto it = message_models_.begin(); it != message_models_.end();) { messages::MessageDispatcherBridge::Get()->DismissMessage( &(*it++)->GetMessage(/*pass_key=*/{}),
diff --git a/chrome/browser/ui/autofill/autofill_message_controller_impl.h b/chrome/browser/ui/autofill/autofill_message_controller_impl.h new file mode 100644 index 0000000..5a8039cb9 --- /dev/null +++ b/chrome/browser/ui/autofill/autofill_message_controller_impl.h
@@ -0,0 +1,51 @@ +// Copyright 2024 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_UI_AUTOFILL_AUTOFILL_MESSAGE_CONTROLLER_IMPL_H_ +#define CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_MESSAGE_CONTROLLER_IMPL_H_ + +#include <memory> + +#include "base/containers/unique_ptr_adapters.h" +#include "chrome/browser/ui/autofill/autofill_message_controller.h" +#include "chrome/browser/ui/autofill/autofill_message_model.h" +#include "content/public/browser/web_contents.h" + +namespace autofill { + +// AutofillMessageControllerImpl is used to control the lifecycle of autofill +// Messages on Android. This includes handling the show, dismiss and callbacks +// of the messages. +class AutofillMessageControllerImpl : public AutofillMessageController { + public: + explicit AutofillMessageControllerImpl(content::WebContents* web_contents); + AutofillMessageControllerImpl(const AutofillMessageControllerImpl&) = delete; + AutofillMessageControllerImpl& operator=( + const AutofillMessageControllerImpl&) = delete; + ~AutofillMessageControllerImpl() override; + + // AutofillMessageController: + void Show(std::unique_ptr<AutofillMessageModel> message_model) override; + + private: + friend class AutofillMessageControllerTestApi; + + // Callback for when the action button on the message is clicked. + void OnActionClicked(AutofillMessageModel* message_model_ptr); + + // Callback for when the message is dismissed. + void OnDismissed(AutofillMessageModel* message_model_ptr, + messages::DismissReason reason); + + void Dismiss(); + + const raw_ref<content::WebContents> web_contents_; + std::set<std::unique_ptr<AutofillMessageModel>, base::UniquePtrComparator> + message_models_; + base::WeakPtrFactory<AutofillMessageControllerImpl> weak_ptr_factory_{this}; +}; + +} // namespace autofill + +#endif // CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_MESSAGE_CONTROLLER_IMPL_H_
diff --git a/chrome/browser/ui/autofill/autofill_message_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_message_controller_impl_unittest.cc similarity index 84% rename from chrome/browser/ui/autofill/autofill_message_controller_unittest.cc rename to chrome/browser/ui/autofill/autofill_message_controller_impl_unittest.cc index c60fb2b..860bf7e 100644 --- a/chrome/browser/ui/autofill/autofill_message_controller_unittest.cc +++ b/chrome/browser/ui/autofill/autofill_message_controller_impl_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/autofill/autofill_message_controller.h" +#include "chrome/browser/ui/autofill/autofill_message_controller_impl.h" #include <memory> @@ -14,9 +14,10 @@ #include "testing/gtest/include/gtest/gtest.h" namespace autofill { -class AutofillMessageControllerTest : public ChromeRenderViewHostTestHarness { +class AutofillMessageControllerImplTest + : public ChromeRenderViewHostTestHarness { public: - AutofillMessageControllerTest() = default; + AutofillMessageControllerImplTest() = default; void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); @@ -59,9 +60,9 @@ return (*it).get(); } - AutofillMessageController& controller() { + AutofillMessageControllerImpl& controller() { if (!controller_) { - controller_ = new AutofillMessageController(web_contents()); + controller_ = new AutofillMessageControllerImpl(web_contents()); } return *controller_; } @@ -71,11 +72,11 @@ } private: - raw_ptr<AutofillMessageController> controller_; + raw_ptr<AutofillMessageControllerImpl> controller_; messages::MockMessageDispatcherBridge message_dispatcher_bridge_; }; -TEST_F(AutofillMessageControllerTest, Show) { +TEST_F(AutofillMessageControllerImplTest, Show) { ExpectEnqueueMessageCall(); raw_ptr<AutofillMessageModel> message = CreateAndShowNewMessage(); @@ -83,7 +84,7 @@ EXPECT_EQ(FindMessageModel(message), message); } -TEST_F(AutofillMessageControllerTest, ShowTwiceWithoutDismiss) { +TEST_F(AutofillMessageControllerImplTest, ShowTwiceWithoutDismiss) { ExpectEnqueueMessageCall(/*times=*/2); CreateAndShowNewMessage(); @@ -92,7 +93,7 @@ EXPECT_THAT(message_models(), testing::SizeIs(2)); } -TEST_F(AutofillMessageControllerTest, OnDismissed) { +TEST_F(AutofillMessageControllerImplTest, OnDismissed) { raw_ptr<AutofillMessageModel> first_message = CreateAndShowNewMessage(); raw_ptr<AutofillMessageModel> second_message = CreateAndShowNewMessage(); @@ -103,7 +104,7 @@ EXPECT_EQ(FindMessageModel(second_message), second_message); } -TEST_F(AutofillMessageControllerTest, Dismiss) { +TEST_F(AutofillMessageControllerImplTest, Dismiss) { CreateAndShowNewMessage(); CreateAndShowNewMessage(); @@ -113,14 +114,14 @@ test_api(controller()).Dismiss(); } -TEST_F(AutofillMessageControllerTest, DismissWithoutMessages) { +TEST_F(AutofillMessageControllerImplTest, DismissWithoutMessages) { ExpectDismissMessageCallWithReason(messages::DismissReason::UNKNOWN, /*times=*/0); test_api(controller()).Dismiss(); } -TEST_F(AutofillMessageControllerTest, Metrics_Show) { +TEST_F(AutofillMessageControllerImplTest, Metrics_Show) { base::HistogramTester histogram_tester; raw_ptr<AutofillMessageModel> message = CreateAndShowNewMessage(); @@ -129,7 +130,7 @@ true, 1); } -TEST_F(AutofillMessageControllerTest, Metrics_OnActionClicked) { +TEST_F(AutofillMessageControllerImplTest, Metrics_OnActionClicked) { base::HistogramTester histogram_tester; raw_ptr<AutofillMessageModel> message = CreateAndShowNewMessage(); @@ -141,7 +142,7 @@ true, 1); } -TEST_F(AutofillMessageControllerTest, Metrics_OnDismissed) { +TEST_F(AutofillMessageControllerImplTest, Metrics_OnDismissed) { base::HistogramTester histogram_tester; messages::DismissReason dismiss_reason = messages::DismissReason::PRIMARY_ACTION;
diff --git a/chrome/browser/ui/autofill/autofill_message_controller_test_api.h b/chrome/browser/ui/autofill/autofill_message_controller_test_api.h index d1e1d53..8cd57a2c 100644 --- a/chrome/browser/ui/autofill/autofill_message_controller_test_api.h +++ b/chrome/browser/ui/autofill/autofill_message_controller_test_api.h
@@ -5,14 +5,14 @@ #ifndef CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_MESSAGE_CONTROLLER_TEST_API_H_ #define CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_MESSAGE_CONTROLLER_TEST_API_H_ -#include "chrome/browser/ui/autofill/autofill_message_controller.h" +#include "chrome/browser/ui/autofill/autofill_message_controller_impl.h" namespace autofill { class AutofillMessageControllerTestApi { public: explicit AutofillMessageControllerTestApi( - AutofillMessageController& controller) + AutofillMessageControllerImpl& controller) : controller_(controller) {} ~AutofillMessageControllerTestApi() = default; @@ -40,11 +40,11 @@ void Dismiss() { controller_->Dismiss(); } private: - const raw_ref<AutofillMessageController> controller_; + const raw_ref<AutofillMessageControllerImpl> controller_; }; inline AutofillMessageControllerTestApi test_api( - AutofillMessageController& controller) { + AutofillMessageControllerImpl& controller) { return AutofillMessageControllerTestApi(controller); }
diff --git a/chrome/browser/ui/autofill/autofill_message_model.cc b/chrome/browser/ui/autofill/autofill_message_model.cc index 6db43de..4a2a579 100644 --- a/chrome/browser/ui/autofill/autofill_message_model.cc +++ b/chrome/browser/ui/autofill/autofill_message_model.cc
@@ -65,7 +65,7 @@ } messages::MessageWrapper& AutofillMessageModel::GetMessage( - base::PassKey<AutofillMessageController> pass_key) { + base::PassKey<AutofillMessageControllerImpl> pass_key) { return *message_; }
diff --git a/chrome/browser/ui/autofill/autofill_message_model.h b/chrome/browser/ui/autofill/autofill_message_model.h index f3650ab..e6c6f54 100644 --- a/chrome/browser/ui/autofill/autofill_message_model.h +++ b/chrome/browser/ui/autofill/autofill_message_model.h
@@ -13,7 +13,7 @@ namespace autofill { -class AutofillMessageController; +class AutofillMessageControllerImpl; // AutofillMessageModel is used to create autofill Android Messages to be used // with the AutofillMessageController. @@ -43,7 +43,7 @@ CreateForVirtualCardEnrollFailure(std::u16string card_label); messages::MessageWrapper& GetMessage( - base::PassKey<AutofillMessageController> pass_key); + base::PassKey<AutofillMessageControllerImpl> pass_key); const Type& GetType() const; std::string_view GetTypeAsString() const;
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index da348ef..74748ee 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -166,7 +166,7 @@ #include "chrome/browser/signin/android/signin_bridge.h" #include "chrome/browser/ui/android/autofill/autofill_accessibility_utils.h" #include "chrome/browser/ui/android/autofill/save_update_address_profile_flow_manager.h" -#include "chrome/browser/ui/autofill/autofill_message_controller.h" +#include "chrome/browser/ui/autofill/autofill_message_controller_impl.h" #include "chrome/browser/ui/autofill/autofill_snackbar_type.h" #include "chrome/browser/ui/autofill/payments/offer_notification_controller_android.h" #include "components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h" @@ -1161,7 +1161,7 @@ ChromeAutofillClient::GetAutofillMessageController() { if (!autofill_message_controller_) { autofill_message_controller_ = - std::make_unique<AutofillMessageController>(web_contents()); + std::make_unique<AutofillMessageControllerImpl>(web_contents()); } return autofill_message_controller_.get();
diff --git a/chrome/browser/ui/autofill/mock_autofill_message_controller.cc b/chrome/browser/ui/autofill/mock_autofill_message_controller.cc new file mode 100644 index 0000000..2fcf1457 --- /dev/null +++ b/chrome/browser/ui/autofill/mock_autofill_message_controller.cc
@@ -0,0 +1,13 @@ +// Copyright 2025 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/ui/autofill/mock_autofill_message_controller.h" + +namespace autofill { + +MockAutofillMessageController::MockAutofillMessageController() = default; + +MockAutofillMessageController::~MockAutofillMessageController() = default; + +} // namespace autofill
diff --git a/chrome/browser/ui/autofill/mock_autofill_message_controller.h b/chrome/browser/ui/autofill/mock_autofill_message_controller.h new file mode 100644 index 0000000..faaeeec --- /dev/null +++ b/chrome/browser/ui/autofill/mock_autofill_message_controller.h
@@ -0,0 +1,26 @@ +// Copyright 2025 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_UI_AUTOFILL_MOCK_AUTOFILL_MESSAGE_CONTROLLER_H_ +#define CHROME_BROWSER_UI_AUTOFILL_MOCK_AUTOFILL_MESSAGE_CONTROLLER_H_ + +#include <memory> + +#include "chrome/browser/ui/autofill/autofill_message_controller.h" +#include "chrome/browser/ui/autofill/autofill_message_model.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace autofill { + +class MockAutofillMessageController : public AutofillMessageController { + public: + MockAutofillMessageController(); + ~MockAutofillMessageController() override; + + MOCK_METHOD(void, Show, (std::unique_ptr<AutofillMessageModel>), (override)); +}; + +} // namespace autofill + +#endif // CHROME_BROWSER_UI_AUTOFILL_MOCK_AUTOFILL_MESSAGE_CONTROLLER_H_
diff --git a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.cc b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.cc index 6f7faa9d..c3946b03 100644 --- a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.cc +++ b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.cc
@@ -92,7 +92,7 @@ #include "chrome/browser/ui/android/autofill/card_expiration_date_fix_flow_view_android.h" #include "chrome/browser/ui/android/autofill/card_name_fix_flow_view_android.h" #include "chrome/browser/ui/android/tab_model/tab_model_list.h" -#include "chrome/browser/ui/autofill/autofill_message_controller.h" +#include "chrome/browser/ui/autofill/autofill_message_controller_impl.h" #include "chrome/browser/ui/autofill/autofill_message_model.h" #include "chrome/browser/ui/autofill/autofill_snackbar_controller_impl.h" #include "chrome/browser/ui/autofill/payments/android_bnpl_ui_delegate.h" @@ -1225,7 +1225,7 @@ ChromePaymentsAutofillClient::GetAutofillMessageController() { if (!autofill_message_controller_) { autofill_message_controller_ = - std::make_unique<AutofillMessageController>(web_contents()); + std::make_unique<AutofillMessageControllerImpl>(web_contents()); } return *autofill_message_controller_;
diff --git a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client_unittest.cc b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client_unittest.cc index 2284f86..0c06957b 100644 --- a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client_unittest.cc +++ b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client_unittest.cc
@@ -39,6 +39,7 @@ #include "chrome/browser/ui/android/tab_model/tab_model_test_helper.h" #include "chrome/browser/ui/autofill/autofill_message_controller.h" #include "chrome/browser/ui/autofill/autofill_snackbar_controller_impl.h" +#include "chrome/browser/ui/autofill/mock_autofill_message_controller.h" #include "components/autofill/core/browser/data_model/payments/bnpl_issuer.h" #include "components/autofill/core/browser/payments/android_bnpl_strategy.h" #include "components/autofill/core/browser/payments/autofill_save_card_ui_info.h" @@ -128,14 +129,6 @@ base::OnceClosure), (override)); }; - -class MockAutofillMessageController : public AutofillMessageController { - public: - explicit MockAutofillMessageController(content::WebContents* web_contents) - : AutofillMessageController(web_contents) {} - - MOCK_METHOD(void, Show, (std::unique_ptr<AutofillMessageModel>), (override)); -}; #else //! BUILDFLAG(IS_ANDROID) class MockSaveCardBubbleController : public SaveCardBubbleControllerImpl { public: @@ -255,7 +248,7 @@ MockAutofillMessageController* InjectMockAutofillMessageController() { std::unique_ptr<MockAutofillMessageController> mock = - std::make_unique<MockAutofillMessageController>(web_contents()); + std::make_unique<MockAutofillMessageController>(); MockAutofillMessageController* pointer = mock.get(); chrome_payments_client()->SetAutofillMessageControllerForTesting( std::move(mock));
diff --git a/chrome/browser/ui/views/dark_mode_manager_linux.cc b/chrome/browser/ui/views/dark_mode_manager_linux.cc index a856c6a..01e5f00 100644 --- a/chrome/browser/ui/views/dark_mode_manager_linux.cc +++ b/chrome/browser/ui/views/dark_mode_manager_linux.cc
@@ -74,8 +74,8 @@ SetColorScheme(observed_theme->preferred_color_scheme(), true); } -void DarkModeManagerLinux::OnPortalRequestResult(bool success) { - if (!success) { +void DarkModeManagerLinux::OnPortalRequestResult(uint32_t version) { + if (version == 0) { return; } // Subscribe to changes in the color scheme preference.
diff --git a/chrome/browser/ui/views/dark_mode_manager_linux.h b/chrome/browser/ui/views/dark_mode_manager_linux.h index e4ad855..2bce8d68 100644 --- a/chrome/browser/ui/views/dark_mode_manager_linux.h +++ b/chrome/browser/ui/views/dark_mode_manager_linux.h
@@ -81,7 +81,7 @@ void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override; // D-Bus async handlers - void OnPortalRequestResult(bool success); + void OnPortalRequestResult(uint32_t version); void OnSignalConnected(const std::string& interface_name, const std::string& signal_name, bool connected);
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc index 319ec7d6..f8dfb7d 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
@@ -1388,15 +1388,8 @@ // there are no other buttons at the end. ProfileMenuViewBase::ActionableItem::kAutofillSettingsButton}; -// TODO(crbug.com/341975308): re-enable test. -#if BUILDFLAG(IS_WIN) -#define MAYBE_ProfileMenuClickTest_SyncEnabled \ - DISABLED_ProfileMenuClickTest_SyncEnabled -#else -#define MAYBE_ProfileMenuClickTest_SyncEnabled ProfileMenuClickTest_SyncEnabled -#endif PROFILE_MENU_CLICK_TEST(kActionableItems_SyncEnabled, - MAYBE_ProfileMenuClickTest_SyncEnabled) { + ProfileMenuClickTest_SyncEnabled) { EnableSync(); RunTest(); } @@ -1450,15 +1443,8 @@ // there are no other buttons at the end. ProfileMenuViewBase::ActionableItem::kSyncErrorButton}; -// TODO(crbug.com/40822972): flaky on Windows and Mac -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) -#define MAYBE_ProfileMenuClickTest_SyncPaused \ - DISABLED_ProfileMenuClickTest_SyncPaused -#else -#define MAYBE_ProfileMenuClickTest_SyncPaused ProfileMenuClickTest_SyncPaused -#endif PROFILE_MENU_CLICK_TEST(kActionableItems_SyncPaused, - MAYBE_ProfileMenuClickTest_SyncPaused) { + ProfileMenuClickTest_SyncPaused) { EnableSync(); sync_harness()->EnterSyncPausedStateForPrimaryAccount(); // Check that the setup was successful. @@ -2058,17 +2044,9 @@ // there are no other buttons at the end. ProfileMenuViewBase::ActionableItem::kSigninReauthButton}; -// TODO(crbug.com/40822972): flaky on Windows and Mac -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) -#define MAYBE_ProfileMenuClickTest_WithPendingAccount_ReplaceSyncPromosEnabled \ - DISABLED_ProfileMenuClickTest_WithPendingAccount_ReplaceSyncPromosEnabled -#else -#define MAYBE_ProfileMenuClickTest_WithPendingAccount_ReplaceSyncPromosEnabled \ - ProfileMenuClickTest_WithPendingAccount_ReplaceSyncPromosEnabled -#endif PROFILE_MENU_CLICK_WITH_FEATURE_TEST( kActionableItems_WithPendingAccount_ReplaceSyncPromosEnabled, - MAYBE_ProfileMenuClickTest_WithPendingAccount_ReplaceSyncPromosEnabled, + ProfileMenuClickTest_WithPendingAccount_ReplaceSyncPromosEnabled, {syncer::kReplaceSyncPromosWithSignInPromos}, {}) { AccountInfo account_info = signin::MakePrimaryAccountAvailable( @@ -2107,17 +2085,9 @@ // there are no other buttons at the end. ProfileMenuViewBase::ActionableItem::kSigninReauthButton}; -// TODO(crbug.com/40822972): flaky on Windows and Mac -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) -#define MAYBE_ProfileMenuClickTest_WithPendingAccount_ReplaceSyncPromosDisabled \ - DISABLED_ProfileMenuClickTest_WithPendingAccount_ReplaceSyncPromosDisabled -#else -#define MAYBE_ProfileMenuClickTest_WithPendingAccount_ReplaceSyncPromosDisabled \ - ProfileMenuClickTest_WithPendingAccount_ReplaceSyncPromosDisabled -#endif PROFILE_MENU_CLICK_WITH_FEATURE_TEST( kActionableItems_WithPendingAccount_ReplaceSyncPromosDisabled, - MAYBE_ProfileMenuClickTest_WithPendingAccount_ReplaceSyncPromosDisabled, + ProfileMenuClickTest_WithPendingAccount_ReplaceSyncPromosDisabled, {}, {syncer::kReplaceSyncPromosWithSignInPromos}) { AccountInfo account_info = signin::MakePrimaryAccountAvailable(
diff --git a/chrome/browser/ui/webui/regional_capabilities_internals/BUILD.gn b/chrome/browser/ui/webui/regional_capabilities_internals/BUILD.gn index 3b53560..0bd3047 100644 --- a/chrome/browser/ui/webui/regional_capabilities_internals/BUILD.gn +++ b/chrome/browser/ui/webui/regional_capabilities_internals/BUILD.gn
@@ -15,10 +15,12 @@ "//chrome/browser:browser_process", "//chrome/browser/profiles:profile", "//chrome/browser/regional_capabilities", + "//chrome/browser/search_engines", "//chrome/common", "//components/regional_capabilities", "//components/regional_capabilities:country_access_reason", "//components/resources", + "//components/search_engines", "//components/strings", "//components/webui/chrome_urls", "//components/webui/regional_capabilities_internals:constants",
diff --git a/chrome/browser/ui/webui/regional_capabilities_internals/regional_capabilities_internals_ui.cc b/chrome/browser/ui/webui/regional_capabilities_internals/regional_capabilities_internals_ui.cc index 5ceac52..4fef089 100644 --- a/chrome/browser/ui/webui/regional_capabilities_internals/regional_capabilities_internals_ui.cc +++ b/chrome/browser/ui/webui/regional_capabilities_internals/regional_capabilities_internals_ui.cc
@@ -7,11 +7,13 @@ #include "base/check_deref.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/regional_capabilities/regional_capabilities_service_factory.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" #include "components/grit/regional_capabilities_internals_resources.h" #include "components/grit/regional_capabilities_internals_resources_map.h" #include "components/regional_capabilities/access/country_access_reason.h" #include "components/regional_capabilities/regional_capabilities_internals_data_holder.h" #include "components/regional_capabilities/regional_capabilities_service.h" +#include "components/search_engines/template_url_service.h" #include "components/webui/regional_capabilities_internals/constants.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/web_ui_data_source.h" @@ -21,6 +23,24 @@ using regional_capabilities::CountryAccessReason; using regional_capabilities::RegionalCapabilitiesServiceFactory; +namespace { + +#if BUILDFLAG(IS_ANDROID) +std::u16string GetExternalChoiceTemplateURL(Profile* profile) { + TemplateURLService* template_url_service = + TemplateURLServiceFactory::GetForProfile(profile); + for (const auto& template_url : template_url_service->GetTemplateURLs()) { + if (template_url->CreatedByRegulatoryProgram()) { + return template_url->keyword(); + } + } + + return u"NONE FOUND"; +} +#endif + +} // namespace + RegionalCapabilitiesInternalsUI::RegionalCapabilitiesInternalsUI( content::WebUI* web_ui, const GURL& url) @@ -40,6 +60,11 @@ source->AddString(key, value); } +#if BUILDFLAG(IS_ANDROID) + source->AddString(regional_capabilities::kExternalChoiceKeywordKey, + GetExternalChoiceTemplateURL(profile)); +#endif + webui::SetupWebUIDataSource(source, kRegionalCapabilitiesInternalsResources, IDR_REGIONAL_CAPABILITIES_INTERNALS_INDEX_HTML); }
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index 8563be9e..95819f16 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1765173445-a0222e33c7298f767f55369284e5e04b428688c5-89e15c703a7f2034682e32241e39909027a35428.profdata +chrome-android32-main-1765195063-effc20fbf9573c35953bd0d7f3be1d6def6c8298-3457ecae229e55e3260f1b3210acda332e80a8a5.profdata
diff --git a/chrome/build/android-desktop-x64.pgo.txt b/chrome/build/android-desktop-x64.pgo.txt index 7890510..6e9e84ec 100644 --- a/chrome/build/android-desktop-x64.pgo.txt +++ b/chrome/build/android-desktop-x64.pgo.txt
@@ -1 +1 @@ -chrome-android-desktop-x64-main-1765173445-021950a5f71b0cd10121f3d81a3c6276f681a9e1-89e15c703a7f2034682e32241e39909027a35428.profdata +chrome-android-desktop-x64-main-1765195063-53599a94dbea7afc2c13e2fedcb1cd828817b170-3457ecae229e55e3260f1b3210acda332e80a8a5.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index f8bcdac1..e7f9c818 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1765150054-09565681b11d74d91a37eb511de9f3cfea4bedff-e8dc846fb8405aa740d4b659d6f0669b4f1a8591.profdata +chrome-linux-main-1765195063-118e42d1bc3a8585be34ab95feeb2e6c718bf6e4-3457ecae229e55e3260f1b3210acda332e80a8a5.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index b24eb64..1d98ea3 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1765173445-62c05740b4e7f8f11dd6abbc555589a875ec56b8-89e15c703a7f2034682e32241e39909027a35428.profdata +chrome-mac-arm-main-1765195063-f0f6d87e7b28478a29d42365c049b9c02618800b-3457ecae229e55e3260f1b3210acda332e80a8a5.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index acefc0e..4543180 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1765150054-923a2d510c8e0e0a35d76ab416d2e583e3e1adbb-e8dc846fb8405aa740d4b659d6f0669b4f1a8591.profdata +chrome-mac-main-1765173445-1158ecae655b1a894fcf24a8866bba524ec947e2-89e15c703a7f2034682e32241e39909027a35428.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index 5f259b2..d683e53 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1765150054-79a1069f4808b840eb285e20b93873c48febd403-e8dc846fb8405aa740d4b659d6f0669b4f1a8591.profdata +chrome-win-arm64-main-1765173445-bb072361def816ef35c60a2973216e501f3a7c00-89e15c703a7f2034682e32241e39909027a35428.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index f250e98..4bd4686 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1765150054-bd74b354d46c549e388d86b5bfa754446faaa8d9-e8dc846fb8405aa740d4b659d6f0669b4f1a8591.profdata +chrome-win32-main-1765173445-fd311b18a0cff0a21f3e5c3a6e91d70bf9630bb5-89e15c703a7f2034682e32241e39909027a35428.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 2963c415..4c236ed 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1765105739-d2f83079a34ed5ed2d4e406f6e5f174386e2f549-b5f7f1049c1c66374a70dc4e9110c063c9c66aea.profdata +chrome-win64-main-1765150054-55825df52e5b6d839071978c22c001ae188eb7e4-e8dc846fb8405aa740d4b659d6f0669b4f1a8591.profdata
diff --git a/chrome/renderer/accessibility/read_anything/read_anything_app_controller.cc b/chrome/renderer/accessibility/read_anything/read_anything_app_controller.cc index 98a2815fc..9b8ea3e 100644 --- a/chrome/renderer/accessibility/read_anything/read_anything_app_controller.cc +++ b/chrome/renderer/accessibility/read_anything/read_anything_app_controller.cc
@@ -2117,6 +2117,7 @@ if (read_aloud_model_.speech_playing() && tab_active) { read_aloud_model_.LogSpeechStop( ReadAloudAppModel::ReadAloudStopSource::kCloseReadingMode); + ReadingModeWillClose(); } RecordEstimatedWordsSeen(); RecordEstimatedWordsHeard(); @@ -2127,11 +2128,20 @@ if (read_aloud_model_.speech_playing()) { read_aloud_model_.LogSpeechStop( ReadAloudAppModel::ReadAloudStopSource::kCloseTabOrWindow); + ReadingModeWillClose(); } RecordEstimatedWordsSeen(); RecordEstimatedWordsHeard(); } +void ReadAnythingAppController::ReadingModeWillClose() { + if (!features::IsImmersiveReadAnythingEnabled()) { + return; + } + + ExecuteJavaScript("chrome.readingMode.readingModeWillClose();"); +} + void ReadAnythingAppController::OnTabMuteStateChange(bool muted) { ExecuteJavaScript("chrome.readingMode.onTabMuteStateChange(" + base::ToString(muted) + ")");
diff --git a/chrome/renderer/accessibility/read_anything/read_anything_app_controller.h b/chrome/renderer/accessibility/read_anything/read_anything_app_controller.h index 5750fe3..218dffb 100644 --- a/chrome/renderer/accessibility/read_anything/read_anything_app_controller.h +++ b/chrome/renderer/accessibility/read_anything/read_anything_app_controller.h
@@ -386,6 +386,10 @@ // processed accessibility events. void SendEventUpdates(); + // Helper for forwarding reading mode hide events to the webui so we can + // perform cleaning operations on it. + void ReadingModeWillClose(); + // Records the number of selections that occurred for the active page. Called // when the active tree changes. void RecordNumSelections();
diff --git a/chrome/test/data/webui/side_panel/read_anything/speech_controller_test.ts b/chrome/test/data/webui/side_panel/read_anything/speech_controller_test.ts index 040111c..4e24c27 100644 --- a/chrome/test/data/webui/side_panel/read_anything/speech_controller_test.ts +++ b/chrome/test/data/webui/side_panel/read_anything/speech_controller_test.ts
@@ -655,6 +655,26 @@ assertEquals(0, speech.getCallCount('speak')); }); + test('onReadingModeWillHide while playing cancels speech', () => { + onPlayPauseToggle('Sleepy jack the fire drill'); + speech.reset(); + assertTrue(speechController.isSpeechActive()); + + speechController.onReadingModeWillClose(); + + assertEquals(1, speech.getCallCount('cancel')); + assertEquals(0, speech.getCallCount('pause')); + assertEquals(0, speech.getCallCount('speak')); + }); + + test('onReadingModeWillHide while paused does nothing', () => { + speechController.onReadingModeWillClose(); + + assertEquals(0, speech.getCallCount('pause')); + assertEquals(0, speech.getCallCount('cancel')); + assertEquals(0, speech.getCallCount('speak')); + }); + test('onVoiceSelected sets current voice', () => { const voice1 = createSpeechSynthesisVoice({lang: 'pt-pt', name: 'Donkey'}); const voice2 = createSpeechSynthesisVoice({lang: 'pt-br', name: 'Corgi'});
diff --git a/clank b/clank index 78c4f12..fe18f15 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 78c4f1290f499ca246f0c7763f32c0c44a41a00d +Subproject commit fe18f1532fab7fddfaac4b6fb1b53dd222e0a532
diff --git a/components/autofill/core/browser/filling/form_filler.cc b/components/autofill/core/browser/filling/form_filler.cc index 916c5f0..63b928d7 100644 --- a/components/autofill/core/browser/filling/form_filler.cc +++ b/components/autofill/core/browser/filling/form_filler.cc
@@ -277,8 +277,8 @@ NOTREACHED(); } -// Called by `FormFiller::MaybeTriggerRefill()` and constructs a refill value in -// case the website used JavaScript to reformat an expiration date like +// Called by `FormFiller::MaybeTriggerAutomaticRefill()` and constructs a refill +// value in case the website used JavaScript to reformat an expiration date like // "05/2023" into "05 / 20" (i.e. it broke the year by cutting the last two // digits instead of stripping the first two digits). std::optional<FormFiller::ValueAndType> GetRefillValueForExpirationDate( @@ -1015,7 +1015,7 @@ filling_payload, trigger_source, refill_trigger_reason); } -void FormFiller::MaybeTriggerRefill( +void FormFiller::MaybeTriggerAutomaticRefill( const FormData& form, const FormStructure& form_structure, RefillTriggerReason refill_trigger_reason,
diff --git a/components/autofill/core/browser/filling/form_filler.h b/components/autofill/core/browser/filling/form_filler.h index 51a65918..6e8bd833 100644 --- a/components/autofill/core/browser/filling/form_filler.h +++ b/components/autofill/core/browser/filling/form_filler.h
@@ -171,7 +171,7 @@ // `RefillTriggerReason::kExpirationDateFormatted`, and in that case `field` // is the one that was reformatted and `old_value` is the value `field` had // before the reformatting. - void MaybeTriggerRefill( + void MaybeTriggerAutomaticRefill( const FormData& form, const FormStructure& form_structure, RefillTriggerReason refill_trigger_reason,
diff --git a/components/autofill/core/browser/foundations/browser_autofill_manager.cc b/components/autofill/core/browser/foundations/browser_autofill_manager.cc index 404197c9..a8fdb99 100644 --- a/components/autofill/core/browser/foundations/browser_autofill_manager.cc +++ b/components/autofill/core/browser/foundations/browser_autofill_manager.cc
@@ -2351,10 +2351,10 @@ if (!form_structure) { return; } - form_filler_->MaybeTriggerRefill(form, *form_structure, - RefillTriggerReason::kSelectOptionsChanged, - AutofillTriggerSource::kSelectOptionsChanged, - form_structure->GetFieldById(field_id)); + form_filler_->MaybeTriggerAutomaticRefill( + form, *form_structure, RefillTriggerReason::kSelectOptionsChanged, + AutofillTriggerSource::kSelectOptionsChanged, + form_structure->GetFieldById(field_id)); } void BrowserAutofillManager::OnJavaScriptChangedAutofilledValueImpl( @@ -2405,7 +2405,7 @@ return; } AnalyzeJavaScriptChangedAutofilledValue(*form_structure, *autofill_field); - form_filler_->MaybeTriggerRefill( + form_filler_->MaybeTriggerAutomaticRefill( form, *form_structure, RefillTriggerReason::kExpirationDateFormatted, AutofillTriggerSource::kJavaScriptChangedAutofilledValue, *autofill_field, old_value); @@ -3034,9 +3034,9 @@ // If a form with the same FormGlobalId was previously filled, the structure // of the form changed, and we might be able to refill the form with other // information. - form_filler_->MaybeTriggerRefill(form, form_structure, - RefillTriggerReason::kFormChanged, - AutofillTriggerSource::kFormsSeen); + form_filler_->MaybeTriggerAutomaticRefill(form, form_structure, + RefillTriggerReason::kFormChanged, + AutofillTriggerSource::kFormsSeen); } void BrowserAutofillManager::OnDidIdentifyFormForMetrics(
diff --git a/components/capture_mode/BUILD.gn b/components/capture_mode/BUILD.gn index 07bbf64..7995351 100644 --- a/components/capture_mode/BUILD.gn +++ b/components/capture_mode/BUILD.gn
@@ -20,6 +20,7 @@ "//mojo/public/cpp/bindings", "//services/audio/public/cpp", "//services/video_capture/public/mojom", + "//ui/base:features", "//ui/compositor", "//ui/gfx", ]
diff --git a/components/capture_mode/DEPS b/components/capture_mode/DEPS index b4f09b4..927dd96 100644 --- a/components/capture_mode/DEPS +++ b/components/capture_mode/DEPS
@@ -5,11 +5,13 @@ "+gpu/command_buffer/common/context_result.h", "+gpu/command_buffer/common/shared_image_capabilities.h", "+gpu/command_buffer/common/shared_image_usage.h", + "+gpu/config/gpu_feature_info.h", "+gpu/config/gpu_finch_features.h", "+media", "+mojo/public", "+services/audio/public/cpp/device_factory.h", "+services/video_capture/public", + "+ui/base/ui_base_features.h", "+ui/compositor/compositor.h", "+ui/gfx", "+ui/ozone/public",
diff --git a/components/capture_mode/camera_video_frame_handler.cc b/components/capture_mode/camera_video_frame_handler.cc index 864a8bbc..bee03e5 100644 --- a/components/capture_mode/camera_video_frame_handler.cc +++ b/components/capture_mode/camera_video_frame_handler.cc
@@ -19,12 +19,14 @@ #include "gpu/command_buffer/client/shared_image_interface.h" #include "gpu/command_buffer/common/shared_image_capabilities.h" #include "gpu/command_buffer/common/shared_image_usage.h" +#include "gpu/config/gpu_feature_info.h" #include "gpu/config/gpu_finch_features.h" #include "media/base/media_switches.h" #include "media/base/video_frame.h" #include "media/base/video_types.h" #include "media/capture/video_capture_types.h" #include "mojo/public/cpp/system/buffer.h" +#include "ui/base/ui_base_features.h" #include "ui/compositor/compositor.h" #include "ui/gfx/buffer_types.h" #include "ui/gfx/geometry/size.h" @@ -94,7 +96,11 @@ bool IsGpuRasterizationSupported(ui::ContextFactory* context_factory) { DCHECK(context_factory); auto provider = context_factory->SharedMainThreadRasterContextProvider(); - return provider && provider->ContextCapabilities().gpu_rasterization; + const auto& gpu_feature_info = provider->GetGpuFeatureInfo(); + return features::IsUiGpuRasterizationEnabled() && + gpu_feature_info + .status_values[gpu::GPU_FEATURE_TYPE_GPU_TILE_RASTERIZATION] == + gpu::kGpuFeatureStatusEnabled; } #endif
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json index 64d1af9..5862548 100644 --- a/components/certificate_transparency/data/log_list.json +++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@ { - "version": "77.6", - "log_list_timestamp": "2025-12-07T12:52:59Z", + "version": "77.7", + "log_list_timestamp": "2025-12-08T12:53:03Z", "operators": [ { "name": "Google",
diff --git a/components/dbus/xdg/portal.cc b/components/dbus/xdg/portal.cc index 76510e96..37e4414 100644 --- a/components/dbus/xdg/portal.cc +++ b/components/dbus/xdg/portal.cc
@@ -41,7 +41,8 @@ // otherwise add it to the callback list. if (state_ == PortalRegistrarState::kSuccess || state_ == PortalRegistrarState::kFailed) { - std::move(callback).Run(state_ == PortalRegistrarState::kSuccess); + std::move(callback).Run( + state_ == PortalRegistrarState::kSuccess ? version_ : 0); return; } callbacks_.push_back(std::move(callback)); @@ -63,6 +64,7 @@ void SetStateForTesting(PortalRegistrarState state) { state_ = state; bus_ = nullptr; + version_ = (state == PortalRegistrarState::kSuccess) ? 3 : 0; callbacks_.clear(); weak_ptr_factory_.InvalidateWeakPtrs(); } @@ -87,7 +89,7 @@ if (systemd_unit_status_ == internal::SystemdUnitStatus::kUnitNotNecessary || systemd_unit_status_ == internal::SystemdUnitStatus::kUnitStarted) { - SetStateAndRunCallbacks(PortalRegistrarState::kSuccess); + GetVersion(); return; } @@ -122,6 +124,34 @@ LOG(WARNING) << "Failed to register with " << kRegistryInterface; } + GetVersion(); + } + + void GetVersion() { + dbus::ObjectProxy* proxy = bus_->GetObjectProxy( + kPortalServiceName, dbus::ObjectPath(kPortalObjectPath)); + + dbus::MethodCall method_call(DBUS_INTERFACE_PROPERTIES, "Get"); + dbus::MessageWriter writer(&method_call); + writer.AppendString(kFileChooserInterfaceName); + writer.AppendString("version"); + proxy->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::BindOnce(&PortalRegistrar::OnGetVersionReply, + weak_ptr_factory_.GetWeakPtr())); + } + + void OnGetVersionReply(dbus::Response* response) { + if (!response) { + SetStateAndRunCallbacks(PortalRegistrarState::kFailed); + return; + } + + dbus::MessageReader reader(response); + if (!reader.PopVariantOfUint32(&version_)) { + SetStateAndRunCallbacks(PortalRegistrarState::kFailed); + return; + } + SetStateAndRunCallbacks(PortalRegistrarState::kSuccess); } @@ -135,17 +165,19 @@ void SetStateAndRunCallbacks(PortalRegistrarState state) { state_ = state; - bool success = (state_ == PortalRegistrarState::kSuccess); + uint32_t version = + (state_ == PortalRegistrarState::kSuccess) ? version_ : 0; std::vector<PortalSetupCallback> callbacks; callbacks.swap(callbacks_); for (auto& callback : callbacks) { - std::move(callback).Run(success); + std::move(callback).Run(version); } } scoped_refptr<dbus::Bus> bus_; PortalRegistrarState state_ = PortalRegistrarState::kIdle; std::optional<internal::SystemdUnitStatus> systemd_unit_status_; + uint32_t version_ = 0; std::vector<PortalSetupCallback> callbacks_; base::WeakPtrFactory<PortalRegistrar> weak_ptr_factory_{this}; };
diff --git a/components/dbus/xdg/portal.h b/components/dbus/xdg/portal.h index 82fc24d..ca8bbbc 100644 --- a/components/dbus/xdg/portal.h +++ b/components/dbus/xdg/portal.h
@@ -5,6 +5,8 @@ #ifndef COMPONENTS_DBUS_XDG_PORTAL_H_ #define COMPONENTS_DBUS_XDG_PORTAL_H_ +#include <cstdint> + #include "base/component_export.h" #include "base/functional/callback_forward.h" @@ -21,12 +23,13 @@ kFailed, }; -using PortalSetupCallback = base::OnceCallback<void(bool success)>; +using PortalSetupCallback = base::OnceCallback<void(uint32_t version)>; // Initializes the XDG desktop portal by setting the systemd scope unit name, // ensuring the portal service is started, and registering the application. // This function caches its results and may be called more than once. -// `callback` is run with true iff the portal is available. +// `callback` is run with the portal version if the portal is available, or 0 +// otherwise. COMPONENT_EXPORT(COMPONENTS_DBUS) void RequestXdgDesktopPortal(dbus::Bus* bus, PortalSetupCallback callback);
diff --git a/components/dbus/xdg/portal_constants.h b/components/dbus/xdg/portal_constants.h index 510b8c8..3af1f2b 100644 --- a/components/dbus/xdg/portal_constants.h +++ b/components/dbus/xdg/portal_constants.h
@@ -11,6 +11,8 @@ inline constexpr char kPortalObjectPath[] = "/org/freedesktop/portal/desktop"; inline constexpr char kRegistryInterface[] = "org.freedesktop.host.portal.Registry"; +inline constexpr char kFileChooserInterfaceName[] = + "org.freedesktop.portal.FileChooser"; inline constexpr char kMethodRegister[] = "Register"; } // namespace dbus_xdg
diff --git a/components/dbus/xdg/portal_unittest.cc b/components/dbus/xdg/portal_unittest.cc index fd9c75e..3f7e87b 100644 --- a/components/dbus/xdg/portal_unittest.cc +++ b/components/dbus/xdg/portal_unittest.cc
@@ -101,18 +101,43 @@ // Expect SetNameOwnerChangedCallback EXPECT_CALL(*mock_portal_proxy, SetNameOwnerChangedCallback(_)); - bool success = false; + // Expect GetVersion call + EXPECT_CALL(*mock_portal_proxy, CallMethod(_, _, _)) + .WillRepeatedly([](dbus::MethodCall* method_call, int timeout_ms, + dbus::ObjectProxy::ResponseCallback callback) { + if (method_call->GetInterface() == DBUS_INTERFACE_PROPERTIES && + method_call->GetMember() == "Get") { + dbus::MessageReader reader(method_call); + std::string interface_name; + std::string property_name; + reader.PopString(&interface_name); + reader.PopString(&property_name); + + if (interface_name == kFileChooserInterfaceName && + property_name == "version") { + auto response = dbus::Response::CreateEmpty(); + dbus::MessageWriter writer(response.get()); + writer.AppendVariantOfUint32(3); + std::move(callback).Run(response.get()); + return; + } + } + std::move(callback).Run(nullptr); + }); + + uint32_t version = 0; base::RunLoop run_loop; RequestXdgDesktopPortal( - bus_.get(), base::BindOnce( - [](bool* out, base::OnceClosure quit_closure, bool res) { - *out = res; - std::move(quit_closure).Run(); - }, - &success, run_loop.QuitClosure())); + bus_.get(), + base::BindOnce( + [](uint32_t* out, base::OnceClosure quit_closure, uint32_t res) { + *out = res; + std::move(quit_closure).Run(); + }, + &version, run_loop.QuitClosure())); run_loop.Run(); - EXPECT_TRUE(success); + EXPECT_EQ(version, 3u); } TEST_F(RequestXdgDesktopPortalTest, RequestXdgDesktopPortalSuccessWithSystemd) { @@ -199,24 +224,46 @@ dbus::ObjectPath(kPortalObjectPath))) .WillRepeatedly(Return(mock_portal_proxy.get())); - // Expect NO Register call because systemd unit creation succeeded - EXPECT_CALL(*mock_portal_proxy, CallMethod(_, _, _)).Times(0); - // Expect NO SetNameOwnerChangedCallback EXPECT_CALL(*mock_portal_proxy, SetNameOwnerChangedCallback(_)).Times(0); - bool success = false; + // Expect GetVersion call + EXPECT_CALL(*mock_portal_proxy, CallMethod(_, _, _)) + .WillRepeatedly([](dbus::MethodCall* method_call, int timeout_ms, + dbus::ObjectProxy::ResponseCallback callback) { + if (method_call->GetInterface() == DBUS_INTERFACE_PROPERTIES && + method_call->GetMember() == "Get") { + dbus::MessageReader reader(method_call); + std::string interface_name; + std::string property_name; + reader.PopString(&interface_name); + reader.PopString(&property_name); + + if (interface_name == kFileChooserInterfaceName && + property_name == "version") { + auto response = dbus::Response::CreateEmpty(); + dbus::MessageWriter writer(response.get()); + writer.AppendVariantOfUint32(3); + std::move(callback).Run(response.get()); + return; + } + } + std::move(callback).Run(nullptr); + }); + + uint32_t version = 0; base::RunLoop run_loop; RequestXdgDesktopPortal( - bus_.get(), base::BindOnce( - [](bool* out, base::OnceClosure quit_closure, bool res) { - *out = res; - std::move(quit_closure).Run(); - }, - &success, run_loop.QuitClosure())); + bus_.get(), + base::BindOnce( + [](uint32_t* out, base::OnceClosure quit_closure, uint32_t res) { + *out = res; + std::move(quit_closure).Run(); + }, + &version, run_loop.QuitClosure())); run_loop.Run(); - EXPECT_TRUE(success); + EXPECT_EQ(version, 3u); } } // namespace
diff --git a/components/enterprise/BUILD.gn b/components/enterprise/BUILD.gn index f668ed1..f3bb1faf 100644 --- a/components/enterprise/BUILD.gn +++ b/components/enterprise/BUILD.gn
@@ -186,7 +186,6 @@ "//components/enterprise/browser/identifiers:test_support", "//components/enterprise/connectors/core:constants", "//components/enterprise/device_attestation:test_support", - "//components/enterprise/signin:unit_tests", "//components/policy/core/common:test_support", "//components/prefs:test_support", "//components/version_info",
diff --git a/components/enterprise/obfuscation/core/utils.cc b/components/enterprise/obfuscation/core/utils.cc index 232ceee..88390d0 100644 --- a/components/enterprise/obfuscation/core/utils.cc +++ b/components/enterprise/obfuscation/core/utils.cc
@@ -67,6 +67,8 @@ } // namespace BASE_FEATURE(kEnterpriseFileObfuscation, base::FEATURE_ENABLED_BY_DEFAULT); +BASE_FEATURE(kEnterpriseFileObfuscationArchiveAnalyzer, + base::FEATURE_DISABLED_BY_DEFAULT); bool IsFileObfuscationEnabled() { return base::FeatureList::IsEnabled(kEnterpriseFileObfuscation);
diff --git a/components/enterprise/obfuscation/core/utils.h b/components/enterprise/obfuscation/core/utils.h index 4c8b6aa..224599731 100644 --- a/components/enterprise/obfuscation/core/utils.h +++ b/components/enterprise/obfuscation/core/utils.h
@@ -49,6 +49,10 @@ COMPONENT_EXPORT(ENTERPRISE_OBFUSCATION) BASE_DECLARE_FEATURE(kEnterpriseFileObfuscation); +// Feature to enable the archive analyzer for obfuscated files. +COMPONENT_EXPORT(ENTERPRISE_OBFUSCATION) +BASE_DECLARE_FEATURE(kEnterpriseFileObfuscationArchiveAnalyzer); + // Returns true if `kEnterpriseFileObfuscation` feature is enabled. COMPONENT_EXPORT(ENTERPRISE_OBFUSCATION) bool IsFileObfuscationEnabled();
diff --git a/components/enterprise/signin/BUILD.gn b/components/enterprise/signin/BUILD.gn deleted file mode 100644 index 6311b16d..0000000 --- a/components/enterprise/signin/BUILD.gn +++ /dev/null
@@ -1,34 +0,0 @@ -# Copyright 2025 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/enterprise/buildflags/buildflags.gni") - -static_library("signin") { - sources = [ "enterprise_identity_service.cc" ] - - public = [ "enterprise_identity_service.h" ] - - deps = [ - "//base", - "//components/signin/public/identity_manager", - ] - - public_deps = [ "//components/keyed_service/core" ] -} - -source_set("unit_tests") { - testonly = true - - sources = [ "enterprise_identity_service_unittest.cc" ] - - deps = [ - ":signin", - "//base", - "//base/test:test_support", - "//components/signin/public/identity_manager", - "//components/signin/public/identity_manager:test_support", - "//testing/gmock", - "//testing/gtest", - ] -}
diff --git a/components/enterprise/signin/DEPS b/components/enterprise/signin/DEPS deleted file mode 100644 index 688775d..0000000 --- a/components/enterprise/signin/DEPS +++ /dev/null
@@ -1,5 +0,0 @@ -include_rules = [ - "+components/keyed_service/core", - "+components/signin/public/identity_manager", - "+google_apis/gaia", -]
diff --git a/components/enterprise/signin/enterprise_identity_service.cc b/components/enterprise/signin/enterprise_identity_service.cc deleted file mode 100644 index d9ece07..0000000 --- a/components/enterprise/signin/enterprise_identity_service.cc +++ /dev/null
@@ -1,317 +0,0 @@ -// Copyright 2025 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/enterprise/signin/enterprise_identity_service.h" - -#include "base/barrier_callback.h" -#include "base/barrier_closure.h" -#include "base/functional/bind.h" -#include "base/functional/callback.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/observer_list.h" -#include "base/time/time.h" -#include "components/signin/public/base/oauth_consumer_id.h" -#include "components/signin/public/identity_manager/access_token_info.h" -#include "components/signin/public/identity_manager/account_info.h" -#include "components/signin/public/identity_manager/account_managed_status_finder.h" -#include "components/signin/public/identity_manager/identity_manager.h" -#include "google_apis/gaia/google_service_auth_error.h" - -namespace enterprise { - -namespace { - -constexpr int kAccountTypeFetchTimeoutInMs = 20000; - -void HandleAccessTokenFetched( - base::OnceCallback<void(base::expected<signin::AccessTokenInfo, - GoogleServiceAuthError>)> callback, - GoogleServiceAuthError error, - signin::AccessTokenInfo token_info) { - if (error.state() == GoogleServiceAuthError::NONE) { - std::move(callback).Run(std::move(token_info)); - return; - } - - std::move(callback).Run(base::unexpected(std::move(error))); -} - -} // namespace - -using GetManagedAccountsCallback = - EnterpriseIdentityService::GetManagedAccountsCallback; - -class EnterpriseIdentityServiceImpl : public EnterpriseIdentityService, - public signin::IdentityManager::Observer { - public: - explicit EnterpriseIdentityServiceImpl( - signin::IdentityManager* identity_manager); - - ~EnterpriseIdentityServiceImpl() override; - - // EnterpriseIdentityService: - void GetManagedAccountsWithRefreshTokens( - GetManagedAccountsCallback callback) override; - void GetManagedAccountsAccessTokens( - base::OnceCallback<void(std::vector<std::string>)> callback) override; - void AddObserver(EnterpriseIdentityService::Observer* observer) override; - void RemoveObserver(EnterpriseIdentityService::Observer* observer) override; - - // signin::IdentityManager::Observer: - void OnRefreshTokensLoaded() override; - void OnRefreshTokenUpdatedForAccount( - const CoreAccountInfo& account_info) override; - void OnIdentityManagerShutdown( - signin::IdentityManager* identity_manager) override; - - private: - // Will invoke `callback` with the subset of `accounts` which end up being - // identified as managed. - void GetManagedAccounts(const std::vector<CoreAccountInfo>& accounts, - GetManagedAccountsCallback callback); - - void OnAccountTypesIdentified( - std::unique_ptr<std::vector< - std::unique_ptr<signin::AccountManagedStatusFinder>>> status_finders, - GetManagedAccountsCallback callback); - - void OnManagedAccountsIdentified( - base::OnceCallback<void(std::vector<std::string>)> callback, - std::vector<CoreAccountInfo> managed_accounts); - - void OnAccessTokensFetched( - std::unique_ptr<std::vector<std::unique_ptr<signin::AccessTokenFetcher>>> - token_fetchers, - base::OnceCallback<void(std::vector<std::string>)> callback, - std::vector<base::expected<signin::AccessTokenInfo, - GoogleServiceAuthError>> access_token_infos); - - void OnRefreshTokenUpdatedForManagedAccounts( - std::vector<CoreAccountInfo> accounts); - - bool refresh_tokens_loaded_{false}; - std::vector<base::OnceClosure> pending_requests_; - const raw_ptr<signin::IdentityManager> identity_manager_; - base::ObserverList<EnterpriseIdentityService::Observer> observers_; - - // Singular status finder used to verify if a single account is managed or - // not, for the purpose of notifying observers. - std::unique_ptr<signin::AccountManagedStatusFinder> status_finder_; - - base::WeakPtrFactory<EnterpriseIdentityServiceImpl> weak_factory_{this}; -}; - -// static -std::unique_ptr<EnterpriseIdentityService> EnterpriseIdentityService::Create( - signin::IdentityManager* identity_manager) { - return std::make_unique<EnterpriseIdentityServiceImpl>(identity_manager); -} - -EnterpriseIdentityServiceImpl::EnterpriseIdentityServiceImpl( - signin::IdentityManager* identity_manager) - : identity_manager_(identity_manager) { - CHECK(identity_manager_); - - refresh_tokens_loaded_ = identity_manager_->AreRefreshTokensLoaded(); - identity_manager_->AddObserver(this); -} - -EnterpriseIdentityServiceImpl::~EnterpriseIdentityServiceImpl() { - identity_manager_->RemoveObserver(this); -} - -void EnterpriseIdentityServiceImpl::GetManagedAccountsWithRefreshTokens( - GetManagedAccountsCallback callback) { - if (!refresh_tokens_loaded_) { - pending_requests_.push_back(base::BindOnce( - &EnterpriseIdentityServiceImpl::GetManagedAccountsWithRefreshTokens, - weak_factory_.GetWeakPtr(), std::move(callback))); - return; - } - - GetManagedAccounts(identity_manager_->GetAccountsWithRefreshTokens(), - std::move(callback)); -} - -void EnterpriseIdentityServiceImpl::GetManagedAccountsAccessTokens( - base::OnceCallback<void(std::vector<std::string>)> callback) { - GetManagedAccountsWithRefreshTokens(base::BindOnce( - &EnterpriseIdentityServiceImpl::OnManagedAccountsIdentified, - weak_factory_.GetWeakPtr(), std::move(callback))); -} - -void EnterpriseIdentityServiceImpl::AddObserver( - EnterpriseIdentityService::Observer* observer) { - observers_.AddObserver(observer); -} - -void EnterpriseIdentityServiceImpl::RemoveObserver( - EnterpriseIdentityService::Observer* observer) { - observers_.RemoveObserver(observer); -} - -void EnterpriseIdentityServiceImpl::OnRefreshTokensLoaded() { - if (refresh_tokens_loaded_) { - // No-op. - return; - } - - refresh_tokens_loaded_ = true; - - // Resume all pending requests. - for (auto& closure : pending_requests_) { - std::move(closure).Run(); - } - - pending_requests_.clear(); -} - -void EnterpriseIdentityServiceImpl::OnRefreshTokenUpdatedForAccount( - const CoreAccountInfo& account_info) { - if (!refresh_tokens_loaded_) { - return; - } - - // Verify if `account_info` represents a managed account. If so, notify - // observers. - GetManagedAccounts(std::vector<CoreAccountInfo>{account_info}, - base::BindOnce(&EnterpriseIdentityServiceImpl:: - OnRefreshTokenUpdatedForManagedAccounts, - weak_factory_.GetWeakPtr())); -} - -void EnterpriseIdentityServiceImpl::OnIdentityManagerShutdown( - signin::IdentityManager* identity_manager) { - // Needs to be shutdown before IdentityManager. - NOTREACHED(base::NotFatalUntil::M142); -} - -void EnterpriseIdentityServiceImpl::GetManagedAccounts( - const std::vector<CoreAccountInfo>& accounts, - GetManagedAccountsCallback callback) { - if (accounts.empty()) { - // No signed-in accounts. - std::move(callback).Run(std::vector<CoreAccountInfo>()); - return; - } - - // Using a unique pointer of a vector, as we'll need to fill-in the vector - // beyond transferring its ownership to the barrier closure. - auto status_finders = std::make_unique< - std::vector<std::unique_ptr<signin::AccountManagedStatusFinder>>>(); - auto* status_finders_ptr = status_finders.get(); - auto barrier_closure = base::BarrierClosure( - accounts.size(), - base::BindOnce(&EnterpriseIdentityServiceImpl::OnAccountTypesIdentified, - weak_factory_.GetWeakPtr(), std::move(status_finders), - std::move(callback))); - for (const auto& account : accounts) { - status_finders_ptr->push_back( - std::make_unique<signin::AccountManagedStatusFinder>( - identity_manager_, account, barrier_closure, - base::Milliseconds(kAccountTypeFetchTimeoutInMs))); - - // If the account was resolved synchronously, `barrier_closure` needs to be - // invoked manually. - if (status_finders_ptr->back()->GetOutcome() != - signin::AccountManagedStatusFinder::Outcome::kPending) { - barrier_closure.Run(); - } - } -} - -void EnterpriseIdentityServiceImpl::OnAccountTypesIdentified( - std::unique_ptr<std::vector< - std::unique_ptr<signin::AccountManagedStatusFinder>>> status_finders, - GetManagedAccountsCallback callback) { - std::vector<CoreAccountInfo> managed_accounts; - if (!status_finders) { - std::move(callback).Run(managed_accounts); - return; - } - - for (const auto& status_finder : *status_finders) { - if (!status_finder) { - continue; - } - - // Listing out all enum values to enforce all values are evaluated at - // compile-time. - switch (status_finder->GetOutcome()) { - case signin::AccountManagedStatusFinder::Outcome::kEnterpriseGoogleDotCom: - case signin::AccountManagedStatusFinder::Outcome::kEnterprise: - managed_accounts.push_back(status_finder->GetAccountInfo()); - break; - case signin::AccountManagedStatusFinder::Outcome::kConsumerGmail: - case signin::AccountManagedStatusFinder::Outcome::kConsumerWellKnown: - case signin::AccountManagedStatusFinder::Outcome::kConsumerNotWellKnown: - case signin::AccountManagedStatusFinder::Outcome::kPending: - case signin::AccountManagedStatusFinder::Outcome::kError: - case signin::AccountManagedStatusFinder::Outcome::kTimeout: - continue; - } - } - - std::move(callback).Run(managed_accounts); -} - -void EnterpriseIdentityServiceImpl::OnManagedAccountsIdentified( - base::OnceCallback<void(std::vector<std::string>)> callback, - std::vector<CoreAccountInfo> managed_accounts) { - if (managed_accounts.empty()) { - std::move(callback).Run(std::vector<std::string>()); - return; - } - - // Have to bind the token fetchers to the barrier callback to ensure they - // remain alive while tokens are still being fetched. - auto token_fetchers = std::make_unique< - std::vector<std::unique_ptr<signin::AccessTokenFetcher>>>(); - auto* token_fetchers_ptr = token_fetchers.get(); - auto barrier_callback = base::BarrierCallback< - base::expected<signin::AccessTokenInfo, GoogleServiceAuthError>>( - managed_accounts.size(), - base::BindOnce(&EnterpriseIdentityServiceImpl::OnAccessTokensFetched, - weak_factory_.GetWeakPtr(), std::move(token_fetchers), - std::move(callback))); - - for (const auto& account : managed_accounts) { - token_fetchers_ptr->push_back( - identity_manager_->CreateAccessTokenFetcherForAccount( - account.account_id, - signin::OAuthConsumerId::kEnterpriseIdentityService, - base::BindOnce(HandleAccessTokenFetched, barrier_callback), - signin::AccessTokenFetcher::Mode::kImmediate)); - } -} - -void EnterpriseIdentityServiceImpl::OnAccessTokensFetched( - std::unique_ptr<std::vector<std::unique_ptr<signin::AccessTokenFetcher>>> - token_fetchers, - base::OnceCallback<void(std::vector<std::string>)> callback, - std::vector<base::expected<signin::AccessTokenInfo, GoogleServiceAuthError>> - access_token_infos) { - std::vector<std::string> access_tokens; - for (const auto& access_token_info : access_token_infos) { - if (access_token_info.has_value()) { - access_tokens.push_back(access_token_info->token); - } - } - std::move(callback).Run(access_tokens); -} - -void EnterpriseIdentityServiceImpl::OnRefreshTokenUpdatedForManagedAccounts( - std::vector<CoreAccountInfo> accounts) { - if (accounts.empty()) { - // Refresh tokens were updated for a consumer user, so no-op. - return; - } - - // Notify observers. - observers_.Notify( - &EnterpriseIdentityService::Observer::OnManagedAccountSessionChanged); -} - -} // namespace enterprise
diff --git a/components/enterprise/signin/enterprise_identity_service.h b/components/enterprise/signin/enterprise_identity_service.h deleted file mode 100644 index e7f7896..0000000 --- a/components/enterprise/signin/enterprise_identity_service.h +++ /dev/null
@@ -1,67 +0,0 @@ -// Copyright 2025 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_ENTERPRISE_SIGNIN_ENTERPRISE_IDENTITY_SERVICE_H_ -#define COMPONENTS_ENTERPRISE_SIGNIN_ENTERPRISE_IDENTITY_SERVICE_H_ - -#include <memory> -#include <string> -#include <vector> - -#include "base/functional/callback_forward.h" -#include "base/observer_list_types.h" -#include "components/keyed_service/core/keyed_service.h" - -struct CoreAccountInfo; - -namespace signin { -class IdentityManager; -} - -namespace enterprise { - -class EnterpriseIdentityService : public KeyedService { - public: - static std::unique_ptr<EnterpriseIdentityService> Create( - signin::IdentityManager* identity_manager); - - class Observer : public base::CheckedObserver { - public: - ~Observer() override = default; - - Observer(const Observer&) = delete; - Observer& operator=(const Observer&) = delete; - - // Invoked when a managed account's session state has changed (e.g. account - // added, refresh tokens updated). - virtual void OnManagedAccountSessionChanged() {} - - protected: - Observer() = default; - }; - - using GetManagedAccountsCallback = - base::OnceCallback<void(std::vector<CoreAccountInfo>)>; - - // Will invoke `callback` with the list of valid managed accounts. Makes sure - // to wait for the extended account information to be available when needed - // before resolving the callback. - virtual void GetManagedAccountsWithRefreshTokens( - GetManagedAccountsCallback callback) = 0; - - // Will invoke `callback` with a list of OAuth access tokens created with the - // DM server scope for each valid managed accounts. - virtual void GetManagedAccountsAccessTokens( - base::OnceCallback<void(std::vector<std::string>)> callback) = 0; - - // Adds `observer` to the list of observers. - virtual void AddObserver(Observer* observer) = 0; - - // Removes `observer` from the list of observers. - virtual void RemoveObserver(Observer* observer) = 0; -}; - -} // namespace enterprise - -#endif // COMPONENTS_ENTERPRISE_SIGNIN_ENTERPRISE_IDENTITY_SERVICE_H_
diff --git a/components/enterprise/signin/enterprise_identity_service_unittest.cc b/components/enterprise/signin/enterprise_identity_service_unittest.cc deleted file mode 100644 index f6e4d049..0000000 --- a/components/enterprise/signin/enterprise_identity_service_unittest.cc +++ /dev/null
@@ -1,320 +0,0 @@ -// Copyright 2025 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/enterprise/signin/enterprise_identity_service.h" - -#include "base/run_loop.h" -#include "base/test/task_environment.h" -#include "base/test/test_future.h" -#include "components/signin/public/identity_manager/account_info.h" -#include "components/signin/public/identity_manager/identity_manager.h" -#include "components/signin/public/identity_manager/identity_test_environment.h" -#include "components/signin/public/identity_manager/identity_test_utils.h" -#include "components/signin/public/identity_manager/scope_set.h" -#include "google_apis/gaia/gaia_constants.h" -#include "google_apis/gaia/google_service_auth_error.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace enterprise { - -using ::testing::StrictMock; - -namespace { - -constexpr char kAccessToken1[] = "access_token1"; -constexpr char kAccessToken2[] = "access_token2"; - -class MockEnterpriseIdentityServiceObserver - : public EnterpriseIdentityService::Observer { - public: - MockEnterpriseIdentityServiceObserver() = default; - ~MockEnterpriseIdentityServiceObserver() override = default; - - MOCK_METHOD(void, OnManagedAccountSessionChanged, (), (override)); -}; - -} // namespace - -class EnterpriseIdentityServiceTest : public testing::Test { - protected: - EnterpriseIdentityServiceTest() { - identity_env_.WaitForRefreshTokensLoaded(); - } - - std::unique_ptr<EnterpriseIdentityService> CreateService() { - return EnterpriseIdentityService::Create(identity_env_.identity_manager()); - } - - const signin::IdentityManager* identity_manager() const { - return identity_env_.identity_manager(); - } - - base::test::SingleThreadTaskEnvironment task_env_{ - base::test::TaskEnvironment::TimeSource::MOCK_TIME}; - signin::IdentityTestEnvironment identity_env_; -}; - -TEST_F(EnterpriseIdentityServiceTest, - GetManagedAccountsWithRefreshTokens_NoUser) { - ASSERT_TRUE(identity_manager()->AreRefreshTokensLoaded()); - ASSERT_TRUE(identity_manager()->GetAccountsWithRefreshTokens().empty()); - - auto service = CreateService(); - ASSERT_TRUE(service); - base::test::TestFuture<std::vector<CoreAccountInfo>> test_future; - service->GetManagedAccountsWithRefreshTokens(test_future.GetCallback()); - - EXPECT_TRUE(test_future.Get().empty()); -} - -TEST_F(EnterpriseIdentityServiceTest, - GetManagedAccountsWithRefreshTokens_SingleManagedUser_Async) { - AccountInfo account = - identity_env_.MakeAccountAvailable("account@enterprise.com"); - - auto service = CreateService(); - base::test::TestFuture<std::vector<CoreAccountInfo>> test_future; - service->GetManagedAccountsWithRefreshTokens(test_future.GetCallback()); - - // Value not already available. - EXPECT_FALSE(test_future.IsReady()); - - // Full info becomes available. - identity_env_.SimulateSuccessfulFetchOfAccountInfo( - account.account_id, account.email, account.gaia, - /*hosted_domain=*/"enterprise.com", "Full Name", "Given Name", "en-US", - /*picture_url=*/""); - - auto managed_accounts = test_future.Get(); - ASSERT_EQ(managed_accounts.size(), 1U); - EXPECT_EQ(managed_accounts.front(), account); -} - -TEST_F(EnterpriseIdentityServiceTest, - GetManagedAccountsWithRefreshTokens_SingleManagedUser_Sync) { - // google.com accounts are determined as managed accounts synchronously. - AccountInfo account = - identity_env_.MakeAccountAvailable("account@google.com"); - - auto service = CreateService(); - base::test::TestFuture<std::vector<CoreAccountInfo>> test_future; - service->GetManagedAccountsWithRefreshTokens(test_future.GetCallback()); - - // Value is already available. - EXPECT_TRUE(test_future.IsReady()); - - auto managed_accounts = test_future.Get(); - ASSERT_EQ(managed_accounts.size(), 1U); - EXPECT_EQ(managed_accounts.front(), account); -} - -TEST_F(EnterpriseIdentityServiceTest, - GetManagedAccountsWithRefreshTokens_NoRefreshTokens_ThenOneUser) { - AccountInfo account = - identity_env_.MakeAccountAvailable("account@enterprise.com"); - identity_env_.ResetToAccountsNotYetLoadedFromDiskState(); - EXPECT_FALSE(identity_manager()->AreRefreshTokensLoaded()); - - auto service = CreateService(); - base::test::TestFuture<std::vector<CoreAccountInfo>> test_future; - service->GetManagedAccountsWithRefreshTokens(test_future.GetCallback()); - - // Value not already available, as the request is waiting for refresh tokens - // to have been loaded. - EXPECT_FALSE(test_future.IsReady()); - - identity_env_.ReloadAccountsFromDisk(); - identity_env_.WaitForRefreshTokensLoaded(); - - EXPECT_FALSE(test_future.IsReady()); - - identity_env_.SimulateSuccessfulFetchOfAccountInfo( - account.account_id, account.email, account.gaia, - /*hosted_domain=*/"enterprise.com", "Full Name", "Given Name", "en-US", - /*picture_url=*/""); - - auto managed_accounts = test_future.Get(); - ASSERT_EQ(managed_accounts.size(), 1U); - EXPECT_EQ(managed_accounts.front(), account); -} - -TEST_F(EnterpriseIdentityServiceTest, - GetManagedAccountsWithRefreshTokens_MultipleMixedUsers) { - AccountInfo google_account = - identity_env_.MakeAccountAvailable("account@google.com"); - AccountInfo async_enterprise_account = - identity_env_.MakeAccountAvailable("account@enterprise.com"); - AccountInfo gmail_account = - identity_env_.MakeAccountAvailable("account@gmail.com"); - AccountInfo async_consumer_account = - identity_env_.MakeAccountAvailable("account@consumer.com"); - - auto service = CreateService(); - base::test::TestFuture<std::vector<CoreAccountInfo>> test_future; - service->GetManagedAccountsWithRefreshTokens(test_future.GetCallback()); - - EXPECT_FALSE(test_future.IsReady()); - - identity_env_.SimulateSuccessfulFetchOfAccountInfo( - async_enterprise_account.account_id, async_enterprise_account.email, - async_enterprise_account.gaia, - /*hosted_domain=*/"enterprise.com", "Full Name", "Given Name", "en-US", - /*picture_url=*/""); - - EXPECT_FALSE(test_future.IsReady()); - - identity_env_.SimulateSuccessfulFetchOfAccountInfo( - async_consumer_account.account_id, async_consumer_account.email, - async_consumer_account.gaia, - /*hosted_domain=*/"", "Full Name", "Given Name", "en-US", - /*picture_url=*/""); - - auto managed_accounts = test_future.Get(); - ASSERT_EQ(managed_accounts.size(), 2U); - ASSERT_THAT(managed_accounts, testing::UnorderedElementsAre( - google_account, async_enterprise_account)); -} - -TEST_F(EnterpriseIdentityServiceTest, - GetManagedAccountsAccessTokens_SingleManagedUser_Success) { - AccountInfo account = - identity_env_.MakeAccountAvailable("account@enterprise.com"); - identity_env_.SimulateSuccessfulFetchOfAccountInfo( - account.account_id, account.email, account.gaia, - /*hosted_domain=*/"enterprise.com", "Full Name", "Given Name", "en-US", - /*picture_url=*/""); - - auto service = CreateService(); - base::test::TestFuture<std::vector<std::string>> test_future; - service->GetManagedAccountsAccessTokens(test_future.GetCallback()); - - identity_env_ - .WaitForAccessTokenRequestIfNecessaryAndRespondWithTokenForScopes( - kAccessToken1, base::Time::Max(), /*id_token=*/std::string(), - signin::ScopeSet{GaiaConstants::kDeviceManagementServiceOAuth}); - - EXPECT_THAT(test_future.Get(), testing::ElementsAre(kAccessToken1)); -} - -TEST_F(EnterpriseIdentityServiceTest, - GetManagedAccountsAccessTokens_SingleManagedUser_Error) { - AccountInfo account = - identity_env_.MakeAccountAvailable("account@enterprise.com"); - identity_env_.SimulateSuccessfulFetchOfAccountInfo( - account.account_id, account.email, account.gaia, - /*hosted_domain=*/"enterprise.com", "Full Name", "Given Name", "en-US", - /*picture_url=*/""); - - auto service = CreateService(); - base::test::TestFuture<std::vector<std::string>> test_future; - service->GetManagedAccountsAccessTokens(test_future.GetCallback()); - - identity_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithError( - GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE)); - - EXPECT_TRUE(test_future.Get().empty()); -} - -TEST_F(EnterpriseIdentityServiceTest, - GetManagedAccountsAccessTokens_MixedUsers) { - AccountInfo google_account = - identity_env_.MakeAccountAvailable("account@google.com"); - AccountInfo async_enterprise_account = - identity_env_.MakeAccountAvailable("account@enterprise.com"); - AccountInfo gmail_account = - identity_env_.MakeAccountAvailable("account@gmail.com"); - AccountInfo async_consumer_account = - identity_env_.MakeAccountAvailable("account@consumer.com"); - - identity_env_.SimulateSuccessfulFetchOfAccountInfo( - async_enterprise_account.account_id, async_enterprise_account.email, - async_enterprise_account.gaia, - /*hosted_domain=*/"enterprise.com", "Full Name", "Given Name", "en-US", - /*picture_url=*/""); - identity_env_.SimulateSuccessfulFetchOfAccountInfo( - async_consumer_account.account_id, async_consumer_account.email, - async_consumer_account.gaia, - /*hosted_domain=*/"", "Full Name", "Given Name", "en-US", - /*picture_url=*/""); - - auto service = CreateService(); - base::test::TestFuture<std::vector<std::string>> test_future; - service->GetManagedAccountsAccessTokens(test_future.GetCallback()); - - identity_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( - google_account.account_id, kAccessToken1, base::Time::Max()); - identity_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( - async_enterprise_account.account_id, kAccessToken2, base::Time::Max()); - - EXPECT_THAT(test_future.Get(), - testing::UnorderedElementsAre(kAccessToken1, kAccessToken2)); -} - -TEST_F(EnterpriseIdentityServiceTest, - Observer_OnManagedAccountSessionChanged_SyncManagedUser) { - StrictMock<MockEnterpriseIdentityServiceObserver> observer; - EXPECT_CALL(observer, OnManagedAccountSessionChanged).Times(1); - - auto service = CreateService(); - service->AddObserver(&observer); - identity_env_.MakeAccountAvailable("account@google.com"); - - service->RemoveObserver(&observer); -} - -TEST_F(EnterpriseIdentityServiceTest, - Observer_OnManagedAccountSessionChanged_SyncConsumerUser) { - StrictMock<MockEnterpriseIdentityServiceObserver> observer; - EXPECT_CALL(observer, OnManagedAccountSessionChanged).Times(0); - - auto service = CreateService(); - service->AddObserver(&observer); - identity_env_.MakeAccountAvailable("account@gmail.com"); - - service->RemoveObserver(&observer); -} - -TEST_F(EnterpriseIdentityServiceTest, - Observer_OnManagedAccountSessionChanged_AsyncManagedUser) { - base::RunLoop run_loop; - StrictMock<MockEnterpriseIdentityServiceObserver> observer; - EXPECT_CALL(observer, OnManagedAccountSessionChanged).WillOnce([&run_loop]() { - run_loop.Quit(); - }); - - auto service = CreateService(); - service->AddObserver(&observer); - auto async_enterprise_account = - identity_env_.MakeAccountAvailable("account@enterprise.com"); - identity_env_.SimulateSuccessfulFetchOfAccountInfo( - async_enterprise_account.account_id, async_enterprise_account.email, - async_enterprise_account.gaia, - /*hosted_domain=*/"enterprise.com", "Full Name", "Given Name", "en-US", - /*picture_url=*/""); - - run_loop.Run(); - - service->RemoveObserver(&observer); -} - -TEST_F(EnterpriseIdentityServiceTest, - Observer_OnManagedAccountSessionChanged_ManagedUserRefresh) { - auto account = identity_env_.MakeAccountAvailable("account@google.com"); - - StrictMock<MockEnterpriseIdentityServiceObserver> observer; - auto service = CreateService(); - service->AddObserver(&observer); - - base::RunLoop run_loop; - EXPECT_CALL(observer, OnManagedAccountSessionChanged).WillOnce([&run_loop]() { - run_loop.Quit(); - }); - identity_env_.SetRefreshTokenForAccount(account.account_id); - run_loop.Run(); - - service->RemoveObserver(&observer); -} - -} // namespace enterprise
diff --git a/components/enterprise/signin/mock_enterprise_identity_service.h b/components/enterprise/signin/mock_enterprise_identity_service.h deleted file mode 100644 index 4ee7e9cf..0000000 --- a/components/enterprise/signin/mock_enterprise_identity_service.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2025 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_ENTERPRISE_SIGNIN_MOCK_ENTERPRISE_IDENTITY_SERVICE_H_ -#define COMPONENTS_ENTERPRISE_SIGNIN_MOCK_ENTERPRISE_IDENTITY_SERVICE_H_ - -#include "base/functional/callback.h" -#include "components/enterprise/signin/enterprise_identity_service.h" -#include "components/signin/public/identity_manager/account_info.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace enterprise { - -class MockEnterpriseIdentityService : public EnterpriseIdentityService { - public: - MockEnterpriseIdentityService(); - ~MockEnterpriseIdentityService() override; - - MOCK_METHOD(void, - GetManagedAccountsWithRefreshTokens, - (GetManagedAccountsCallback), - (override)); - MOCK_METHOD(void, - GetManagedAccountsAccessTokens, - (base::OnceCallback<void(std::vector<std::string>)>), - (override)); - MOCK_METHOD(void, - AddObserver, - (EnterpriseIdentityService::Observer*), - (override)); - MOCK_METHOD(void, - RemoveObserver, - (EnterpriseIdentityService::Observer*), - (override)); -}; - -} // namespace enterprise - -#endif // COMPONENTS_ENTERPRISE_SIGNIN_MOCK_ENTERPRISE_IDENTITY_SERVICE_H_
diff --git a/components/os_crypt/async/browser/secret_portal_key_provider.cc b/components/os_crypt/async/browser/secret_portal_key_provider.cc index cb5455a..fdc5dbb 100644 --- a/components/os_crypt/async/browser/secret_portal_key_provider.cc +++ b/components/os_crypt/async/browser/secret_portal_key_provider.cc
@@ -84,9 +84,9 @@ return false; } -void SecretPortalKeyProvider::OnPortalServiceStarted(bool service_started) { +void SecretPortalKeyProvider::OnPortalServiceStarted(uint32_t version) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!service_started) { + if (version == 0) { return Finalize(InitStatus::kNoService); }
diff --git a/components/os_crypt/async/browser/secret_portal_key_provider.h b/components/os_crypt/async/browser/secret_portal_key_provider.h index eb64734f..98dc8cd1 100644 --- a/components/os_crypt/async/browser/secret_portal_key_provider.h +++ b/components/os_crypt/async/browser/secret_portal_key_provider.h
@@ -107,7 +107,7 @@ bool UseForEncryption() override; bool IsCompatibleWithOsCryptSync() override; - void OnPortalServiceStarted(bool service_started); + void OnPortalServiceStarted(uint32_t version); void OnRetrieveSecret( base::expected<dbus_xdg::Dictionary, dbus_xdg::ResponseError> results);
diff --git a/components/regional_capabilities/regional_capabilities_internals_data_holder.cc b/components/regional_capabilities/regional_capabilities_internals_data_holder.cc index bd86264..1923f1a 100644 --- a/components/regional_capabilities/regional_capabilities_internals_data_holder.cc +++ b/components/regional_capabilities/regional_capabilities_internals_data_holder.cc
@@ -5,36 +5,47 @@ #include "components/regional_capabilities/regional_capabilities_internals_data_holder.h" #include "base/check_is_test.h" +#include "base/notreached.h" #include "components/regional_capabilities/access/country_access_reason.h" #include "components/regional_capabilities/regional_capabilities_service.h" #include "components/webui/regional_capabilities_internals/constants.h" namespace regional_capabilities { +namespace { +std::string ProgramToString(Program program) { + switch (program) { + case Program::kDefault: + return "Default"; + case Program::kTaiyaki: + return "Taiyaki"; + case Program::kWaffle: + return "Waffle"; + } + NOTREACHED(); +} +} // namespace + InternalsDataHolder::InternalsDataHolder( RegionalCapabilitiesService& regional_capabilities) { - std::string active_program_name = "Unknown Program"; - switch (regional_capabilities.GetActiveProgramSettings().program) { - case Program::kDefault: - active_program_name = "Default"; - break; - case Program::kTaiyaki: - active_program_name = "Taiyaki"; - break; - case Program::kWaffle: - active_program_name = "Waffle"; - break; - } - data_.insert_or_assign(kActiveProgramNameKey, active_program_name); + data_.insert_or_assign( + kActiveProgramNameKey, + ProgramToString( + regional_capabilities.GetActiveProgramSettings().program)); data_.insert_or_assign( kActiveCountryCodeKey, regional_capabilities.GetCountryIdInternal().CountryCode()); - // DO_NOT_SUBMIT: Ensure this doesn't cause histograms to be recorded first. data_.insert_or_assign( kPrefsCountryCodeKey, regional_capabilities.GetPersistedCountryId().CountryCode()); + +#if BUILDFLAG(IS_ANDROID) + data_.insert_or_assign( + kDeviceDeterminedProgramKey, + ProgramToString(regional_capabilities.client_->GetDeviceProgram())); +#endif } InternalsDataHolder::~InternalsDataHolder() = default;
diff --git a/components/signin/DESKTOP_OWNERS b/components/signin/DESKTOP_OWNERS index 7d5c51b..89c7a5a 100644 --- a/components/signin/DESKTOP_OWNERS +++ b/components/signin/DESKTOP_OWNERS
@@ -1,11 +1,19 @@ +# Note: Unless you want a specific reviewer's expertise, please send CLs to +# chrome-signin-desktop-reviews@google.com rather than to specific individuals. +# +# These CLs will be automatically reassigned to a reviewer within +# about 5 minutes. This approach helps our team to load-balance incoming +# reviews. +chrome-signin-desktop-reviews@google.com + # keep-sorted start -alexilin@chromium.org -amelies@google.com -anthie@google.com -ddac@chromium.org -droger@chromium.org -ernn@google.com -msalama@chromium.org -msarda@chromium.org -rsult@google.com +alexilin@chromium.org #{LAST_RESORT_SUGGESTION} +amelies@google.com #{LAST_RESORT_SUGGESTION} +anthie@google.com #{LAST_RESORT_SUGGESTION} +ddac@chromium.org #{LAST_RESORT_SUGGESTION} +droger@chromium.org #{LAST_RESORT_SUGGESTION} +ernn@google.com #{LAST_RESORT_SUGGESTION} +msalama@chromium.org #{LAST_RESORT_SUGGESTION} +msarda@chromium.org #{LAST_RESORT_SUGGESTION} +rsult@google.com #{LAST_RESORT_SUGGESTION} # keep-sorted end
diff --git a/components/signin/public/base/oauth_consumer_id.h b/components/signin/public/base/oauth_consumer_id.h index 8580eab28..30d19c7 100644 --- a/components/signin/public/base/oauth_consumer_id.h +++ b/components/signin/public/base/oauth_consumer_id.h
@@ -10,7 +10,8 @@ namespace oauth_consumer_name { inline extern const char kEnterprisePlusAddressName[] = "enterprise_plus_address"; -} +inline extern const char kGlicUserStatusName[] = "glic_user_status"; +} // namespace oauth_consumer_name // LINT.IfChange(OAuthConsumerId) // These values are persisted to logs. Entries should not be renumbered and @@ -68,7 +69,7 @@ kEduCoexistenceLoginHandler = 48, kEduAccountLoginHandler = 49, kChromeosFamilyLinkUserMetricsProvider = 50, - kEnterpriseIdentityService = 51, + // kEnterpriseIdentityService = 51, // Removed due to deprecation. kPromotionEligibilityChecker = 52, kPasswordManagerLeakDetection = 53, kAndroidManagementClient = 54, @@ -97,7 +98,9 @@ kYouTubeMusic = 77, kContextualTasks = 78, kEnterprisePlusAddress = 79, - kMaxValue = kEnterprisePlusAddress, + kGlicUserStatus = 80, + kDevtoolsGdp = 81, + kMaxValue = kDevtoolsGdp, }; // LINT.ThenChange(//tools/metrics/histograms/metadata/signin/enums.xml:OAuthConsumerId)
diff --git a/components/signin/public/base/oauth_consumer_registry.cc b/components/signin/public/base/oauth_consumer_registry.cc index 515526b..a5e6e56 100644 --- a/components/signin/public/base/oauth_consumer_registry.cc +++ b/components/signin/public/base/oauth_consumer_registry.cc
@@ -76,7 +76,6 @@ constexpr char kEduAccountLoginHandlerName[] = "edu_account_login_handler"; constexpr char kChromeosFamilyLinkUserMetricsProviderName[] = "chromeos_family_link_user_metrics_provider"; -constexpr char kEnterpriseIdentityServiceName[] = "enterprise_identity_service"; constexpr char kPromotionEligibilityCheckerName[] = "promotion_eligibility_checker"; constexpr char kPasswordManagerLeakDetectionName[] = @@ -110,6 +109,7 @@ constexpr char kAuthServiceTasksClientName[] = "auth_service_tasks_client"; constexpr char kYouTubeMusicName[] = "youtube_music"; constexpr char kContextualTasksName[] = "contextual_tasks"; +constexpr char kDevtoolsGdpName[] = "devtools_gdp_client"; } // namespace @@ -351,10 +351,6 @@ return OAuthConsumer( /*name=*/kChromeosFamilyLinkUserMetricsProviderName, /*scopes=*/{}); - case OAuthConsumerId::kEnterpriseIdentityService: - return OAuthConsumer( - /*name=*/kEnterpriseIdentityServiceName, - /*scopes=*/{GaiaConstants::kDeviceManagementServiceOAuth}); case OAuthConsumerId::kPromotionEligibilityChecker: return OAuthConsumer( /*name=*/kPromotionEligibilityCheckerName, @@ -484,6 +480,12 @@ GaiaConstants::kClearCutOAuth2Scope}); case OAuthConsumerId::kEnterprisePlusAddress: return GetOAuthConsumerForEnterprisePlusAddress(); + case OAuthConsumerId::kGlicUserStatus: + return GetOAuthConsumerForGlicUserStatus(); + case OAuthConsumerId::kDevtoolsGdp: + return OAuthConsumer( + /*name=*/kDevtoolsGdpName, + /*scopes=*/{GaiaConstants::kGdpOAuth2Scope}); } }
diff --git a/components/signin/public/base/oauth_consumer_registry.h b/components/signin/public/base/oauth_consumer_registry.h index 64fa2296..026c33976 100644 --- a/components/signin/public/base/oauth_consumer_registry.h +++ b/components/signin/public/base/oauth_consumer_registry.h
@@ -31,6 +31,7 @@ protected: virtual OAuthConsumer GetOAuthConsumerForEnterprisePlusAddress() const = 0; + virtual OAuthConsumer GetOAuthConsumerForGlicUserStatus() const = 0; }; } // namespace signin
diff --git a/components/signin/public/base/test_signin_client.cc b/components/signin/public/base/test_signin_client.cc index 142ca96c..402c142 100644 --- a/components/signin/public/base/test_signin_client.cc +++ b/components/signin/public/base/test_signin_client.cc
@@ -30,6 +30,10 @@ signin::oauth_consumer_name::kEnterprisePlusAddressName, {plus_addresses::features::kEnterprisePlusAddressOAuthScope.Get()}); } + + signin::OAuthConsumer GetOAuthConsumerForGlicUserStatus() const override { + NOTREACHED(); + } }; } // namespace
diff --git a/components/signin/public/webdata/token_service_table.cc b/components/signin/public/webdata/token_service_table.cc index 0d09d86b..fd7faa31 100644 --- a/components/signin/public/webdata/token_service_table.cc +++ b/components/signin/public/webdata/token_service_table.cc
@@ -5,6 +5,7 @@ #include "components/signin/public/webdata/token_service_table.h" #include <map> +#include <optional> #include <string> #include "base/logging.h" @@ -16,6 +17,7 @@ #include "components/webdata/common/web_database.h" #include "sql/statement.h" #include "sql/transaction.h" +#include "third_party/abseil-cpp/absl/cleanup/cleanup.h" namespace { @@ -46,6 +48,19 @@ kMaxValue = kSqlFailure, }; +// Entries in the `Signin.TokenTable.GetAllWrappedBindingKeysResult` histogram. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +// +// LINT.IfChange(GetAllWrappedBindingKeysResult) +enum class GetAllWrappedBindingKeysResult { + kSuccess = 0, + kSqlInvalidStatement = 1, + kSqlFailure = 2, + kMaxValue = kSqlFailure, +}; +// LINT.ThenChange(//tools/metrics/histograms/metadata/signin/enums.xml:SigninTokenTableGetAllWrappedBindingKeysResult) + void RecordRemoveOtherTokensHistogram(size_t remove_count) { base::UmaHistogramCounts100("Signin.TokenTable.RemoveOtherTokensCount", remove_count); @@ -235,6 +250,37 @@ return read_all_tokens_result; } +std::optional<absl::flat_hash_set<std::vector<uint8_t>>> +TokenServiceTable::GetAllWrappedBindingKeys() { + GetAllWrappedBindingKeysResult result = + GetAllWrappedBindingKeysResult::kSuccess; + + absl::Cleanup record_result = [&result] { + base::UmaHistogramEnumeration( + "Signin.TokenTable.GetAllWrappedBindingKeysResult", result); + }; + + sql::Statement s( + db()->GetUniqueStatement("SELECT binding_key FROM token_service")); + + if (!s.is_valid()) { + result = GetAllWrappedBindingKeysResult::kSqlInvalidStatement; + return std::nullopt; + } + + absl::flat_hash_set<std::vector<uint8_t>> wrapped_binding_keys; + while (s.Step()) { + wrapped_binding_keys.insert(s.ColumnBlobAsVector(0)); + } + + if (!s.Succeeded()) { + result = GetAllWrappedBindingKeysResult::kSqlFailure; + return std::nullopt; + } + + return wrapped_binding_keys; +} + bool TokenServiceTable::MigrateToVersion130AddBindingKeyColumn() { sql::Transaction transaction(db()); return transaction.Begin() &&
diff --git a/components/signin/public/webdata/token_service_table.h b/components/signin/public/webdata/token_service_table.h index 7c38aa9..d7285cf 100644 --- a/components/signin/public/webdata/token_service_table.h +++ b/components/signin/public/webdata/token_service_table.h
@@ -6,11 +6,12 @@ #define COMPONENTS_SIGNIN_PUBLIC_WEBDATA_TOKEN_SERVICE_TABLE_H_ #include <map> +#include <optional> #include <string> #include <vector> -#include "base/compiler_specific.h" #include "components/webdata/common/web_database_table.h" +#include "third_party/abseil-cpp/absl/container/flat_hash_set.h" class WebDatabase; @@ -72,6 +73,11 @@ Result GetAllTokens(std::map<std::string, TokenWithBindingKey>* tokens, bool& should_reencrypt); + // Retrieves all wrapped binding keys previously set with + // `SetTokenForService`. Returns nullopt if there was a failure somehow. + std::optional<absl::flat_hash_set<std::vector<uint8_t>>> + GetAllWrappedBindingKeys(); + // Stores a token with an optional binding key in the token_service table. // Token is stored encrypted. May cause a mac keychain popup. // Returns true if we encrypted a token and stored it, false otherwise.
diff --git a/components/signin/public/webdata/token_service_table_unittest.cc b/components/signin/public/webdata/token_service_table_unittest.cc index 3e28700..02373552 100644 --- a/components/signin/public/webdata/token_service_table_unittest.cc +++ b/components/signin/public/webdata/token_service_table_unittest.cc
@@ -24,8 +24,10 @@ #include "testing/gtest/include/gtest/gtest.h" using ::base::Time; +using ::testing::ElementsAre; using ::testing::IsEmpty; using ::testing::Key; +using ::testing::Optional; using ::testing::SizeIs; using ::testing::UnorderedElementsAre; using ::testing::UnorderedElementsAreArray; @@ -93,6 +95,23 @@ EXPECT_EQ(TokenWithBindingKey("cheese"), out_map.find(service)->second); } +TEST_F(TokenServiceTableTest, TokenServiceGetAllWrappedBindingKeys) { + EXPECT_THAT(table_->GetAllWrappedBindingKeys(), Optional(IsEmpty())); + + EXPECT_TRUE(table_->SetTokenForService("service1", "token1", {1, 2, 3})); + EXPECT_TRUE(table_->SetTokenForService("service2", "token2", {4, 5, 6})); + EXPECT_TRUE(table_->SetTokenForService("service3", "token3", {7, 8, 9})); + EXPECT_THAT( + table_->GetAllWrappedBindingKeys(), + Optional(UnorderedElementsAre(ElementsAre(1, 2, 3), ElementsAre(4, 5, 6), + ElementsAre(7, 8, 9)))); + + EXPECT_TRUE(table_->RemoveTokenForService("service1")); + EXPECT_THAT(table_->GetAllWrappedBindingKeys(), + Optional(UnorderedElementsAre(ElementsAre(4, 5, 6), + ElementsAre(7, 8, 9)))); +} + TEST_F(TokenServiceTableTest, TokenServiceGetSet) { std::map<std::string, TokenWithBindingKey> out_map; std::string service; @@ -265,6 +284,15 @@ histograms.ExpectUniqueSample("Signin.TokenTable.ReadTokenFromDBResult", /*READ_ONE_TOKEN_SUCCESS*/ 0, 1u); } + + { + base::HistogramTester histograms; + EXPECT_THAT(table_->GetAllWrappedBindingKeys(), + Optional(UnorderedElementsAre(IsEmpty()))); + histograms.ExpectUniqueSample( + "Signin.TokenTable.GetAllWrappedBindingKeysResult", + /*kSuccess*/ 0, 1u); + } } class TokenServiceTableEncryptionOptionsTest : public testing::Test {
diff --git a/components/signin/public/webdata/token_web_data.cc b/components/signin/public/webdata/token_web_data.cc index 1748c3e..1d9bdbb 100644 --- a/components/signin/public/webdata/token_web_data.cc +++ b/components/signin/public/webdata/token_web_data.cc
@@ -5,12 +5,15 @@ #include "components/signin/public/webdata/token_web_data.h" #include <memory> +#include <optional> #include "base/functional/bind.h" #include "base/memory/ref_counted_delete_on_sequence.h" #include "base/task/sequenced_task_runner.h" +#include "base/types/expected_macros.h" #include "components/signin/public/webdata/token_service_table.h" #include "components/webdata/common/web_database_service.h" +#include "third_party/abseil-cpp/absl/container/flat_hash_set.h" using base::BindOnce; @@ -68,6 +71,17 @@ std::move(result)); } + std::unique_ptr<WDTypedResult> GetAllWrappedBindingKeys(WebDatabase* db) { + ASSIGN_OR_RETURN( + absl::flat_hash_set<std::vector<uint8_t>> keys, + TokenServiceTable::FromWebDatabase(db)->GetAllWrappedBindingKeys(), + [] -> std::unique_ptr<WDTypedResult> { return nullptr; }); + + return std::make_unique< + WDResult<absl::flat_hash_set<std::vector<uint8_t>>>>( + WRAPPED_BINDING_KEYS_RESULT, std::move(keys)); + } + protected: virtual ~TokenWebDataBackend() = default; @@ -126,4 +140,13 @@ consumer); } +// Null on failure. Success is WDResult<std::vector<std::vector<uint8_t>>> +WebDataServiceBase::Handle TokenWebData::GetAllWrappedBindingKeys( + WebDataServiceConsumer* consumer) { + return wdbs_->ScheduleDBTaskWithResult( + FROM_HERE, + BindOnce(&TokenWebDataBackend::GetAllWrappedBindingKeys, token_backend_), + consumer); +} + TokenWebData::~TokenWebData() = default;
diff --git a/components/signin/public/webdata/token_web_data.h b/components/signin/public/webdata/token_web_data.h index e5583d9..0249236 100644 --- a/components/signin/public/webdata/token_web_data.h +++ b/components/signin/public/webdata/token_web_data.h
@@ -67,9 +67,12 @@ // service is present in `services_to_keep`. void RemoveOtherTokens(const std::vector<std::string>& services_to_keep); - // Null on failure. Success is `WDResult<std::vector<std::string>>`. + // Null on failure. Success is `WDResult<TokenResult>`. virtual Handle GetAllTokens(WebDataServiceConsumer* consumer); + // Null on failure. Success is `WDResult<std::vector<std::vector<uint8_t>>>`. + virtual Handle GetAllWrappedBindingKeys(WebDataServiceConsumer* consumer); + protected: ~TokenWebData() override;
diff --git a/components/tabs/impl/tab_strip_collection.cc b/components/tabs/impl/tab_strip_collection.cc index fd10031..24109a6 100644 --- a/components/tabs/impl/tab_strip_collection.cc +++ b/components/tabs/impl/tab_strip_collection.cc
@@ -339,7 +339,7 @@ void TabStripCollection::InsertTabCollectionAt( std::unique_ptr<TabCollection> collection, int index, - int pinned, + bool pinned, std::optional<tab_groups::TabGroupId> parent_group) { TabCollection::Position insertion_details = GetInsertionDetails(index, pinned, parent_group); @@ -728,7 +728,7 @@ TabCollection::Position TabStripCollection::GetInsertionDetails( int index, - int pinned, + bool pinned, std::optional<tab_groups::TabGroupId> group) { size_t direct_dst_index; TabCollection* insert_collection = nullptr;
diff --git a/components/tabs/public/tab_strip_collection.h b/components/tabs/public/tab_strip_collection.h index 43cae28..b703709 100644 --- a/components/tabs/public/tab_strip_collection.h +++ b/components/tabs/public/tab_strip_collection.h
@@ -72,7 +72,7 @@ void InsertTabCollectionAt( std::unique_ptr<TabCollection> collection, int index, - int pinned, + bool pinned, std::optional<tab_groups::TabGroupId> parent_group); // Remove a tab collection and send the appropriate notifications. @@ -187,7 +187,7 @@ // recursive index, pinned state and group to insert. TabCollection::Position GetInsertionDetails( int index, - int pinned, + bool pinned, std::optional<tab_groups::TabGroupId> group); // Returns the parent collection and the direct child index within that
diff --git a/components/wallet/core/browser/data_models/boarding_pass.cc b/components/wallet/core/browser/data_models/boarding_pass.cc index 4856d91..87fb099 100644 --- a/components/wallet/core/browser/data_models/boarding_pass.cc +++ b/components/wallet/core/browser/data_models/boarding_pass.cc
@@ -90,6 +90,13 @@ constexpr int kFlightCodeLength = 5; constexpr int kDateLength = 3; +// Removes leading zeros from a string, e.g., "007" becomes "7". If the string +// is "000", it becomes "0". +std::string RemoveLeadingZeros(std::string_view s) { + std::string_view trimmed = base::TrimString(s, "0", base::TRIM_LEADING); + return (trimmed.empty() && !s.empty()) ? "0" : std::string(trimmed); +} + } // namespace // static @@ -122,7 +129,7 @@ pass.origin = value.GetStripped(kOriginLength); pass.destination = value.GetStripped(kDestinationLength); pass.airline = value.GetStripped(kAirlineLength); - pass.flight_code = value.GetStripped(kFlightCodeLength); + pass.flight_code = RemoveLeadingZeros(value.GetStripped(kFlightCodeLength)); pass.date = value.GetStripped(kDateLength); pass.barcode = barcode;
diff --git a/components/wallet/core/browser/data_models/boarding_pass_unittest.cc b/components/wallet/core/browser/data_models/boarding_pass_unittest.cc index f8e83ff..be22bf1 100644 --- a/components/wallet/core/browser/data_models/boarding_pass_unittest.cc +++ b/components/wallet/core/browser/data_models/boarding_pass_unittest.cc
@@ -92,8 +92,30 @@ ExpectedBoardingPass{.origin = "PPT", .destination = "CDG", .airline = "AF", - .flight_code = "0077", + .flight_code = "77", .date = "137"}); } +TEST(BoardingPassTest, ParseBoardingPass_FlightCodeLeadingZeros) { + // Flight codes with leading zeros should have them removed. + TestValue("M1PASSENGER NAME EABCDEFGSFOJFKUA 0007 123Y12A 00001100", + ExpectedBoardingPass{.origin = "SFO", + .destination = "JFK", + .airline = "UA", + .flight_code = "7", + .date = "123"}); + TestValue("M1PASSENGER NAME EABCDEFGSFOJFKUA 0707 123Y12A 00001100", + ExpectedBoardingPass{.origin = "SFO", + .destination = "JFK", + .airline = "UA", + .flight_code = "707", + .date = "123"}); + TestValue("M1PASSENGER NAME EABCDEFGSFOJFKUA 0000 123Y12A 00001100", + ExpectedBoardingPass{.origin = "SFO", + .destination = "JFK", + .airline = "UA", + .flight_code = "0", + .date = "123"}); +} + } // namespace wallet
diff --git a/components/webdata/common/web_data_results.h b/components/webdata/common/web_data_results.h index 231787c4..2050a6bb 100644 --- a/components/webdata/common/web_data_results.h +++ b/components/webdata/common/web_data_results.h
@@ -52,6 +52,7 @@ // sync_pb::PaymentInstrument>> PAYMENT_INSTRUMENT_CREATION_OPTION_RESULT, // WDResult<std::vector< // sync_pb::PaymentInstrumentCreationOption>> + WRAPPED_BINDING_KEYS_RESULT, // WDResult<absl::flat_hash_set<std::vector<uint8_t>>> #if BUILDFLAG(USE_BLINK) // // The browser bound key id is retrieved by the payments component // during secure payment confirmation requests and payment credential
diff --git a/components/webui/regional_capabilities_internals/constants.cc b/components/webui/regional_capabilities_internals/constants.cc index 0a771ff..ca0524d 100644 --- a/components/webui/regional_capabilities_internals/constants.cc +++ b/components/webui/regional_capabilities_internals/constants.cc
@@ -10,5 +10,7 @@ const char kActiveProgramNameKey[] = "activeProgramName"; const char kActiveCountryCodeKey[] = "activeCountryCode"; const char kPrefsCountryCodeKey[] = "prefsCountryCode"; +const char kDeviceDeterminedProgramKey[] = "deviceDeterminedProgram"; +const char kExternalChoiceKeywordKey[] = "externalChoiceKeyword"; } // namespace regional_capabilities
diff --git a/components/webui/regional_capabilities_internals/constants.h b/components/webui/regional_capabilities_internals/constants.h index a39ac414..a1b7439 100644 --- a/components/webui/regional_capabilities_internals/constants.h +++ b/components/webui/regional_capabilities_internals/constants.h
@@ -14,6 +14,8 @@ extern const char kActiveProgramNameKey[]; extern const char kActiveCountryCodeKey[]; extern const char kPrefsCountryCodeKey[]; +extern const char kDeviceDeterminedProgramKey[]; +extern const char kExternalChoiceKeywordKey[]; } // namespace regional_capabilities
diff --git a/components/webui/regional_capabilities_internals/resources/app.ts b/components/webui/regional_capabilities_internals/resources/app.ts index 3c244ae..11cbf8c6 100644 --- a/components/webui/regional_capabilities_internals/resources/app.ts +++ b/components/webui/regional_capabilities_internals/resources/app.ts
@@ -24,16 +24,22 @@ return tr; } +function appendRow( + tableElement: HTMLElement, headerName: string, dataKey: string) { + if (loadTimeData.valueExists(dataKey)) { + tableElement.appendChild(buildTableRow(headerName, dataKey)); + } +} /* All the work we do onload. */ function initialize() { - const tableElement = getRequiredElement('data-table'); - tableElement.textContent = ''; - tableElement.appendChild( - buildTableRow('Active Program', 'activeProgramName')); - tableElement.appendChild( - buildTableRow('Active Country', 'activeCountryCode')); - tableElement.appendChild( - buildTableRow('Country in prefs', 'prefsCountryCode')); + const tableEl = getRequiredElement('data-table'); + tableEl.textContent = ''; + + appendRow(tableEl, 'Active Program', 'activeProgramName'); + appendRow(tableEl, 'Device Determined Program', 'deviceDeterminedProgram'); + appendRow(tableEl, 'Active Country', 'activeCountryCode'); + appendRow(tableEl, 'Country in prefs', 'prefsCountryCode'); + appendRow(tableEl, 'External Choice', 'externalChoiceKeyword'); } document.addEventListener('DOMContentLoaded', initialize);
diff --git a/content/browser/media/capture/pip_screen_capture_coordinator.cc b/content/browser/media/capture/pip_screen_capture_coordinator.cc index 120d4443..ae988e2 100644 --- a/content/browser/media/capture/pip_screen_capture_coordinator.cc +++ b/content/browser/media/capture/pip_screen_capture_coordinator.cc
@@ -40,7 +40,8 @@ void PipScreenCaptureCoordinator::OnPipShown(WebContents& pip_web_contents) { #if BUILDFLAG(IS_MAC) if (auto* instance = PipScreenCaptureCoordinatorImpl::GetInstance()) { - instance->OnPipShown(pip_web_contents); + instance->OnPipShown(pip_web_contents, + GetWebContents().GetPrimaryMainFrame()->GetGlobalId()); } #endif }
diff --git a/content/browser/media/capture/pip_screen_capture_coordinator_impl.cc b/content/browser/media/capture/pip_screen_capture_coordinator_impl.cc index 82dbf37..1d388bd0 100644 --- a/content/browser/media/capture/pip_screen_capture_coordinator_impl.cc +++ b/content/browser/media/capture/pip_screen_capture_coordinator_impl.cc
@@ -9,6 +9,7 @@ #include "build/build_config.h" #include "content/browser/media/capture/pip_screen_capture_coordinator_proxy_impl.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "media/capture/capture_switches.h" @@ -60,24 +61,26 @@ PipScreenCaptureCoordinatorImpl::~PipScreenCaptureCoordinatorImpl() = default; void PipScreenCaptureCoordinatorImpl::OnPipShown( - WebContents& pip_web_contents) { + WebContents& pip_web_contents, + const GlobalRenderFrameHostId& new_pip_owner_render_frame_host_id) { std::optional<NativeWindowId> new_pip_window_id; new_pip_window_id = GetNativeWindowIdMac(pip_web_contents); if (new_pip_window_id) { - OnPipShown(*new_pip_window_id); + OnPipShown(*new_pip_window_id, new_pip_owner_render_frame_host_id); } } void PipScreenCaptureCoordinatorImpl::OnPipShown( - NativeWindowId new_pip_window_id) { - if (pip_window_id_ == new_pip_window_id) { + NativeWindowId new_pip_window_id, + const GlobalRenderFrameHostId& new_pip_owner_render_frame_host_id) { + if (pip_window_id_ == new_pip_window_id && + pip_owner_render_frame_host_id_ == new_pip_owner_render_frame_host_id) { return; } pip_window_id_ = new_pip_window_id; - for (Observer& obs : observers_) { - obs.OnPipWindowIdChanged(pip_window_id_); - } + pip_owner_render_frame_host_id_ = new_pip_owner_render_frame_host_id; + NotifyStateChanged(); } void PipScreenCaptureCoordinatorImpl::OnPipClosed() { @@ -85,9 +88,8 @@ return; } pip_window_id_ = std::nullopt; - for (Observer& obs : observers_) { - obs.OnPipWindowIdChanged(pip_window_id_); - } + pip_owner_render_frame_host_id_ = {}; + NotifyStateChanged(); } std::optional<NativeWindowId> PipScreenCaptureCoordinatorImpl::PipWindowId() @@ -95,6 +97,11 @@ return pip_window_id_; } +GlobalRenderFrameHostId +PipScreenCaptureCoordinatorImpl::GetPipOwnerRenderFrameHostId() const { + return pip_owner_render_frame_host_id_; +} + std::vector<PipScreenCaptureCoordinatorProxy::CaptureInfo> PipScreenCaptureCoordinatorImpl::Captures() const { return captures_; @@ -103,9 +110,7 @@ void PipScreenCaptureCoordinatorImpl::AddCaptureOnUIThread( PipScreenCaptureCoordinatorProxy::CaptureInfo capture_info) { captures_.push_back(std::move(capture_info)); - for (Observer& obs : observers_) { - obs.OnCapturesChanged(captures_); - } + NotifyStateChanged(); } void PipScreenCaptureCoordinatorImpl::RemoveCaptureOnUIThread( @@ -115,15 +120,21 @@ return c.session_id == session_id; }), captures_.end()); + NotifyStateChanged(); +} + +void PipScreenCaptureCoordinatorImpl::NotifyStateChanged() { for (Observer& obs : observers_) { - obs.OnCapturesChanged(captures_); + obs.OnStateChanged(pip_window_id_, pip_owner_render_frame_host_id_, + captures_); } } std::unique_ptr<PipScreenCaptureCoordinatorProxy> PipScreenCaptureCoordinatorImpl::CreateProxy() { return std::make_unique<PipScreenCaptureCoordinatorProxyImpl>( - weak_factory_.GetWeakPtr(), PipWindowId(), captures_); + weak_factory_.GetWeakPtr(), PipWindowId(), GetPipOwnerRenderFrameHostId(), + captures_); } void PipScreenCaptureCoordinatorImpl::AddObserver(Observer* observer) { @@ -136,6 +147,7 @@ void PipScreenCaptureCoordinatorImpl::ResetForTesting() { pip_window_id_ = std::nullopt; + pip_owner_render_frame_host_id_ = {}; observers_.Clear(); captures_.clear(); weak_factory_.InvalidateWeakPtrs();
diff --git a/content/browser/media/capture/pip_screen_capture_coordinator_impl.h b/content/browser/media/capture/pip_screen_capture_coordinator_impl.h index 597aa41de..9f858bcd 100644 --- a/content/browser/media/capture/pip_screen_capture_coordinator_impl.h +++ b/content/browser/media/capture/pip_screen_capture_coordinator_impl.h
@@ -27,12 +27,10 @@ class Observer : public base::CheckedObserver { public: - // Called with the NativeWindowId of the PiP window when it is - // shown, or nullopt when it is closed. - virtual void OnPipWindowIdChanged( - std::optional<NativeWindowId> new_pip_window_id) = 0; - // Called when the list of captures changes. - virtual void OnCapturesChanged( + // Called when the state of the coordinator changes. + virtual void OnStateChanged( + std::optional<NativeWindowId> new_pip_window_id, + const GlobalRenderFrameHostId& new_pip_owner_render_frame_host_id, const std::vector<PipScreenCaptureCoordinatorProxy::CaptureInfo>& captures) = 0; }; @@ -44,11 +42,16 @@ PipScreenCaptureCoordinatorImpl& operator=( const PipScreenCaptureCoordinatorImpl&) = delete; - void OnPipShown(WebContents& pip_web_contents); - void OnPipShown(NativeWindowId pip_window_id); + void OnPipShown( + WebContents& pip_web_contents, + const GlobalRenderFrameHostId& pip_owner_render_frame_host_id); + void OnPipShown( + NativeWindowId pip_window_id, + const GlobalRenderFrameHostId& pip_owner_render_frame_host_id); void OnPipClosed(); std::optional<NativeWindowId> PipWindowId() const; + GlobalRenderFrameHostId GetPipOwnerRenderFrameHostId() const; std::vector<PipScreenCaptureCoordinatorProxy::CaptureInfo> Captures() const; std::unique_ptr<PipScreenCaptureCoordinatorProxy> CreateProxy(); @@ -62,10 +65,12 @@ void AddCaptureOnUIThread( PipScreenCaptureCoordinatorProxy::CaptureInfo capture_info); void RemoveCaptureOnUIThread(const base::UnguessableToken& session_id); + void NotifyStateChanged(); friend class base::NoDestructor<PipScreenCaptureCoordinatorImpl>; PipScreenCaptureCoordinatorImpl(); std::optional<NativeWindowId> pip_window_id_; + GlobalRenderFrameHostId pip_owner_render_frame_host_id_; base::ObserverList<Observer> observers_; std::vector<PipScreenCaptureCoordinatorProxy::CaptureInfo> captures_; base::WeakPtrFactory<PipScreenCaptureCoordinatorImpl> weak_factory_{this};
diff --git a/content/browser/media/capture/pip_screen_capture_coordinator_impl_unittest.cc b/content/browser/media/capture/pip_screen_capture_coordinator_impl_unittest.cc index fdc305e..4b8c9ae 100644 --- a/content/browser/media/capture/pip_screen_capture_coordinator_impl_unittest.cc +++ b/content/browser/media/capture/pip_screen_capture_coordinator_impl_unittest.cc
@@ -27,14 +27,12 @@ MockObserver() = default; ~MockObserver() override = default; - MOCK_METHOD(void, - OnPipWindowIdChanged, - (std::optional<NativeWindowId>), - (override)); MOCK_METHOD( void, - OnCapturesChanged, - (const std::vector<PipScreenCaptureCoordinatorProxy::CaptureInfo>&), + OnStateChanged, + (std::optional<NativeWindowId>, + const GlobalRenderFrameHostId&, + const std::vector<PipScreenCaptureCoordinatorProxy::CaptureInfo>&), (override)); }; @@ -43,31 +41,32 @@ MockProxyObserver() = default; ~MockProxyObserver() override = default; - MOCK_METHOD(void, - OnPipWindowIdChanged, - (const std::optional<NativeWindowId>&), - (override)); MOCK_METHOD( void, - OnCapturesChanged, - (const std::vector<PipScreenCaptureCoordinatorProxy::CaptureInfo>&), + OnStateChanged, + ((const std::optional<NativeWindowId>&), + (const GlobalRenderFrameHostId&), + (const std::vector<PipScreenCaptureCoordinatorProxy::CaptureInfo>&)), (override)); }; void CallOnPipShownAndWaitUntilDone( content::BrowserTaskEnvironment& task_environment, PipScreenCaptureCoordinatorImpl* coordinator, - NativeWindowId window_id) { + NativeWindowId window_id, + const GlobalRenderFrameHostId& owner_id) { base::RunLoop run_loop; task_environment.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce( [](PipScreenCaptureCoordinatorImpl* coordinator, - NativeWindowId window_id, base::OnceClosure quit_closure) { - coordinator->OnPipShown(window_id); + NativeWindowId window_id, const GlobalRenderFrameHostId& owner_id, + base::OnceClosure quit_closure) { + coordinator->OnPipShown(window_id, owner_id); std::move(quit_closure).Run(); }, - base::Unretained(coordinator), window_id, run_loop.QuitClosure())); + base::Unretained(coordinator), window_id, owner_id, + run_loop.QuitClosure())); run_loop.Run(); } @@ -76,8 +75,10 @@ PipScreenCaptureCoordinatorImpl* coordinator, MockProxyObserver& observer) { base::RunLoop run_loop; - EXPECT_CALL(observer, OnPipWindowIdChanged(std::optional<NativeWindowId>())) - .WillOnce([&run_loop](const auto&) { run_loop.Quit(); }); + EXPECT_CALL(observer, OnStateChanged(std::optional<NativeWindowId>(), _, _)) + .WillOnce([&run_loop](const auto&, const auto&, const auto&) { + run_loop.Quit(); + }); task_environment.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce( [](PipScreenCaptureCoordinatorImpl* coordinator) { @@ -91,16 +92,22 @@ content::BrowserTaskEnvironment& task_environment, PipScreenCaptureCoordinatorImpl* coordinator, MockProxyObserver& observer, - const std::optional<NativeWindowId>& new_pip_window_id) { + const std::optional<NativeWindowId>& new_pip_window_id, + const GlobalRenderFrameHostId& new_pip_owner_id) { base::RunLoop run_loop; - EXPECT_CALL(observer, OnPipWindowIdChanged(new_pip_window_id)) - .WillOnce([&run_loop](const auto&) { run_loop.Quit(); }); + EXPECT_CALL(observer, OnStateChanged(new_pip_window_id, new_pip_owner_id, _)) + .WillOnce([&run_loop](const auto&, const auto&, const auto&) { + run_loop.Quit(); + }); task_environment.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce( [](PipScreenCaptureCoordinatorImpl* coordinator, - NativeWindowId window_id) { coordinator->OnPipShown(window_id); }, - base::Unretained(coordinator), *new_pip_window_id)); + NativeWindowId window_id, + const GlobalRenderFrameHostId& owner_id) { + coordinator->OnPipShown(window_id, owner_id); + }, + base::Unretained(coordinator), *new_pip_window_id, new_pip_owner_id)); run_loop.Run(); } @@ -121,15 +128,21 @@ raw_ptr<PipScreenCaptureCoordinatorImpl> coordinator_; }; -TEST_F(PipScreenCaptureCoordinatorImplTest, PipWindowId) { +TEST_F(PipScreenCaptureCoordinatorImplTest, PipStateAccessors) { EXPECT_EQ(coordinator_->PipWindowId(), std::nullopt); + EXPECT_EQ(coordinator_->GetPipOwnerRenderFrameHostId(), + GlobalRenderFrameHostId()); const NativeWindowId pip_window_id = 123; - coordinator_->OnPipShown(pip_window_id); + const GlobalRenderFrameHostId pip_owner_id(1, 1); + coordinator_->OnPipShown(pip_window_id, pip_owner_id); EXPECT_EQ(coordinator_->PipWindowId(), pip_window_id); + EXPECT_EQ(coordinator_->GetPipOwnerRenderFrameHostId(), pip_owner_id); coordinator_->OnPipClosed(); EXPECT_EQ(coordinator_->PipWindowId(), std::nullopt); + EXPECT_EQ(coordinator_->GetPipOwnerRenderFrameHostId(), + GlobalRenderFrameHostId()); } TEST_F(PipScreenCaptureCoordinatorImplTest, OnPipShownNotifiesObservers) { @@ -137,15 +150,16 @@ coordinator_->AddObserver(&observer); const NativeWindowId pip_window_id = 123; - EXPECT_CALL(observer, - OnPipWindowIdChanged(std::make_optional(pip_window_id))); - coordinator_->OnPipShown(pip_window_id); + const GlobalRenderFrameHostId pip_owner_id(1, 1); + EXPECT_CALL(observer, OnStateChanged(std::make_optional(pip_window_id), + pip_owner_id, _)); + coordinator_->OnPipShown(pip_window_id, pip_owner_id); EXPECT_EQ(coordinator_->PipWindowId(), pip_window_id); // Calling again with the same ID should not notify. - EXPECT_CALL(observer, OnPipWindowIdChanged(_)).Times(0); - coordinator_->OnPipShown(pip_window_id); + EXPECT_CALL(observer, OnStateChanged(_, _, _)).Times(0); + coordinator_->OnPipShown(pip_window_id, pip_owner_id); coordinator_->RemoveObserver(&observer); } @@ -155,12 +169,14 @@ coordinator_->AddObserver(&observer); const NativeWindowId pip_window_id = 123; - EXPECT_CALL(observer, - OnPipWindowIdChanged(std::make_optional(pip_window_id))); - coordinator_->OnPipShown(pip_window_id); + const GlobalRenderFrameHostId pip_owner_id(1, 1); + EXPECT_CALL(observer, OnStateChanged(std::make_optional(pip_window_id), + pip_owner_id, _)); + coordinator_->OnPipShown(pip_window_id, pip_owner_id); testing::Mock::VerifyAndClearExpectations(&observer); - EXPECT_CALL(observer, OnPipWindowIdChanged(testing::Eq(std::nullopt))); + EXPECT_CALL(observer, OnStateChanged(testing::Eq(std::nullopt), + GlobalRenderFrameHostId(), _)); coordinator_->OnPipClosed(); coordinator_->RemoveObserver(&observer); @@ -174,21 +190,23 @@ coordinator_->AddObserver(&observer2); const NativeWindowId pip_window_id = 123; - EXPECT_CALL(observer1, - OnPipWindowIdChanged(std::make_optional(pip_window_id))); - EXPECT_CALL(observer2, - OnPipWindowIdChanged(std::make_optional(pip_window_id))); - coordinator_->OnPipShown(pip_window_id); + const GlobalRenderFrameHostId pip_owner_id(1, 1); + EXPECT_CALL(observer1, OnStateChanged(std::make_optional(pip_window_id), + pip_owner_id, _)); + EXPECT_CALL(observer2, OnStateChanged(std::make_optional(pip_window_id), + pip_owner_id, _)); + coordinator_->OnPipShown(pip_window_id, pip_owner_id); testing::Mock::VerifyAndClearExpectations(&observer1); testing::Mock::VerifyAndClearExpectations(&observer2); coordinator_->RemoveObserver(&observer1); const NativeWindowId new_pip_window_id = 456; - EXPECT_CALL(observer1, OnPipWindowIdChanged(_)).Times(0); - EXPECT_CALL(observer2, - OnPipWindowIdChanged(std::make_optional(new_pip_window_id))); - coordinator_->OnPipShown(new_pip_window_id); + const GlobalRenderFrameHostId new_pip_owner_id(2, 2); + EXPECT_CALL(observer1, OnStateChanged(_, _, _)).Times(0); + EXPECT_CALL(observer2, OnStateChanged(std::make_optional(new_pip_window_id), + new_pip_owner_id, _)); + coordinator_->OnPipShown(new_pip_window_id, new_pip_owner_id); coordinator_->RemoveObserver(&observer2); } @@ -196,8 +214,9 @@ TEST_F(PipScreenCaptureCoordinatorImplTest, CreateProxy) { // The proxy should start with the current ID. const NativeWindowId pip_window_id = 123; - CallOnPipShownAndWaitUntilDone(task_environment_, coordinator_, - pip_window_id); + const GlobalRenderFrameHostId pip_owner_id(1, 1); + CallOnPipShownAndWaitUntilDone(task_environment_, coordinator_, pip_window_id, + pip_owner_id); auto proxy = coordinator_->CreateProxy(); ASSERT_TRUE(proxy); @@ -205,16 +224,20 @@ MockProxyObserver observer; proxy->AddObserver(&observer); EXPECT_EQ(proxy->PipWindowId(), pip_window_id); + EXPECT_EQ(proxy->GetPipOwnerRenderFrameHostId(), pip_owner_id); // The proxy should be updated when the ID changes. const std::optional<NativeWindowId> new_pip_window_id = 456; + const GlobalRenderFrameHostId new_pip_owner_id(2, 2); CallOnPipShownAndWaitForObserver(task_environment_, coordinator_, observer, - new_pip_window_id); + new_pip_window_id, new_pip_owner_id); EXPECT_EQ(proxy->PipWindowId(), new_pip_window_id); + EXPECT_EQ(proxy->GetPipOwnerRenderFrameHostId(), new_pip_owner_id); // The proxy should be updated when the pip window is closed. CallOnPipClosedAndWaitForObserver(task_environment_, coordinator_, observer); EXPECT_EQ(proxy->PipWindowId(), std::nullopt); + EXPECT_EQ(proxy->GetPipOwnerRenderFrameHostId(), GlobalRenderFrameHostId()); proxy->RemoveObserver(&observer); } @@ -233,8 +256,9 @@ .render_frame_host_id = render_frame_host_id, .desktop_media_id = desktop_media_id}; - EXPECT_CALL(observer, OnCapturesChanged(testing::ElementsAre( - testing::Eq(std::ref(expected_capture_info))))); + EXPECT_CALL(observer, OnStateChanged(_, _, + testing::ElementsAre(testing::Eq( + std::ref(expected_capture_info))))); coordinator_->AddCapture(expected_capture_info); coordinator_->RemoveObserver(&observer); @@ -254,11 +278,11 @@ .render_frame_host_id = render_frame_host_id, .desktop_media_id = desktop_media_id}; - EXPECT_CALL(observer, OnCapturesChanged(_)).Times(1); + EXPECT_CALL(observer, OnStateChanged(_, _, _)).Times(1); coordinator_->AddCapture(expected_capture_info); testing::Mock::VerifyAndClearExpectations(&observer); - EXPECT_CALL(observer, OnCapturesChanged(testing::IsEmpty())); + EXPECT_CALL(observer, OnStateChanged(_, _, testing::IsEmpty())); coordinator_->RemoveCapture(session_id); coordinator_->RemoveObserver(&observer); @@ -288,23 +312,28 @@ .render_frame_host_id = render_frame_host_id2, .desktop_media_id = desktop_media_id2}; - EXPECT_CALL(observer, OnCapturesChanged(testing::ElementsAre( - testing::Eq(std::ref(expected_capture_info1))))); + EXPECT_CALL(observer, OnStateChanged(_, _, + testing::ElementsAre(testing::Eq( + std::ref(expected_capture_info1))))); coordinator_->AddCapture(expected_capture_info1); testing::Mock::VerifyAndClearExpectations(&observer); - EXPECT_CALL(observer, OnCapturesChanged(testing::UnorderedElementsAre( - testing::Eq(std::ref(expected_capture_info1)), - testing::Eq(std::ref(expected_capture_info2))))); + EXPECT_CALL( + observer, + OnStateChanged(_, _, + testing::UnorderedElementsAre( + testing::Eq(std::ref(expected_capture_info1)), + testing::Eq(std::ref(expected_capture_info2))))); coordinator_->AddCapture(expected_capture_info2); testing::Mock::VerifyAndClearExpectations(&observer); - EXPECT_CALL(observer, OnCapturesChanged(testing::ElementsAre( - testing::Eq(std::ref(expected_capture_info2))))); + EXPECT_CALL(observer, OnStateChanged(_, _, + testing::ElementsAre(testing::Eq( + std::ref(expected_capture_info2))))); coordinator_->RemoveCapture(session_id1); testing::Mock::VerifyAndClearExpectations(&observer); - EXPECT_CALL(observer, OnCapturesChanged(testing::IsEmpty())); + EXPECT_CALL(observer, OnStateChanged(_, _, testing::IsEmpty())); coordinator_->RemoveCapture(session_id2); coordinator_->RemoveObserver(&observer); @@ -339,36 +368,51 @@ { base::RunLoop run_loop; - EXPECT_CALL(observer, OnCapturesChanged(testing::ElementsAre( - testing::Eq(std::ref(expected_capture_info1))))) - .WillOnce([&run_loop](const auto&) { run_loop.Quit(); }); + EXPECT_CALL(observer, + OnStateChanged(_, _, + testing::ElementsAre(testing::Eq( + std::ref(expected_capture_info1))))) + .WillOnce([&run_loop](const auto&, const auto&, const auto&) { + run_loop.Quit(); + }); PipScreenCaptureCoordinatorImpl::AddCapture(expected_capture_info1); run_loop.Run(); } { base::RunLoop run_loop; - EXPECT_CALL(observer, OnCapturesChanged(testing::UnorderedElementsAre( - testing::Eq(std::ref(expected_capture_info1)), - testing::Eq(std::ref(expected_capture_info2))))) - .WillOnce([&run_loop](const auto&) { run_loop.Quit(); }); + EXPECT_CALL( + observer, + OnStateChanged(_, _, + testing::UnorderedElementsAre( + testing::Eq(std::ref(expected_capture_info1)), + testing::Eq(std::ref(expected_capture_info2))))) + .WillOnce([&run_loop](const auto&, const auto&, const auto&) { + run_loop.Quit(); + }); PipScreenCaptureCoordinatorImpl::AddCapture(expected_capture_info2); run_loop.Run(); } { base::RunLoop run_loop; - EXPECT_CALL(observer, OnCapturesChanged(testing::ElementsAre( - testing::Eq(std::ref(expected_capture_info2))))) - .WillOnce([&run_loop](const auto&) { run_loop.Quit(); }); + EXPECT_CALL(observer, + OnStateChanged(_, _, + testing::ElementsAre(testing::Eq( + std::ref(expected_capture_info2))))) + .WillOnce([&run_loop](const auto&, const auto&, const auto&) { + run_loop.Quit(); + }); PipScreenCaptureCoordinatorImpl::RemoveCapture(session_id1); run_loop.Run(); } { base::RunLoop run_loop; - EXPECT_CALL(observer, OnCapturesChanged(testing::IsEmpty())) - .WillOnce([&run_loop](const auto&) { run_loop.Quit(); }); + EXPECT_CALL(observer, OnStateChanged(_, _, testing::IsEmpty())) + .WillOnce([&run_loop](const auto&, const auto&, const auto&) { + run_loop.Quit(); + }); PipScreenCaptureCoordinatorImpl::RemoveCapture(session_id2); run_loop.Run(); }
diff --git a/content/browser/media/capture/pip_screen_capture_coordinator_proxy.h b/content/browser/media/capture/pip_screen_capture_coordinator_proxy.h index f99c103b..5b9a237 100644 --- a/content/browser/media/capture/pip_screen_capture_coordinator_proxy.h +++ b/content/browser/media/capture/pip_screen_capture_coordinator_proxy.h
@@ -33,9 +33,9 @@ class Observer : public base::CheckedObserver { public: - virtual void OnPipWindowIdChanged( - const std::optional<NativeWindowId>& new_pip_window_id) = 0; - virtual void OnCapturesChanged( + virtual void OnStateChanged( + const std::optional<NativeWindowId>& new_pip_window_id, + const GlobalRenderFrameHostId& new_pip_owner_render_frame_host_id, const std::vector<CaptureInfo>& captures) = 0; }; @@ -43,6 +43,7 @@ // Returns the tracked PiP window ID. virtual std::optional<NativeWindowId> PipWindowId() const = 0; + virtual GlobalRenderFrameHostId GetPipOwnerRenderFrameHostId() const = 0; virtual const std::vector<CaptureInfo>& Captures() const = 0; virtual void AddObserver(Observer* observer) = 0;
diff --git a/content/browser/media/capture/pip_screen_capture_coordinator_proxy_impl.cc b/content/browser/media/capture/pip_screen_capture_coordinator_proxy_impl.cc index 67dd48cc..9614cdd 100644 --- a/content/browser/media/capture/pip_screen_capture_coordinator_proxy_impl.cc +++ b/content/browser/media/capture/pip_screen_capture_coordinator_proxy_impl.cc
@@ -36,29 +36,24 @@ coordinator_->AddObserver(this); // Update the proxy with the latest state - OnPipWindowIdChanged(coordinator_->PipWindowId()); - OnCapturesChanged(coordinator_->Captures()); + OnStateChanged(coordinator_->PipWindowId(), + coordinator_->GetPipOwnerRenderFrameHostId(), + coordinator_->Captures()); } } // PipScreenCaptureCoordinatorImpl::Observer: - void OnPipWindowIdChanged( - std::optional<NativeWindowId> new_pip_window_id) override { - DCHECK_CALLED_ON_VALID_SEQUENCE(ui_thread_sequence_checker_); - proxy_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&PipScreenCaptureCoordinatorProxyImpl::SetPipWindowId, - proxy_, new_pip_window_id)); - } - - void OnCapturesChanged( + void OnStateChanged( + std::optional<NativeWindowId> new_pip_window_id, + const GlobalRenderFrameHostId& new_pip_owner_render_frame_host_id, const std::vector<PipScreenCaptureCoordinatorProxy::CaptureInfo>& captures) override { DCHECK_CALLED_ON_VALID_SEQUENCE(ui_thread_sequence_checker_); proxy_task_runner_->PostTask( FROM_HERE, - base::BindOnce(&PipScreenCaptureCoordinatorProxyImpl::SetCaptures, - proxy_, captures)); + base::BindOnce(&PipScreenCaptureCoordinatorProxyImpl::UpdateState, + proxy_, new_pip_window_id, + new_pip_owner_render_frame_host_id, captures)); } private: @@ -71,9 +66,11 @@ PipScreenCaptureCoordinatorProxyImpl::PipScreenCaptureCoordinatorProxyImpl( base::WeakPtr<PipScreenCaptureCoordinatorImpl> coordinator, std::optional<NativeWindowId> initial_pip_window_id, + GlobalRenderFrameHostId initial_pip_owner_render_frame_host_id, const std::vector<CaptureInfo>& initial_captures) : coordinator_(std::move(coordinator)), pip_window_id_(initial_pip_window_id), + pip_owner_render_frame_host_id_(initial_pip_owner_render_frame_host_id), captures_(initial_captures), ui_thread_observer_( nullptr, @@ -95,6 +92,12 @@ return pip_window_id_; } +GlobalRenderFrameHostId +PipScreenCaptureCoordinatorProxyImpl::GetPipOwnerRenderFrameHostId() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return pip_owner_render_frame_host_id_; +} + const std::vector<PipScreenCaptureCoordinatorProxy::CaptureInfo>& PipScreenCaptureCoordinatorProxyImpl::Captures() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -136,27 +139,22 @@ } } -void PipScreenCaptureCoordinatorProxyImpl::SetPipWindowId( - const std::optional<NativeWindowId>& new_pip_window_id) { +void PipScreenCaptureCoordinatorProxyImpl::UpdateState( + const std::optional<NativeWindowId>& new_pip_window_id, + const GlobalRenderFrameHostId& new_pip_owner_render_frame_host_id, + const std::vector<CaptureInfo>& new_captures) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (pip_window_id_ == new_pip_window_id) { + if (pip_window_id_ == new_pip_window_id && + pip_owner_render_frame_host_id_ == new_pip_owner_render_frame_host_id && + captures_ == new_captures) { return; } pip_window_id_ = new_pip_window_id; + pip_owner_render_frame_host_id_ = new_pip_owner_render_frame_host_id; + captures_ = new_captures; for (Observer& obs : observers_) { - obs.OnPipWindowIdChanged(pip_window_id_); - } -} - -void PipScreenCaptureCoordinatorProxyImpl::SetCaptures( - const std::vector<CaptureInfo>& captures) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (captures_ == captures) { - return; - } - captures_ = captures; - for (Observer& obs : observers_) { - obs.OnCapturesChanged(captures_); + obs.OnStateChanged(pip_window_id_, pip_owner_render_frame_host_id_, + captures_); } }
diff --git a/content/browser/media/capture/pip_screen_capture_coordinator_proxy_impl.h b/content/browser/media/capture/pip_screen_capture_coordinator_proxy_impl.h index d1778036..ed158d9 100644 --- a/content/browser/media/capture/pip_screen_capture_coordinator_proxy_impl.h +++ b/content/browser/media/capture/pip_screen_capture_coordinator_proxy_impl.h
@@ -21,11 +21,13 @@ PipScreenCaptureCoordinatorProxyImpl( base::WeakPtr<PipScreenCaptureCoordinatorImpl> coordinator, std::optional<NativeWindowId> initial_pip_window_id, + GlobalRenderFrameHostId initial_pip_owner_render_frame_host_id, const std::vector<CaptureInfo>& initial_captures); ~PipScreenCaptureCoordinatorProxyImpl() override; std::optional<NativeWindowId> PipWindowId() const override; + GlobalRenderFrameHostId GetPipOwnerRenderFrameHostId() const override; const std::vector<CaptureInfo>& Captures() const override; void AddObserver(Observer* observer) override; @@ -35,13 +37,17 @@ class UiThreadObserver; friend class UiThreadObserver; - void SetPipWindowId(const std::optional<NativeWindowId>& new_pip_window_id); - void SetCaptures(const std::vector<CaptureInfo>& captures); + void UpdateState( + const std::optional<NativeWindowId>& new_pip_window_id, + const GlobalRenderFrameHostId& new_pip_owner_render_frame_host_id, + const std::vector<CaptureInfo>& new_captures); base::WeakPtr<PipScreenCaptureCoordinatorImpl> coordinator_ GUARDED_BY_CONTEXT(sequence_checker_); std::optional<NativeWindowId> pip_window_id_ GUARDED_BY_CONTEXT(sequence_checker_); + GlobalRenderFrameHostId pip_owner_render_frame_host_id_ + GUARDED_BY_CONTEXT(sequence_checker_); std::vector<CaptureInfo> captures_ GUARDED_BY_CONTEXT(sequence_checker_); scoped_refptr<base::SequencedTaskRunner> bound_sequence_task_runner_ GUARDED_BY_CONTEXT(sequence_checker_);
diff --git a/content/browser/media/capture/screen_capture_kit_device_mac.mm b/content/browser/media/capture/screen_capture_kit_device_mac.mm index db54df43..9b666086 100644 --- a/content/browser/media/capture/screen_capture_kit_device_mac.mm +++ b/content/browser/media/capture/screen_capture_kit_device_mac.mm
@@ -585,8 +585,11 @@ } // PipScreenCaptureCoordinatorProxy::Observer: - void OnPipWindowIdChanged( - const std::optional<NativeWindowId>& new_pip_window_id) override { + void OnStateChanged( + const std::optional<NativeWindowId>& new_pip_window_id, + const GlobalRenderFrameHostId& new_pip_owner_render_frame_host_id, + const std::vector<PipScreenCaptureCoordinatorProxy::CaptureInfo>& + captures) override { DCHECK(device_task_runner_->RunsTasksInCurrentSequence()); if (!stream_) { @@ -607,9 +610,6 @@ }; [SCShareableContent getShareableContentWithCompletionHandler:handler]; } - void OnCapturesChanged( - const std::vector<PipScreenCaptureCoordinatorProxy::CaptureInfo>& - captures) override {} // IOSurfaceCaptureDeviceBase: void OnStart() override {
diff --git a/content/browser/preloading/prerender/prerender_host_registry.h b/content/browser/preloading/prerender/prerender_host_registry.h index 581b9b9..cc4f2a75 100644 --- a/content/browser/preloading/prerender/prerender_host_registry.h +++ b/content/browser/preloading/prerender/prerender_host_registry.h
@@ -387,8 +387,6 @@ // Hosts that are not reserved for activation yet. This map also includes the // hosts still waiting for their start. - // TODO(crbug.com/40150744): Expire prerendered contents if they are - // not used for a while. base::flat_map<FrameTreeNodeId, std::unique_ptr<PrerenderHost>> prerender_host_by_frame_tree_node_id_;
diff --git a/content/browser/preloading/prerenderer_impl.cc b/content/browser/preloading/prerenderer_impl.cc index 00957881..cb5a5b18 100644 --- a/content/browser/preloading/prerenderer_impl.cc +++ b/content/browser/preloading/prerenderer_impl.cc
@@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/feature_list.h" #include "base/strings/stringprintf.h" +#include "base/trace_event/named_trigger.h" #include "content/browser/preloading/prefetch/no_vary_search_helper.h" #include "content/browser/preloading/prefetch/prefetch_document_manager.h" #include "content/browser/preloading/preloading.h" @@ -446,6 +447,9 @@ case blink::mojom::SpeculationTargetHint::kSelf: { if (base::FeatureList::IsEnabled( features::kPrerender2FallbackPrefetchSpecRules)) { + base::trace_event::EmitNamedTrigger( + "specrules-prerender-trigger-prefetch"); + auto* prefetch_document_manager = content::PrefetchDocumentManager::GetOrCreateForCurrentDocument( web_contents->GetPrimaryMainFrame());
diff --git a/content/renderer/webgraphicscontext3d_provider_impl.cc b/content/renderer/webgraphicscontext3d_provider_impl.cc index 17d5081..1d89abeb 100644 --- a/content/renderer/webgraphicscontext3d_provider_impl.cc +++ b/content/renderer/webgraphicscontext3d_provider_impl.cc
@@ -163,7 +163,6 @@ cc::ImageDecodeCache* WebGraphicsContext3DProviderImpl::ImageDecodeCache( SkColorType color_type) { - CHECK(GetCapabilities().gpu_rasterization); auto cache_iterator = image_decode_cache_map_.find(color_type); if (cache_iterator != image_decode_cache_map_.end()) return cache_iterator->second.get();
diff --git a/docs/website b/docs/website index 105a469..1e6b908 160000 --- a/docs/website +++ b/docs/website
@@ -1 +1 @@ -Subproject commit 105a46915f47f94998e4a3084520835f24ea5a6c +Subproject commit 1e6b9080b485c33e823208661cebb5e1f470960c
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 321f8be..04efc21 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -3890,9 +3890,9 @@ } UNSAFE_TODO(source += num_rows * pixels_padded_row_size); if (unpack_image_height_ > height && num_image_paddings > 0) { - UNSAFE_TODO(source += - num_image_paddings * (unpack_image_height_ - height)) * - pixels_padded_row_size; + UNSAFE_TODO(source += num_image_paddings * + (unpack_image_height_ - height) * + pixels_padded_row_size); } } }
diff --git a/gpu/command_buffer/client/internal/mappable_buffer_dxgi.cc b/gpu/command_buffer/client/internal/mappable_buffer_dxgi.cc index 2f538d3..e047bace 100644 --- a/gpu/command_buffer/client/internal/mappable_buffer_dxgi.cc +++ b/gpu/command_buffer/client/internal/mappable_buffer_dxgi.cc
@@ -226,8 +226,8 @@ .data(); // This is safe, since we already checked that the requested plane is // valid for current format. - UNSAFE_TODO(plane_addr += viz)::SharedMemoryOffsetForSharedImageFormat( - format_, plane, size_); + UNSAFE_TODO(plane_addr += viz::SharedMemoryOffsetForSharedImageFormat( + format_, plane, size_)); return plane_addr; }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 0bb2581f..2c42b6b 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -11368,8 +11368,7 @@ copy_binder = std::make_unique<ScopedFramebufferCopyBinder>(this); } if (y < 0) { - UNSAFE_TODO(pixels += static_cast<uint32_t>(-y)) * padded_row_size; - ; + UNSAFE_TODO(pixels += static_cast<uint32_t>(-y) * padded_row_size); } if (x < 0) { uint32_t group_size = GLES2Util::ComputeImageGroupSize(format, type);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc index d9fe1d60..2e65e4e 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc
@@ -982,7 +982,7 @@ EXPECT_CALL(*gl_, PixelStorei(GL_PACK_ALIGNMENT, 1)) .Times(1) .RetiresOnSaturation(); - UNSAFE_TODO(offset += (kWidth * kBytesPerPixel + kPadding)) * (kHeight - 1); + UNSAFE_TODO(offset += (kWidth * kBytesPerPixel + kPadding) * (kHeight - 1)); EXPECT_CALL(*gl_, ReadPixels(0, kHeight - 1, kWidth, 1, kFormat, kType, offset)) .Times(1)
diff --git a/gpu/config/software_rendering_list.json b/gpu/config/software_rendering_list.json index a4ca69c..33d51c5 100644 --- a/gpu/config/software_rendering_list.json +++ b/gpu/config/software_rendering_list.json
@@ -1450,15 +1450,15 @@ }, { "id": 184, - "cr_bugs": [383521542], + "cr_bugs": [383521542, 458062283], "description": "Disable Graphite on very old Intel drivers", "os": { "type": "win" }, "vendor_id": "0x8086", "driver_version": { - "op": "<=", - "value": "10.18.10.5161" + "op": "<", + "value": "31.0.101.2121" }, "features": [ "skia_graphite" @@ -1492,6 +1492,22 @@ "features": [ "webgpu_on_vk_via_gl_interop" ] + }, + { + "id": 187, + "cr_bugs": [458062283], + "description": "Disable Graphite on very old Intel GPU generations due to crashiness", + "os": { + "type": "win" + }, + "vendor_id": "0x8086", + "intel_gpu_generation": { + "op": "<=", + "value": "8" + }, + "features": [ + "skia_graphite" + ] } ] }
diff --git a/infra/config/autoshard_exceptions.json b/infra/config/autoshard_exceptions.json index 950b0f9..e7abb05e 100644 --- a/infra/config/autoshard_exceptions.json +++ b/infra/config/autoshard_exceptions.json
@@ -190,7 +190,7 @@ "try_builder": "linux_chromium_asan_rel_ng" }, "sync_integration_tests": { - "shards": 13, + "shards": 12, "try_builder": "linux_chromium_asan_rel_ng" }, "unit_tests": {
diff --git a/infra/config/generated/builders/alerting-builders.txt b/infra/config/generated/builders/alerting-builders.txt index 07edc79c..8a30bdf1 100644 --- a/infra/config/generated/builders/alerting-builders.txt +++ b/infra/config/generated/builders/alerting-builders.txt
@@ -330,6 +330,7 @@ ci/chromeos-arm64-generic-rel ci/chromeos-jacuzzi-rel ci/chromeos-octopus-rel +ci/chromeos-x64-libfuzzer-asan-rel-tests ci/fuchsia-angle-builder ci/fuchsia-arm64-cast-receiver-rel ci/fuchsia-fyi-arm64-dbg @@ -380,12 +381,19 @@ ci/linux-wayland-weston-rel-tests ci/linux-win-cross-clang-tot-rel ci/linux-win-cross-rel +ci/linux-x64-centipede-asan-rel-tests +ci/linux-x64-libfuzzer-asan-dbg-tests +ci/linux-x64-libfuzzer-asan-rel-tests +ci/linux-x64-libfuzzer-msan-rel-tests +ci/linux-x64-libfuzzer-ubsan-rel-tests +ci/linux-x86-libfuzzer-asan-rel-tests ci/mac-angle-chromium-amd ci/mac-angle-chromium-builder ci/mac-angle-chromium-intel ci/mac-archive-rel ci/mac-arm64-archive-rel ci/mac-arm64-dbg +ci/mac-arm64-libfuzzer-asan-rel-tests ci/mac-arm64-on-arm64-rel ci/mac-arm64-rel ci/mac-official @@ -410,6 +418,7 @@ ci/win-swangle-tot-swiftshader-x86 ci/win-swangle-x64 ci/win-swangle-x86 +ci/win-x64-libfuzzer-asan-rel-tests ci/win10-angle-chromium-x64-intel ci/win10-angle-chromium-x64-nvidia ci/win11-arm64-rel-tests @@ -497,6 +506,7 @@ try/chromeos-js-coverage-rel try/chromeos-libfuzzer-asan-rel try/chromeos-octopus-rel +try/chromeos-x64-libfuzzer-asan-rel-tests try/compile-size try/fuchsia-angle-try try/fuchsia-arm64-cast-receiver-rel @@ -639,6 +649,12 @@ try/linux-wayland-mutter-rel try/linux-wayland-weston-rel try/linux-win-cross-rel +try/linux-x64-centipede-asan-rel-tests +try/linux-x64-libfuzzer-asan-dbg-tests +try/linux-x64-libfuzzer-asan-rel-tests +try/linux-x64-libfuzzer-msan-rel-tests +try/linux-x64-libfuzzer-ubsan-rel-tests +try/linux-x86-libfuzzer-asan-rel-tests try/linux_chromium_archive_rel_ng try/linux_chromium_asan_rel_ng try/linux_chromium_cfi_rel_ng @@ -652,6 +668,7 @@ try/linux_chromium_ubsan_rel_ng try/mac-angle-chromium-try try/mac-arm64-clobber-rel +try/mac-arm64-libfuzzer-asan-rel-tests try/mac-arm64-on-arm64-rel try/mac-asan-media-rel try/mac-asan-rel @@ -713,6 +730,7 @@ try/win-updater-try-builder-dbg try/win-updater-try-builder-rel try/win-utr-tester +try/win-x64-libfuzzer-asan-rel-tests try/win10-dbg try/win11-rel try/win32-clobber-rel
diff --git a/infra/config/generated/builders/ci/Linux ASan LSan Builder/targets/chromium.memory.json b/infra/config/generated/builders/ci/Linux ASan LSan Builder/targets/chromium.memory.json index a7dc77b..6eb011a 100644 --- a/infra/config/generated/builders/ci/Linux ASan LSan Builder/targets/chromium.memory.json +++ b/infra/config/generated/builders/ci/Linux ASan LSan Builder/targets/chromium.memory.json
@@ -1503,7 +1503,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 13 + "shards": 12 }, "test": "sync_integration_tests", "test_id_prefix": "ninja://chrome/test:sync_integration_tests/"
diff --git "a/infra/config/generated/builders/ci/Linux ASan LSan Tests \0501\051/targets/chromium.memory.json" "b/infra/config/generated/builders/ci/Linux ASan LSan Tests \0501\051/targets/chromium.memory.json" index a7dc77b..6eb011a 100644 --- "a/infra/config/generated/builders/ci/Linux ASan LSan Tests \0501\051/targets/chromium.memory.json" +++ "b/infra/config/generated/builders/ci/Linux ASan LSan Tests \0501\051/targets/chromium.memory.json"
@@ -1503,7 +1503,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 13 + "shards": 12 }, "test": "sync_integration_tests", "test_id_prefix": "ninja://chrome/test:sync_integration_tests/"
diff --git a/infra/config/generated/builders/ci/chromeos-x64-libfuzzer-asan-rel-tests/properties.json b/infra/config/generated/builders/ci/chromeos-x64-libfuzzer-asan-rel-tests/properties.json index cfc544e..7f3f869 100644 --- a/infra/config/generated/builders/ci/chromeos-x64-libfuzzer-asan-rel-tests/properties.json +++ b/infra/config/generated/builders/ci/chromeos-x64-libfuzzer-asan-rel-tests/properties.json
@@ -72,5 +72,11 @@ ] }, "builder_group": "chromium.fuzz", - "recipe": "chromium" + "gardener_rotations": [ + "chromium" + ], + "recipe": "chromium", + "sheriff_rotations": [ + "chromium" + ] } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-x64-centipede-asan-rel-tests/properties.json b/infra/config/generated/builders/ci/linux-x64-centipede-asan-rel-tests/properties.json index ba38522..24b8f5a 100644 --- a/infra/config/generated/builders/ci/linux-x64-centipede-asan-rel-tests/properties.json +++ b/infra/config/generated/builders/ci/linux-x64-centipede-asan-rel-tests/properties.json
@@ -69,5 +69,11 @@ ] }, "builder_group": "chromium.fuzz", - "recipe": "chromium" + "gardener_rotations": [ + "chromium" + ], + "recipe": "chromium", + "sheriff_rotations": [ + "chromium" + ] } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-x64-libfuzzer-asan-dbg-tests/properties.json b/infra/config/generated/builders/ci/linux-x64-libfuzzer-asan-dbg-tests/properties.json index eb5b6f0..77d9582 100644 --- a/infra/config/generated/builders/ci/linux-x64-libfuzzer-asan-dbg-tests/properties.json +++ b/infra/config/generated/builders/ci/linux-x64-libfuzzer-asan-dbg-tests/properties.json
@@ -69,5 +69,11 @@ ] }, "builder_group": "chromium.fuzz", - "recipe": "chromium" + "gardener_rotations": [ + "chromium" + ], + "recipe": "chromium", + "sheriff_rotations": [ + "chromium" + ] } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-x64-libfuzzer-asan-rel-tests/properties.json b/infra/config/generated/builders/ci/linux-x64-libfuzzer-asan-rel-tests/properties.json index 2177e5f..fd76981 100644 --- a/infra/config/generated/builders/ci/linux-x64-libfuzzer-asan-rel-tests/properties.json +++ b/infra/config/generated/builders/ci/linux-x64-libfuzzer-asan-rel-tests/properties.json
@@ -69,5 +69,11 @@ ] }, "builder_group": "chromium.fuzz", - "recipe": "chromium" + "gardener_rotations": [ + "chromium" + ], + "recipe": "chromium", + "sheriff_rotations": [ + "chromium" + ] } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-x64-libfuzzer-msan-rel-tests/properties.json b/infra/config/generated/builders/ci/linux-x64-libfuzzer-msan-rel-tests/properties.json index cffc941..76544012 100644 --- a/infra/config/generated/builders/ci/linux-x64-libfuzzer-msan-rel-tests/properties.json +++ b/infra/config/generated/builders/ci/linux-x64-libfuzzer-msan-rel-tests/properties.json
@@ -70,5 +70,11 @@ ] }, "builder_group": "chromium.fuzz", - "recipe": "chromium" + "gardener_rotations": [ + "chromium" + ], + "recipe": "chromium", + "sheriff_rotations": [ + "chromium" + ] } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-x64-libfuzzer-ubsan-rel-tests/properties.json b/infra/config/generated/builders/ci/linux-x64-libfuzzer-ubsan-rel-tests/properties.json index 11a2753d..08b456c 100644 --- a/infra/config/generated/builders/ci/linux-x64-libfuzzer-ubsan-rel-tests/properties.json +++ b/infra/config/generated/builders/ci/linux-x64-libfuzzer-ubsan-rel-tests/properties.json
@@ -69,5 +69,11 @@ ] }, "builder_group": "chromium.fuzz", - "recipe": "chromium" + "gardener_rotations": [ + "chromium" + ], + "recipe": "chromium", + "sheriff_rotations": [ + "chromium" + ] } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-x86-libfuzzer-asan-rel-tests/properties.json b/infra/config/generated/builders/ci/linux-x86-libfuzzer-asan-rel-tests/properties.json index 13777765..61b1d5e 100644 --- a/infra/config/generated/builders/ci/linux-x86-libfuzzer-asan-rel-tests/properties.json +++ b/infra/config/generated/builders/ci/linux-x86-libfuzzer-asan-rel-tests/properties.json
@@ -69,5 +69,11 @@ ] }, "builder_group": "chromium.fuzz", - "recipe": "chromium" + "gardener_rotations": [ + "chromium" + ], + "recipe": "chromium", + "sheriff_rotations": [ + "chromium" + ] } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/mac-arm64-libfuzzer-asan-rel-tests/properties.json b/infra/config/generated/builders/ci/mac-arm64-libfuzzer-asan-rel-tests/properties.json index 26082fd2a..19539f3 100644 --- a/infra/config/generated/builders/ci/mac-arm64-libfuzzer-asan-rel-tests/properties.json +++ b/infra/config/generated/builders/ci/mac-arm64-libfuzzer-asan-rel-tests/properties.json
@@ -70,5 +70,11 @@ ] }, "builder_group": "chromium.fuzz", - "recipe": "chromium" + "gardener_rotations": [ + "chromium" + ], + "recipe": "chromium", + "sheriff_rotations": [ + "chromium" + ] } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/win-x64-libfuzzer-asan-rel-tests/properties.json b/infra/config/generated/builders/ci/win-x64-libfuzzer-asan-rel-tests/properties.json index a15e5e6..76e500e6 100644 --- a/infra/config/generated/builders/ci/win-x64-libfuzzer-asan-rel-tests/properties.json +++ b/infra/config/generated/builders/ci/win-x64-libfuzzer-asan-rel-tests/properties.json
@@ -69,5 +69,11 @@ ] }, "builder_group": "chromium.fuzz", - "recipe": "chromium" + "gardener_rotations": [ + "chromium" + ], + "recipe": "chromium", + "sheriff_rotations": [ + "chromium" + ] } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/linux_chromium_asan_rel_ng/targets/chromium.memory.json b/infra/config/generated/builders/try/linux_chromium_asan_rel_ng/targets/chromium.memory.json index a7dc77b..6eb011a 100644 --- a/infra/config/generated/builders/try/linux_chromium_asan_rel_ng/targets/chromium.memory.json +++ b/infra/config/generated/builders/try/linux_chromium_asan_rel_ng/targets/chromium.memory.json
@@ -1503,7 +1503,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 13 + "shards": 12 }, "test": "sync_integration_tests", "test_id_prefix": "ninja://chrome/test:sync_integration_tests/"
diff --git a/infra/config/generated/cq-usage/mega_cq_bots.txt b/infra/config/generated/cq-usage/mega_cq_bots.txt index 593a8d4..5670f8a3 100644 --- a/infra/config/generated/cq-usage/mega_cq_bots.txt +++ b/infra/config/generated/cq-usage/mega_cq_bots.txt
@@ -71,6 +71,7 @@ chromium/try/chromeos-jacuzzi-rel chromium/try/chromeos-libfuzzer-asan-rel chromium/try/chromeos-octopus-rel +chromium/try/chromeos-x64-libfuzzer-asan-rel-tests chromium/try/fuchsia-arm64-cast-receiver-rel chromium/try/fuchsia-fyi-arm64-dbg chromium/try/fuchsia-fyi-x64-asan @@ -128,6 +129,12 @@ chromium/try/linux-wayland-mutter-rel chromium/try/linux-wayland-weston-rel chromium/try/linux-win-cross-rel +chromium/try/linux-x64-centipede-asan-rel-tests +chromium/try/linux-x64-libfuzzer-asan-dbg-tests +chromium/try/linux-x64-libfuzzer-asan-rel-tests +chromium/try/linux-x64-libfuzzer-msan-rel-tests +chromium/try/linux-x64-libfuzzer-ubsan-rel-tests +chromium/try/linux-x86-libfuzzer-asan-rel-tests chromium/try/linux_chromium_archive_rel_ng chromium/try/linux_chromium_asan_rel_ng chromium/try/linux_chromium_cfi_rel_ng @@ -140,6 +147,7 @@ chromium/try/linux_chromium_tsan_rel_ng chromium/try/linux_chromium_ubsan_rel_ng chromium/try/mac-arm64-clobber-rel +chromium/try/mac-arm64-libfuzzer-asan-rel-tests chromium/try/mac-arm64-on-arm64-rel chromium/try/mac-asan-media-rel chromium/try/mac-asan-rel @@ -168,6 +176,7 @@ chromium/try/win-libfuzzer-asan-rel chromium/try/win-official chromium/try/win-rel +chromium/try/win-x64-libfuzzer-asan-rel-tests chromium/try/win10-dbg chromium/try/win11-rel chromium/try/win32-clobber-rel
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 7e66ecb..7f246074 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -49893,9 +49893,16 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "chromium.fuzz",' + ' "gardener_rotations": [' + ' "chromium"' + ' ],' ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' + ' "recipe": "chromium",' + ' "sheriff_rotations": [' + ' "chromium"' + ' ]' '}' execution_timeout_secs: 21600 build_numbers: YES @@ -49945,6 +49952,11 @@ } contact_team_email: "chrome-fuzzing-core@google.com" custom_metric_definitions { + name: "/chrome/infra/browser/builds/alerts_enabled_count" + predicates: "has(build.input.properties.alerts_enabled)" + predicates: "string(build.input.properties.alerts_enabled) == \"true\"" + } + custom_metric_definitions { name: "/chrome/infra/browser/builds/cached_count" predicates: "has(build.output.properties.is_cached)" predicates: "string(build.output.properties.is_cached) == \"true\"" @@ -61839,9 +61851,16 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "chromium.fuzz",' + ' "gardener_rotations": [' + ' "chromium"' + ' ],' ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' + ' "recipe": "chromium",' + ' "sheriff_rotations": [' + ' "chromium"' + ' ]' '}' execution_timeout_secs: 18000 build_numbers: YES @@ -61891,6 +61910,11 @@ } contact_team_email: "chrome-fuzzing-core@google.com" custom_metric_definitions { + name: "/chrome/infra/browser/builds/alerts_enabled_count" + predicates: "has(build.input.properties.alerts_enabled)" + predicates: "string(build.input.properties.alerts_enabled) == \"true\"" + } + custom_metric_definitions { name: "/chrome/infra/browser/builds/cached_count" predicates: "has(build.output.properties.is_cached)" predicates: "string(build.output.properties.is_cached) == \"true\"" @@ -62054,9 +62078,16 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "chromium.fuzz",' + ' "gardener_rotations": [' + ' "chromium"' + ' ],' ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' + ' "recipe": "chromium",' + ' "sheriff_rotations": [' + ' "chromium"' + ' ]' '}' execution_timeout_secs: 14400 build_numbers: YES @@ -62106,6 +62137,11 @@ } contact_team_email: "chrome-fuzzing-core@google.com" custom_metric_definitions { + name: "/chrome/infra/browser/builds/alerts_enabled_count" + predicates: "has(build.input.properties.alerts_enabled)" + predicates: "string(build.input.properties.alerts_enabled) == \"true\"" + } + custom_metric_definitions { name: "/chrome/infra/browser/builds/cached_count" predicates: "has(build.output.properties.is_cached)" predicates: "string(build.output.properties.is_cached) == \"true\"" @@ -62161,9 +62197,16 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "chromium.fuzz",' + ' "gardener_rotations": [' + ' "chromium"' + ' ],' ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' + ' "recipe": "chromium",' + ' "sheriff_rotations": [' + ' "chromium"' + ' ]' '}' execution_timeout_secs: 14400 build_numbers: YES @@ -62213,6 +62256,11 @@ } contact_team_email: "chrome-fuzzing-core@google.com" custom_metric_definitions { + name: "/chrome/infra/browser/builds/alerts_enabled_count" + predicates: "has(build.input.properties.alerts_enabled)" + predicates: "string(build.input.properties.alerts_enabled) == \"true\"" + } + custom_metric_definitions { name: "/chrome/infra/browser/builds/cached_count" predicates: "has(build.output.properties.is_cached)" predicates: "string(build.output.properties.is_cached) == \"true\"" @@ -62268,9 +62316,16 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "chromium.fuzz",' + ' "gardener_rotations": [' + ' "chromium"' + ' ],' ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' + ' "recipe": "chromium",' + ' "sheriff_rotations": [' + ' "chromium"' + ' ]' '}' execution_timeout_secs: 10800 build_numbers: YES @@ -62320,6 +62375,11 @@ } contact_team_email: "chrome-fuzzing-core@google.com" custom_metric_definitions { + name: "/chrome/infra/browser/builds/alerts_enabled_count" + predicates: "has(build.input.properties.alerts_enabled)" + predicates: "string(build.input.properties.alerts_enabled) == \"true\"" + } + custom_metric_definitions { name: "/chrome/infra/browser/builds/cached_count" predicates: "has(build.output.properties.is_cached)" predicates: "string(build.output.properties.is_cached) == \"true\"" @@ -62375,9 +62435,16 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "chromium.fuzz",' + ' "gardener_rotations": [' + ' "chromium"' + ' ],' ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' + ' "recipe": "chromium",' + ' "sheriff_rotations": [' + ' "chromium"' + ' ]' '}' execution_timeout_secs: 18000 build_numbers: YES @@ -62427,6 +62494,11 @@ } contact_team_email: "chrome-fuzzing-core@google.com" custom_metric_definitions { + name: "/chrome/infra/browser/builds/alerts_enabled_count" + predicates: "has(build.input.properties.alerts_enabled)" + predicates: "string(build.input.properties.alerts_enabled) == \"true\"" + } + custom_metric_definitions { name: "/chrome/infra/browser/builds/cached_count" predicates: "has(build.output.properties.is_cached)" predicates: "string(build.output.properties.is_cached) == \"true\"" @@ -62482,9 +62554,16 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "chromium.fuzz",' + ' "gardener_rotations": [' + ' "chromium"' + ' ],' ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' + ' "recipe": "chromium",' + ' "sheriff_rotations": [' + ' "chromium"' + ' ]' '}' execution_timeout_secs: 10800 build_numbers: YES @@ -62534,6 +62613,11 @@ } contact_team_email: "chrome-fuzzing-core@google.com" custom_metric_definitions { + name: "/chrome/infra/browser/builds/alerts_enabled_count" + predicates: "has(build.input.properties.alerts_enabled)" + predicates: "string(build.input.properties.alerts_enabled) == \"true\"" + } + custom_metric_definitions { name: "/chrome/infra/browser/builds/cached_count" predicates: "has(build.output.properties.is_cached)" predicates: "string(build.output.properties.is_cached) == \"true\"" @@ -63575,9 +63659,16 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "chromium.fuzz",' + ' "gardener_rotations": [' + ' "chromium"' + ' ],' ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' + ' "recipe": "chromium",' + ' "sheriff_rotations": [' + ' "chromium"' + ' ]' '}' execution_timeout_secs: 10800 build_numbers: YES @@ -63627,6 +63718,11 @@ } contact_team_email: "chrome-fuzzing-core@google.com" custom_metric_definitions { + name: "/chrome/infra/browser/builds/alerts_enabled_count" + predicates: "has(build.input.properties.alerts_enabled)" + predicates: "string(build.input.properties.alerts_enabled) == \"true\"" + } + custom_metric_definitions { name: "/chrome/infra/browser/builds/cached_count" predicates: "has(build.output.properties.is_cached)" predicates: "string(build.output.properties.is_cached) == \"true\"" @@ -72301,9 +72397,16 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "chromium.fuzz",' + ' "gardener_rotations": [' + ' "chromium"' + ' ],' ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' + ' "recipe": "chromium",' + ' "sheriff_rotations": [' + ' "chromium"' + ' ]' '}' execution_timeout_secs: 28800 build_numbers: YES @@ -72353,6 +72456,11 @@ } contact_team_email: "chrome-fuzzing-core@google.com" custom_metric_definitions { + name: "/chrome/infra/browser/builds/alerts_enabled_count" + predicates: "has(build.input.properties.alerts_enabled)" + predicates: "string(build.input.properties.alerts_enabled) == \"true\"" + } + custom_metric_definitions { name: "/chrome/infra/browser/builds/cached_count" predicates: "has(build.output.properties.is_cached)" predicates: "string(build.output.properties.is_cached) == \"true\"" @@ -93365,6 +93473,7 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "tryserver.chromium.fuzz",' ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' @@ -118258,6 +118367,7 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "tryserver.chromium.fuzz",' ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' @@ -118371,6 +118481,7 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "tryserver.chromium.fuzz",' ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' @@ -118484,6 +118595,7 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "tryserver.chromium.fuzz",' ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' @@ -118597,6 +118709,7 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "tryserver.chromium.fuzz",' ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' @@ -118710,6 +118823,7 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "tryserver.chromium.fuzz",' ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' @@ -118823,6 +118937,7 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "tryserver.chromium.fuzz",' ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' @@ -121418,6 +121533,7 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "tryserver.chromium.fuzz",' ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' @@ -132986,6 +133102,7 @@ ' }' ' }' ' },' + ' "alerts_enabled": true,' ' "builder_group": "tryserver.chromium.fuzz",' ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"'
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg index 3a91a9c6..e9ff747 100644 --- a/infra/config/generated/luci/luci-milo.cfg +++ b/infra/config/generated/luci/luci-milo.cfg
@@ -6671,6 +6671,11 @@ short_name: "cent high" } builders { + name: "buildbucket/luci.chromium.ci/linux-x64-centipede-asan-rel-tests" + category: "chromium.fuzz|centipede-tests" + short_name: "cent" + } + builders { name: "buildbucket/luci.chromium.ci/ChromiumOS ASAN Release" category: "chromium.fuzz|cros asan" short_name: "rel" @@ -6741,6 +6746,46 @@ short_name: "win-asan" } builders { + name: "buildbucket/luci.chromium.ci/chromeos-x64-libfuzzer-asan-rel-tests" + category: "chromium.fuzz|libfuzzer-tests" + short_name: "chromeos-asan" + } + builders { + name: "buildbucket/luci.chromium.ci/linux-x64-libfuzzer-asan-rel-tests" + category: "chromium.fuzz|libfuzzer-tests" + short_name: "linux" + } + builders { + name: "buildbucket/luci.chromium.ci/linux-x64-libfuzzer-asan-dbg-tests" + category: "chromium.fuzz|libfuzzer-tests" + short_name: "linux-dbg" + } + builders { + name: "buildbucket/luci.chromium.ci/linux-x64-libfuzzer-msan-rel-tests" + category: "chromium.fuzz|libfuzzer-tests" + short_name: "linux-msan" + } + builders { + name: "buildbucket/luci.chromium.ci/linux-x64-libfuzzer-ubsan-rel-tests" + category: "chromium.fuzz|libfuzzer-tests" + short_name: "linux-ubsan" + } + builders { + name: "buildbucket/luci.chromium.ci/linux-x86-libfuzzer-asan-rel-tests" + category: "chromium.fuzz|libfuzzer-tests" + short_name: "linux32" + } + builders { + name: "buildbucket/luci.chromium.ci/mac-arm64-libfuzzer-asan-rel-tests" + category: "chromium.fuzz|libfuzzer-tests" + short_name: "mac-arm64-asan" + } + builders { + name: "buildbucket/luci.chromium.ci/win-x64-libfuzzer-asan-rel-tests" + category: "chromium.fuzz|libfuzzer-tests" + short_name: "win-asan" + } + builders { name: "buildbucket/luci.chromium.ci/UBSan Release" category: "chromium.fuzz|linux UBSan" short_name: "rel"
diff --git a/infra/config/generated/luci/luci-notify.cfg b/infra/config/generated/luci/luci-notify.cfg index aa41b2097..881ccce1 100644 --- a/infra/config/generated/luci/luci-notify.cfg +++ b/infra/config/generated/luci/luci-notify.cfg
@@ -4758,6 +4758,42 @@ bucket: "ci" name: "Libfuzzer Upload iOS Catalyst Debug" } + builders { + bucket: "ci" + name: "chromeos-x64-libfuzzer-asan-rel-tests" + } + builders { + bucket: "ci" + name: "linux-x64-centipede-asan-rel-tests" + } + builders { + bucket: "ci" + name: "linux-x64-libfuzzer-asan-dbg-tests" + } + builders { + bucket: "ci" + name: "linux-x64-libfuzzer-asan-rel-tests" + } + builders { + bucket: "ci" + name: "linux-x64-libfuzzer-msan-rel-tests" + } + builders { + bucket: "ci" + name: "linux-x64-libfuzzer-ubsan-rel-tests" + } + builders { + bucket: "ci" + name: "linux-x86-libfuzzer-asan-rel-tests" + } + builders { + bucket: "ci" + name: "mac-arm64-libfuzzer-asan-rel-tests" + } + builders { + bucket: "ci" + name: "win-x64-libfuzzer-asan-rel-tests" + } } builder_health_notifier { owner_email: "chrome-gpu-infra@google.com"
diff --git a/infra/config/generated/sheriff-rotations/chromium.txt b/infra/config/generated/sheriff-rotations/chromium.txt index 28838fe..d88f434 100644 --- a/infra/config/generated/sheriff-rotations/chromium.txt +++ b/infra/config/generated/sheriff-rotations/chromium.txt
@@ -77,6 +77,7 @@ ci/chromeos-arm-generic-dbg ci/chromeos-arm-generic-rel ci/chromeos-arm64-generic-rel +ci/chromeos-x64-libfuzzer-asan-rel-tests ci/fuchsia-arm64-cast-receiver-rel ci/fuchsia-x64-cast-receiver-dbg ci/fuchsia-x64-cast-receiver-rel @@ -107,9 +108,16 @@ ci/linux-wayland-mutter-rel-tests ci/linux-wayland-weston-rel-tests ci/linux-win-cross-rel +ci/linux-x64-centipede-asan-rel-tests +ci/linux-x64-libfuzzer-asan-dbg-tests +ci/linux-x64-libfuzzer-asan-rel-tests +ci/linux-x64-libfuzzer-msan-rel-tests +ci/linux-x64-libfuzzer-ubsan-rel-tests +ci/linux-x86-libfuzzer-asan-rel-tests ci/mac-archive-rel ci/mac-arm64-archive-rel ci/mac-arm64-dbg +ci/mac-arm64-libfuzzer-asan-rel-tests ci/mac-arm64-on-arm64-rel ci/mac-arm64-rel ci/mac-official @@ -124,6 +132,7 @@ ci/win-asan ci/win-official ci/win-presubmit +ci/win-x64-libfuzzer-asan-rel-tests ci/win11-arm64-rel-tests ci/win32-archive-rel ci/win32-official
diff --git a/infra/config/subprojects/chromium/ci/chromium.fuzz.star b/infra/config/subprojects/chromium/ci/chromium.fuzz.star index 8ccce51..1b3a75d 100644 --- a/infra/config/subprojects/chromium/ci/chromium.fuzz.star +++ b/infra/config/subprojects/chromium/ci/chromium.fuzz.star
@@ -347,9 +347,6 @@ targets.mixin(args = ["--asan-detect-odr-violation=0"]), ] + swarming_mixins, ), - # TODO(https://crbug.com/432407787): Add to a gardening rotation - # once the bots are proven green enough. - gardener_rotations = args.ignore_default(None), console_category = fuzzing_engine + "-tests", **kwargs )
diff --git a/internal b/internal index cac0eda..96d5677 160000 --- a/internal +++ b/internal
@@ -1 +1 @@ -Subproject commit cac0eda4f931b94c714acd417202a318f49cc1cd +Subproject commit 96d567763cde6fce93437285efeffbe518734435
diff --git a/ios/chrome/app/profile/BUILD.gn b/ios/chrome/app/profile/BUILD.gn index 610b4d9..a15f8e0 100644 --- a/ios/chrome/app/profile/BUILD.gn +++ b/ios/chrome/app/profile/BUILD.gn
@@ -41,6 +41,7 @@ ":first_run_profile_agent", ":identity_confirmation_profile_agent", ":multi_profile_forced_migration_profile_agent", + ":otr_profile_destroyer_profile_agent", ":post_restore_profile_agent", ":profile", ":search_engine_choice_profile_agent", @@ -374,6 +375,27 @@ ] } +source_set("otr_profile_destroyer_profile_agent") { + sources = [ + "otr_profile_destroyer_profile_agent.h", + "otr_profile_destroyer_profile_agent.mm", + ] + deps = [ + ":profile", + "//base", + "//ios/chrome/browser/browsing_data/model", + "//ios/chrome/browser/browsing_data/model:model_remove_mask", + "//ios/chrome/browser/crash_report/model", + "//ios/chrome/browser/shared/coordinator/scene:scene_state_header", + "//ios/chrome/browser/shared/coordinator/scene:scene_state_header_for_otr_profile_deletion", + "//ios/chrome/browser/shared/model/browser", + "//ios/chrome/browser/shared/model/profile", + "//ios/chrome/browser/shared/model/profile:incognito_session_tracker", + "//ios/chrome/browser/web_state_list/model/web_usage_enabler", + "//ios/web/public/thread", + ] +} + source_set("test_utils") { testonly = true sources = [
diff --git a/ios/chrome/app/profile/otr_profile_destroyer_profile_agent.h b/ios/chrome/app/profile/otr_profile_destroyer_profile_agent.h new file mode 100644 index 0000000..1c48444 --- /dev/null +++ b/ios/chrome/app/profile/otr_profile_destroyer_profile_agent.h
@@ -0,0 +1,15 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_APP_PROFILE_OTR_PROFILE_DESTROYER_PROFILE_AGENT_H_ +#define IOS_CHROME_APP_PROFILE_OTR_PROFILE_DESTROYER_PROFILE_AGENT_H_ + +#import "ios/chrome/app/profile/profile_state_agent.h" + +// ProfileAgent responsible for destroying and recreating the OTR profile +// when the last incognito tab is closed. +@interface OTRPRofileDestroyerProfileAgent : NSObject <ProfileStateAgent> +@end + +#endif // IOS_CHROME_APP_PROFILE_OTR_PROFILE_DESTROYER_PROFILE_AGENT_H_
diff --git a/ios/chrome/app/profile/otr_profile_destroyer_profile_agent.mm b/ios/chrome/app/profile/otr_profile_destroyer_profile_agent.mm new file mode 100644 index 0000000..2f116953 --- /dev/null +++ b/ios/chrome/app/profile/otr_profile_destroyer_profile_agent.mm
@@ -0,0 +1,166 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/app/profile/otr_profile_destroyer_profile_agent.h" + +#import "base/callback_list.h" +#import "base/check.h" +#import "base/check_op.h" +#import "base/functional/bind.h" +#import "base/functional/callback.h" +#import "base/functional/callback_helpers.h" +#import "base/sequence_checker.h" +#import "ios/chrome/app/profile/profile_init_stage.h" +#import "ios/chrome/app/profile/profile_state.h" +#import "ios/chrome/browser/browsing_data/model/browsing_data_remove_mask.h" +#import "ios/chrome/browser/browsing_data/model/browsing_data_remover.h" +#import "ios/chrome/browser/browsing_data/model/browsing_data_remover_factory.h" +#import "ios/chrome/browser/crash_report/model/crash_keys_helper.h" +#import "ios/chrome/browser/shared/coordinator/scene/scene_controller+OTRProfileDeletion.h" +#import "ios/chrome/browser/shared/coordinator/scene/scene_controller.h" +#import "ios/chrome/browser/shared/coordinator/scene/scene_state.h" +#import "ios/chrome/browser/shared/model/browser/browser_list.h" +#import "ios/chrome/browser/shared/model/browser/browser_list_factory.h" +#import "ios/chrome/browser/shared/model/profile/profile_incognito_session_tracker.h" +#import "ios/chrome/browser/shared/model/profile/profile_ios.h" +#import "ios/chrome/browser/web_state_list/model/web_usage_enabler/web_usage_enabler_browser_agent.h" +#import "ios/web/public/thread/web_task_traits.h" +#import "ios/web/public/thread/web_thread.h" + +namespace { + +// For readability of the loop in -onBrowsingDataRemoved. +constexpr BrowserList::BrowserType kRegularAndIncognito = + BrowserList::BrowserType::kRegularAndIncognito; + +} // namespace + +@implementation OTRPRofileDestroyerProfileAgent { + // The owning ProfileState. + __weak ProfileState* _profileState; + + // Subscription to listen for the profile destruction. + base::CallbackListSubscription _profileSubscription; + + // Used to track whether the profile has any open off-the-record tabs. + std::unique_ptr<ProfileIncognitoSessionTracker> _tracker; + + // Ensure sequence-affinity. + SEQUENCE_CHECKER(_sequenceChecker); +} + +#pragma mark - ProfileStateAgent + +- (void)setProfileState:(ProfileState*)profileState { + DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); + CHECK_GE(profileState.initStage, ProfileInitStage::kProfileLoaded); + _profileState = profileState; + + ProfileIOS* profile = _profileState.profile; + CHECK(profile); + + __weak OTRPRofileDestroyerProfileAgent* weakSelf = self; + _profileSubscription = + profile->RegisterProfileDestroyedCallback(base::BindOnce(^{ + [weakSelf onProfileDestroyed]; + })); + + _tracker = std::make_unique<ProfileIncognitoSessionTracker>( + BrowserListFactory::GetForProfile(profile), + base::BindRepeating(^(bool has_incognito_tabs) { + [weakSelf onHasIncognitoTabsChanged:has_incognito_tabs]; + })); +} + +#pragma mark - Private methods + +- (void)onProfileDestroyed { + DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); + _profileState = nil; + _tracker.reset(); +} + +- (void)onHasIncognitoTabsChanged:(bool)hasIncognitoTabs { + DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); + if (!hasIncognitoTabs) { + // The last incognito tab has been closed, and the off-the-record profile + // must be destroyed and recreated. Queue an empty task on the IO thread + // to give a chance for the task in progress to complete before destroying + // the profile. + __weak OTRPRofileDestroyerProfileAgent* weakSelf = self; + web::GetIOThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::DoNothing(), base::BindOnce(^{ + [weakSelf maybeDestroyAndRecreateOTRProfile]; + })); + } +} + +- (void)maybeDestroyAndRecreateOTRProfile { + DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); + // It is possible for new incognito tabs to have been opened while waiting + // for the IO requests to finish. If this is the case, do nothing. Profile + // will be destroyed the next time the last incognito tab is closed. + if (_tracker && !_tracker->has_incognito_tabs()) { + [self destroyAndRecreateOTRProfile]; + } +} + +- (void)destroyAndRecreateOTRProfile { + DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); + crash_keys::SetDestroyingAndRebuildingIncognitoBrowserState(true); + + ProfileIOS* profile = _profileState.profile; + CHECK(profile->HasOffTheRecordProfile()); + + // Notify all connected scenes that the incognito profile will be destroyed. + for (SceneState* sceneState in _profileState.connectedScenes) { + [sceneState.controller willDestroyIncognitoProfile]; + } + + // Clears incognito data that is specific to iOS and won't be cleared by + // deleting the profile. + __weak OTRPRofileDestroyerProfileAgent* weakSelf = self; + BrowsingDataRemoverFactory::GetForProfile(profile->GetOffTheRecordProfile()) + ->Remove(browsing_data::TimePeriod::ALL_TIME, + BrowsingDataRemoveMask::REMOVE_ALL, base::BindOnce(^{ + [weakSelf onBrowsingDataRemoved]; + })); + + // Destroy and recreate the incognito profile. + profile->DestroyOffTheRecordProfile(); + CHECK(!profile->HasOffTheRecordProfile()); + + profile->GetOffTheRecordProfile(); + CHECK(profile->HasOffTheRecordProfile()); + + // Notify all connected scenes that the incognito profile has been recreated. + for (SceneState* sceneState in _profileState.connectedScenes) { + [sceneState.controller incognitoProfileCreated]; + } + + crash_keys::SetDestroyingAndRebuildingIncognitoBrowserState(false); +} + +- (void)onBrowsingDataRemoved { + DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); + ProfileIOS* profile = _profileState.profile; + if (!profile) { + // If the profile has already been destroyed, there is nothing to do. + return; + } + + if (BrowsingDataRemover* remover = + BrowsingDataRemoverFactory::GetForProfileIfExists(profile); + remover && remover->IsRemoving()) { + // If data removing is in progress, then do not enable web usage. + return; + } + + BrowserList* browser_list = BrowserListFactory::GetForProfile(profile); + for (Browser* browser : browser_list->BrowsersOfType(kRegularAndIncognito)) { + WebUsageEnablerBrowserAgent::FromBrowser(browser)->SetWebUsageEnabled(true); + } +} + +@end
diff --git a/ios/chrome/app/profile/profile_controller.mm b/ios/chrome/app/profile/profile_controller.mm index 428a90a..c7ce80a 100644 --- a/ios/chrome/app/profile/profile_controller.mm +++ b/ios/chrome/app/profile/profile_controller.mm
@@ -44,6 +44,7 @@ #import "ios/chrome/app/profile/first_run_profile_agent.h" #import "ios/chrome/app/profile/identity_confirmation_profile_agent.h" #import "ios/chrome/app/profile/multi_profile_forced_migration_profile_agent.h" +#import "ios/chrome/app/profile/otr_profile_destroyer_profile_agent.h" #import "ios/chrome/app/profile/post_restore_profile_agent.h" #import "ios/chrome/app/profile/profile_state.h" #import "ios/chrome/app/profile/profile_state_observer.h" @@ -647,6 +648,7 @@ } - (void)attachProfileAgents { + [_state addAgent:[[OTRPRofileDestroyerProfileAgent alloc] init]]; [_state addAgent:[[CertificatePolicyProfileAgent alloc] init]]; [_state addAgent:[[FirstRunProfileAgent alloc] init]]; [_state addAgent:[[MultiProfileForcedMigrationProfileAgent alloc] init]];
diff --git a/ios/chrome/browser/authentication/account_menu/coordinator/account_menu_coordinator.mm b/ios/chrome/browser/authentication/account_menu/coordinator/account_menu_coordinator.mm index c26fe0bc..173ea83 100644 --- a/ios/chrome/browser/authentication/account_menu/coordinator/account_menu_coordinator.mm +++ b/ios/chrome/browser/authentication/account_menu/coordinator/account_menu_coordinator.mm
@@ -161,6 +161,8 @@ DCHECK(!_mediator); } +#pragma mark - ChromeCoordinator + - (void)start { ProfileIOS* profile = self.profile; _identityManager = IdentityManagerFactory::GetForProfile(profile);
diff --git a/ios/chrome/browser/authentication/account_menu/ui/account_menu_view_controller.mm b/ios/chrome/browser/authentication/account_menu/ui/account_menu_view_controller.mm index 691ddae..3e3bf2ff 100644 --- a/ios/chrome/browser/authentication/account_menu/ui/account_menu_view_controller.mm +++ b/ios/chrome/browser/authentication/account_menu/ui/account_menu_view_controller.mm
@@ -476,20 +476,16 @@ presentationController.prefersEdgeAttachedInCompactHeight = YES; presentationController.widthFollowsPreferredContentSizeWhenEdgeAttached = YES; - // In case of compact width only, adjust detents. - if (self.traitCollection.horizontalSizeClass == - UIUserInterfaceSizeClassCompact) { - __weak __typeof(self) weakSelf = self; - auto preferredHeightForSheetContent = ^CGFloat( - id<UISheetPresentationControllerDetentResolutionContext> context) { - return [weakSelf preferredHeightForSheetContent]; - }; - UISheetPresentationControllerDetent* customDetent = - [UISheetPresentationControllerDetent - customDetentWithIdentifier:kCustomMinimizedDetentIdentifier - resolver:preferredHeightForSheetContent]; - presentationController.detents = @[ customDetent ]; - } + __weak __typeof(self) weakSelf = self; + auto preferredHeightForSheetContent = ^CGFloat( + id<UISheetPresentationControllerDetentResolutionContext> context) { + return [weakSelf preferredHeightForSheetContent]; + }; + UISheetPresentationControllerDetent* customDetent = + [UISheetPresentationControllerDetent + customDetentWithIdentifier:kCustomMinimizedDetentIdentifier + resolver:preferredHeightForSheetContent]; + presentationController.detents = @[ customDetent ]; presentationController.selectedDetentIdentifier = kCustomMinimizedDetentIdentifier;
diff --git a/ios/chrome/browser/autocomplete/model/BUILD.gn b/ios/chrome/browser/autocomplete/model/BUILD.gn index e73577bf..08acac06 100644 --- a/ios/chrome/browser/autocomplete/model/BUILD.gn +++ b/ios/chrome/browser/autocomplete/model/BUILD.gn
@@ -4,6 +4,8 @@ source_set("model") { sources = [ + "autocomplete_browser_agent.h", + "autocomplete_browser_agent.mm", "autocomplete_classifier_factory.cc", "autocomplete_classifier_factory.h", "autocomplete_provider_client_impl.h", @@ -12,10 +14,6 @@ "autocomplete_scheme_classifier_impl.mm", "autocomplete_scoring_model_service_factory.h", "autocomplete_scoring_model_service_factory.mm", - "autocomplete_service.h", - "autocomplete_service.mm", - "autocomplete_service_factory.h", - "autocomplete_service_factory.mm", "in_memory_url_index_factory.cc", "in_memory_url_index_factory.h", "omnibox_pedal_implementation.h",
diff --git a/ios/chrome/browser/autocomplete/model/autocomplete_service.h b/ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.h similarity index 76% rename from ios/chrome/browser/autocomplete/model/autocomplete_service.h rename to ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.h index 4f458486..b1b31b1 100644 --- a/ios/chrome/browser/autocomplete/model/autocomplete_service.h +++ b/ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_SERVICE_H_ -#define IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_SERVICE_H_ +#ifndef IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_BROWSER_AGENT_H_ +#define IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_BROWSER_AGENT_H_ #import <map> #import <memory> @@ -12,9 +12,9 @@ #import "base/functional/callback.h" #import "base/memory/raw_ptr.h" #import "base/memory/weak_ptr.h" -#import "components/keyed_service/core/keyed_service.h" #import "ios/chrome/browser/autocomplete/model/omnibox_shortcuts_helper.h" #import "ios/chrome/browser/omnibox/public/omnibox_presentation_context.h" +#import "ios/chrome/browser/shared/model/browser/browser_user_data.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list_observer.h" #import "ios/web/public/web_state.h" @@ -22,21 +22,16 @@ @class ZeroSuggestPrefetcher; class AutocompleteController; -class AutocompleteProviderClient; -class ShortcutsBackend; +class Browser; /// Keyed Service that owns and manages long-lived Omnibox objects /// (AutocompleteController, etc.) per presentation context. -class AutocompleteService : public KeyedService { +class AutocompleteBrowserAgent + : public BrowserUserData<AutocompleteBrowserAgent> { public: - explicit AutocompleteService( - base::RepeatingCallback<std::unique_ptr<AutocompleteProviderClient>()> - client_factory, - ShortcutsBackend* shortcuts_backend); - ~AutocompleteService() override; - - // KeyedService implementation. - void Shutdown() override; + AutocompleteBrowserAgent(const AutocompleteBrowserAgent&) = delete; + AutocompleteBrowserAgent& operator=(const AutocompleteBrowserAgent&) = delete; + ~AutocompleteBrowserAgent() override; // Returns the AutocompleteController for the given context. // If it doesn't exist, it creates one. @@ -75,20 +70,20 @@ // Unregisters a single WebState for prefetching. void UnregisterWebStateForPrefetching(web::WebState* web_state); - base::WeakPtr<AutocompleteService> AsWeakPtr() { + base::WeakPtr<AutocompleteBrowserAgent> AsWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } private: + friend class BrowserUserData<AutocompleteBrowserAgent>; + + explicit AutocompleteBrowserAgent(Browser* browser); + // Creates a new AutocompleteController. std::unique_ptr<AutocompleteController> CreateAutocompleteController(); // Creates a new OmniboxShortcutsHelper for the given context. std::unique_ptr<OmniboxShortcutsHelper> CreateOmniboxShortcutsHelper(); - base::RepeatingCallback<std::unique_ptr<AutocompleteProviderClient>()> - client_factory_; - raw_ptr<ShortcutsBackend> shortcuts_backend_; - std::map<OmniboxPresentationContext, std::unique_ptr<AutocompleteController>> controllers_; std::map<OmniboxPresentationContext, std::unique_ptr<OmniboxShortcutsHelper>> @@ -96,7 +91,7 @@ std::map<WebStateList*, ZeroSuggestPrefetcher*> web_state_list_prefetchers_; std::map<web::WebState*, ZeroSuggestPrefetcher*> web_state_prefetchers_; - base::WeakPtrFactory<AutocompleteService> weak_ptr_factory_{this}; + base::WeakPtrFactory<AutocompleteBrowserAgent> weak_ptr_factory_{this}; }; -#endif // IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_SERVICE_H_ +#endif // IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_BROWSER_AGENT_H_
diff --git a/ios/chrome/browser/autocomplete/model/autocomplete_service.mm b/ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.mm similarity index 73% rename from ios/chrome/browser/autocomplete/model/autocomplete_service.mm rename to ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.mm index 89d0311..09eca91a 100644 --- a/ios/chrome/browser/autocomplete/model/autocomplete_service.mm +++ b/ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/autocomplete/model/autocomplete_service.h" +#import "ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.h" #import <algorithm> @@ -11,24 +11,21 @@ #import "components/omnibox/browser/autocomplete_provider_client.h" #import "components/omnibox/browser/page_classification_functions.h" #import "components/omnibox/browser/shortcuts_backend.h" +#import "ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.h" +#import "ios/chrome/browser/autocomplete/model/shortcuts_backend_factory.h" #import "ios/chrome/browser/autocomplete/model/zero_suggest_prefetcher.h" +#import "ios/chrome/browser/shared/model/browser/browser.h" #import "ios/chrome/browser/shared/model/profile/profile_ios.h" #import "ios/web/public/web_state.h" -AutocompleteService::AutocompleteService( - base::RepeatingCallback<std::unique_ptr<AutocompleteProviderClient>()> - client_factory, - ShortcutsBackend* shortcuts_backend) - : client_factory_(std::move(client_factory)), - shortcuts_backend_(shortcuts_backend) {} +AutocompleteBrowserAgent::AutocompleteBrowserAgent(Browser* browser) + : BrowserUserData(browser) {} -AutocompleteService::~AutocompleteService() {} - -void AutocompleteService::Shutdown() { +AutocompleteBrowserAgent::~AutocompleteBrowserAgent() { RemoveServices(); } -AutocompleteController* AutocompleteService::GetAutocompleteController( +AutocompleteController* AutocompleteBrowserAgent::GetAutocompleteController( OmniboxPresentationContext context) { auto it = controllers_.find(context); if (it != controllers_.end()) { @@ -44,7 +41,7 @@ return controller_ptr; } -OmniboxShortcutsHelper* AutocompleteService::GetOmniboxShortcutsHelper( +OmniboxShortcutsHelper* AutocompleteBrowserAgent::GetOmniboxShortcutsHelper( OmniboxPresentationContext context) { auto it = shortcuts_helpers_.find(context); if (it != shortcuts_helpers_.end()) { @@ -57,7 +54,7 @@ return helper_ptr; } -void AutocompleteService::RemoveServices() { +void AutocompleteBrowserAgent::RemoveServices() { for (auto it = web_state_list_prefetchers_.begin(); it != web_state_list_prefetchers_.end(); ++it) { [it->second disconnect]; @@ -72,7 +69,7 @@ controllers_.clear(); } -void AutocompleteService::RegisterWebStateListForPrefetching( +void AutocompleteBrowserAgent::RegisterWebStateListForPrefetching( OmniboxPresentationContext context, WebStateList* web_state_list, PageClassificationCallback classification_callback) { @@ -81,13 +78,13 @@ webStateList:web_state_list classificationCallback:std::move(classification_callback) disconnectCallback: - base::BindOnce(&AutocompleteService:: + base::BindOnce(&AutocompleteBrowserAgent:: UnregisterWebStateListForPrefetching, AsWeakPtr())]; web_state_list_prefetchers_[web_state_list] = prefetcher; } -void AutocompleteService::UnregisterWebStateListForPrefetching( +void AutocompleteBrowserAgent::UnregisterWebStateListForPrefetching( WebStateList* web_state_list) { auto it = web_state_list_prefetchers_.find(web_state_list); if (it != web_state_list_prefetchers_.end()) { @@ -96,7 +93,7 @@ } } -void AutocompleteService::RegisterWebStateForPrefetching( +void AutocompleteBrowserAgent::RegisterWebStateForPrefetching( OmniboxPresentationContext context, web::WebState* web_state, PageClassificationCallback classification_callback) { @@ -105,13 +102,13 @@ webState:web_state classificationCallback:std::move(classification_callback) disconnectCallback:base::BindOnce( - &AutocompleteService:: + &AutocompleteBrowserAgent:: UnregisterWebStateForPrefetching, AsWeakPtr())]; web_state_prefetchers_[web_state] = prefetcher; } -void AutocompleteService::UnregisterWebStateForPrefetching( +void AutocompleteBrowserAgent::UnregisterWebStateForPrefetching( web::WebState* web_state) { auto it = web_state_prefetchers_.find(web_state); if (it != web_state_prefetchers_.end()) { @@ -121,12 +118,9 @@ } std::unique_ptr<AutocompleteController> -AutocompleteService::CreateAutocompleteController() { +AutocompleteBrowserAgent::CreateAutocompleteController() { std::unique_ptr<AutocompleteProviderClient> provider_client = - client_factory_.Run(); - if (!provider_client) { - return nullptr; - } + std::make_unique<AutocompleteProviderClientImpl>(browser_->GetProfile()); int providers = AutocompleteClassifier::DefaultOmniboxProviders(); @@ -136,6 +130,8 @@ } std::unique_ptr<OmniboxShortcutsHelper> -AutocompleteService::CreateOmniboxShortcutsHelper() { - return std::make_unique<OmniboxShortcutsHelper>(shortcuts_backend_); +AutocompleteBrowserAgent::CreateOmniboxShortcutsHelper() { + return std::make_unique<OmniboxShortcutsHelper>( + ios::ShortcutsBackendFactory::GetForProfile(browser_->GetProfile()) + .get()); }
diff --git a/ios/chrome/browser/autocomplete/model/autocomplete_service_factory.h b/ios/chrome/browser/autocomplete/model/autocomplete_service_factory.h deleted file mode 100644 index 41acb903..0000000 --- a/ios/chrome/browser/autocomplete/model/autocomplete_service_factory.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2025 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_SERVICE_FACTORY_H_ -#define IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_SERVICE_FACTORY_H_ - -#import "base/no_destructor.h" -#import "ios/chrome/browser/shared/model/profile/profile_keyed_service_factory_ios.h" - -class ProfileIOS; -class AutocompleteService; - -/// Factory for the AutocompleteService. -class AutocompleteServiceFactory : public ProfileKeyedServiceFactoryIOS { - public: - static AutocompleteService* GetForProfile(ProfileIOS* profile); - static AutocompleteServiceFactory* GetInstance(); - - private: - friend class base::NoDestructor<AutocompleteServiceFactory>; - - AutocompleteServiceFactory(); - ~AutocompleteServiceFactory() override; - - // ProfileKeyedServiceFactoryIOS - std::unique_ptr<KeyedService> BuildServiceInstanceFor( - ProfileIOS* profile) const override; -}; - -#endif // IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_SERVICE_FACTORY_H_
diff --git a/ios/chrome/browser/autocomplete/model/autocomplete_service_factory.mm b/ios/chrome/browser/autocomplete/model/autocomplete_service_factory.mm deleted file mode 100644 index a1427396..0000000 --- a/ios/chrome/browser/autocomplete/model/autocomplete_service_factory.mm +++ /dev/null
@@ -1,82 +0,0 @@ -// Copyright 2025 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/autocomplete/model/autocomplete_service_factory.h" - -#import "base/functional/bind.h" -#import "base/memory/scoped_refptr.h" -#import "components/omnibox/browser/shortcuts_backend.h" -#import "ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.h" -#import "ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.h" -#import "ios/chrome/browser/autocomplete/model/autocomplete_scoring_model_service_factory.h" -#import "ios/chrome/browser/autocomplete/model/autocomplete_service.h" -#import "ios/chrome/browser/autocomplete/model/in_memory_url_index_factory.h" -#import "ios/chrome/browser/autocomplete/model/on_device_tail_model_service_factory.h" -#import "ios/chrome/browser/autocomplete/model/provider_state_service_factory.h" -#import "ios/chrome/browser/autocomplete/model/remote_suggestions_service_factory.h" -#import "ios/chrome/browser/autocomplete/model/shortcuts_backend_factory.h" -#import "ios/chrome/browser/autocomplete/model/zero_suggest_cache_service_factory.h" -#import "ios/chrome/browser/bookmarks/model/bookmark_model_factory.h" -#import "ios/chrome/browser/history/model/history_service_factory.h" -#import "ios/chrome/browser/history/model/top_sites_factory.h" -#import "ios/chrome/browser/search_engines/model/template_url_service_factory.h" -#import "ios/chrome/browser/shared/model/profile/profile_ios.h" -#import "ios/chrome/browser/signin/model/identity_manager_factory.h" -#import "ios/chrome/browser/sync/model/sync_service_factory.h" - -namespace { - -// Factory for AutocompleteProviderClient. -std::unique_ptr<AutocompleteProviderClient> CreateAutocompleteProviderClient( - base::WeakPtr<ProfileIOS> profile) { - CHECK(profile); - return std::make_unique<AutocompleteProviderClientImpl>(profile.get()); -} - -} // namespace - -// static -AutocompleteService* AutocompleteServiceFactory::GetForProfile( - ProfileIOS* profile) { - return GetInstance()->GetServiceForProfileAs<AutocompleteService>( - profile, /*create=*/true); -} - -// static -AutocompleteServiceFactory* AutocompleteServiceFactory::GetInstance() { - static base::NoDestructor<AutocompleteServiceFactory> instance; - return instance.get(); -} - -AutocompleteServiceFactory::AutocompleteServiceFactory() - : ProfileKeyedServiceFactoryIOS("AutocompleteService", - ProfileSelection::kOwnInstanceInIncognito, - TestingCreation::kCreateService) { - DependsOn(ios::AutocompleteClassifierFactory::GetInstance()); - DependsOn(ios::AutocompleteScoringModelServiceFactory::GetInstance()); - DependsOn(ios::BookmarkModelFactory::GetInstance()); - DependsOn(ios::HistoryServiceFactory::GetInstance()); - DependsOn(IdentityManagerFactory::GetInstance()); - DependsOn(ios::InMemoryURLIndexFactory::GetInstance()); - DependsOn(OnDeviceTailModelServiceFactory::GetInstance()); - DependsOn(ios::ProviderStateServiceFactory::GetInstance()); - DependsOn(RemoteSuggestionsServiceFactory::GetInstance()); - DependsOn(ios::ShortcutsBackendFactory::GetInstance()); - DependsOn(SyncServiceFactory::GetInstance()); - DependsOn(ios::TemplateURLServiceFactory::GetInstance()); - DependsOn(ios::TopSitesFactory::GetInstance()); - DependsOn(ios::ZeroSuggestCacheServiceFactory::GetInstance()); -} - -AutocompleteServiceFactory::~AutocompleteServiceFactory() = default; - -std::unique_ptr<KeyedService> -AutocompleteServiceFactory::BuildServiceInstanceFor(ProfileIOS* profile) const { - scoped_refptr<ShortcutsBackend> shortcuts_backend = - ios::ShortcutsBackendFactory::GetForProfile(profile); - return std::make_unique<AutocompleteService>( - base::BindRepeating(&CreateAutocompleteProviderClient, - profile->AsWeakPtr()), - shortcuts_backend.get()); -}
diff --git a/ios/chrome/browser/autofill/ui_bundled/form_input_accessory/form_input_accessory_coordinator.mm b/ios/chrome/browser/autofill/ui_bundled/form_input_accessory/form_input_accessory_coordinator.mm index c3bc2a5..1478dcc 100644 --- a/ios/chrome/browser/autofill/ui_bundled/form_input_accessory/form_input_accessory_coordinator.mm +++ b/ios/chrome/browser/autofill/ui_bundled/form_input_accessory/form_input_accessory_coordinator.mm
@@ -578,8 +578,14 @@ [applicationHandler openURLInNewTab:command]; return; } + } - if (type == autofill::AutofillProfile::RecordType::kAccountNameEmail) { + if (base::FeatureList::IsEnabled( + autofill::features::kAutofillEnableSupportForNameAndEmail)) { + id<ApplicationCommands> applicationHandler = HandlerForProtocol( + self.browser->GetCommandDispatcher(), ApplicationCommands); + if (address.record_type() == + autofill::AutofillProfile::RecordType::kAccountNameEmail) { OpenNewTabCommand* command = [OpenNewTabCommand commandWithURLFromChrome:GURL(kGoogleAccountNameEmailAddressEditURL)]; [applicationHandler openURLInNewTab:command];
diff --git a/ios/chrome/browser/autofill/ui_bundled/manual_fill/address_view_controller_egtest.mm b/ios/chrome/browser/autofill/ui_bundled/manual_fill/address_view_controller_egtest.mm index 663a09b..8ded457 100644 --- a/ios/chrome/browser/autofill/ui_bundled/manual_fill/address_view_controller_egtest.mm +++ b/ios/chrome/browser/autofill/ui_bundled/manual_fill/address_view_controller_egtest.mm
@@ -227,6 +227,11 @@ autofill::features::kAutofillEnableSupportForHomeAndWork); } + if ([self isRunningTest:@selector(testDoNotEditNamEmailFromOverflowMenu)]) { + config.features_enabled.push_back( + autofill::features::kAutofillEnableSupportForNameAndEmail); + } + return config; } @@ -510,6 +515,31 @@ assertWithMatcher:grey_notVisible()]; } +// Tests the "Edit" action of the overflow menu button does not display the +// address's details for Name and Email profile. +- (void)testDoNotEditNamEmailFromOverflowMenu { + [AutofillAppInterface clearProfilesStore]; + [AutofillAppInterface saveExampleAccountNameEmailProfile]; + + // Bring up the keyboard + [[EarlGrey selectElementWithMatcher:WebViewMatcher()] + performAction:TapWebElementWithId(kFormElementName)]; + [ChromeEarlGrey waitForKeyboardToAppear]; + + // Open the address manual fill view. + OpenAddressManualFillView(); + + // Tap the overflow menu button and select the "Edit" action. + [[EarlGrey selectElementWithMatcher:OverflowMenuButton(/*cell_index=*/0)] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:OverflowMenuEditAction()] + performAction:grey_tap()]; + + // Check that the address details page is not opened. + [[EarlGrey selectElementWithMatcher:AddressDetailsPage()] + assertWithMatcher:grey_notVisible()]; +} + #pragma mark - Private // Verify that the address info has been filled.
diff --git a/ios/chrome/browser/browser_state/model/DEPS b/ios/chrome/browser/browser_state/model/DEPS deleted file mode 100644 index 7e7414c0f..0000000 --- a/ios/chrome/browser/browser_state/model/DEPS +++ /dev/null
@@ -1,27 +0,0 @@ -include_rules = [ - "+components/page_content_annotations/core", - "+ios/chrome/browser/affiliations/model", - "+ios/chrome/browser/bookmarks/model", - "+ios/chrome/browser/content_settings/model", - "+ios/chrome/browser/net/model", - "+ios/chrome/browser/optimization_guide/model", - "+ios/chrome/browser/page_info/model", - "+ios/chrome/browser/plus_addresses/model", - "+ios/chrome/browser/policy/model", - "+ios/chrome/browser/prefs/model", - "+ios/chrome/browser/profile/model", - "+ios/chrome/browser/push_notification/model", - "+ios/chrome/browser/segmentation_platform/model", - "+ios/chrome/browser/signin/model", - "+ios/chrome/browser/supervised_user/model", - "+ios/chrome/browser/sync/model", - "+ios/chrome/browser/unified_consent/model", -] - -specific_include_rules = { - # TODO(crbug.com/40820398): Remove this dependency. - "^browser_state_keyed_service_factories.mm": [ - "+ios/chrome/browser", - "+ios/chrome/browser/voice/ui_bundled/text_to_speech_playback_controller_factory.h", - ], -}
diff --git a/ios/chrome/browser/browser_state/model/OWNERS b/ios/chrome/browser/browser_state/model/OWNERS deleted file mode 100644 index c5cd5cb..0000000 --- a/ios/chrome/browser/browser_state/model/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -sdefresne@chromium.org
diff --git a/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator_unittest.mm b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator_unittest.mm index 8e1feb2..7988d23 100644 --- a/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator_unittest.mm +++ b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator_unittest.mm
@@ -10,6 +10,7 @@ #import "components/sync/service/sync_service_utils.h" #import "components/trusted_vault/trusted_vault_server_constants.h" #import "ios/chrome/browser/authentication/trusted_vault_reauthentication/coordinator/trusted_vault_reauthentication_coordinator.h" +#import "ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.h" #import "ios/chrome/browser/bookmarks/model/bookmark_model_factory.h" #import "ios/chrome/browser/browser_view/model/browser_view_visibility_notifier_browser_agent.h" #import "ios/chrome/browser/browser_view/ui_bundled/browser_coordinator+Testing.h" @@ -144,6 +145,7 @@ DiscoverFeedVisibilityBrowserAgent::CreateForBrowser(browser_.get()); ToolbarsSizeBrowserAgent::CreateForBrowser(browser_.get()); TestFullscreenController::CreateForBrowser(browser_.get()); + AutocompleteBrowserAgent::CreateForBrowser(browser_.get()); WebUsageEnablerBrowserAgent* enabler = WebUsageEnablerBrowserAgent::FromBrowser(browser_.get());
diff --git a/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller_unittest.mm b/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller_unittest.mm index 7156652..a41d5a4b 100644 --- a/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller_unittest.mm +++ b/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller_unittest.mm
@@ -17,8 +17,7 @@ #import "components/open_from_clipboard/fake_clipboard_recent_content.h" #import "components/search_engines/template_url_service.h" #import "components/supervised_user/core/common/features.h" -#import "ios/chrome/browser/autocomplete/model/autocomplete_service.h" -#import "ios/chrome/browser/autocomplete/model/autocomplete_service_factory.h" +#import "ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.h" #import "ios/chrome/browser/bookmarks/model/bookmark_model_factory.h" #import "ios/chrome/browser/bookmarks/ui_bundled/home/bookmarks_coordinator.h" #import "ios/chrome/browser/browser_container/ui_bundled/browser_container_view_controller.h" @@ -182,6 +181,7 @@ TabUsageRecorderBrowserAgent::CreateForBrowser(browser_.get()); StartSurfaceRecentTabBrowserAgent::CreateForBrowser(browser_.get()); OmniboxPositionBrowserAgent::CreateForBrowser(browser_.get()); + AutocompleteBrowserAgent::CreateForBrowser(browser_.get()); BrowserViewVisibilityNotifierBrowserAgent::CreateForBrowser(browser_.get()); // FullscreenController depends on ToolbarsSizeBrowserAgent, so the agent // must be created first. Please maintain this order.
diff --git a/ios/chrome/browser/composebox/coordinator/composebox_input_plate_mediator.mm b/ios/chrome/browser/composebox/coordinator/composebox_input_plate_mediator.mm index 7712396..72fcea4 100644 --- a/ios/chrome/browser/composebox/coordinator/composebox_input_plate_mediator.mm +++ b/ios/chrome/browser/composebox/coordinator/composebox_input_plate_mediator.mm
@@ -45,6 +45,7 @@ #import "ios/chrome/browser/composebox/public/composebox_input_plate_controls.h" #import "ios/chrome/browser/composebox/public/features.h" #import "ios/chrome/browser/composebox/ui/composebox_input_item.h" +#import "ios/chrome/browser/composebox/ui/composebox_input_item_collection.h" #import "ios/chrome/browser/composebox/ui/composebox_metrics_recorder.h" #import "ios/chrome/browser/favicon/model/favicon_loader.h" #import "ios/chrome/browser/intelligence/persist_tab_context/model/persist_tab_context_browser_agent.h" @@ -139,12 +140,14 @@ } // namespace -@interface ComposeboxInputPlateMediator () <SearchEngineObserving> +@interface ComposeboxInputPlateMediator () < + SearchEngineObserving, + ComposeboxInputItemCollectionDelegate> @end @implementation ComposeboxInputPlateMediator { // The ordered list of items for display. - NSMutableArray<ComposeboxInputItem*>* _items; + ComposeboxInputItemCollection* _items; // The C++ session handle for this feature. std::unique_ptr<contextual_search::ContextualSearchSessionHandle> _contextualSearchSession; @@ -208,7 +211,9 @@ (AimEligibilityService*)aimEligibilityService { self = [super init]; if (self) { - _items = [NSMutableArray array]; + _items = [[ComposeboxInputItemCollection alloc] + initWithAttachmentLimit:kAttachmentLimit]; + _items.delegate = self; _contextualSearchSession = std::move(contextualSearchSession); _contextualSearchSession->NotifySessionStarted(); CHECK(_contextualSearchSession->GetController()); @@ -269,7 +274,7 @@ BOOL unableToLoadUIImage = ![itemProvider canLoadObjectOfClass:[UIImage class]]; - BOOL assetAlreadyLoaded = [self assetAlreadyLoaded:assetID]; + BOOL assetAlreadyLoaded = [_items assetAlreadyLoaded:assetID]; if (unableToLoadUIImage || assetAlreadyLoaded) { return; } @@ -278,8 +283,7 @@ initWithComposeboxInputItemType:ComposeboxInputItemType:: kComposeboxInputItemTypeImage assetID:assetID]; - [_items addObject:item]; - [self updateConsumerItems]; + [_items addItem:item]; __block base::UnguessableToken identifier = item.identifier; __weak __typeof(self) weakSelf = self; @@ -332,7 +336,7 @@ - (void)processPDFFileURL:(GURL)PDFFileURL { DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); NSString* assetID = base::SysUTF8ToNSString(PDFFileURL.spec()); - if ([self assetAlreadyLoaded:assetID]) { + if ([_items assetAlreadyLoaded:assetID]) { return; } @@ -352,8 +356,7 @@ kComposeboxInputItemTypeFile assetID:assetID]; item.title = base::SysUTF8ToNSString(PDFFileURL.ExtractFileName()); - [_items addObject:item]; - [self updateConsumerItems]; + [_items addItem:item]; base::UnguessableToken identifier = item.identifier; // Read the data in the background then call `onDataReadForItem`. @@ -369,14 +372,13 @@ } - (BOOL)canAddMoreAttachments { - DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - return _items.count < kAttachmentLimit; + return _items.canAddMoreAttachments; } - (NSUInteger)maxNumberOfGalleryItemsAllowed { DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - NSUInteger availableSlots = kAttachmentLimit - _items.count; + NSUInteger availableSlots = _items.availableSlots; switch (_modeHolder.mode) { case ComposeboxMode::kRegularSearch: case ComposeboxMode::kAIM: { @@ -386,15 +388,7 @@ case ComposeboxMode::kImageGeneration: { // For ImageGeneration, allow 1 image if no images are present, otherwise // 0. - BOOL hasImage = NO; - for (ComposeboxInputItem* item in _items) { - if (item.type == - ComposeboxInputItemType::kComposeboxInputItemTypeImage) { - hasImage = YES; - break; - } - } - return hasImage ? 0 : MIN(availableSlots, 1); + return _items.hasImage ? 0 : MIN(availableSlots, 1); } } } @@ -403,19 +397,16 @@ - (void)removeItem:(ComposeboxInputItem*)item { DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - [_items removeObject:item]; + [_items removeItem:item]; if (_contextualSearchSession) { _contextualSearchSession->DeleteFile(item.serverToken); [self reloadSuggestions]; } - if (base::FeatureList::IsEnabled(kComposeboxAutoattachTab) && - _items.count == 0) { + if (base::FeatureList::IsEnabled(kComposeboxAutoattachTab) && _items.empty) { _modeHolder.mode = ComposeboxMode::kRegularSearch; } - - [self updateConsumerItems]; } - (void)sendText:(NSString*)text { @@ -463,8 +454,7 @@ if (_contextualSearchSession) { _contextualSearchSession->ClearFiles(); } - [_items removeAllObjects]; - [self updateConsumerItems]; + [_items clearItems]; break; case ComposeboxMode::kAIM: break; @@ -482,7 +472,7 @@ - (std::set<web::WebStateID>)webStateIDsForAttachedTabs { std::set<web::WebStateID> webStateIDs; - for (ComposeboxInputItem* item in _items) { + for (ComposeboxInputItem* item in _items.containedItems) { web::WebStateID webStateID = _latestTabSelectionMapping[item.identifier]; if (webStateID.valid()) { webStateIDs.insert(webStateID); @@ -493,13 +483,7 @@ } - (NSUInteger)nonTabAttachmentCount { - NSUInteger result = 0; - for (ComposeboxInputItem* item in _items) { - if (item.type != ComposeboxInputItemType::kComposeboxInputItemTypeTab) { - result++; - } - } - return result; + return _items.nonTabAttachmentCount; } - (void)attachSelectedTabsWithWebStateIDs: @@ -562,7 +546,7 @@ } - (void)removeDeselectedIDs:(std::set<web::WebStateID>)deselectedIDs { - NSArray<ComposeboxInputItem*>* items = [_items copy]; + NSArray<ComposeboxInputItem*>* items = _items.containedItems; for (ComposeboxInputItem* item in items) { web::WebStateID webStateID = _latestTabSelectionMapping[item.identifier]; if (webStateID.valid() && deselectedIDs.contains(webStateID)) { @@ -579,12 +563,10 @@ initWithComposeboxInputItemType:ComposeboxInputItemType:: kComposeboxInputItemTypeTab]; item.title = base::SysUTF16ToNSString(webState->GetTitle()); - [_items addObject:item]; base::UnguessableToken identifier = item.identifier; _latestTabSelectionMapping[identifier] = webState->GetUniqueIdentifier(); - [self updateConsumerItems]; - [self updateConsumerActionsState]; + [_items addItem:item]; if (_faviconLoader) { __weak __typeof(self) weakSelf = self; @@ -715,7 +697,7 @@ inputData: (std::unique_ptr<lens::ContextualInputData>)inputData { DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - ComposeboxInputItem* item = [self itemForIdentifier:identifier]; + ComposeboxInputItem* item = [_items itemForIdentifier:identifier]; if (item) { item.serverToken = serverToken; } @@ -737,7 +719,7 @@ - (void)onFileContextAdded:(base::UnguessableToken)serverToken forIdentifier:(base::UnguessableToken)identifier { DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - ComposeboxInputItem* item = [self itemForIdentifier:identifier]; + ComposeboxInputItem* item = [_items itemForIdentifier:identifier]; if (item) { item.serverToken = serverToken; } @@ -767,7 +749,7 @@ - (void)attachCurrentTabContent { DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - if (![self canAddMoreAttachments]) { + if (!_items.canAddMoreAttachments) { [self.delegate showAttachmentLimitError]; return; } @@ -794,7 +776,7 @@ contextual_search::FileUploadErrorType>&) errorType { DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - ComposeboxInputItem* item = [self itemForServerToken:fileToken]; + ComposeboxInputItem* item = [_items itemForServerToken:fileToken]; if (!item) { return; } @@ -832,11 +814,11 @@ // Reloads the displayed suggestions based on the attachments/modeHolder. - (void)reloadSuggestions { - BOOL shouldRestartAutocomplete = (_items.count == 0); + BOOL shouldRestartAutocomplete = _items.empty; if (_items.count == 1) { shouldRestartAutocomplete = YES; - if (_items[0].type == + if (_items.firstItem.type == ComposeboxInputItemType::kComposeboxInputItemTypeImage) { shouldRestartAutocomplete = IsComposeboxFetchContextualSuggestionsForImageEnabled(); @@ -857,7 +839,7 @@ ComposeboxInputItem* imageToKeep = nil; // Find one image to keep. - for (ComposeboxInputItem* item in _items) { + for (ComposeboxInputItem* item in _items.containedItems) { if (item.type == ComposeboxInputItemType::kComposeboxInputItemTypeImage && !imageToKeep) { imageToKeep = item; @@ -872,7 +854,7 @@ } // Find items to remove from the backend. - for (ComposeboxInputItem* item in _items) { + for (ComposeboxInputItem* item in _items.containedItems) { if (![itemsToKeep containsObject:item]) { if (_contextualSearchSession) { _contextualSearchSession->DeleteFile(item.serverToken); @@ -880,16 +862,14 @@ } } - _items = itemsToKeep; - - [self updateConsumerItems]; + [_items replaceWithItems:itemsToKeep]; } // Handles the loaded preview `image` for the item with the given `identifier`. - (void)didLoadPreviewImage:(UIImage*)previewImage forItemWithIdentifier:(base::UnguessableToken)identifier { DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - ComposeboxInputItem* item = [self itemForIdentifier:identifier]; + ComposeboxInputItem* item = [_items itemForIdentifier:identifier]; if (!item) { return; } @@ -906,7 +886,7 @@ - (void)didLoadFaviconIcon:(UIImage*)faviconImage forItemWithIdentifier:(base::UnguessableToken)identifier { DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - ComposeboxInputItem* item = [self itemForIdentifier:identifier]; + ComposeboxInputItem* item = [_items itemForIdentifier:identifier]; if (!item) { return; } @@ -923,7 +903,7 @@ - (void)didLoadFullImage:(UIImage*)image forItemWithIdentifier:(base::UnguessableToken)identifier { DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - ComposeboxInputItem* item = [self itemForIdentifier:identifier]; + ComposeboxInputItem* item = [_items itemForIdentifier:identifier]; if (!item) { return; } @@ -949,7 +929,7 @@ - (void)didFinishSimulatedLoadForImage:(UIImage*)image itemIdentifier:(base::UnguessableToken)identifier { DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - ComposeboxInputItem* item = [self itemForIdentifier:identifier]; + ComposeboxInputItem* item = [_items itemForIdentifier:identifier]; if (!item) { return; } @@ -989,7 +969,7 @@ - (void)uploadImage:(UIImage*)image itemIdentifier:(base::UnguessableToken)identifier { DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - ComposeboxInputItem* item = [self itemForIdentifier:identifier]; + ComposeboxInputItem* item = [_items itemForIdentifier:identifier]; if (!item || !_contextualSearchSession) { return; } @@ -1012,28 +992,6 @@ std::move(callback)); } -// Returns the item with the given `identifier` or nil if not found. -- (ComposeboxInputItem*)itemForIdentifier:(base::UnguessableToken)identifier { - DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - for (ComposeboxInputItem* item in _items) { - if (item.identifier == identifier) { - return item; - } - } - return nil; -} - -// Returns the item with the given `serverToken` or nil if not found. -- (ComposeboxInputItem*)itemForServerToken:(base::UnguessableToken)serverToken { - DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - for (ComposeboxInputItem* item in _items) { - if (item.serverToken == serverToken) { - return item; - } - } - return nil; -} - // Handles uploading the context after the snapshot is generated. - (void)didRetrieveColorSnapshot:(UIImage*)image inputData:(std::unique_ptr<lens::ContextualInputData>) @@ -1057,7 +1015,7 @@ fromURL:(GURL)url withData:(NSData*)data { DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - ComposeboxInputItem* item = [self itemForIdentifier:identifier]; + ComposeboxInputItem* item = [_items itemForIdentifier:identifier]; if (!item) { return; } @@ -1095,19 +1053,6 @@ })); } -- (BOOL)assetAlreadyLoaded:(NSString*)assetID { - if (!assetID) { - return NO; - } - for (ComposeboxInputItem* item in _items) { - if ([item.assetID isEqualToString:assetID]) { - return YES; - } - } - - return NO; -} - - (BOOL)isEligibleToAIM { if (!_aimEligibilityService) { return NO; @@ -1196,12 +1141,12 @@ - (void)handleFailedAttachment:(base::UnguessableToken)identifier { [self.delegate showSnackbarForItemUploadDidFail]; - [self removeItem:[self itemForIdentifier:identifier]]; + [self removeItem:[_items itemForIdentifier:identifier]]; } - (void)updateButtonsVisibility { BOOL compactMode = [self compactModeRequired]; - BOOL hasAttachments = _items.count > 0; + BOOL hasAttachments = !_items.empty; BOOL hasContent = hasAttachments || _hasText; BOOL dseGoogle = [self isDSEGoogle]; BOOL eligibleToAIM = [self isEligibleToAIM]; @@ -1268,14 +1213,7 @@ /// Updates the consumer actions enabled/disable state. - (void)updateConsumerActionsState { - BOOL hasTabOrFile = NO; - for (ComposeboxInputItem* item in _items) { - if (item.type == ComposeboxInputItemType::kComposeboxInputItemTypeTab || - item.type == ComposeboxInputItemType::kComposeboxInputItemTypeFile) { - hasTabOrFile = YES; - break; - } - } + BOOL hasTabOrFile = _items.hasTabOrFile; [self.consumer disableCreateImageActions:hasTabOrFile]; BOOL isImageCreation = _modeHolder.mode == ComposeboxMode::kImageGeneration; @@ -1289,12 +1227,12 @@ /// Updates the consumer items and maybe trigger AIM. - (void)updateConsumerItems { DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); - [self.consumer setItems:_items]; + [self.consumer setItems:_items.containedItems]; [self updateOptionToAttachCurrentTab]; [self updateConsumerActionsState]; [self updateButtonsVisibility]; - if (_items.count > 0 && [_modeHolder isRegularSearch]) { + if (!_items.empty && [_modeHolder isRegularSearch]) { // AI mode is implicitly enabled by items attachment. [self.metricsRecorder recordAiModeActivationSource:AiModeActivationSource::kImplicit]; @@ -1335,4 +1273,9 @@ _isUpdatingCompactMode = NO; } +- (void)composeboxInputItemCollectionDidUpdateItems: + (ComposeboxInputItemCollection*)composeboxInputItemCollection { + [self updateConsumerItems]; +} + @end
diff --git a/ios/chrome/browser/composebox/coordinator/composebox_omnibox_client.mm b/ios/chrome/browser/composebox/coordinator/composebox_omnibox_client.mm index 59a1648..44a04b3 100644 --- a/ios/chrome/browser/composebox/coordinator/composebox_omnibox_client.mm +++ b/ios/chrome/browser/composebox/coordinator/composebox_omnibox_client.mm
@@ -19,10 +19,9 @@ #import "components/omnibox/browser/omnibox_log.h" #import "components/omnibox/common/omnibox_features.h" #import "components/search_engines/template_url_service.h" +#import "ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.h" #import "ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.h" #import "ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.h" -#import "ios/chrome/browser/autocomplete/model/autocomplete_service.h" -#import "ios/chrome/browser/autocomplete/model/autocomplete_service_factory.h" #import "ios/chrome/browser/autocomplete/model/omnibox_shortcuts_helper.h" #import "ios/chrome/browser/bookmarks/model/bookmark_model_factory.h" #import "ios/chrome/browser/bookmarks/model/bookmarks_utils.h" @@ -331,10 +330,10 @@ const std::u16string& text, const AutocompleteMatch& match, const AutocompleteMatch& alternative_nav_match) { - AutocompleteService* autocomplete_service = - AutocompleteServiceFactory::GetForProfile(profile_); + AutocompleteBrowserAgent* autocomplete_browser_agent = + AutocompleteBrowserAgent::FromBrowser(browser_); OmniboxShortcutsHelper* shortcuts_helper = - autocomplete_service->GetOmniboxShortcutsHelper( + autocomplete_browser_agent->GetOmniboxShortcutsHelper( OmniboxPresentationContext::kComposebox); if (shortcuts_helper) { shortcuts_helper->OnAutocompleteAccept(text, match,
diff --git a/ios/chrome/browser/composebox/ui/BUILD.gn b/ios/chrome/browser/composebox/ui/BUILD.gn index 067c039..671919d 100644 --- a/ios/chrome/browser/composebox/ui/BUILD.gn +++ b/ios/chrome/browser/composebox/ui/BUILD.gn
@@ -11,6 +11,8 @@ "composebox_input_item.mm", "composebox_input_item_cell.h", "composebox_input_item_cell.mm", + "composebox_input_item_collection.h", + "composebox_input_item_collection.mm", "composebox_input_item_view.h", "composebox_input_item_view.mm", "composebox_input_plate_consumer.h",
diff --git a/ios/chrome/browser/composebox/ui/composebox_input_item_collection.h b/ios/chrome/browser/composebox/ui/composebox_input_item_collection.h new file mode 100644 index 0000000..082fd62 --- /dev/null +++ b/ios/chrome/browser/composebox/ui/composebox_input_item_collection.h
@@ -0,0 +1,87 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_COMPOSEBOX_UI_COMPOSEBOX_INPUT_ITEM_COLLECTION_H_ +#define IOS_CHROME_BROWSER_COMPOSEBOX_UI_COMPOSEBOX_INPUT_ITEM_COLLECTION_H_ + +#import <UIKit/UIKit.h> + +namespace base { +class UnguessableToken; +} + +@class ComposeboxInputItem; +@class ComposeboxInputItemCollection; + +// Delegate for a `ComposeboxInputItemCollection`. +@protocol ComposeboxInputItemCollectionDelegate <NSObject> + +// Informs the caller that the collection was updated. +- (void)composeboxInputItemCollectionDidUpdateItems: + (ComposeboxInputItemCollection*)composeboxInputItemCollection; + +@end + +// A ordered container for `ComposeboxInputItem`, modeling the attachments +// carousel in the inputplate. +@interface ComposeboxInputItemCollection : NSObject + +// Creates a new input item collection with the given attachment limit. +- (instancetype)initWithAttachmentLimit:(size_t)attachmentLimit; + +// The delegate for this instance. +@property(nonatomic, weak) id<ComposeboxInputItemCollectionDelegate> delegate; + +// The contained items in this collection. +@property(nonatomic, readonly, copy) + NSArray<ComposeboxInputItem*>* containedItems; + +// The number of objects in the array. +@property(nonatomic, readonly) size_t count; + +// Whether the collection is empty. +@property(nonatomic, readonly, getter=isEmpty) BOOL empty; + +// Whether the collection has at least one image added. +@property(nonatomic, readonly) BOOL hasImage; + +// Whether the collection contains a tab or a file attachment. +@property(nonatomic, readonly) BOOL hasTabOrFile; + +// Whether more attachment can be added. +@property(nonatomic, readonly) BOOL canAddMoreAttachments; + +// The available slots in this collection. +@property(nonatomic, readonly) size_t availableSlots; + +// The number of non tab attachments. +@property(nonatomic, readonly) size_t nonTabAttachmentCount; + +// The first item in this collection, or `nil` if not present. +@property(nonatomic, readonly) ComposeboxInputItem* firstItem; + +// Adds an items to the collection. +- (void)addItem:(ComposeboxInputItem*)item; + +// Replaces the items in the collection with the given updated items. +- (void)replaceWithItems:(NSArray<ComposeboxInputItem*>*)updatedItems; + +// Removes an item from the collection. +- (void)removeItem:(ComposeboxInputItem*)item; + +// Removes all items from the collection. +- (void)clearItems; + +// Returns the item with the given `identifier` or nil if not found. +- (ComposeboxInputItem*)itemForIdentifier:(base::UnguessableToken)identifier; + +// Returns the item with the given `serverToken` or nil if not found. +- (ComposeboxInputItem*)itemForServerToken:(base::UnguessableToken)serverToken; + +// Whether the given asset identified by the `assetID` was loaded. +- (BOOL)assetAlreadyLoaded:(NSString*)assetID; + +@end + +#endif // IOS_CHROME_BROWSER_COMPOSEBOX_UI_COMPOSEBOX_INPUT_ITEM_COLLECTION_H_
diff --git a/ios/chrome/browser/composebox/ui/composebox_input_item_collection.mm b/ios/chrome/browser/composebox/ui/composebox_input_item_collection.mm new file mode 100644 index 0000000..80ff11e --- /dev/null +++ b/ios/chrome/browser/composebox/ui/composebox_input_item_collection.mm
@@ -0,0 +1,153 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/composebox/ui/composebox_input_item_collection.h" + +#import "base/check.h" +#import "base/sequence_checker.h" +#import "base/unguessable_token.h" +#import "ios/chrome/browser/composebox/ui/composebox_input_item.h" + +@implementation ComposeboxInputItemCollection { + // Check that the different methods are called from the correct sequence, as + // this class defers work via PostTask APIs. + SEQUENCE_CHECKER(_sequenceChecker); + + // The ordered list of items for display. + NSMutableArray<ComposeboxInputItem*>* _containedItems; + + // The limit of attachments. + size_t _attachmentLimit; +} + +- (instancetype)initWithAttachmentLimit:(size_t)attachmentLimit { + self = [super init]; + if (self) { + _containedItems = [[NSMutableArray alloc] init]; + _attachmentLimit = attachmentLimit; + } + + return self; +} + +#pragma mark - Public properties + +- (size_t)count { + return _containedItems.count; +} + +- (BOOL)isEmpty { + return self.count == 0; +} + +- (BOOL)hasImage { + DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); + for (ComposeboxInputItem* item in _containedItems) { + if (item.type == ComposeboxInputItemType::kComposeboxInputItemTypeImage) { + return YES; + } + } + + return NO; +} + +- (BOOL)hasTabOrFile { + DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); + for (ComposeboxInputItem* item in _containedItems) { + if (item.type == ComposeboxInputItemType::kComposeboxInputItemTypeTab || + item.type == ComposeboxInputItemType::kComposeboxInputItemTypeFile) { + return YES; + } + } + + return NO; +} + +- (BOOL)canAddMoreAttachments { + DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); + return self.count < _attachmentLimit; +} + +- (size_t)availableSlots { + DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); + return _attachmentLimit - self.count; +} + +- (size_t)nonTabAttachmentCount { + DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); + NSUInteger result = 0; + for (ComposeboxInputItem* item in _containedItems) { + if (item.type != ComposeboxInputItemType::kComposeboxInputItemTypeTab) { + result++; + } + } + return result; +} + +- (ComposeboxInputItem*)firstItem { + if (self.empty) { + return nil; + } + + return _containedItems[0]; +} + +#pragma mark - Public methods + +- (void)addItem:(ComposeboxInputItem*)item { + [_containedItems addObject:item]; + [_delegate composeboxInputItemCollectionDidUpdateItems:self]; +} + +- (void)replaceWithItems:(NSArray<ComposeboxInputItem*>*)updatedItems { + _containedItems = [updatedItems copy]; + [_delegate composeboxInputItemCollectionDidUpdateItems:self]; +} + +- (void)removeItem:(ComposeboxInputItem*)item { + [_containedItems removeObject:item]; + [_delegate composeboxInputItemCollectionDidUpdateItems:self]; +} + +- (void)clearItems { + [_containedItems removeAllObjects]; + [_delegate composeboxInputItemCollectionDidUpdateItems:self]; +} + +- (ComposeboxInputItem*)itemForIdentifier:(base::UnguessableToken)identifier { + DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); + for (ComposeboxInputItem* item in _containedItems) { + if (item.identifier == identifier) { + return item; + } + } + return nil; +} + +- (ComposeboxInputItem*)itemForServerToken:(base::UnguessableToken)serverToken { + DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); + for (ComposeboxInputItem* item in _containedItems) { + if (item.serverToken == serverToken) { + return item; + } + } + return nil; +} + +- (BOOL)assetAlreadyLoaded:(NSString*)assetID { + DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker); + + if (!assetID) { + return NO; + } + for (ComposeboxInputItem* item in _containedItems) { + if ([item.assetID isEqualToString:assetID]) { + return YES; + } + } + + return NO; +} + +@end
diff --git a/ios/chrome/browser/content_suggestions/ui_bundled/content_suggestions_coordinator.mm b/ios/chrome/browser/content_suggestions/ui_bundled/content_suggestions_coordinator.mm index 6b787e0..2696c34 100644 --- a/ios/chrome/browser/content_suggestions/ui_bundled/content_suggestions_coordinator.mm +++ b/ios/chrome/browser/content_suggestions/ui_bundled/content_suggestions_coordinator.mm
@@ -362,34 +362,31 @@ [moduleMediators addObject:_shortcutsMediator]; self.contentSuggestionsMediator.shortcutsMediator = _shortcutsMediator; - if (IsTabResumptionEnabled()) { - _tabResumptionMediator = [[TabResumptionMediator alloc] - initWithLocalState:GetApplicationContext()->GetLocalState() - prefService:prefs - identityManager:identityManager - browser:self.browser - optimizationGuideService:OptimizationGuideServiceFactory::GetForProfile( - profile) - impressionLimitService: - base::FeatureList::IsEnabled(commerce::kShopCardImpressionLimits) - ? ImpressionLimitServiceFactory::GetForProfile(profile) - : nil - shoppingService:commerce::ShoppingServiceFactory:: - GetForProfile(profile) - bookmarkModel:ios::BookmarkModelFactory::GetForProfile( - profile) - pushNotificationService:GetApplicationContext() - ->GetPushNotificationService() - authenticationService:self.authService]; - _tabResumptionMediator.NTPActionsDelegate = self.NTPActionsDelegate; - _tabResumptionMediator.contentSuggestionsMetricsRecorder = - self.contentSuggestionsMetricsRecorder; - _tabResumptionMediator.dispatcher = static_cast< - id<ApplicationCommands, PriceTrackedItemsCommands, SnackbarCommands>>( - self.browser->GetCommandDispatcher()); + _tabResumptionMediator = [[TabResumptionMediator alloc] + initWithLocalState:GetApplicationContext()->GetLocalState() + prefService:prefs + identityManager:identityManager + browser:self.browser + optimizationGuideService:OptimizationGuideServiceFactory::GetForProfile( + profile) + impressionLimitService: + base::FeatureList::IsEnabled(commerce::kShopCardImpressionLimits) + ? ImpressionLimitServiceFactory::GetForProfile(profile) + : nil + shoppingService:commerce::ShoppingServiceFactory::GetForProfile( + profile) + bookmarkModel:ios::BookmarkModelFactory::GetForProfile(profile) + pushNotificationService:GetApplicationContext() + ->GetPushNotificationService() + authenticationService:self.authService]; + _tabResumptionMediator.NTPActionsDelegate = self.NTPActionsDelegate; + _tabResumptionMediator.contentSuggestionsMetricsRecorder = + self.contentSuggestionsMetricsRecorder; + _tabResumptionMediator.dispatcher = static_cast< + id<ApplicationCommands, PriceTrackedItemsCommands, SnackbarCommands>>( + self.browser->GetCommandDispatcher()); - [moduleMediators addObject:_tabResumptionMediator]; - } + [moduleMediators addObject:_tabResumptionMediator]; if (IsPriceTrackingPromoCardEnabled(shoppingService, self.authService, prefs)) { _priceTrackingPromoMediator = [[PriceTrackingPromoMediator alloc]
diff --git a/ios/chrome/browser/content_suggestions/ui_bundled/magic_stack/coordinator/magic_stack_ranking_model.mm b/ios/chrome/browser/content_suggestions/ui_bundled/magic_stack/coordinator/magic_stack_ranking_model.mm index d60c024..c2313c62 100644 --- a/ios/chrome/browser/content_suggestions/ui_bundled/magic_stack/coordinator/magic_stack_ranking_model.mm +++ b/ios/chrome/browser/content_suggestions/ui_bundled/magic_stack/coordinator/magic_stack_ranking_model.mm
@@ -387,7 +387,6 @@ #pragma mark - TabResumptionMediatorDelegate - (void)tabResumptionMediatorDidReceiveItem { - CHECK(IsTabResumptionEnabled()); if (tab_resumption_prefs::IsTabResumptionDisabled(_prefService)) { return; } @@ -1046,8 +1045,7 @@ // Returns YES if the tab resumption module should added into the Magic Stack. - (BOOL)shouldShowTabResumption { - return IsTabResumptionEnabled() && - !tab_resumption_prefs::IsTabResumptionDisabled(_prefService) && + return !tab_resumption_prefs::IsTabResumptionDisabled(_prefService) && _tabResumptionMediator.itemConfig; }
diff --git a/ios/chrome/browser/content_suggestions/ui_bundled/tab_resumption/coordinator/tab_resumption_mediator.mm b/ios/chrome/browser/content_suggestions/ui_bundled/tab_resumption/coordinator/tab_resumption_mediator.mm index dd4c50f..5a9ef72 100644 --- a/ios/chrome/browser/content_suggestions/ui_bundled/tab_resumption/coordinator/tab_resumption_mediator.mm +++ b/ios/chrome/browser/content_suggestions/ui_bundled/tab_resumption/coordinator/tab_resumption_mediator.mm
@@ -110,6 +110,21 @@ namespace { +// A command line flag to override the default sync threshold. +const char kTabResumptionThresholdParameter[] = "tab-resumption-sync-threshold"; + +const base::TimeDelta TabResumptionForXDevicesTimeThreshold() { + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + std::string paramter = + command_line->GetSwitchValueASCII(kTabResumptionThresholdParameter); + int threshold = 0; + if (!base::StringToInt(kTabResumptionThresholdParameter, &threshold)) { + threshold = 12 * 3600; + } + return base::Seconds(threshold); +} + // Whether the item should be displayed immediately (before fetching an image). bool ShouldShowItemImmediately() { return base::CommandLine::ForCurrentProcess()->HasSwitch( @@ -422,7 +437,6 @@ authenticationService:(AuthenticationService*)authenticationService { self = [super init]; if (self) { - CHECK(IsTabResumptionEnabled()); _profilePrefs = prefService; _browser = browser; _tabId = SessionID::InvalidValue(); @@ -947,8 +961,6 @@ } else { if (item.itemType == kMostRecentTab) { [self fetchSnapshotForItem:item]; - } else { - [self fetchSalientImageForItem:item]; } } [self fetchFaviconForItem:item]; @@ -1008,8 +1020,8 @@ // Fetches the snapshot of the tab showing `item`. - (void)fetchSnapshotForItem:(TabResumptionItem*)item { - if (!IsTabResumptionImagesThumbnailsEnabled() || !item.localWebState) { - return [self fetchSalientImageForItem:item]; + if (!item.localWebState) { + return; } web::WebState* webState = item.localWebState.get(); @@ -1028,35 +1040,18 @@ [weakSelf snapshotFetched:image forItem:item]; }); - return; } - return [self fetchSalientImageForItem:item]; } // The snapshot of the tab showing `item` was fetched. - (void)snapshotFetched:(UIImage*)image forItem:(TabResumptionItem*)item { if (!image) { - return [self fetchSalientImageForItem:item]; + return; } item.contentImage = image; [self showItem:item]; } -// Fetches the salient image for `item`. -- (void)fetchSalientImageForItem:(TabResumptionItem*)item { - if (!IsTabResumptionImagesSalientEnabled() || !_pageImageService) { - return; - } - __weak TabResumptionMediator* weakSelf = self; - page_image_service::mojom::Options options; - options.optimization_guide_images = true; - options.suggest_images = false; - _pageImageService->FetchImageFor( - page_image_service::mojom::ClientId::NtpTabResumption, item.tabURL, - options, base::BindOnce(^(const GURL& URL) { - [weakSelf salientImageURLReceived:URL forItem:item updateImage:NO]; - })); -} // The URL for the salient image has been received. Download the image if it // is valid or fallbacks to favicon.
diff --git a/ios/chrome/browser/content_suggestions/ui_bundled/tab_resumption/ui/tab_resumption_view.mm b/ios/chrome/browser/content_suggestions/ui_bundled/tab_resumption/ui/tab_resumption_view.mm index c3a0c6e..741532f1 100644 --- a/ios/chrome/browser/content_suggestions/ui_bundled/tab_resumption/ui/tab_resumption_view.mm +++ b/ios/chrome/browser/content_suggestions/ui_bundled/tab_resumption/ui/tab_resumption_view.mm
@@ -29,10 +29,10 @@ const CGFloat kImageContainerCornerRadius = 12.0; -// Image container with Salient image constants -const CGFloat kImageSalientContainerSize = 72.0; +// Image container with Content image constants +const CGFloat kImageContentContainerSize = 72.0; -// Image container without Salient image constants +// Image container without Content image constants const CGFloat kImageEmptyContainerSize = 56.0; // Center Favicon constants. @@ -61,7 +61,7 @@ const CGFloat kPriceDropOverlayStartAlpha = 0.0; const CGFloat kPriceDropOverlayEndAlpha = 0.14; -// Adds the fallback image that should be used if there is no salient nor +// Adds the fallback image that should be used if there is no content nor // favicon image. void SetFallbackImageToImageView(UIImageView* image_view, UIView* background_view, @@ -232,7 +232,7 @@ } // Configures and returns the leading UIView that may contain the favicon image. -- (UIView*)configuredFaviconViewWithSalientImage:(BOOL)hasSalientImage { +- (UIView*)configuredFaviconViewWithContentImage:(BOOL)hasContentImage { UIView* faviconBackgroundView = [[UIView alloc] init]; faviconBackgroundView.translatesAutoresizingMaskIntoConstraints = NO; faviconBackgroundView.backgroundColor = UIColor.whiteColor; @@ -242,7 +242,7 @@ CGFloat faviconCornerRadius; CGFloat faviconBackgoundSize; CGFloat faviconBackgroundCornerRadius; - if (hasSalientImage) { + if (hasContentImage) { faviconSize = kCornerFaviconSize; faviconCornerRadius = kCornerFaviconCornerRadius; faviconBackgoundSize = kCornerFaviconBackgroundSize; @@ -278,7 +278,7 @@ ]]; AddSameCenterConstraints(faviconBackgroundView, faviconImageView); - if (hasSalientImage) { + if (hasContentImage) { UIRectCorner bottomTrail = UIRectCornerBottomRight; if (base::i18n::IsRTL()) { bottomTrail = UIRectCornerBottomLeft; @@ -299,9 +299,9 @@ return faviconBackgroundView; } -// Configures and returns the leading UIView that may contain the Salient image. -- (UIView*)configuredSalientImageViewWithSize:(CGFloat)containerSize { - UIImageView* salientView = [[UIImageView alloc] init]; +// Configures and returns the leading UIView that may contain the Content image. +- (UIView*)configuredContentImageViewWithSize:(CGFloat)containerSize { + UIImageView* contentImageView = [[UIImageView alloc] init]; // Compute the size of the image. CGFloat width = _item.contentImage.size.width; @@ -314,7 +314,7 @@ width = containerSize; } - // Resize the salient image. + // Resize the content image. UIGraphicsImageRendererFormat* format = [UIGraphicsImageRendererFormat preferredFormat]; format.scale = 0.0; @@ -326,11 +326,11 @@ [renderer imageWithActions:^(UIGraphicsImageRendererContext* context) { [_item.contentImage drawInRect:CGRectMake(0, 0, width, height)]; }]; - [salientView setImage:scaledImage]; + [contentImageView setImage:scaledImage]; - salientView.translatesAutoresizingMaskIntoConstraints = NO; + contentImageView.translatesAutoresizingMaskIntoConstraints = NO; - salientView.contentMode = UIViewContentModeTop; + contentImageView.contentMode = UIViewContentModeTop; // Add a gradient overlay. CAGradientLayer* gradientLayer = [CAGradientLayer layer]; @@ -352,8 +352,8 @@ static_cast<id>([UIColor colorWithWhite:0 alpha:0.2].CGColor) ]; } - [salientView.layer insertSublayer:gradientLayer atIndex:0]; - return salientView; + [contentImageView.layer insertSublayer:gradientLayer atIndex:0]; + return contentImageView; } // Configures and returns the leading UIView that contains the image. @@ -363,18 +363,16 @@ containerView.layer.cornerRadius = kImageContainerCornerRadius; containerView.clipsToBounds = YES; - BOOL hasSalientImage = NO; + BOOL hasContentImage = NO; CGFloat containerSize; if (_item.contentImage && - (IsTabResumptionImagesSalientEnabled() || - IsTabResumptionImagesThumbnailsEnabled() || HasPriceDropOnTab(_item)) && _item.contentImage.size.width && _item.contentImage.size.height) { - hasSalientImage = YES; - containerSize = kImageSalientContainerSize; - UIView* salientView = - [self configuredSalientImageViewWithSize:containerSize]; - [containerView addSubview:salientView]; - AddSameConstraints(salientView, containerView); + hasContentImage = YES; + containerSize = kImageContentContainerSize; + UIView* contentImageView = + [self configuredContentImageViewWithSize:containerSize]; + [containerView addSubview:contentImageView]; + AddSameConstraints(contentImageView, containerView); } else { containerView.backgroundColor = [UIColor colorNamed:kGrey100Color]; containerSize = kImageEmptyContainerSize; @@ -385,14 +383,14 @@ [containerView.heightAnchor constraintEqualToConstant:containerSize], ]]; - if (hasSalientImage && !_item.faviconImage) { + if (hasContentImage && !_item.faviconImage) { return containerView; } UIView* faviconView = - [self configuredFaviconViewWithSalientImage:hasSalientImage]; + [self configuredFaviconViewWithContentImage:hasContentImage]; [containerView addSubview:faviconView]; - if (!hasSalientImage) { + if (!hasContentImage) { AddSameCenterConstraints(faviconView, containerView); } else { [NSLayoutConstraint activateConstraints:@[
diff --git a/ios/chrome/browser/data_import/public/BUILD.gn b/ios/chrome/browser/data_import/public/BUILD.gn index c49b5b02..fcad350b 100644 --- a/ios/chrome/browser/data_import/public/BUILD.gn +++ b/ios/chrome/browser/data_import/public/BUILD.gn
@@ -6,6 +6,8 @@ sources = [ "accessibility_utils.h", "accessibility_utils.mm", + "conflict_item_identifier.h", + "conflict_item_identifier.mm", "import_data_item.h", "import_data_item.mm", "import_data_item_consumer.h",
diff --git a/ios/chrome/browser/data_import/public/conflict_item_identifier.h b/ios/chrome/browser/data_import/public/conflict_item_identifier.h new file mode 100644 index 0000000..9b41a1f918 --- /dev/null +++ b/ios/chrome/browser/data_import/public/conflict_item_identifier.h
@@ -0,0 +1,28 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_DATA_IMPORT_PUBLIC_CONFLICT_ITEM_IDENTIFIER_H_ +#define IOS_CHROME_BROWSER_DATA_IMPORT_PUBLIC_CONFLICT_ITEM_IDENTIFIER_H_ + +#import <Foundation/Foundation.h> + +enum class CredentialConflictType { + kPassword, + kPasskey, +}; + +// Identifier for a conflicting credential item used in +// UITableViewDiffableDataSource of a conflict resolution screen. +@interface ConflictItemIdentifier : NSObject + +@property(nonatomic, readonly) CredentialConflictType type; +@property(nonatomic, readonly) NSUInteger index; + +- (instancetype)initWithType:(CredentialConflictType)type + index:(NSInteger)index NS_DESIGNATED_INITIALIZER; +- (instancetype)init NS_UNAVAILABLE; + +@end + +#endif // IOS_CHROME_BROWSER_DATA_IMPORT_PUBLIC_CONFLICT_ITEM_IDENTIFIER_H_
diff --git a/ios/chrome/browser/data_import/public/conflict_item_identifier.mm b/ios/chrome/browser/data_import/public/conflict_item_identifier.mm new file mode 100644 index 0000000..802c61fc --- /dev/null +++ b/ios/chrome/browser/data_import/public/conflict_item_identifier.mm
@@ -0,0 +1,42 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/data_import/public/conflict_item_identifier.h" + +#import "base/apple/foundation_util.h" + +@implementation ConflictItemIdentifier + +- (instancetype)initWithType:(CredentialConflictType)type + index:(NSInteger)index { + self = [super init]; + if (self) { + _type = type; + _index = index; + } + return self; +} + +#pragma mark - NSObject + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + ConflictItemIdentifier* other = + base::apple::ObjCCast<ConflictItemIdentifier>(object); + return other && self.type == other.type && self.index == other.index; +} + +- (NSUInteger)hash { + return (static_cast<NSUInteger>(self.type) << 31) + self.index; +} + +- (NSString*)description { + return [NSString stringWithFormat:@"<%@: %p, type: %ld, index: %lu>", + [self class], self, (long)self.type, + (unsigned long)self.index]; +} + +@end
diff --git a/ios/chrome/browser/data_import/ui/data_import_credential_conflict_resolution_view_controller.mm b/ios/chrome/browser/data_import/ui/data_import_credential_conflict_resolution_view_controller.mm index 9dc64ea3..5b2fea86 100644 --- a/ios/chrome/browser/data_import/ui/data_import_credential_conflict_resolution_view_controller.mm +++ b/ios/chrome/browser/data_import/ui/data_import_credential_conflict_resolution_view_controller.mm
@@ -7,6 +7,7 @@ #import "base/check_op.h" #import "components/strings/grit/components_strings.h" #import "ios/chrome/browser/data_import/public/accessibility_utils.h" +#import "ios/chrome/browser/data_import/public/conflict_item_identifier.h" #import "ios/chrome/browser/data_import/public/metrics.h" #import "ios/chrome/browser/data_import/public/password_import_item.h" #import "ios/chrome/browser/data_import/ui/data_import_credential_conflict_mutator.h" @@ -40,7 +41,8 @@ /// at the respective index should be unmasked for display. NSMutableArray<NSNumber*>* _shouldUnmaskPasswordAtIndex; /// The data source painting each cell in the table from `_passwordConflicts`. - UITableViewDiffableDataSource<NSString*, NSNumber*>* _dataSource; + UITableViewDiffableDataSource<NSString*, ConflictItemIdentifier*>* + _dataSource; /// The "select" and "deselect" buttons. UIBarButtonItem* _selectButton; UIBarButtonItem* _deselectButton; @@ -134,8 +136,11 @@ DataImportCredentialConflictScreenAction::kContinue); NSMutableArray<NSNumber*>* passwordIdentifiers = [NSMutableArray array]; for (NSIndexPath* indexPath in [self.tableView indexPathsForSelectedRows]) { - [passwordIdentifiers - addObject:[_dataSource itemIdentifierForIndexPath:indexPath]]; + ConflictItemIdentifier* identifier = + [_dataSource itemIdentifierForIndexPath:indexPath]; + if (identifier.type == CredentialConflictType::kPassword) { + [passwordIdentifiers addObject:@(identifier.index)]; + } } [self.mutator continueToImportPasswords:passwordIdentifiers]; [self.presentingViewController dismissViewControllerAnimated:YES @@ -145,8 +150,12 @@ - (void)didTapSelectionButton { NSUInteger totalCount = _passwordConflicts.count; BOOL deselect = totalCount == [self selectedItemsCount]; - for (NSUInteger idx = 0; idx < totalCount; idx++) { - NSIndexPath* indexPath = [_dataSource indexPathForItemIdentifier:@(idx)]; + NSArray<ConflictItemIdentifier*>* identifiers = [[_dataSource snapshot] + itemIdentifiersInSectionWithIdentifier: + kDataImportCredentialConflictResolutionSection]; + for (ConflictItemIdentifier* identifier in identifiers) { + NSIndexPath* indexPath = + [_dataSource indexPathForItemIdentifier:identifier]; if (deselect) { [self.tableView deselectRowAtIndexPath:indexPath animated:NO]; } else { @@ -180,15 +189,15 @@ /// Returns the cell with the properties of the `item` displayed. - (UITableViewCell*)cellForIndexPath:(NSIndexPath*)indexPath - itemIdentifier:(NSNumber*)identifier { + itemIdentifier:(ConflictItemIdentifier*)identifier { /// Populate cell with information. - PasswordImportItem* item = _passwordConflicts[identifier.intValue]; + PasswordImportItem* item = _passwordConflicts[identifier.index]; UITableViewCell* cell = DequeueTableViewCell<UITableViewCell>(self.tableView); cell.accessibilityIdentifier = GetPasswordConflictResolutionTableViewCellAccessibilityIdentifier( - indexPath.item); + identifier.index); PasswordImportItemCellContentConfiguration* config; - if (_shouldUnmaskPasswordAtIndex[identifier.intValue].boolValue) { + if (_shouldUnmaskPasswordAtIndex[identifier.index].boolValue) { config = [PasswordImportItemCellContentConfiguration cellConfigurationForUnmaskPassword:item]; } else { @@ -212,8 +221,8 @@ } /// Helper method to update the cell with `identifier`. -- (void)updateItemWithIdentifier:(NSNumber*)identifier { - NSDiffableDataSourceSnapshot<NSString*, NSNumber*>* snapshot = +- (void)updateItemWithIdentifier:(ConflictItemIdentifier*)identifier { + NSDiffableDataSourceSnapshot<NSString*, ConflictItemIdentifier*>* snapshot = [_dataSource snapshot]; [snapshot reconfigureItemsWithIdentifiers:@[ identifier ]]; [_dataSource applySnapshot:snapshot animatingDifferences:NO]; @@ -265,7 +274,7 @@ __weak __typeof(self) weakSelf = self; UITableViewDiffableDataSourceCellProvider cellProvider = ^UITableViewCell*( UITableView* tableView, NSIndexPath* indexPath, - NSNumber* itemIdentifier) { + ConflictItemIdentifier* itemIdentifier) { CHECK_EQ(tableView, weakSelf.tableView); return [weakSelf cellForIndexPath:indexPath itemIdentifier:itemIdentifier]; }; @@ -278,11 +287,17 @@ [snapshot appendSectionsWithIdentifiers:@[ kDataImportCredentialConflictResolutionSection ]]; - NSMutableArray* indicesForPasswordConflicts = [NSMutableArray array]; + + NSMutableArray<ConflictItemIdentifier*>* itemIdentifiers = + [NSMutableArray array]; for (NSUInteger i = 0; i < _passwordConflicts.count; i++) { - [indicesForPasswordConflicts addObject:@(i)]; + [itemIdentifiers + addObject:[[ConflictItemIdentifier alloc] + initWithType:CredentialConflictType::kPassword + index:i]]; } - [snapshot appendItemsWithIdentifiers:indicesForPasswordConflicts + + [snapshot appendItemsWithIdentifiers:itemIdentifiers intoSectionWithIdentifier: kDataImportCredentialConflictResolutionSection]; [_dataSource applySnapshot:snapshot animatingDifferences:NO]; @@ -298,12 +313,13 @@ } /// Helper method to set up the accessory view. -- (UIView*)accessoryViewForItemIdentifier:(NSNumber*)identifier { - if (![[self reauthenticationModule] canAttemptReauth]) { +- (UIView*)accessoryViewForItemIdentifier:(ConflictItemIdentifier*)identifier { + if (identifier.type == CredentialConflictType::kPasskey || + ![[self reauthenticationModule] canAttemptReauth]) { return nil; } BOOL forUnmaskAction = - !(_shouldUnmaskPasswordAtIndex[identifier.intValue].boolValue); + !(_shouldUnmaskPasswordAtIndex[identifier.index].boolValue); UIButtonConfiguration* configuration = [UIButtonConfiguration plainButtonConfiguration]; NSString* symbol_name = @@ -333,11 +349,15 @@ /// Reveal password if `shouldUnmask` is YES and user is authenticated to view /// passwords; mask password if otherwise. - (void)maybeUpdatePasswordMasking:(BOOL)shouldUnmask - forItemWithIdentifier:(NSNumber*)identifier + forItemWithIdentifier:(ConflictItemIdentifier*)identifier authenticated:(BOOL)authenticated { + if (identifier.type == CredentialConflictType::kPasskey) { + return; + } + if (!shouldUnmask || authenticated || ![[self reauthenticationModule] canAttemptReauth]) { - _shouldUnmaskPasswordAtIndex[identifier.intValue] = @(shouldUnmask); + _shouldUnmaskPasswordAtIndex[identifier.index] = @(shouldUnmask); [self updateItemWithIdentifier:identifier]; return; }
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 6f1f8b5..b1354b7 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -456,18 +456,6 @@ {"Display promo during FRE", kIOSDockingPromoDisplayedDuringFRE, std::size(kIOSDockingPromoDisplayedDuringFRE), nullptr}}; -const FeatureEntry::FeatureParam kTabResumptionImagesOnlyThumbnail[] = { - {kTabResumptionImagesTypes, kTabResumptionImagesTypesThumbnails}}; -const FeatureEntry::FeatureParam kTabResumptionImagesOnlySalient[] = { - {kTabResumptionImagesTypes, kTabResumptionImagesTypesSalient}}; - -const FeatureEntry::FeatureVariation kTabResumptionImagesVariations[] = { - {"Only thumbnails", kTabResumptionImagesOnlyThumbnail, - std::size(kTabResumptionImagesOnlyThumbnail), nullptr}, - {"Only salient", kTabResumptionImagesOnlySalient, - std::size(kTabResumptionImagesOnlySalient), nullptr}, -}; - // Uses int values from Lens filters ablation mode enum. const FeatureEntry::FeatureParam kLensFiltersAblationModeDisabled[] = { {kLensFiltersAblationMode, "0"}}; @@ -1872,9 +1860,6 @@ flag_descriptions::kSpotlightNeverRetainIndexName, flag_descriptions::kSpotlightNeverRetainIndexDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kSpotlightNeverRetainIndex)}, - {"tab-resumption", flag_descriptions::kTabResumptionName, - flag_descriptions::kTabResumptionDescription, flags_ui::kOsIos, - FEATURE_VALUE_TYPE(kTabResumption)}, {"bottom-omnibox-evolution", flag_descriptions::kBottomOmniboxEvolutionName, flag_descriptions::kBottomOmniboxEvolutionDescription, flags_ui::kOsIos, FEATURE_WITH_PARAMS_VALUE_TYPE(kBottomOmniboxEvolution, @@ -2139,11 +2124,6 @@ FEATURE_WITH_PARAMS_VALUE_TYPE(kIOSSoftLock, kIOSSoftLockVariations, "IOSSoftLock")}, - {"tab-resumption-images", flag_descriptions::kTabResumptionImagesName, - flag_descriptions::kTabResumptionImagesDescription, flags_ui::kOsIos, - FEATURE_WITH_PARAMS_VALUE_TYPE(kTabResumptionImages, - kTabResumptionImagesVariations, - "TabResumption1_5")}, {"segmentation-platform-tips-ephemeral-card", flag_descriptions::kSegmentationPlatformTipsEphemeralCardName, flag_descriptions::kSegmentationPlatformTipsEphemeralCardDescription,
diff --git a/ios/chrome/browser/location_bar/ui_bundled/location_bar_coordinator.mm b/ios/chrome/browser/location_bar/ui_bundled/location_bar_coordinator.mm index 3574c809..44f0588 100644 --- a/ios/chrome/browser/location_bar/ui_bundled/location_bar_coordinator.mm +++ b/ios/chrome/browser/location_bar/ui_bundled/location_bar_coordinator.mm
@@ -17,9 +17,8 @@ #import "components/profile_metrics/browser_profile_type.h" #import "components/search_engines/util.h" #import "components/strings/grit/components_strings.h" +#import "ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.h" #import "ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.h" -#import "ios/chrome/browser/autocomplete/model/autocomplete_service.h" -#import "ios/chrome/browser/autocomplete/model/autocomplete_service_factory.h" #import "ios/chrome/browser/badges/ui_bundled/badge_button_factory.h" #import "ios/chrome/browser/badges/ui_bundled/badge_delegate.h" #import "ios/chrome/browser/badges/ui_bundled/badge_mediator.h" @@ -420,11 +419,11 @@ omniboxPositionBrowserAgent->SetOmniboxStateProvider(self); } - AutocompleteService* autocompleteService = - AutocompleteServiceFactory::GetForProfile(self.profile); - if (autocompleteService) { + AutocompleteBrowserAgent* autocompleteBrowserAgent = + AutocompleteBrowserAgent::FromBrowser(self.browser); + if (autocompleteBrowserAgent) { __weak __typeof__(self) weakSelf = self; - autocompleteService->RegisterWebStateListForPrefetching( + autocompleteBrowserAgent->RegisterWebStateListForPrefetching( IsComposeboxIOSEnabled() ? OmniboxPresentationContext::kComposebox : OmniboxPresentationContext::kLocationBar, self.webStateList, @@ -467,12 +466,12 @@ // TODO(crbug.com/462700929): Cleanup the service's objects like when it was // owned by the omnibox. Remove this workaround once the service can be safely // cleaned up during shutdown. - AutocompleteService* autocompleteService = - AutocompleteServiceFactory::GetForProfile(self.profile); - if (autocompleteService) { - autocompleteService->UnregisterWebStateListForPrefetching( + AutocompleteBrowserAgent* autocompleteBrowserAgent = + AutocompleteBrowserAgent::FromBrowser(self.browser); + if (autocompleteBrowserAgent) { + autocompleteBrowserAgent->UnregisterWebStateListForPrefetching( self.webStateList); - autocompleteService->RemoveServices(); + autocompleteBrowserAgent->RemoveServices(); } [self.badgeMediator disconnect]; self.badgeMediator = nil;
diff --git a/ios/chrome/browser/location_bar/ui_bundled/location_bar_coordinator_unittest.mm b/ios/chrome/browser/location_bar/ui_bundled/location_bar_coordinator_unittest.mm index 518a09aa..5315f159 100644 --- a/ios/chrome/browser/location_bar/ui_bundled/location_bar_coordinator_unittest.mm +++ b/ios/chrome/browser/location_bar/ui_bundled/location_bar_coordinator_unittest.mm
@@ -11,6 +11,7 @@ #import "components/omnibox/browser/test_location_bar_model.h" #import "components/variations/scoped_variations_ids_provider.h" #import "components/variations/variations_ids_provider.h" +#import "ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.h" #import "ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.h" #import "ios/chrome/browser/favicon/model/favicon_service_factory.h" #import "ios/chrome/browser/favicon/model/ios_chrome_favicon_loader_factory.h" @@ -111,6 +112,7 @@ // must be created first. Please maintain this order. ToolbarsSizeBrowserAgent::CreateForBrowser(browser_.get()); FullscreenController::CreateForBrowser(browser_.get()); + AutocompleteBrowserAgent::CreateForBrowser(browser_.get()); auto web_state = std::make_unique<web::FakeWebState>(); web_state->SetBrowserState(profile_.get());
diff --git a/ios/chrome/browser/main/model/BUILD.gn b/ios/chrome/browser/main/model/BUILD.gn index 8765d36..a6a7b97d 100644 --- a/ios/chrome/browser/main/model/BUILD.gn +++ b/ios/chrome/browser/main/model/BUILD.gn
@@ -21,6 +21,7 @@ "//components/breadcrumbs/core:status", "//components/data_sharing/public:features", "//ios/chrome/browser/app_launcher/model", + "//ios/chrome/browser/autocomplete/model", "//ios/chrome/browser/browser_view/model", "//ios/chrome/browser/bubble/model", "//ios/chrome/browser/collaboration/model",
diff --git a/ios/chrome/browser/main/model/DEPS b/ios/chrome/browser/main/model/DEPS index 3089df4..3c246a0 100644 --- a/ios/chrome/browser/main/model/DEPS +++ b/ios/chrome/browser/main/model/DEPS
@@ -14,6 +14,7 @@ # go/keep-sorted start "+components/data_sharing/public/features.h", "+ios/chrome/browser/app_launcher/model/app_launcher_browser_agent.h", + "+ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.h", "+ios/chrome/browser/browser_view/model/browser_view_visibility_notifier_browser_agent.h", "+ios/chrome/browser/bubble/model", "+ios/chrome/browser/collaboration/model/collaboration_service_factory.h",
diff --git a/ios/chrome/browser/main/model/browser_agent_util.mm b/ios/chrome/browser/main/model/browser_agent_util.mm index 18ee1e74..76e667b 100644 --- a/ios/chrome/browser/main/model/browser_agent_util.mm +++ b/ios/chrome/browser/main/model/browser_agent_util.mm
@@ -9,6 +9,7 @@ #import "components/breadcrumbs/core/breadcrumbs_status.h" #import "components/data_sharing/public/features.h" #import "ios/chrome/browser/app_launcher/model/app_launcher_browser_agent.h" +#import "ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.h" #import "ios/chrome/browser/browser_view/model/browser_view_visibility_notifier_browser_agent.h" #import "ios/chrome/browser/bubble/model/tab_based_iph_browser_agent.h" #import "ios/chrome/browser/collaboration/model/collaboration_service_factory.h" @@ -120,6 +121,7 @@ UrlLoadingNotifierBrowserAgent::CreateForBrowser(browser); AppLauncherBrowserAgent::CreateForBrowser(browser); OmniboxPositionBrowserAgent::CreateForBrowser(browser); + AutocompleteBrowserAgent::CreateForBrowser(browser); ToolbarsSizeBrowserAgent::CreateForBrowser(browser); // Only create the FullscreenBrowserAgent and ReaderModeBrowserAgent for
diff --git a/ios/chrome/browser/omnibox/coordinator/omnibox_coordinator.mm b/ios/chrome/browser/omnibox/coordinator/omnibox_coordinator.mm index fcfbafb..44071011 100644 --- a/ios/chrome/browser/omnibox/coordinator/omnibox_coordinator.mm +++ b/ios/chrome/browser/omnibox/coordinator/omnibox_coordinator.mm
@@ -16,8 +16,7 @@ #import "components/open_from_clipboard/clipboard_recent_content.h" #import "components/search_engines/template_url_service.h" #import "components/strings/grit/components_strings.h" -#import "ios/chrome/browser/autocomplete/model/autocomplete_service.h" -#import "ios/chrome/browser/autocomplete/model/autocomplete_service_factory.h" +#import "ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.h" #import "ios/chrome/browser/favicon/model/ios_chrome_favicon_loader_factory.h" #import "ios/chrome/browser/feature_engagement/model/tracker_factory.h" #import "ios/chrome/browser/location_bar/ui_bundled/location_bar_constants.h" @@ -179,10 +178,10 @@ _omniboxTextModel = std::make_unique<OmniboxTextModel>(_client.get()); id<OmniboxTextInput> textInput = viewController.textInput; - AutocompleteService* autocompleteService = - AutocompleteServiceFactory::GetForProfile(profile); + AutocompleteBrowserAgent* autocompleteBrowserAgent = + AutocompleteBrowserAgent::FromBrowser(browser); AutocompleteController* autocompleteController = - autocompleteService->GetAutocompleteController(_presentationContext); + autocompleteBrowserAgent->GetAutocompleteController(_presentationContext); _omniboxAutocompleteController = [[OmniboxAutocompleteController alloc] initWithOmniboxClient:_client.get()
diff --git a/ios/chrome/browser/omnibox/eg_tests/inttest/omnibox_inttest_coordinator.mm b/ios/chrome/browser/omnibox/eg_tests/inttest/omnibox_inttest_coordinator.mm index 9346e55..c37660d4 100644 --- a/ios/chrome/browser/omnibox/eg_tests/inttest/omnibox_inttest_coordinator.mm +++ b/ios/chrome/browser/omnibox/eg_tests/inttest/omnibox_inttest_coordinator.mm
@@ -29,7 +29,7 @@ OmniboxInttestViewController* _viewController; raw_ptr<FakeOmniboxClient> _fakeOmniboxClient; raw_ptr<FakeSuggestionsBuilder> _fakeSuggestionsBuilder; - // TODO(crbug.com/462066136): Move to a TestAutocompleteService. + // TODO(crbug.com/462066136): Move to a TestAutocompleteBrowserAgent. std::unique_ptr<OmniboxInttestAutocompleteController> _autocompleteController; }
diff --git a/ios/chrome/browser/omnibox/model/chrome_omnibox_client_ios.mm b/ios/chrome/browser/omnibox/model/chrome_omnibox_client_ios.mm index ca35b71f..54b8b3bd 100644 --- a/ios/chrome/browser/omnibox/model/chrome_omnibox_client_ios.mm +++ b/ios/chrome/browser/omnibox/model/chrome_omnibox_client_ios.mm
@@ -19,10 +19,9 @@ #import "components/omnibox/browser/omnibox_log.h" #import "components/omnibox/common/omnibox_features.h" #import "components/search_engines/template_url_service.h" +#import "ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.h" #import "ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.h" #import "ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.h" -#import "ios/chrome/browser/autocomplete/model/autocomplete_service.h" -#import "ios/chrome/browser/autocomplete/model/autocomplete_service_factory.h" #import "ios/chrome/browser/autocomplete/model/omnibox_shortcuts_helper.h" #import "ios/chrome/browser/bookmarks/model/bookmark_model_factory.h" #import "ios/chrome/browser/bookmarks/model/bookmarks_utils.h" @@ -279,10 +278,10 @@ const std::u16string& text, const AutocompleteMatch& match, const AutocompleteMatch& alternative_nav_match) { - AutocompleteService* autocomplete_service = - AutocompleteServiceFactory::GetForProfile(profile_); + AutocompleteBrowserAgent* autocomplete_browser_agent = + AutocompleteBrowserAgent::FromBrowser(browser_); OmniboxShortcutsHelper* shortcuts_helper = - autocomplete_service->GetOmniboxShortcutsHelper( + autocomplete_browser_agent->GetOmniboxShortcutsHelper( OmniboxPresentationContext::kLocationBar); if (shortcuts_helper) { shortcuts_helper->OnAutocompleteAccept(text, match,
diff --git a/ios/chrome/browser/omnibox/ui/omnibox_drs_view_controller.mm b/ios/chrome/browser/omnibox/ui/omnibox_drs_view_controller.mm index 8d3f3ab6..a98f88e 100644 --- a/ios/chrome/browser/omnibox/ui/omnibox_drs_view_controller.mm +++ b/ios/chrome/browser/omnibox/ui/omnibox_drs_view_controller.mm
@@ -237,7 +237,7 @@ } - (void)popupDidCloseForPresenter:(OmniboxPopupPresenter*)presenter { - [self.proxiedPresenterDelegate popupDidOpenForPresenter:presenter]; + [self.proxiedPresenterDelegate popupDidCloseForPresenter:presenter]; [self close]; }
diff --git a/ios/chrome/browser/profile/model/keyed_service_factories.mm b/ios/chrome/browser/profile/model/keyed_service_factories.mm index 2043831..a3a6e202 100644 --- a/ios/chrome/browser/profile/model/keyed_service_factories.mm +++ b/ios/chrome/browser/profile/model/keyed_service_factories.mm
@@ -11,7 +11,6 @@ #import "ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.h" #import "ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.h" #import "ios/chrome/browser/autocomplete/model/autocomplete_scoring_model_service_factory.h" -#import "ios/chrome/browser/autocomplete/model/autocomplete_service_factory.h" #import "ios/chrome/browser/autocomplete/model/in_memory_url_index_factory.h" #import "ios/chrome/browser/autocomplete/model/on_device_tail_model_service_factory.h" #import "ios/chrome/browser/autocomplete/model/provider_state_service_factory.h" @@ -268,7 +267,6 @@ AcceptLanguagesServiceFactory::GetInstance(); AppStoreBundleServiceFactory::GetInstance(); AuthenticationServiceFactory::GetInstance(); - AutocompleteServiceFactory::GetInstance(); BackgroundDownloadServiceFactory::GetInstance(); BookmarkModelMetricsServiceFactory::GetInstance(); BreadcrumbManagerKeyedServiceFactory::GetInstance();
diff --git a/ios/chrome/browser/qr_scanner/ui_bundled/BUILD.gn b/ios/chrome/browser/qr_scanner/ui_bundled/BUILD.gn index 0fc463d..9854426c 100644 --- a/ios/chrome/browser/qr_scanner/ui_bundled/BUILD.gn +++ b/ios/chrome/browser/qr_scanner/ui_bundled/BUILD.gn
@@ -55,6 +55,7 @@ "//ios/chrome/app/strings", "//ios/chrome/browser/scanner/ui_bundled:camera_state", "//ios/chrome/browser/settings/ui_bundled:eg_test_support+eg2", + "//ios/chrome/browser/shared/public/features", "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/testing/earl_grey:eg_test_support+eg2", "//net",
diff --git a/ios/chrome/browser/qr_scanner/ui_bundled/qr_scanner_view_controller_egtest.mm b/ios/chrome/browser/qr_scanner/ui_bundled/qr_scanner_view_controller_egtest.mm index 7a5bead..8d9e7daa 100644 --- a/ios/chrome/browser/qr_scanner/ui_bundled/qr_scanner_view_controller_egtest.mm +++ b/ios/chrome/browser/qr_scanner/ui_bundled/qr_scanner_view_controller_egtest.mm
@@ -12,6 +12,7 @@ #import "ios/chrome/browser/qr_scanner/ui_bundled/qr_scanner_app_interface.h" #import "ios/chrome/browser/scanner/ui_bundled/camera_state.h" #import "ios/chrome/browser/settings/ui_bundled/settings_app_interface.h" +#import "ios/chrome/browser/shared/public/features/features.h" #import "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" @@ -214,6 +215,12 @@ std::unique_ptr<EarlGreyScopedBlockSwizzler> _camera_controller_swizzler; } +- (AppLaunchConfiguration)appConfigurationForTestCase { + AppLaunchConfiguration config = [super appConfigurationForTestCase]; + config.features_disabled.push_back(kComposeboxIOS); + return config; +} + - (void)setUp { [super setUp];
diff --git a/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_table_view_controller.mm b/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_table_view_controller.mm index d78f1eb5..1a9f45a 100644 --- a/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_table_view_controller.mm +++ b/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_table_view_controller.mm
@@ -102,10 +102,8 @@ withRowAnimation:UITableViewRowAnimationMiddle]; } else { [UIView performWithoutAnimation:^{ - [self.tableView beginUpdates]; [self.tableView insertSections:sections withRowAnimation:UITableViewRowAnimationNone]; - [self.tableView endUpdates]; }]; } } @@ -121,10 +119,8 @@ } else { // To avoid animation glitches related to crbug.com/1469539. [UIView performWithoutAnimation:^{ - [self.tableView beginUpdates]; [self.tableView deleteSections:sections withRowAnimation:UITableViewRowAnimationNone]; - [self.tableView endUpdates]; }]; } } @@ -149,10 +145,8 @@ } // To avoid animation glitches related to crbug.com/1469539. [UIView performWithoutAnimation:^{ - [self.tableView beginUpdates]; [self.tableView reloadRowsAtIndexPaths:@[ indexPath ] withRowAnimation:UITableViewRowAnimationNone]; - [self.tableView endUpdates]; }]; }
diff --git a/ios/chrome/browser/shared/coordinator/scene/BUILD.gn b/ios/chrome/browser/shared/coordinator/scene/BUILD.gn index aef439a..46a3f72 100644 --- a/ios/chrome/browser/shared/coordinator/scene/BUILD.gn +++ b/ios/chrome/browser/shared/coordinator/scene/BUILD.gn
@@ -47,6 +47,15 @@ ] } +source_set("scene_state_header_for_otr_profile_deletion") { + visibility = [ + ":scene", + "//ios/chrome/app/profile:otr_profile_destroyer_profile_agent", + ] + sources = [ "scene_controller+OTRProfileDeletion.h" ] + deps = [ ":scene_state_header" ] +} + source_set("scene_testing") { sources = [ "scene_controller_testing.h" ] frameworks = [ "UIKit.framework" ] @@ -60,6 +69,7 @@ ] deps = [ + ":scene_state_header_for_otr_profile_deletion", ":scene_util", "//base", "//components/autofill/core/browser", @@ -205,7 +215,6 @@ "//ios/chrome/browser/tab_switcher/ui_bundled:utils", "//ios/chrome/browser/tab_switcher/ui_bundled/tab_grid", "//ios/chrome/browser/url_loading/model", - "//ios/chrome/browser/web_state_list/model:session_metrics", "//ios/chrome/browser/web_state_list/model/web_usage_enabler", "//ios/chrome/browser/whats_new/coordinator/promo", "//ios/chrome/browser/widget_kit/model:features",
diff --git a/ios/chrome/browser/shared/coordinator/scene/scene_controller+OTRProfileDeletion.h b/ios/chrome/browser/shared/coordinator/scene/scene_controller+OTRProfileDeletion.h new file mode 100644 index 0000000..ecfd66c --- /dev/null +++ b/ios/chrome/browser/shared/coordinator/scene/scene_controller+OTRProfileDeletion.h
@@ -0,0 +1,20 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_SHARED_COORDINATOR_SCENE_SCENE_CONTROLLER_OTRPROFILEDELETION_H_ +#define IOS_CHROME_BROWSER_SHARED_COORDINATOR_SCENE_SCENE_CONTROLLER_OTRPROFILEDELETION_H_ + +#import "ios/chrome/browser/shared/coordinator/scene/scene_controller.h" + +@interface SceneController (OTRProfileDeletion) + +// Must be called before destroying the incognito Profile. +- (void)willDestroyIncognitoProfile; + +// Must be called after recreating the incognito Profile. +- (void)incognitoProfileCreated; + +@end + +#endif // IOS_CHROME_BROWSER_SHARED_COORDINATOR_SCENE_SCENE_CONTROLLER_OTRPROFILEDELETION_H_
diff --git a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm index 6812f08..c810732 100644 --- a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm +++ b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
@@ -74,7 +74,6 @@ #import "ios/chrome/browser/browsing_data/model/browsing_data_remover.h" #import "ios/chrome/browser/browsing_data/model/browsing_data_remover_factory.h" #import "ios/chrome/browser/crash_report/model/breadcrumbs/breadcrumb_manager_browser_agent.h" -#import "ios/chrome/browser/crash_report/model/crash_keys_helper.h" #import "ios/chrome/browser/crash_report/model/crash_loop_detection_util.h" #import "ios/chrome/browser/crash_report/model/crash_report_helper.h" #import "ios/chrome/browser/credential_provider_promo/ui_bundled/credential_provider_promo_scene_agent.h" @@ -140,6 +139,7 @@ #import "ios/chrome/browser/share_extension/model/share_extension_scene_agent.h" #import "ios/chrome/browser/shared/coordinator/default_browser_promo/non_modal_default_browser_promo_scheduler_scene_agent.h" #import "ios/chrome/browser/shared/coordinator/layout_guide/layout_guide_scene_agent.h" +#import "ios/chrome/browser/shared/coordinator/scene/scene_controller+OTRProfileDeletion.h" #import "ios/chrome/browser/shared/coordinator/scene/scene_ui_provider.h" #import "ios/chrome/browser/shared/coordinator/scene/url_context.h" #import "ios/chrome/browser/shared/model/application_context/application_context.h" @@ -203,7 +203,6 @@ #import "ios/chrome/browser/url_loading/model/scene_url_loading_service.h" #import "ios/chrome/browser/url_loading/model/url_loading_browser_agent.h" #import "ios/chrome/browser/url_loading/model/url_loading_params.h" -#import "ios/chrome/browser/web_state_list/model/session_metrics.h" #import "ios/chrome/browser/web_state_list/model/web_usage_enabler/web_usage_enabler_browser_agent.h" #import "ios/chrome/browser/whats_new/coordinator/promo/whats_new_scene_agent.h" #import "ios/chrome/browser/widget_kit/model/features.h" @@ -222,8 +221,6 @@ #import "ios/web/public/navigation/navigation_manager.h" #import "ios/web/public/navigation/navigation_util.h" #import "ios/web/public/session/proto/storage.pb.h" -#import "ios/web/public/thread/web_task_traits.h" -#import "ios/web/public/thread/web_thread.h" #import "ios/web/public/web_state.h" #import "net/base/apple/url_conversions.h" #import "net/base/url_util.h" @@ -4390,27 +4387,6 @@ // Called when the last incognito tab was closed. - (void)lastIncognitoTabClosed { - // If no other window has incognito tab, then destroy and rebuild the - // Profile. Otherwise, just do the state transition animation. - if ([self shouldDestroyAndRebuildIncognitoProfile]) { - // Incognito profile cannot be deleted before all the requests are - // deleted. Queue empty task on IO thread and destroy the Profile - // when the task has executed, again verifying that no incognito tabs are - // present. When an incognito tab is moved between browsers, there is - // a point where the tab isn't attached to any web state list. However, when - // this queued cleanup step executes, the moved tab will be attached, so - // the cleanup shouldn't proceed. - - auto cleanup = ^{ - if ([self shouldDestroyAndRebuildIncognitoProfile]) { - [self destroyAndRebuildIncognitoProfile]; - } - }; - - web::GetIOThreadTaskRunner({})->PostTaskAndReply( - FROM_HERE, base::DoNothing(), base::BindRepeating(cleanup)); - } - // a) The first condition can happen when the last incognito tab is closed // from the tab switcher. // b) The second condition can happen if some other code (like JS) triggers @@ -4440,22 +4416,6 @@ [self showTabSwitcher]; } -// Clears incognito data that is specific to iOS and won't be cleared by -// deleting the profile. -- (void)clearIOSSpecificIncognitoData { - DCHECK(self.profile->HasOffTheRecordProfile()); - ProfileIOS* otrProfile = self.profile->GetOffTheRecordProfile(); - - __weak SceneController* weakSelf = self; - BrowsingDataRemover* browsingDataRemover = - BrowsingDataRemoverFactory::GetForProfile(otrProfile); - browsingDataRemover->Remove(browsing_data::TimePeriod::ALL_TIME, - BrowsingDataRemoveMask::REMOVE_ALL, - base::BindOnce(^{ - [weakSelf activateBVCAndMakeCurrentBVCPrimary]; - })); -} - - (void)activateBVCAndMakeCurrentBVCPrimary { // If there are pending removal operations, the activation will be deferred // until the callback is received. @@ -4547,79 +4507,6 @@ #pragma mark - Handling of destroying the incognito profile -// The incognito Profile should be closed when the last incognito tab is -// closed (i.e. if there are other incognito tabs open in another Scene, the -// Profile must not be destroyed). -- (BOOL)shouldDestroyAndRebuildIncognitoProfile { - ProfileIOS* profile = self.profile; - if (!profile->HasOffTheRecordProfile()) { - return NO; - } - - ProfileIOS* otrProfile = profile->GetOffTheRecordProfile(); - DCHECK(otrProfile); - - BrowserList* browserList = BrowserListFactory::GetForProfile(otrProfile); - for (Browser* browser : - browserList->BrowsersOfType(BrowserList::BrowserType::kIncognito)) { - WebStateList* webStateList = browser->GetWebStateList(); - if (!webStateList->empty()) { - return NO; - } - } - - return YES; -} - -// Destroys and rebuilds the incognito Profile. This will inform all the -// other SceneController to destroy state tied to the Profile and to -// recreate it. -- (void)destroyAndRebuildIncognitoProfile { - // This seems the best place to mark the start of destroying the incognito - // profile. - crash_keys::SetDestroyingAndRebuildingIncognitoBrowserState( - /*in_progress=*/true); - - [self clearIOSSpecificIncognitoData]; - - ProfileIOS* profile = self.profile; - DCHECK(profile->HasOffTheRecordProfile()); - ProfileIOS* otrProfile = profile->GetOffTheRecordProfile(); - - NSMutableArray<SceneController*>* sceneControllers = - [[NSMutableArray alloc] init]; - for (SceneState* sceneState in self.sceneState.profileState.connectedScenes) { - SceneController* sceneController = sceneState.controller; - // In some circumstances, the scene state may still exist while the - // corresponding scene controller has been deallocated. - // (see crbug.com/1142782). - if (sceneController) { - [sceneControllers addObject:sceneController]; - } - } - - for (SceneController* sceneController in sceneControllers) { - [sceneController willDestroyIncognitoProfile]; - } - - // Record off-the-record metrics before detroying the Profile. - SessionMetrics::FromProfile(otrProfile) - ->RecordAndClearSessionMetrics(MetricsToRecordFlags::kNoMetrics); - - // Destroy and recreate the off-the-record Profile. - profile->DestroyOffTheRecordProfile(); - profile->GetOffTheRecordProfile(); - - for (SceneController* sceneController in sceneControllers) { - [sceneController incognitoProfileCreated]; - } - - // This seems the best place to deem the destroying and rebuilding the - // incognito profile to be completed. - crash_keys::SetDestroyingAndRebuildingIncognitoBrowserState( - /*in_progress=*/false); -} - - (void)willDestroyIncognitoProfile { // Clear the Incognito Browser and notify the TabGrid that its otrBrowser // will be destroyed.
diff --git a/ios/chrome/browser/shared/model/profile/BUILD.gn b/ios/chrome/browser/shared/model/profile/BUILD.gn index 76fce0a..d2162ec0 100644 --- a/ios/chrome/browser/shared/model/profile/BUILD.gn +++ b/ios/chrome/browser/shared/model/profile/BUILD.gn
@@ -76,6 +76,8 @@ sources = [ "incognito_session_tracker.h", "incognito_session_tracker.mm", + "profile_incognito_session_tracker.h", + "profile_incognito_session_tracker.mm", ] deps = [ ":profile",
diff --git a/ios/chrome/browser/shared/model/profile/incognito_session_tracker.h b/ios/chrome/browser/shared/model/profile/incognito_session_tracker.h index f2f8370f..f2d4e1b 100644 --- a/ios/chrome/browser/shared/model/profile/incognito_session_tracker.h +++ b/ios/chrome/browser/shared/model/profile/incognito_session_tracker.h
@@ -12,6 +12,7 @@ #import "ios/chrome/browser/shared/model/profile/profile_manager_observer_ios.h" class ProfileIOS; +class ProfileIncognitoSessionTracker; class ProfileManagerIOS; // Tracks whether there are any open off-the-record tabs open by any Profile in @@ -52,10 +53,6 @@ ProfileIOS* profile) override; private: - // Forward-declaration of the observer used to track the state of - // an individual Profile. - class Observer; - // Invoked when the state of invoked when the presence of off-the-record // tabs for a specific Profile has changed. void OnIncognitoSessionStateChanged(bool has_incognito_tabs); @@ -64,9 +61,10 @@ base::ScopedObservation<ProfileManagerIOS, ProfileManagerObserverIOS> scoped_manager_observation_{this}; - // Map from Profile to the observer used to track whether it has any open - // off-the-record tabs. - base::flat_map<ProfileIOS*, std::unique_ptr<Observer>> observers_; + // Map from profile to the ProfileIncognitoSessionTracker used to track + // whether this profile has any open off-the-record tabs. + base::flat_map<ProfileIOS*, std::unique_ptr<ProfileIncognitoSessionTracker>> + trackers_; // List of registered callbacks. SessionStateChangedCallbackList callbacks_;
diff --git a/ios/chrome/browser/shared/model/profile/incognito_session_tracker.mm b/ios/chrome/browser/shared/model/profile/incognito_session_tracker.mm index 7ee6cf3f..3f71705 100644 --- a/ios/chrome/browser/shared/model/profile/incognito_session_tracker.mm +++ b/ios/chrome/browser/shared/model/profile/incognito_session_tracker.mm
@@ -6,167 +6,10 @@ #import <algorithm> -#import "base/scoped_multi_source_observation.h" #import "base/scoped_observation.h" -#import "ios/chrome/browser/shared/model/browser/browser.h" -#import "ios/chrome/browser/shared/model/browser/browser_list.h" #import "ios/chrome/browser/shared/model/browser/browser_list_factory.h" -#import "ios/chrome/browser/shared/model/browser/browser_list_observer.h" +#import "ios/chrome/browser/shared/model/profile/profile_incognito_session_tracker.h" #import "ios/chrome/browser/shared/model/profile/profile_manager_ios.h" -#import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" -#import "ios/chrome/browser/shared/model/web_state_list/web_state_list_observer.h" - -// Observer used to track the state of an individual Profile -// and inform the IncognitoSessionTracker when the state of the incognito -// session for that Profile changes. -class IncognitoSessionTracker::Observer final : public BrowserListObserver, - public WebStateListObserver { - public: - // Callback invoked when the presence of off-the-record tabs has changed. - using Callback = base::RepeatingCallback<void(bool)>; - - Observer(BrowserList* list, Callback callback); - ~Observer() final; - - // Returns whether any of the BrowserList's Browser has incognito tabs open. - bool has_incognito_tabs() const { return has_incognito_tabs_; } - - // BrowserListObserver: - void OnBrowserAdded(const BrowserList* list, Browser* browser) final; - void OnBrowserRemoved(const BrowserList* list, Browser* browser) final; - void OnBrowserListShutdown(BrowserList* list) final; - - // WebStateListObserver: - void WebStateListDidChange(WebStateList* web_state_list, - const WebStateListChange& change, - const WebStateListStatus& status) final; - void BatchOperationEnded(WebStateList* web_state_list) final; - - private: - // Invoked when a potentially significant change is detected in any of - // the observed WebStateList. - void OnWebStateListChanged(); - - // Closure invoked when the presence of off-the-record tabs has changed. - Callback callback_; - - // Manages the observation of the BrowserList. - base::ScopedObservation<BrowserList, BrowserListObserver> - browser_list_observation_{this}; - - // Manages the observation of all off-the-record WebStateLists. - base::ScopedMultiSourceObservation<WebStateList, WebStateListObserver> - web_state_list_observations_{this}; - - // Whether any of the WebStateList has an off-the-record tab open. - bool has_incognito_tabs_ = false; -}; - -IncognitoSessionTracker::Observer::Observer(BrowserList* browser_list, - Callback callback) - : callback_(std::move(callback)) { - DCHECK(!callback_.is_null()); - browser_list_observation_.Observe(browser_list); - - // Observe all pre-existing off-the-record Browsers. - const auto kIncognitoBrowserType = BrowserList::BrowserType::kIncognito; - for (Browser* browser : browser_list->BrowsersOfType(kIncognitoBrowserType)) { - web_state_list_observations_.AddObservation(browser->GetWebStateList()); - } - - // Check whether any of the Browsers has any open off-the-record tabs. - OnWebStateListChanged(); -} - -IncognitoSessionTracker::Observer::~Observer() = default; - -void IncognitoSessionTracker::Observer::OnBrowserAdded( - const BrowserList* browser_list, - Browser* browser) { - // Ignore non-incognito Browsers. - if (browser->type() != Browser::Type::kIncognito) { - return; - } - - WebStateList* const web_state_list = browser->GetWebStateList(); - web_state_list_observations_.AddObservation(web_state_list); - - // If the WebStateList was not empty, then it may be necessary to - // notify the callback. - if (!web_state_list->empty()) { - OnWebStateListChanged(); - } -} - -void IncognitoSessionTracker::Observer::OnBrowserRemoved( - const BrowserList* browser_list, - Browser* browser) { - // Ignore non-incognito Browsers. - if (browser->type() != Browser::Type::kIncognito) { - return; - } - - WebStateList* const web_state_list = browser->GetWebStateList(); - web_state_list_observations_.RemoveObservation(web_state_list); - - // If the WebStateList was not empty, then it may be necessary to - // notify the callback. - if (!web_state_list->empty()) { - OnWebStateListChanged(); - } -} - -void IncognitoSessionTracker::Observer::WebStateListDidChange( - WebStateList* web_state_list, - const WebStateListChange& change, - const WebStateListStatus& status) { - // Ignore changes during batch operations. - if (web_state_list->IsBatchInProgress()) { - return; - } - - switch (change.type()) { - // None of those events can change the number of off-the-record tabs, - // ignore them. - case WebStateListChange::Type::kStatusOnly: - case WebStateListChange::Type::kMove: - case WebStateListChange::Type::kReplace: - case WebStateListChange::Type::kGroupCreate: - case WebStateListChange::Type::kGroupVisualDataUpdate: - case WebStateListChange::Type::kGroupMove: - case WebStateListChange::Type::kGroupDelete: - return; - - // Those events either increment or decrement the number of open - // off-the-record tabs, so update the state. - case WebStateListChange::Type::kDetach: - case WebStateListChange::Type::kInsert: - OnWebStateListChanged(); - return; - } -} - -void IncognitoSessionTracker::Observer::OnWebStateListChanged() { - const bool has_incognito_tabs = std::ranges::any_of( - web_state_list_observations_.sources(), - [](WebStateList* web_state_list) { return !web_state_list->empty(); }); - - if (has_incognito_tabs_ != has_incognito_tabs) { - has_incognito_tabs_ = has_incognito_tabs; - callback_.Run(has_incognito_tabs_); - } -} - -void IncognitoSessionTracker::Observer::BatchOperationEnded( - WebStateList* web_state_list) { - // Anything can change during a batch operation. Update the state. - OnWebStateListChanged(); -} - -void IncognitoSessionTracker::Observer::OnBrowserListShutdown( - BrowserList* browser_list) { - browser_list_observation_.Reset(); -} IncognitoSessionTracker::IncognitoSessionTracker(ProfileManagerIOS* manager) { // ProfileManagerIOS invoke OnProfileLoaded(...) for all Profiles already @@ -214,8 +57,8 @@ // Observer. The use of `base::Unretained(this)` is safe as the // `IncognitoSessionTracker` owns the `Observer` and the closure cannot // outlive `this`. - auto [_, inserted] = observers_.insert(std::make_pair( - profile, std::make_unique<Observer>( + auto [_, inserted] = trackers_.insert(std::make_pair( + profile, std::make_unique<ProfileIncognitoSessionTracker>( BrowserListFactory::GetForProfile(profile), base::BindRepeating( &IncognitoSessionTracker::OnIncognitoSessionStateChanged, @@ -227,9 +70,9 @@ void IncognitoSessionTracker::OnProfileUnloaded(ProfileManagerIOS* manager, ProfileIOS* profile) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - auto iterator = observers_.find(profile); - DCHECK(iterator != observers_.end()); - observers_.erase(iterator); + auto iterator = trackers_.find(profile); + DCHECK(iterator != trackers_.end()); + trackers_.erase(iterator); // The removed profile does not have any tabs, thus no incognito tabs. OnIncognitoSessionStateChanged(false); @@ -249,8 +92,10 @@ const bool has_incognito_session_tabs = has_incognito_tabs || std::ranges::any_of( - observers_, &Observer::has_incognito_tabs, - [](auto& pair) -> const Observer& { return *pair.second; }); + trackers_, &ProfileIncognitoSessionTracker::has_incognito_tabs, + [](auto& pair) -> const ProfileIncognitoSessionTracker& { + return *pair.second; + }); if (has_incognito_session_tabs_ != has_incognito_session_tabs) { has_incognito_session_tabs_ = has_incognito_session_tabs;
diff --git a/ios/chrome/browser/shared/model/profile/profile_incognito_session_tracker.h b/ios/chrome/browser/shared/model/profile/profile_incognito_session_tracker.h new file mode 100644 index 0000000..30578894 --- /dev/null +++ b/ios/chrome/browser/shared/model/profile/profile_incognito_session_tracker.h
@@ -0,0 +1,60 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_SHARED_MODEL_PROFILE_PROFILE_INCOGNITO_SESSION_TRACKER_H_ +#define IOS_CHROME_BROWSER_SHARED_MODEL_PROFILE_PROFILE_INCOGNITO_SESSION_TRACKER_H_ + +#include "base/functional/callback.h" +#include "base/scoped_multi_source_observation.h" +#include "base/scoped_observation.h" +#include "ios/chrome/browser/shared/model/browser/browser_list_observer.h" +#include "ios/chrome/browser/shared/model/web_state_list/web_state_list_observer.h" + +// Tracks whether a given profile has any open off-the-record tabs open, +// invoking a callback when the state changes. Can also be queried to +// check whether any off-the-record tabs are open at any time. +class ProfileIncognitoSessionTracker final : public BrowserListObserver, + public WebStateListObserver { + public: + // Callback invoked when the presence of off-the-record tabs has changed. + using Callback = base::RepeatingCallback<void(bool)>; + + ProfileIncognitoSessionTracker(BrowserList* list, Callback callback); + ~ProfileIncognitoSessionTracker() final; + + // Returns whether any of the BrowserList's Browser has incognito tabs open. + bool has_incognito_tabs() const { return has_incognito_tabs_; } + + // BrowserListObserver: + void OnBrowserAdded(const BrowserList* list, Browser* browser) final; + void OnBrowserRemoved(const BrowserList* list, Browser* browser) final; + void OnBrowserListShutdown(BrowserList* list) final; + + // WebStateListObserver: + void WebStateListDidChange(WebStateList* web_state_list, + const WebStateListChange& change, + const WebStateListStatus& status) final; + void BatchOperationEnded(WebStateList* web_state_list) final; + + private: + // Invoked when a potentially significant change is detected in any of + // the observed WebStateList. + void OnWebStateListChanged(); + + // Closure invoked when the presence of off-the-record tabs has changed. + Callback callback_; + + // Manages the observation of the BrowserList. + base::ScopedObservation<BrowserList, BrowserListObserver> + browser_list_observation_{this}; + + // Manages the observation of all off-the-record WebStateLists. + base::ScopedMultiSourceObservation<WebStateList, WebStateListObserver> + web_state_list_observations_{this}; + + // Whether any of the WebStateList has an off-the-record tab open. + bool has_incognito_tabs_ = false; +}; + +#endif // IOS_CHROME_BROWSER_SHARED_MODEL_PROFILE_PROFILE_INCOGNITO_SESSION_TRACKER_H_
diff --git a/ios/chrome/browser/shared/model/profile/profile_incognito_session_tracker.mm b/ios/chrome/browser/shared/model/profile/profile_incognito_session_tracker.mm new file mode 100644 index 0000000..3841bd47 --- /dev/null +++ b/ios/chrome/browser/shared/model/profile/profile_incognito_session_tracker.mm
@@ -0,0 +1,117 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/shared/model/profile/profile_incognito_session_tracker.h" + +#import "base/scoped_observation.h" +#import "ios/chrome/browser/shared/model/browser/browser.h" +#import "ios/chrome/browser/shared/model/browser/browser_list.h" +#import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" + +ProfileIncognitoSessionTracker::ProfileIncognitoSessionTracker( + BrowserList* browser_list, + Callback callback) + : callback_(std::move(callback)) { + DCHECK(!callback_.is_null()); + browser_list_observation_.Observe(browser_list); + + // Observe all pre-existing off-the-record Browsers. + const auto kIncognitoBrowserType = BrowserList::BrowserType::kIncognito; + for (Browser* browser : browser_list->BrowsersOfType(kIncognitoBrowserType)) { + web_state_list_observations_.AddObservation(browser->GetWebStateList()); + } + + // Check whether any of the Browsers has any open off-the-record tabs. + OnWebStateListChanged(); +} + +ProfileIncognitoSessionTracker::~ProfileIncognitoSessionTracker() = default; + +void ProfileIncognitoSessionTracker::OnBrowserAdded( + const BrowserList* browser_list, + Browser* browser) { + // Ignore non-incognito Browsers. + if (browser->type() != Browser::Type::kIncognito) { + return; + } + + WebStateList* const web_state_list = browser->GetWebStateList(); + web_state_list_observations_.AddObservation(web_state_list); + + // If the WebStateList was not empty, then it may be necessary to + // notify the callback. + if (!web_state_list->empty()) { + OnWebStateListChanged(); + } +} + +void ProfileIncognitoSessionTracker::OnBrowserRemoved( + const BrowserList* browser_list, + Browser* browser) { + // Ignore non-incognito Browsers. + if (browser->type() != Browser::Type::kIncognito) { + return; + } + + WebStateList* const web_state_list = browser->GetWebStateList(); + web_state_list_observations_.RemoveObservation(web_state_list); + + // If the WebStateList was not empty, then it may be necessary to + // notify the callback. + if (!web_state_list->empty()) { + OnWebStateListChanged(); + } +} + +void ProfileIncognitoSessionTracker::WebStateListDidChange( + WebStateList* web_state_list, + const WebStateListChange& change, + const WebStateListStatus& status) { + // Ignore changes during batch operations. + if (web_state_list->IsBatchInProgress()) { + return; + } + + switch (change.type()) { + // None of those events can change the number of off-the-record tabs, + // ignore them. + case WebStateListChange::Type::kStatusOnly: + case WebStateListChange::Type::kMove: + case WebStateListChange::Type::kReplace: + case WebStateListChange::Type::kGroupCreate: + case WebStateListChange::Type::kGroupVisualDataUpdate: + case WebStateListChange::Type::kGroupMove: + case WebStateListChange::Type::kGroupDelete: + return; + + // Those events either increment or decrement the number of open + // off-the-record tabs, so update the state. + case WebStateListChange::Type::kDetach: + case WebStateListChange::Type::kInsert: + OnWebStateListChanged(); + return; + } +} + +void ProfileIncognitoSessionTracker::OnWebStateListChanged() { + const bool has_incognito_tabs = std::ranges::any_of( + web_state_list_observations_.sources(), + [](WebStateList* web_state_list) { return !web_state_list->empty(); }); + + if (has_incognito_tabs_ != has_incognito_tabs) { + has_incognito_tabs_ = has_incognito_tabs; + callback_.Run(has_incognito_tabs_); + } +} + +void ProfileIncognitoSessionTracker::BatchOperationEnded( + WebStateList* web_state_list) { + // Anything can change during a batch operation. Update the state. + OnWebStateListChanged(); +} + +void ProfileIncognitoSessionTracker::OnBrowserListShutdown( + BrowserList* browser_list) { + browser_list_observation_.Reset(); +}
diff --git a/ios/chrome/browser/shared/public/features/features.h b/ios/chrome/browser/shared/public/features/features.h index ee8f21792..26d0406 100644 --- a/ios/chrome/browser/shared/public/features/features.h +++ b/ios/chrome/browser/shared/public/features/features.h
@@ -648,47 +648,11 @@ // enabled. bool IsIOSKeyboardAccessoryTwoBubbleEnabled(); -// Feature that enables tab resumption. -BASE_DECLARE_FEATURE(kTabResumption); - -// Whether the tab resumption feature is enabled. -bool IsTabResumptionEnabled(); - -// Feature that enables images for Tab Resumption. -BASE_DECLARE_FEATURE(kTabResumptionImages); - -// A parameter to choose what type of images are enabled in -// `kTabResumptionImages` experiment (default to all). -extern const char kTabResumptionImagesTypes[]; - -// A parameter value for `kTabResumptionImagesTypes` to only enable salient -// images images for tab resumption. -extern const char kTabResumptionImagesTypesSalient[]; - -// A parameter value for `kTabResumptionImagesTypes` to only enable thumbnails -// images images for tab resumption. -extern const char kTabResumptionImagesTypesThumbnails[]; - // A parameter to indicate whether the native UI is enabled for the discover // feed. // TODO(crbug.com/40246814): Remove this. extern const char kDiscoverFeedIsNativeUIEnabled[]; -// Feature parameters for the tab resumption feature. The threshold for tabs -// fetched from sync in seconds. Default to 12 hours. -extern const char kTabResumptionThresholdParameterName[]; - -// Whether the tab resumption with salient images for distant tabs (or fallback -// for local tabs) is enabled. -bool IsTabResumptionImagesSalientEnabled(); - -// Whether the tab resumption with salient images for local tabs is enabled. -bool IsTabResumptionImagesThumbnailsEnabled(); - -// Convenience method for determining the tab resumption time threshold for -// X-Devices tabs only. -const base::TimeDelta TabResumptionForXDevicesTimeThreshold(); - // Kill switch for disabling the navigations when the application is in // foreground inactive state after opening an external app. BASE_DECLARE_FEATURE(kInactiveNavigationAfterAppLaunchKillSwitch);
diff --git a/ios/chrome/browser/shared/public/features/features.mm b/ios/chrome/browser/shared/public/features/features.mm index 649b6a4..77d2414 100644 --- a/ios/chrome/browser/shared/public/features/features.mm +++ b/ios/chrome/browser/shared/public/features/features.mm
@@ -651,53 +651,6 @@ return base::FeatureList::IsEnabled(kIOSKeyboardAccessoryTwoBubble); } -BASE_FEATURE(kTabResumption, base::FEATURE_ENABLED_BY_DEFAULT); - -// A parameter to indicate whether the native UI is enabled for the discover -// feed. -const char kDiscoverFeedIsNativeUIEnabled[] = "DiscoverFeedIsNativeUIEnabled"; - -const char kTabResumptionThresholdParameterName[] = - "tab-resumption-sync-threshold"; - -bool IsTabResumptionEnabled() { - return base::FeatureList::IsEnabled(kTabResumption); -} - -const base::TimeDelta TabResumptionForXDevicesTimeThreshold() { - // Default to 12 hours. - int threshold = base::GetFieldTrialParamByFeatureAsInt( - kTabResumption, kTabResumptionThresholdParameterName, - /*default_value*/ 12 * 3600); - return base::Seconds(threshold); -} - -BASE_FEATURE(kTabResumptionImages, base::FEATURE_ENABLED_BY_DEFAULT); - -const char kTabResumptionImagesTypes[] = "tr-images-type"; -const char kTabResumptionImagesTypesSalient[] = "salient"; -const char kTabResumptionImagesTypesThumbnails[] = "thumbnails"; - -bool IsTabResumptionImagesSalientEnabled() { - if (!base::FeatureList::IsEnabled(kTabResumptionImages)) { - return false; - } - std::string image_type = base::GetFieldTrialParamByFeatureAsString( - kTabResumptionImages, kTabResumptionImagesTypes, ""); - - return image_type == kTabResumptionImagesTypesSalient; -} - -bool IsTabResumptionImagesThumbnailsEnabled() { - if (!base::FeatureList::IsEnabled(kTabResumptionImages)) { - return false; - } - std::string image_type = base::GetFieldTrialParamByFeatureAsString( - kTabResumptionImages, kTabResumptionImagesTypes, ""); - - return image_type == kTabResumptionImagesTypesThumbnails || image_type == ""; -} - BASE_FEATURE(kInactiveNavigationAfterAppLaunchKillSwitch, "kInactiveNavigationAfterAppLaunchKillSwitch", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/ios/chrome/browser/signin/model/ios_chrome_signin_client.mm b/ios/chrome/browser/signin/model/ios_chrome_signin_client.mm index 001cfe29..a1df6e3 100644 --- a/ios/chrome/browser/signin/model/ios_chrome_signin_client.mm +++ b/ios/chrome/browser/signin/model/ios_chrome_signin_client.mm
@@ -32,6 +32,10 @@ signin::oauth_consumer_name::kEnterprisePlusAddressName, {plus_addresses::features::kEnterprisePlusAddressOAuthScope.Get()}); } + + signin::OAuthConsumer GetOAuthConsumerForGlicUserStatus() const override { + NOTREACHED(); + } }; } // namespace
diff --git a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/grid/grid_cell.mm b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/grid/grid_cell.mm index bab706f8..040ccbce 100644 --- a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/grid/grid_cell.mm +++ b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/grid/grid_cell.mm
@@ -109,6 +109,9 @@ // UI elements for highlighted state. // Container for the cell's contents to enable shrinking transform. @property(nonatomic, strong) UIView* containerView; +// Horizontal constraints for `containerView`. +@property(nonatomic, strong) NSLayoutConstraint* containerLeadingConstraint; +@property(nonatomic, strong) NSLayoutConstraint* containerTrailingConstraint; // Background view to show while cell is highlighted. @property(nonatomic, strong) UIView* groupingBackgroundView; // Dimming view over the cell contents while cell is highlighted. @@ -216,6 +219,12 @@ self.layer.shadowOpacity = 0.5f; self.layer.masksToBounds = NO; CGFloat margin = IsTabGridEmptyThumbnailUIEnabled() ? kSnapshotInset : 0; + self.containerLeadingConstraint = [snapshotView.leadingAnchor + constraintEqualToAnchor:contentContainer.leadingAnchor + constant:margin]; + self.containerTrailingConstraint = [snapshotView.trailingAnchor + constraintEqualToAnchor:contentContainer.trailingAnchor + constant:-margin]; NSArray* constraints = @[ [topBar.topAnchor constraintEqualToAnchor:contentContainer.topAnchor], [topBar.leadingAnchor @@ -223,12 +232,8 @@ [topBar.trailingAnchor constraintEqualToAnchor:contentContainer.trailingAnchor], [snapshotView.topAnchor constraintEqualToAnchor:topBar.bottomAnchor], - [snapshotView.leadingAnchor - constraintEqualToAnchor:contentContainer.leadingAnchor - constant:margin], - [snapshotView.trailingAnchor - constraintEqualToAnchor:contentContainer.trailingAnchor - constant:-margin], + self.containerLeadingConstraint, + self.containerTrailingConstraint, [snapshotView.bottomAnchor constraintEqualToAnchor:contentContainer.bottomAnchor constant:-margin], @@ -948,20 +953,19 @@ } - (void)positionTabViews { + if (!IsNewTabGridTransitionsEnabled()) { + self.containerLeadingConstraint.constant = 0; + self.containerTrailingConstraint.constant = 0; + self.containerView.layer.cornerRadius = 0; + self.snapshotView.layer.cornerRadius = 0; + } [self scaleTabViews]; self.topBarHeightConstraint.constant = self.topTabView.frame.size.height; [self setNeedsUpdateConstraints]; [self layoutIfNeeded]; PositionView(self.topTabView, CGPointMake(0, 0)); // Position the main view so it's top-aligned with the main cell view. - CGPoint mainTabViewOrigin = self.mainCellView.frame.origin; - if (IsTabGridEmptyThumbnailUIEnabled()) { - // With the snapshot inset horizontally to create containerized feel, need - // to shift the view to a zero x position so the animation of it aligns with - // the frame of the BVC WKWebView. - mainTabViewOrigin.x = 0; - } - PositionView(self.mainTabView, mainTabViewOrigin); + PositionView(self.mainTabView, self.mainCellView.frame.origin); if (!self.bottomTabView) { return; } @@ -973,6 +977,14 @@ } - (void)positionCellViews { + if (!IsNewTabGridTransitionsEnabled()) { + self.containerView.layer.cornerRadius = kGridCellCornerRadius; + self.containerLeadingConstraint.constant = + IsTabGridEmptyThumbnailUIEnabled() ? kSnapshotInset : 0; + self.containerTrailingConstraint.constant = + IsTabGridEmptyThumbnailUIEnabled() ? -kSnapshotInset : 0; + self.snapshotView.layer.cornerRadius = kGridCellCornerRadius; + } [self scaleTabViews]; self.topBarHeightConstraint.constant = [self topBarHeight]; [self setNeedsUpdateConstraints];
diff --git a/ios/chrome/browser/tabs/model/tabs_dependency_installer.mm b/ios/chrome/browser/tabs/model/tabs_dependency_installer.mm index 9319a72..523c14e 100644 --- a/ios/chrome/browser/tabs/model/tabs_dependency_installer.mm +++ b/ios/chrome/browser/tabs/model/tabs_dependency_installer.mm
@@ -40,7 +40,7 @@ public web::WebStateObserver { public: TabsDependencyInstallationHelper( - WebStateList& web_state_list, + Browser& browser, TabsDependencyInstaller& dependency_installer, TabsDependencyInstaller::Policy policy); ~TabsDependencyInstallationHelper() override; @@ -65,6 +65,8 @@ void OnWebStateAdded(web::WebState* web_state); void OnWebStateRemoved(web::WebState* web_state); + // Original browser that is being observed. + const raw_ref<Browser> browser_; // The WebStateList being observed for addition, replacement, and detachment // of WebStates const raw_ref<WebStateList> web_state_list_; @@ -83,10 +85,11 @@ }; TabsDependencyInstallationHelper::TabsDependencyInstallationHelper( - WebStateList& web_state_list, + Browser& browser, TabsDependencyInstaller& dependency_installer, TabsDependencyInstaller::Policy policy) - : web_state_list_(web_state_list), + : browser_(browser), + web_state_list_(CHECK_DEREF(browser.GetWebStateList())), dependency_installer_(dependency_installer), wait_for_realization_to_install_dependencies_( WaitForRealizationToInstallDependencies(policy)) { @@ -94,12 +97,24 @@ for (int i = 0; i < web_state_list_->count(); i++) { OnWebStateAdded(web_state_list_->GetWebStateAt(i)); } + // Start tracking TabsDependencyInstaller. + TabsDependencyInstallerManager* manager = + TabsDependencyInstallerManager::FromBrowser(&*browser_); + if (manager) { + manager->AddInstaller(&*dependency_installer_); + } } TabsDependencyInstallationHelper::~TabsDependencyInstallationHelper() { for (int i = 0; i < web_state_list_->count(); i++) { OnWebStateRemoved(web_state_list_->GetWebStateAt(i)); } + // Stop tracking TabsDependencyInstaller. + TabsDependencyInstallerManager* manager = + TabsDependencyInstallerManager::FromBrowser(&*browser_); + if (manager) { + manager->RemoveInstaller(&*dependency_installer_); + } } #pragma mark - WebStateListObserver @@ -238,12 +253,7 @@ void TabsDependencyInstaller::StartObserving(Browser* browser, Policy policy) { installation_helper_ = std::make_unique<TabsDependencyInstallationHelper>( - CHECK_DEREF(browser->GetWebStateList()), *this, policy); - TabsDependencyInstallerManager* manager = - TabsDependencyInstallerManager::FromBrowser(browser); - if (manager) { - manager->AddInstaller(this); - } + CHECK_DEREF(browser), *this, policy); } void TabsDependencyInstaller::StopObserving() {
diff --git a/ios/chrome/browser/tabs/model/tabs_dependency_installer_unittest.mm b/ios/chrome/browser/tabs/model/tabs_dependency_installer_unittest.mm index b6969f9..1bcf2603 100644 --- a/ios/chrome/browser/tabs/model/tabs_dependency_installer_unittest.mm +++ b/ios/chrome/browser/tabs/model/tabs_dependency_installer_unittest.mm
@@ -15,6 +15,7 @@ #import "ios/chrome/browser/shared/model/web_state_list/test/fake_web_state_list_delegate.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_opener.h" +#import "ios/chrome/browser/tabs/model/tabs_dependency_installer_manager.h" #import "ios/web/common/features.h" #import "ios/web/public/test/fakes/fake_web_state.h" #import "ios/web/public/test/web_task_environment.h" @@ -394,3 +395,31 @@ WebStateList::InsertionParams::Automatic().Activate()); EXPECT_FALSE(installer_.WasInstalled(web_state_2_id)); } + +// Verifies that stopping the observation for an installer will uninstall it +// from the TabsDependencyInstallerManager. +TEST_P(TabsDependencyInstallerTest, UninstallForManagerAfterDisconnect) { + TabsDependencyInstallerManager::CreateForBrowser(browser_.get()); + TabsDependencyInstallerManager* manager = + TabsDependencyInstallerManager::FromBrowser(browser_.get()); + ASSERT_TRUE(manager); + installer_.StartObserving( + browser_.get(), std::get<TabsDependencyInstaller::Policy>(GetParam())); + + auto web_state = std::make_unique<web::FakeWebState>(); + const web::WebStateID web_state_id = web_state->GetUniqueIdentifier(); + + manager->InstallDependencies(web_state.get()); + EXPECT_TRUE(installer_.WasInstalled(web_state_id)); + EXPECT_EQ(1u, installer_.InstallCount(web_state_id)); + EXPECT_FALSE(installer_.WasUninstalled(web_state_id)); + + installer_.StopObserving(); + + manager->UninstallDependencies(web_state.get()); + + // The uninstall should not be performed since the test installer stops + // observing before the manager starts uninstalling dependencies. + EXPECT_FALSE(installer_.WasUninstalled(web_state_id)); + EXPECT_EQ(0u, installer_.UninstallCount(web_state_id)); +}
diff --git a/ios/chrome/browser/toolbar/ui_bundled/BUILD.gn b/ios/chrome/browser/toolbar/ui_bundled/BUILD.gn index b3454bb..3376256 100644 --- a/ios/chrome/browser/toolbar/ui_bundled/BUILD.gn +++ b/ios/chrome/browser/toolbar/ui_bundled/BUILD.gn
@@ -208,6 +208,7 @@ "//components/search_engines", "//components/sync_preferences:test_support", "//ios/chrome/app/strings", + "//ios/chrome/browser/autocomplete/model", "//ios/chrome/browser/bookmarks/model", "//ios/chrome/browser/collaboration/model/messaging", "//ios/chrome/browser/fullscreen/ui_bundled",
diff --git a/ios/chrome/browser/toolbar/ui_bundled/toolbar_coordinator_unittest.mm b/ios/chrome/browser/toolbar/ui_bundled/toolbar_coordinator_unittest.mm index f423b44..fa10518 100644 --- a/ios/chrome/browser/toolbar/ui_bundled/toolbar_coordinator_unittest.mm +++ b/ios/chrome/browser/toolbar/ui_bundled/toolbar_coordinator_unittest.mm
@@ -7,6 +7,7 @@ #import "base/scoped_observation.h" #import "base/test/scoped_feature_list.h" #import "components/omnibox/browser/omnibox_pref_names.h" +#import "ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.h" #import "ios/chrome/browser/fullscreen/ui_bundled/fullscreen_controller.h" #import "ios/chrome/browser/infobars/model/infobar_manager_impl.h" #import "ios/chrome/browser/omnibox/model/omnibox_position/omnibox_position_browser_agent.h" @@ -166,6 +167,7 @@ forProtocol:@protocol(BrowserCoordinatorCommands)]; OmniboxPositionBrowserAgent::CreateForBrowser(browser_.get()); + AutocompleteBrowserAgent::CreateForBrowser(browser_.get()); // FullscreenController depends on ToolbarsSizeBrowserAgent, so the agent // must be created first. Please maintain this order. ToolbarsSizeBrowserAgent::CreateForBrowser(browser_.get());
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index 7d486c3..caf510e 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -125,6 +125,7 @@ "//ios/chrome/browser/ai_prototyping/test:eg_app_support+eg2", "//ios/chrome/browser/authentication/test:eg_app_support+eg2", "//ios/chrome/browser/authentication/ui_bundled/cells", + "//ios/chrome/browser/autocomplete/model", "//ios/chrome/browser/autofill/model", "//ios/chrome/browser/autofill/model/automation:eg_app_support+eg2", "//ios/chrome/browser/autofill/ui_bundled:eg_app_support+eg2",
diff --git a/ios/chrome/test/earl_grey/chrome_coordinator_app_interface.mm b/ios/chrome/test/earl_grey/chrome_coordinator_app_interface.mm index c65b46b..dbb7fcb 100644 --- a/ios/chrome/test/earl_grey/chrome_coordinator_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_coordinator_app_interface.mm
@@ -9,6 +9,7 @@ #import "components/language/ios/browser/ios_language_detection_tab_helper.h" #import "components/prefs/pref_service.h" +#import "ios/chrome/browser/autocomplete/model/autocomplete_browser_agent.h" #import "ios/chrome/browser/history/ui_bundled/history_coordinator.h" #import "ios/chrome/browser/history/ui_bundled/stub_history_coordinator_delegate.h" #import "ios/chrome/browser/main/model/browser_impl.h" @@ -269,6 +270,7 @@ } + (void)startOmniboxCoordinator { + AutocompleteBrowserAgent::CreateForBrowser(self.helper.browser); OmniboxInttestCoordinator* coordinator = [[OmniboxInttestCoordinator alloc] initWithBaseViewController:[self rootViewController] browser:self.helper.browser];
diff --git a/ios/chrome/test/swift_interop/chromium/BUILD.gn b/ios/chrome/test/swift_interop/chromium/BUILD.gn index 4222a6a..43d1635 100644 --- a/ios/chrome/test/swift_interop/chromium/BUILD.gn +++ b/ios/chrome/test/swift_interop/chromium/BUILD.gn
@@ -15,7 +15,10 @@ swift_source_set("tests") { testonly = true - sources = [ "sys_info_xctest.swift" ] + sources = [ + "sys_info_xctest.swift", + "time_xctest.swift", + ] cxx_modulemaps = [ "chromium.modulemap" ] deps = [
diff --git a/ios/chrome/test/swift_interop/chromium/chromium_umbrella.h b/ios/chrome/test/swift_interop/chromium/chromium_umbrella.h index 331f86a..e0b35d22 100644 --- a/ios/chrome/test/swift_interop/chromium/chromium_umbrella.h +++ b/ios/chrome/test/swift_interop/chromium/chromium_umbrella.h
@@ -8,5 +8,6 @@ // TODO(crbug.com/458741717): Remove this file once on swift 6.3 #include "base/system/sys_info.h" +#include "base/time/time.h" #endif // IOS_CHROME_TEST_SWIFT_INTEROP_CHROMIUM_CHROMIUM_UMBRELLA_H_
diff --git a/ios/chrome/test/swift_interop/chromium/time_xctest.swift b/ios/chrome/test/swift_interop/chromium/time_xctest.swift new file mode 100644 index 0000000..ed1086d2 --- /dev/null +++ b/ios/chrome/test/swift_interop/chromium/time_xctest.swift
@@ -0,0 +1,46 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Base +import XCTest + +class TimeTest: XCTestCase { + + func testSeconds() { + let ts = timespec(tv_sec: 2, tv_nsec: 0) + let timeDelta: base.TimeDelta = base.TimeDelta.FromTimeSpec(ts) + XCTAssertEqual(2, timeDelta.InSeconds()) + XCTAssertEqual(2000, timeDelta.InMilliseconds()) + XCTAssertEqual(2_000_000, timeDelta.InMicroseconds()) + XCTAssertEqual(2_000_000_000, timeDelta.InNanoseconds()) + } + + func testMilliseconds() { + let ts = timespec(tv_sec: 0, tv_nsec: 2_000_000) + let timeDelta: base.TimeDelta = base.TimeDelta.FromTimeSpec(ts) + XCTAssertEqual(0, timeDelta.InSeconds()) + XCTAssertEqual(2, timeDelta.InMilliseconds()) + XCTAssertEqual(2000, timeDelta.InMicroseconds()) + XCTAssertEqual(2_000_000, timeDelta.InNanoseconds()) + } + + func testMicroseconds() { + let ts = timespec(tv_sec: 0, tv_nsec: 2000) + let timeDelta: base.TimeDelta = base.TimeDelta.FromTimeSpec(ts) + XCTAssertEqual(0, timeDelta.InSeconds()) + XCTAssertEqual(0, timeDelta.InMilliseconds()) + XCTAssertEqual(2, timeDelta.InMicroseconds()) + XCTAssertEqual(2000, timeDelta.InNanoseconds()) + } + + func testMix() { + let ts = timespec(tv_sec: 1, tv_nsec: 20000) + let timeDelta: base.TimeDelta = base.TimeDelta.FromTimeSpec(ts) + XCTAssertEqual(1, timeDelta.InSeconds()) + XCTAssertEqual(1000, timeDelta.InMilliseconds()) + XCTAssertEqual(1_000_020, timeDelta.InMicroseconds()) + XCTAssertEqual(1_000_020_000, timeDelta.InNanoseconds()) + } + +}
diff --git a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 index 48abb67a..98aeb13 100644 --- a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -b2f9bc0f700ca4fcc8892cd119f9eb25e8766927 \ No newline at end of file +93a19d9329b4425543a8e59735a71bc6c5a77339 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 index 85026a40..7fb009e 100644 --- a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@ -0febdba76d0c8986dd17371719ac530bb48144b4 \ No newline at end of file +e72591a63815aa6ae1c4c6f0ab2ae4a305239ba7 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 index f78609e5..dd956f6 100644 --- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -e46d97316b74284c8fabd4a83b8e10a93d4d4f3b \ No newline at end of file +08470f4ff73659655fe89d7b48c05cf393b27caf \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 index 0f1e4d74..b66cb80 100644 --- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@ -fdd0d611101674153869341e3d79ebe36d18ad6b \ No newline at end of file +3e761f1c50aff18030d4c1978ab01963b87ec3e7 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 index 1fdca8b..f17cda3 100644 --- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -2ccce183f6fb3ea225c734a75c01008cc0765e59 \ No newline at end of file +ab18a7e94b4b505fae478a14e70a9417336fefb1 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 index 9bf4ad2f..79ec2be7 100644 --- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@ -9fa4a102d9d2b2d39a0252713a5901e83a323316 \ No newline at end of file +fbbe740b46b2def86f3f35ca5e95a4f9b0f848c8 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 index cbe9e9c..cdf4be0 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -f8b6d17e3cbb122bff8d91224801b4953a1e8773 \ No newline at end of file +ce1ab4b341ce396f1982ffc5f035aac216be4c38 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 index dd7bc737..681c9f7 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -65f25cdfa83f3b279e6c973df881f379e260ce87 \ No newline at end of file +bb162b47454e0274073ca48bb2e872d239b80883 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 index dcc16e73..4c80cf8d 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -8c3a50e9993e3be7e3c95609f8cbd415d29227c6 \ No newline at end of file +cc056db1b179249d2ed5d42b7fd3efec3d8889d0 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 68be8cd..dba9e65 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -e12b14376200fda2ce9f7e35939dd8814d76f728 \ No newline at end of file +c0ff1d8e3ac4214885e0b9ac03e9772ce48ccd1e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index ec20037..a638998 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -8983a7ad04a5ea91c8023d50b060d7dd9c99cf0d \ No newline at end of file +de347bb0ac76a556d46db78958836701117656f5 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 index 62ea783..35d97031 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -e5adf55eced29d8fed96f105386926306f88597a \ No newline at end of file +f4c54f8d21bafb518eb31baac81e98892ba36f68 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index cf35f6e4cb5..09f6893 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -9079c7b49442a8f9ab1d1f0de660fea8f2a78ab1 \ No newline at end of file +7a3c3db94146242dd62304c65f11d5ce07a70e4f \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 4a66417..31e0cbe6 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -ccdbe9589714598a88741289d70a7e58bed532fb \ No newline at end of file +3bf28f8413af49edcfd00915f8c72f659f820bfe \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index 6450fb7..7cc0b83 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -0c2081741b872f472d272bb8b7b034476e17b7e1 \ No newline at end of file +56e19826fdc3ca3fe49d918cc5d5be0322bdf01c \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 index f038efa..ad8afb22 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -5e6b24f84a23886dc806f880436c868bfad47abf \ No newline at end of file +1789fc6fabf4ad5c9c45da3fa65bc89c8add2d5f \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index ab6f8f8..0c08fa70 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -09ada82ddb4cc8436912bc559d58c2ae3b52d6b5 \ No newline at end of file +9a9089f006a187ef2b21de7b185a8645feea43a5 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 index c0ad0e4..8199731 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -34253678799ff284043163f979a0bec32ac61d95 \ No newline at end of file +0d0edb37266c538fcff59a92bfbe690f82dcd3ba \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 index ce8cb61..147784d 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -2a596002ad6fd05e67a80f74d8676253a1279d31 \ No newline at end of file +065c92d6ea4aaec1ee6bacae28a8fcd1e271c044 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 index c4833d75..ab415eb 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -0b9a8fe4cf0db3c6307797a9167ba2f51d54c47c \ No newline at end of file +18012ef8a793895915b6aa8686dae10da74ed2de \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index cd3d547..38d0afa 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -f43a212086ba89a47ffba0804a5a097c12656983 \ No newline at end of file +c11ef2c35d676f0e6df02d2379707de32c11f68b \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 index d95bef9..b78cf9607 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -b82529e3ad7637e1d3c70070703e32c1641f9f79 \ No newline at end of file +b3d3ff1e142397071695e54089a55561205d4607 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index 1bad51e3..0dc9eae0 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -cc24068b9d2e92222673c58e35aaf6bbd1708173 \ No newline at end of file +354caf7c470bdad8bec94b9e3d9660f8bfeab0ed \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 021d7aa5..248a045 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -c1c73e1da65d7748eca146d43b6deb4e0936bb93 \ No newline at end of file +54c986849ca91864aefb1a44d9134578bfa61c84 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index ddc57af..62e1ce9 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -7b103e297e510349221b3a3a7128d5847c0676ab \ No newline at end of file +d5bb4f6835c9cae95acfc663aa7739ca55777f58 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 index 9f74487..64891c4f 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -b5ee2cc798834117f356ad23c5db407ec3cb8d27 \ No newline at end of file +0617a5207cddad4b43abb24157321647dc43b466 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index bb6a4d5..8fa3285e 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -19eb10fd6fac34d5a719ac9b051cdced20e35fce \ No newline at end of file +fdc9d40cbcab0a9d855ffab3b122cf8731e46e5a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 index b2ebc8c0..db229b86 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -84714f07ca8ad952ccb9af88501be2f877cc8c52 \ No newline at end of file +4f015280a1ce93b5e5d9d16c6e6e9a01eb2fab61 \ No newline at end of file
diff --git a/ios/web_view/internal/signin/ios_web_view_signin_client.mm b/ios/web_view/internal/signin/ios_web_view_signin_client.mm index 5055c50..e4e6d2f 100644 --- a/ios/web_view/internal/signin/ios_web_view_signin_client.mm +++ b/ios/web_view/internal/signin/ios_web_view_signin_client.mm
@@ -25,6 +25,10 @@ signin::oauth_consumer_name::kEnterprisePlusAddressName, {plus_addresses::features::kEnterprisePlusAddressOAuthScope.Get()}); } + + signin::OAuthConsumer GetOAuthConsumerForGlicUserStatus() const override { + NOTREACHED(); + } }; } // namespace
diff --git a/ios_internal b/ios_internal index b751aae..fd52a14 160000 --- a/ios_internal +++ b/ios_internal
@@ -1 +1 @@ -Subproject commit b751aaeca79d1952ef7631a2e83fbb5b00c133b8 +Subproject commit fd52a146a6011abcc1c9c18a07f113fa192a9161
diff --git a/media/mojo/mojom/media_types.mojom b/media/mojo/mojom/media_types.mojom index 282db1a6..1133754 100644 --- a/media/mojo/mojom/media_types.mojom +++ b/media/mojo/mojom/media_types.mojom
@@ -508,9 +508,7 @@ struct SharedImageVideoFrameData { gpu.mojom.ExportedSharedImage shared_image; gpu.mojom.SyncToken sync_token; - // TODO(crbug.com/40263579): Remove this bool once all VideoFrame - // clients use MappableSI. - bool is_mappable_si_enabled; + bool is_mappable; // |ycbcr_data| is present on Android when the // video is hardware decoded and the display compositor uses Vulkan. [EnableIf=is_android]
diff --git a/media/mojo/mojom/video_frame_mojom_traits.cc b/media/mojo/mojom/video_frame_mojom_traits.cc index 6b07388..8b42ffd 100644 --- a/media/mojo/mojom/video_frame_mojom_traits.cc +++ b/media/mojo/mojom/video_frame_mojom_traits.cc
@@ -115,7 +115,6 @@ std::move(region), std::move(strides), std::move(offsets))); } - bool is_mappable_si_enabled = input->HasMappableSharedImage(); if (input->HasMappableSharedImage()) { auto gpu_memory_buffer_handle = input->GetGpuMemoryBufferHandle(); @@ -123,7 +122,6 @@ std::optional<gpu::ExportedSharedImage> shared_image; gpu::SyncToken sync_token; CHECK(input->HasSharedImage()); - CHECK(is_mappable_si_enabled); shared_image = input->shared_image()->Export( /*with_buffer_handle=*/true); sync_token = input->acquire_sync_token(); @@ -131,30 +129,27 @@ return media::mojom::VideoFrameData::NewSharedImageData( media::mojom::SharedImageVideoFrameData::New( std::move(shared_image.value()), std::move(sync_token), - /*is_mappable_si_enabled=*/true, std::move(input->ycbcr_info()))); + /*is_mappable=*/true, std::move(input->ycbcr_info()))); #else return media::mojom::VideoFrameData::NewSharedImageData( media::mojom::SharedImageVideoFrameData::New( std::move(shared_image.value()), std::move(sync_token), - /*is_mappable_si_enabled=*/true)); + /*is_mappable=*/true)); #endif } if (input->HasSharedImage()) { - // Mappable SI should only be used with `HasMappableSharedImage()` - // VideoFrames. - CHECK(!is_mappable_si_enabled); gpu::ExportedSharedImage shared_image = input->shared_image()->Export(); #if BUILDFLAG(IS_ANDROID) return media::mojom::VideoFrameData::NewSharedImageData( media::mojom::SharedImageVideoFrameData::New( std::move(shared_image), input->acquire_sync_token(), - /*is_mappable_si_enabled=*/false, std::move(input->ycbcr_info()))); + /*is_mappable=*/false, std::move(input->ycbcr_info()))); #else return media::mojom::VideoFrameData::NewSharedImageData( media::mojom::SharedImageVideoFrameData::New( std::move(shared_image), input->acquire_sync_token(), - /*is_mappable_si_enabled=*/false)); + /*is_mappable=*/false)); #endif } @@ -355,9 +350,9 @@ return false; } - bool is_mappable_si_enabled = shared_image_data.is_mappable_si_enabled(); - if (is_mappable_si_enabled) { - // VideoFrame should have buffer usage if Mappable SharedImage is enabled. + bool is_mappable = shared_image_data.is_mappable(); + if (is_mappable) { + // VideoFrame should have buffer usage if its SI is mappable. // NOTE: This isn't exactly correct for software SharedImages can be // mappable but do not have buffer usage. But since, such software // SharedImages are not used with VideoFrames this should work.
diff --git a/media/renderers/video_frame_yuv_converter.cc b/media/renderers/video_frame_yuv_converter.cc index daa8578..de1e3a4f 100644 --- a/media/renderers/video_frame_yuv_converter.cc +++ b/media/renderers/video_frame_yuv_converter.cc
@@ -101,7 +101,6 @@ // This SharedImage will be written to (and later read from) via the raster // interface. - CHECK(raster_context_provider->ContextCapabilities().gpu_rasterization); gpu::SharedImageUsageSet src_usage = gpu::SHARED_IMAGE_USAGE_RASTER_READ | gpu::SHARED_IMAGE_USAGE_RASTER_WRITE;
diff --git a/net/socket/client_socket_pool.h b/net/socket/client_socket_pool.h index 87150ef6..04e9fd18 100644 --- a/net/socket/client_socket_pool.h +++ b/net/socket/client_socket_pool.h
@@ -411,8 +411,16 @@ SocketPoolState State() const { return state_; } + // This should be called exactly once before each attempted socket allocation + // via `RequestSocket` or `RequestSockets`. Be sure not to over-invoke to + // prevent early capping of the socket pool. void UpdateStateBeforeAllocation(); + // This should be called once after each successful socket released (and not + // reused) via `RequestSocket`, `RequestSockets`, `CancelRequest`, + // `ReleaseSocket`, `OnConnectJobComplete`, `CloseIdleSockets`, or + // `CloseIdleSocketsInGroup`. Be sure not to over-invoke to prevent early + // uncapping of the socket pool. void UpdateStateAfterRelease(); // This is used to reset the pool to the initial uncapped state when the
diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc index 6bb762ce..142935b 100644 --- a/net/socket/transport_client_socket_pool.cc +++ b/net/socket/transport_client_socket_pool.cc
@@ -936,12 +936,6 @@ } } -bool TransportClientSocketPool::CloseOneIdleSocket() { - if (idle_socket_count_ == 0) - return false; - return CloseOneIdleSocketExceptInGroup(nullptr); -} - bool TransportClientSocketPool::CloseOneIdleConnectionInHigherLayeredPool() { // This pool doesn't have any idle sockets. It's possible that a pool at a // higher layer is holding one of this sockets active, but it's actually idle. @@ -987,6 +981,7 @@ reason_for_closing_socket); idle_socket_it = group->mutable_idle_sockets()->erase(idle_socket_it); DecrementIdleCount(); + UpdateStateAfterRelease(); } else { DCHECK(!reason_for_closing_socket); ++idle_socket_it; @@ -1108,7 +1103,9 @@ if (State() == SocketPoolState::kCapped) { if (idle_socket_count_ > 0) { - CloseOneIdleSocket(); + if (CloseOneIdleSocketExceptInGroup(nullptr)) { + UpdateStateAfterRelease(); + } } else { // We can't activate more sockets since we're already at our global // limit. @@ -1367,6 +1364,7 @@ bound_request->request->socket_tag()); bound_request->request->net_log().EndEventWithNetErrorCode( NetLogEventType::SOCKET_POOL, bound_request->pending_error); + UpdateStateAfterRelease(); OnAvailableSocketSlot(group->group_id(), group); CheckForStalledSocketGroups(); return; @@ -1376,6 +1374,7 @@ // the group, and kick off another request. The socket will be discarded. if (bound_request->generation != group->generation()) { group->InsertUnboundRequest(std::move(bound_request->request)); + UpdateStateAfterRelease(); OnAvailableSocketSlot(group->group_id(), group); CheckForStalledSocketGroups(); return; @@ -1392,6 +1391,9 @@ if (result == OK) AddIdleSocket(job->PassSocket(), group); RemoveConnectJob(job, group); + if (result != OK) { + UpdateStateAfterRelease(); + } OnAvailableSocketSlot(group->group_id(), group); CheckForStalledSocketGroups(); return; @@ -1419,6 +1421,7 @@ RemoveConnectJob(job, group); // If no socket was handed out, there's a new socket slot available. if (!request->handle()->socket()) { + UpdateStateAfterRelease(); OnAvailableSocketSlot(group->group_id(), group); CheckForStalledSocketGroups(); }
diff --git a/net/socket/transport_client_socket_pool.h b/net/socket/transport_client_socket_pool.h index c4e2a4b..24ee65c 100644 --- a/net/socket/transport_client_socket_pool.h +++ b/net/socket/transport_client_socket_pool.h
@@ -654,13 +654,6 @@ // |reason| must be non-empty when |force| is true. void CleanupIdleSockets(bool force, const char* net_log_reason_utf8); - // Closes one idle socket. Picks the first one encountered. - // TODO(willchan): Consider a better algorithm for doing this. Perhaps we - // should keep an ordered list of idle sockets, and close them in order. - // Requires maintaining more state. It's not clear if it's worth it since - // I'm not sure if we hit this situation often. - bool CloseOneIdleSocket(); - // Checks higher layered pools to see if they can close an idle connection. bool CloseOneIdleConnectionInHigherLayeredPool();
diff --git a/net/socket/websocket_transport_client_socket_pool.cc b/net/socket/websocket_transport_client_socket_pool.cc index 24f75db6..7555d96 100644 --- a/net/socket/websocket_transport_client_socket_pool.cc +++ b/net/socket/websocket_transport_client_socket_pool.cc
@@ -169,12 +169,12 @@ ReleaseSocket(handle->group_id(), std::move(socket), handle->group_generation()); if (DeleteJob(handle)) { + UpdateStateAfterRelease(); CHECK(!base::Contains(pending_callbacks_, reinterpret_cast<ClientSocketHandleID>(handle))); } else { pending_callbacks_.erase(reinterpret_cast<ClientSocketHandleID>(handle)); } - UpdateStateAfterRelease(); ActivateStalledRequest(); } @@ -355,8 +355,10 @@ connect_job_delegate = nullptr; - if (!handed_out_socket) + if (!handed_out_socket) { + UpdateStateAfterRelease(); ActivateStalledRequest(); + } InvokeUserCallbackLater(handle, std::move(callback), result); }
diff --git a/remoting/host/installer/linux/BUILD.gn b/remoting/host/installer/linux/BUILD.gn index c51c41b..00f15da 100644 --- a/remoting/host/installer/linux/BUILD.gn +++ b/remoting/host/installer/linux/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//build/config/zip.gni") +import("//build/timestamp.gni") import("//remoting/build/config/remoting_build.gni") import("//remoting/host/installer/credits.gni") import("//remoting/remoting_locales.gni") @@ -106,6 +107,8 @@ rebase_path("//", root_build_dir), "-o", ".", + "-b", + build_timestamp, ] inputs += [ "//remoting/host/installer/linux/chrome-remote-desktop@.service" ]
diff --git a/remoting/host/installer/linux/build-deb.sh b/remoting/host/installer/linux/build-deb.sh index 5113785..8b5771b 100755 --- a/remoting/host/installer/linux/build-deb.sh +++ b/remoting/host/installer/linux/build-deb.sh
@@ -49,9 +49,10 @@ echo "-s path to the top of the src tree." echo "-o output directory path." echo "-O option (no options currently defined)" + echo "-b build timestamp (Epoch seconds)" } -while getopts ":s:o:O:ph" OPTNAME +while getopts ":s:o:O:phb:" OPTNAME do case $OPTNAME in s ) @@ -66,6 +67,9 @@ O ) OPTION="$OPTARG" ;; + b ) + BUILD_TIMESTAMP="$OPTARG" + ;; h ) usage exit 0 @@ -131,7 +135,13 @@ --force-distribution \ --distribution unstable \ "New Debian package $revision_text" - +# Manually overwrite the trailer line to force the timestamp for reproducible +# builds. Without this, debchange uses the current system time (localtime). +# NOTE: When debchange --date is properly supported in the build environment, +# this sed command should be removed and --date "$DATE_RFC5322" added to the +# debchange command above. +DATE_RFC5322="$(date --rfc-email -d "@$BUILD_TIMESTAMP")" +sed -i "s/^ -- $DEBEMAIL .*/ -- $DEBEMAIL $DATE_RFC5322/" debian/changelog CRON_SCRIPT_DIR="${OUTPUT_PATH}/remoting/installer/cron" mkdir -p ${CRON_SCRIPT_DIR} @@ -147,7 +157,8 @@ # but it seems that we don't currently, so this is the most expediant fix. SAVE_LDLP=$LD_LIBRARY_PATH unset LD_LIBRARY_PATH -BUILD_DIR=$OUTPUT_PATH SRC_DIR=${SCRIPTDIR}/../../../.. \ +SOURCE_DATE_EPOCH="$BUILD_TIMESTAMP" \ + BUILD_DIR=$OUTPUT_PATH SRC_DIR=${SCRIPTDIR}/../../../.. \ dpkg-buildpackage -b -us -uc LD_LIBRARY_PATH=$SAVE_LDLP
diff --git a/third_party/angle b/third_party/angle index 0c0d10c..1724ab3 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit 0c0d10c4914aa427d1fe969508ca327fbeece913 +Subproject commit 1724ab3641c825d2ed6fc76e20c3d20301e73696
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 7539c7d0..126fa052 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -368,6 +368,9 @@ BASE_FEATURE(kClearSiteDataPrefetchPrerenderCache, base::FEATURE_ENABLED_BY_DEFAULT); +// Fix for CSS font comparison logic. +BASE_FEATURE(kCSSFontComparisonFix, base::FEATURE_ENABLED_BY_DEFAULT); + // Enable legacy `dpr` client hint. BASE_FEATURE(kClientHintsDPR_DEPRECATED, base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index 4bb1387..bb01a62 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -228,6 +228,9 @@ // "prerenderCache" to clear the Prefetch and Prerender caches respectively. BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kClearSiteDataPrefetchPrerenderCache); +// Fix for CSS font comparison logic. +BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kCSSFontComparisonFix); + // We do intend to deprecate these when possible, do not remove the feature // until they can be disabled by default. BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kClientHintsDeviceMemory_DEPRECATED);
diff --git a/third_party/blink/renderer/core/css/container_query_evaluator.cc b/third_party/blink/renderer/core/css/container_query_evaluator.cc index 11baf86..605ab38 100644 --- a/third_party/blink/renderer/core/css/container_query_evaluator.cc +++ b/third_party/blink/renderer/core/css/container_query_evaluator.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/core/css/container_query_evaluator.h" +#include "base/feature_list.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom-blink.h" #include "third_party/blink/renderer/core/css/container_query.h" #include "third_party/blink/renderer/core/css/container_state.h" @@ -975,7 +977,9 @@ // the container values and invalidate style for any changed queries. bool invalidate_for_font = (unit_flags_ & MediaQueryExpValue::kFontRelative) && - !base::ValuesEquivalent(old_style.GetFont(), new_style.GetFont()); + (base::FeatureList::IsEnabled(blink::features::kCSSFontComparisonFix) + ? !base::ValuesEquivalent(old_style.GetFont(), new_style.GetFont()) + : old_style.GetFont() != new_style.GetFont()); // Writing direction changes may affect how logical queries match for size and // scroll-state() queries even when the physical size or scroll-state do not
diff --git a/third_party/blink/renderer/core/css/style_element.cc b/third_party/blink/renderer/core/css/style_element.cc index be717d4..995ca52 100644 --- a/third_party/blink/renderer/core/css/style_element.cc +++ b/third_party/blink/renderer/core/css/style_element.cc
@@ -49,6 +49,7 @@ #include "third_party/blink/renderer/platform/json/json_values.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" +#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" namespace blink { @@ -290,7 +291,8 @@ // string size in memory (at the expense of decoding on the CPU). url_string = StrCat({"data:text/css,", EncodeWithURLEscapeSequences(text)}); } else { - auto* blob = Blob::Create(text.Span8(), "text/css"); + StringUtf8Adaptor utf8(text, Utf8ConversionMode::kLenient); + auto* blob = Blob::Create(base::as_byte_span(utf8), "text/css"); CHECK(blob); url_string = DOMURL::CreatePublicURL(context, blob); }
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index f1cb26eb..a4c6667 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -33,8 +33,10 @@ #include "base/auto_reset.h" #include "base/containers/adapters.h" +#include "base/feature_list.h" #include "base/hash/hash.h" #include "base/rand_util.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/timing/resource_timing.mojom-blink.h" #include "third_party/blink/renderer/core/css/cascade_layer_map.h" #include "third_party/blink/renderer/core/css/cascade_layered.h" @@ -3268,8 +3270,10 @@ bool root_font_glyphs_changed = !old_root_style || (UsesGlyphRelativeUnits() && - !base::ValuesEquivalent<Font>(old_root_style->GetFont(), - new_root_style->GetFont())); + (base::FeatureList::IsEnabled(blink::features::kCSSFontComparisonFix) + ? !base::ValuesEquivalent<Font>(old_root_style->GetFont(), + new_root_style->GetFont()) + : old_root_style->GetFont() != new_root_style->GetFont())); bool root_line_height_changed = !old_root_style || (UsesLineHeightUnits() &&
diff --git a/third_party/blink/renderer/core/html/media/html_video_element.cc b/third_party/blink/renderer/core/html/media/html_video_element.cc index d18b245..ae0c2e05 100644 --- a/third_party/blink/renderer/core/html/media/html_video_element.cc +++ b/third_party/blink/renderer/core/html/media/html_video_element.cc
@@ -63,7 +63,7 @@ #include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/core/loader/resource/video_timing.h" #include "third_party/blink/renderer/core/paint/timing/paint_timing_detector.h" -#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h" +#include "third_party/blink/renderer/platform/graphics/canvas_snapshot_provider.h" #include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" @@ -351,7 +351,7 @@ } void HTMLVideoElement::ResetCache(TimerBase*) { - resource_provider_.reset(); + snapshot_provider_.reset(); } bool HTMLVideoElement::IsPersistent() const { @@ -575,12 +575,12 @@ gfx::ColorSpace dest_color_space = reinterpret_as_srgb ? gfx::ColorSpace::CreateSRGB() : media_video_frame->CompatRGBColorSpace(); - if (!resource_provider_ || - (resource_provider_->IsAccelerated() && - resource_provider_->IsGpuContextLost()) || + if (!snapshot_provider_ || + (snapshot_provider_->IsAccelerated() && + snapshot_provider_->IsGpuContextLost()) || allow_accelerated_images != allow_accelerated_images_ || - dest_size != resource_provider_->Size() || - dest_color_space != resource_provider_->GetColorSpace()) { + dest_size != snapshot_provider_->Size() || + dest_color_space != snapshot_provider_->GetColorSpace()) { viz::RasterContextProvider* raster_context_provider = nullptr; if (allow_accelerated_images) { if (auto wrapper = SharedGpuContext::ContextProviderWrapper()) { @@ -588,22 +588,23 @@ wrapper->ContextProvider().RasterContextProvider(); } } - resource_provider_.reset(); + snapshot_provider_.reset(); // Providing a null |raster_context_provider| creates a software provider. // TODO(https://crbug.com/1341235): The choice of color type and alpha type // is inappropriate in many circumstances. - resource_provider_ = CreateResourceProviderForVideoFrame( + snapshot_provider_ = CreateSnapshotProviderForVideoFrame( dest_size, GetN32FormatForCanvas(), kPremul_SkAlphaType, dest_color_space, raster_context_provider); - if (!resource_provider_) + if (!snapshot_provider_) { return nullptr; + } allow_accelerated_images_ = allow_accelerated_images; } cache_deleting_timer_.StartOneShot(kTemporaryResourceDeletionDelay, FROM_HERE); auto image = CreateImageFromVideoFrame( - std::move(media_video_frame), resource_provider_.get(), video_renderer, + std::move(media_video_frame), snapshot_provider_.get(), video_renderer, /*prefer_tagged_orientation=*/true, reinterpret_as_srgb); if (image) image->SetOriginClean(!WouldTaintOrigin());
diff --git a/third_party/blink/renderer/core/html/media/html_video_element.h b/third_party/blink/renderer/core/html/media/html_video_element.h index 29995d358..6a3ab8d 100644 --- a/third_party/blink/renderer/core/html/media/html_video_element.h +++ b/third_party/blink/renderer/core/html/media/html_video_element.h
@@ -32,7 +32,7 @@ #include "third_party/blink/renderer/core/html/html_image_loader.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h" -#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h" +#include "third_party/blink/renderer/platform/graphics/canvas_snapshot_provider.h" #include "third_party/blink/renderer/platform/timer.h" namespace blink { @@ -98,7 +98,7 @@ // Helper for GetSourceImageForCanvas() and other external callers who want a // StaticBitmapImage of the current VideoFrame. If `allow_accelerated_images` - // is set to false a software backed CanvasResourceProvider will be used to + // is set to false a software backed CanvasSnapshotProvider will be used to // produce the StaticBitmapImage. If `size` is specified, the image will be // scaled to it, otherwise the image will be in its natural size. If // `reinterpret_as_srgb` is true, then reinterpret the video as thought it @@ -279,7 +279,7 @@ // Used to fulfill blink::Image requests (CreateImage(), // GetSourceImageForCanvas(), etc). Created on demand. - std::unique_ptr<CanvasResourceProvider> resource_provider_; + std::unique_ptr<CanvasSnapshotProvider> snapshot_provider_; bool allow_accelerated_images_ = true; HeapTaskRunnerTimer<HTMLVideoElement> cache_deleting_timer_;
diff --git a/third_party/blink/renderer/core/inspector/inspect_tools.cc b/third_party/blink/renderer/core/inspector/inspect_tools.cc index 769a8f0..a36f7fb 100644 --- a/third_party/blink/renderer/core/inspector/inspect_tools.cc +++ b/third_party/blink/renderer/core/inspector/inspect_tools.cc
@@ -802,16 +802,19 @@ auto task_runner = overlay_->GetFrame()->GetTaskRunner(TaskType::kInternalInspector); if (message_string == "resume") { - task_runner->PostTask(FROM_HERE, - BindOnce(&v8_inspector::V8InspectorSession::resume, - Unretained(v8_session_), - /* setTerminateOnResume */ false)); + task_runner->PostTask( + FROM_HERE, + blink::BindOnce(&PausedInDebuggerTool::ExecuteOnV8Session, + WrapPersistent(weak_factory_.GetWeakCell()), + Action::kResume)); return; } if (message_string == "stepOver") { task_runner->PostTask( - FROM_HERE, BindOnce(&v8_inspector::V8InspectorSession::stepOver, - Unretained(v8_session_))); + FROM_HERE, + blink::BindOnce(&PausedInDebuggerTool::ExecuteOnV8Session, + WrapPersistent(weak_factory_.GetWeakCell()), + Action::kStepOver)); return; } } @@ -819,6 +822,30 @@ kInvalidOverlayCommand); } +void PausedInDebuggerTool::ExecuteOnV8Session(Action action) { + if (!v8_session_) { + return; + } + + switch (action) { + case Action::kResume: + v8_session_->resume(/* setTerminateOnResume */ false); + break; + case Action::kStepOver: + v8_session_->stepOver(); + break; + } +} + +void PausedInDebuggerTool::OnAgentDisable() { + v8_session_ = nullptr; +} + +void PausedInDebuggerTool::Trace(Visitor* visitor) const { + InspectTool::Trace(visitor); + visitor->Trace(weak_factory_); +} + // WcoTool -------------------------------------------------------- WindowControlsOverlayTool::WindowControlsOverlayTool(
diff --git a/third_party/blink/renderer/core/inspector/inspect_tools.h b/third_party/blink/renderer/core/inspector/inspect_tools.h index c8ccf076..5336a4b 100644 --- a/third_party/blink/renderer/core/inspector/inspect_tools.h +++ b/third_party/blink/renderer/core/inspector/inspect_tools.h
@@ -5,12 +5,14 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECT_TOOLS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECT_TOOLS_H_ +#include <v8-inspector.h> + #include <vector> -#include <v8-inspector.h> #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/core/inspector/inspector_overlay_agent.h" #include "third_party/blink/renderer/core/inspector/node_content_visibility_state.h" +#include "third_party/blink/renderer/platform/heap/weak_cell.h" namespace blink { @@ -237,14 +239,21 @@ message_(message) {} PausedInDebuggerTool(const PausedInDebuggerTool&) = delete; PausedInDebuggerTool& operator=(const PausedInDebuggerTool&) = delete; + void Trace(Visitor* visitor) const override; private: + enum class Action { kResume, kStepOver }; + void Draw(float scale) override; void Dispatch(const ScriptValue& message, ExceptionState& exception_state) override; String GetOverlayName() override; + void OnAgentDisable() override; + void ExecuteOnV8Session(Action action); + v8_inspector::V8InspectorSession* v8_session_; String message_; + WeakCellFactory<PausedInDebuggerTool> weak_factory_{this}; }; // -----------------------------------------------------------------------------
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc index ef665e1..74aa9d51b 100644 --- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
@@ -529,6 +529,9 @@ persistent_tool_ = nullptr; hinge_ = nullptr; + if (inspect_tool_) { + inspect_tool_->OnAgentDisable(); + } PickTheRightTool(); SetNeedsUnbufferedInput(false); document_to_ax_context_.clear();
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h index 0256d9a..70b6279 100644 --- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h +++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
@@ -119,6 +119,7 @@ virtual void Trace(Visitor* visitor) const; virtual bool HideOnHideHighlight(); virtual bool HideOnMouseMove(); + virtual void OnAgentDisable() {} protected: Member<InspectorOverlayAgent> overlay_;
diff --git a/third_party/blink/renderer/core/layout/inline/inline_box_state.cc b/third_party/blink/renderer/core/layout/inline/inline_box_state.cc index e49850e..a45005e 100644 --- a/third_party/blink/renderer/core/layout/inline/inline_box_state.cc +++ b/third_party/blink/renderer/core/layout/inline/inline_box_state.cc
@@ -5,6 +5,8 @@ #include "third_party/blink/renderer/core/layout/inline/inline_box_state.h" #include "base/containers/adapters.h" +#include "base/feature_list.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/renderer/core/layout/box_fragment_builder.h" #include "third_party/blink/renderer/core/layout/geometry/logical_offset.h" #include "third_party/blink/renderer/core/layout/geometry/logical_size.h" @@ -274,7 +276,9 @@ return false; DCHECK(style); if (style == &text_style || - base::ValuesEquivalent(style->GetFont(), text_style.GetFont()) || + (base::FeatureList::IsEnabled(blink::features::kCSSFontComparisonFix) + ? base::ValuesEquivalent(style->GetFont(), text_style.GetFont()) + : style->GetFont() == text_style.GetFont()) || style->GetFont()->PrimaryFont() == text_style.GetFont()->PrimaryFont()) { return true; }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc index aee7f0a..576cf2f 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
@@ -24,6 +24,8 @@ #include "third_party/blink/renderer/core/layout/svg/layout_svg_root.h" #include "base/auto_reset.h" +#include "base/feature_list.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/renderer/core/editing/position_with_affinity.h" #include "third_party/blink/renderer/core/frame/frame_owner.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -269,7 +271,9 @@ // any other font-relative unit), any changes to the font may change said // dimensions. if (IntrinsicSizeIsFontMetricsDependent() && - !base::ValuesEquivalent(old_style.GetFont(), style.GetFont())) { + (base::FeatureList::IsEnabled(blink::features::kCSSFontComparisonFix) + ? !base::ValuesEquivalent(old_style.GetFont(), style.GetFont()) + : old_style.GetFont() != style.GetFont())) { return true; } return false;
diff --git a/third_party/blink/renderer/core/paint/outline_painter.cc b/third_party/blink/renderer/core/paint/outline_painter.cc index 3fa78f5..cf12b5a 100644 --- a/third_party/blink/renderer/core/paint/outline_painter.cc +++ b/third_party/blink/renderer/core/paint/outline_painter.cc
@@ -800,13 +800,15 @@ return FloatRoundedRect::Radii(DefaultFocusRingCornerRadius(style)); } -void PaintSingleFocusRing(GraphicsContext& context, - const Vector<gfx::Rect>& rects, - float width, - int offset, - const FloatRoundedRect::Radii& corner_radii, - const Color& color, - const AutoDarkMode& auto_dark_mode) { +void PaintSingleFocusRing( + GraphicsContext& context, + const Vector<gfx::Rect>& rects, + float width, + int offset, + const FloatRoundedRect::Radii& corner_radii, + const ContouredRect::CornerCurvature& corner_curvature, + const Color& color, + const AutoDarkMode& auto_dark_mode) { DCHECK(!rects.empty()); SkPath path; if (!ComputeRightAnglePath(path, rects, offset, 0)) @@ -814,9 +816,22 @@ SkRect rect; if (path.isRect(&rect)) { - context.DrawFocusRingRect( - SkRRect(FloatRoundedRect(gfx::SkRectToRectF(rect), corner_radii)), - color, width, auto_dark_mode); + if (corner_curvature.IsRound()) { + context.DrawFocusRingRect( + SkRRect(FloatRoundedRect(gfx::SkRectToRectF(rect), corner_radii)), + color, width, auto_dark_mode); + } else { + ContouredRect border_rect( + FloatRoundedRect(gfx::SkRectToRectF(rect), corner_radii), + corner_curvature); + ContouredRect contour(border_rect); + const auto outset = AdjustedOutlineOffset(rects[0], offset); + contour.OutsetWithCornerCorrection(gfx::OutsetsF::TLBR( + outset.top(), outset.left(), outset.bottom(), outset.right())); + contour.SetOriginRect(border_rect.AsRoundedRect()); + context.DrawFocusRingPath(contour.GetPath().GetSkPath(), color, width, 0, + auto_dark_mode); + } return; } @@ -849,17 +864,30 @@ const float inner_ring_width = FocusRingInnerStrokeWidth(style); const int offset = FocusRingOffset(style, info); + const ContouredRect::CornerCurvature corner_curvature( + corner_radii.TopLeft().IsEmpty() ? ContouredRect::CornerCurvature::kRound + : style.CornerTopLeftShape().Exponent(), + corner_radii.TopRight().IsEmpty() + ? ContouredRect::CornerCurvature::kRound + : style.CornerTopRightShape().Exponent(), + corner_radii.BottomRight().IsEmpty() + ? ContouredRect::CornerCurvature::kRound + : style.CornerBottomRightShape().Exponent(), + corner_radii.BottomLeft().IsEmpty() + ? ContouredRect::CornerCurvature::kRound + : style.CornerBottomLeftShape().Exponent()); + Color outer_color = style.DarkColorScheme() ? Color(0x10, 0x10, 0x10) : Color::kWhite; PaintSingleFocusRing(context, rects, outer_ring_width, offset + std::ceil(inner_ring_width), corner_radii, - outer_color, AutoDarkMode::Disabled()); + corner_curvature, outer_color, AutoDarkMode::Disabled()); // Draw the inner ring using |outer_ring_width| (which should be wider than // the additional offset of the outer ring) over the outer ring to ensure no // gaps or AA artifacts. DCHECK_GE(outer_ring_width, std::ceil(inner_ring_width)); PaintSingleFocusRing(context, rects, outer_ring_width, offset, corner_radii, - inner_color, AutoDarkMode::Disabled()); + corner_curvature, inner_color, AutoDarkMode::Disabled()); } } // anonymous namespace
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc index 64f5c6a..253c463 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -649,7 +649,9 @@ void CanvasRenderingContext2D::StyleDidChange(const ComputedStyle* old_style, const ComputedStyle& new_style) { if (old_style && - base::ValuesEquivalent(old_style->GetFont(), new_style.GetFont())) { + (base::FeatureList::IsEnabled(blink::features::kCSSFontComparisonFix) + ? base::ValuesEquivalent(old_style->GetFont(), new_style.GetFont()) + : old_style->GetFont() == new_style.GetFont())) { return; } PruneLocalFontCache(0);
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_features.cc b/third_party/blink/renderer/modules/peerconnection/peer_connection_features.cc index a3622a0e..146a3fff 100644 --- a/third_party/blink/renderer/modules/peerconnection/peer_connection_features.cc +++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_features.cc
@@ -34,7 +34,7 @@ // This feature unumutes a track when a packet arrives instead of after // setRemoteDescription. -BASE_FEATURE(kWebRtcUnmuteTracksWhenPacketArrives, - base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kWebRtcUnmuteTracksWhenPacketArrives2, + base::FEATURE_ENABLED_BY_DEFAULT); } // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_features.h b/third_party/blink/renderer/modules/peerconnection/peer_connection_features.h index 677d4f80..2f104a3 100644 --- a/third_party/blink/renderer/modules/peerconnection/peer_connection_features.h +++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_features.h
@@ -12,6 +12,6 @@ MODULES_EXPORT BASE_DECLARE_FEATURE(kWebRtcEncryptedRtpHeaderExtensions); MODULES_EXPORT BASE_DECLARE_FEATURE( kWebRtcRtpScriptTransformerFrameRestrictions); -MODULES_EXPORT BASE_DECLARE_FEATURE(kWebRtcUnmuteTracksWhenPacketArrives); +MODULES_EXPORT BASE_DECLARE_FEATURE(kWebRtcUnmuteTracksWhenPacketArrives2); } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_PEER_CONNECTION_FEATURES_H_
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc index 91b8815..ae9dc1f 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -2550,7 +2550,7 @@ } // TODO(https://crbug.com/40821064): Remove killswitch after rollout. - if (!base::FeatureList::IsEnabled(kWebRtcUnmuteTracksWhenPacketArrives)) { + if (!base::FeatureList::IsEnabled(kWebRtcUnmuteTracksWhenPacketArrives2)) { for (auto& transceiver : track_events) { transceiver->receiver()->track()->Component()->Source()->SetReadyState( MediaStreamSource::kReadyStateLive);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.cc index edbcc59..5691cc09 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.cc
@@ -9,6 +9,7 @@ #include "base/functional/bind.h" #include "base/notreached.h" #include "base/task/single_thread_task_runner.h" +#include "third_party/blink/renderer/modules/mediastream/video_track_adapter.h" // For kMediaStreamTrackEmptyVideoFrameMonitor. #include "third_party/blink/renderer/modules/peerconnection/peer_connection_features.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer.h" @@ -20,6 +21,14 @@ namespace blink { +// The kWebRtcUnmuteTracksWhenPacketArrives2 feature is also gated on +// kMediaStreamTrackEmptyVideoFrameMonitor. +bool ShouldUnmuteTrackWhenPacketsArrive() { + return base::FeatureList::IsEnabled( + kMediaStreamTrackEmptyVideoFrameMonitor) && + base::FeatureList::IsEnabled(kWebRtcUnmuteTracksWhenPacketArrives2); +} + RtpReceiverState::RtpReceiverState( scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, @@ -165,7 +174,7 @@ } DCHECK(!encoded_audio_transformer_ || !encoded_video_transformer_); // TODO(https://crbug.com/40821064): Remove killswitch after rollout. - if (base::FeatureList::IsEnabled(kWebRtcUnmuteTracksWhenPacketArrives)) { + if (ShouldUnmuteTrackWhenPacketsArrive()) { CHECK(webrtc_receiver_); webrtc_receiver_->SetObserver(this); } @@ -248,8 +257,7 @@ ~RTCRtpReceiverInternal() override { DCHECK(main_task_runner_->BelongsToCurrentThread()); // TODO(https://crbug.com/40821064): Remove killswitch after rollout. - if (webrtc_receiver_ && - base::FeatureList::IsEnabled(kWebRtcUnmuteTracksWhenPacketArrives)) { + if (webrtc_receiver_ && ShouldUnmuteTrackWhenPacketsArrive()) { webrtc_receiver_->SetObserver(nullptr); } }
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame.cc b/third_party/blink/renderer/modules/webcodecs/video_frame.cc index 59f768418..465c0750 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_frame.cc +++ b/third_party/blink/renderer/modules/webcodecs/video_frame.cc
@@ -54,6 +54,7 @@ #include "third_party/blink/renderer/modules/webcodecs/video_frame_init_util.h" #include "third_party/blink/renderer/modules/webcodecs/video_frame_rect_util.h" #include "third_party/blink/renderer/platform/geometry/geometry_hash_traits.h" +#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h" #include "third_party/blink/renderer/platform/graphics/canvas_snapshot_provider.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" #include "third_party/blink/renderer/platform/graphics/image.h" @@ -364,7 +365,7 @@ if (info_to_provider_.size() >= kMaxSize) info_to_provider_.clear(); - auto provider = CreateResourceProviderForVideoFrame( + auto provider = CreateSnapshotProviderForVideoFrame( size, viz::SkColorTypeToSinglePlaneSharedImageFormat(info.colorType()), info.alphaType(), SkColorSpaceToGfxColorSpace(info.refColorSpace()), GetRasterContextProvider().get());
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc index ace4bb4..c6487cad 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -8809,7 +8809,7 @@ raster_context_provider = wrapper->ContextProvider().RasterContextProvider(); } - temp = CreateResourceProviderForVideoFrame( + temp = CreateSnapshotProviderForVideoFrame( size, format, alpha_type, color_space, raster_context_provider); } else { temp = CanvasResourceProvider::CreateExternalBitmapProvider(
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h index 31393f32..bbbcfd2 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
@@ -235,7 +235,7 @@ // rate. virtual bool IsSingleBuffered() const = 0; - bool IsGpuContextLost() const; + bool IsGpuContextLost() const override; virtual bool WritePixels(const SkImageInfo& orig_info, const void* pixels,
diff --git a/third_party/blink/renderer/platform/graphics/canvas_snapshot_provider.h b/third_party/blink/renderer/platform/graphics/canvas_snapshot_provider.h index 2146641..06610ef 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_snapshot_provider.h +++ b/third_party/blink/renderer/platform/graphics/canvas_snapshot_provider.h
@@ -6,6 +6,7 @@ #include "base/functional/function_ref.h" #include "third_party/blink/renderer/platform/graphics/image_orientation.h" +#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" #include "ui/gfx/geometry/size.h" namespace blink { @@ -26,6 +27,7 @@ virtual gfx::ColorSpace GetColorSpace() const = 0; virtual SkAlphaType GetAlphaType() const = 0; virtual bool IsValid() const = 0; + virtual bool IsGpuContextLost() const = 0; virtual bool IsExternalBitmapProvider() const { return false; } };
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_image_util.cc b/third_party/blink/renderer/platform/graphics/video_frame_image_util.cc index bb6d5fe..6cb1c30 100644 --- a/third_party/blink/renderer/platform/graphics/video_frame_image_util.cc +++ b/third_party/blink/renderer/platform/graphics/video_frame_image_util.cc
@@ -130,10 +130,6 @@ const auto transform = frame->metadata().transformation.value_or(media::kNoTransformation); - // This method should only be called with context providers supporting OOP-R. - CHECK(!raster_context_provider || - raster_context_provider->ContextCapabilities().gpu_rasterization); - // If the provider isn't accelerated, avoid GPU round trips to upload frame // data from GpuMemoryBuffer backed frames which aren't mappable. if (frame->HasMappableSharedImage() && !frame->IsMappable() && @@ -211,7 +207,7 @@ wrapper->ContextProvider().RasterContextProvider()); } -std::unique_ptr<CanvasResourceProvider> CreateResourceProviderForVideoFrame( +std::unique_ptr<CanvasSnapshotProvider> CreateSnapshotProviderForVideoFrame( gfx::Size size, viz::SharedImageFormat format, SkAlphaType alpha_type,
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_image_util.h b/third_party/blink/renderer/platform/graphics/video_frame_image_util.h index 469ec40d..2675349 100644 --- a/third_party/blink/renderer/platform/graphics/video_frame_image_util.h +++ b/third_party/blink/renderer/platform/graphics/video_frame_image_util.h
@@ -34,7 +34,6 @@ } // namespace cc namespace blink { -class CanvasResourceProvider; class CanvasSnapshotProvider; class StaticBitmapImage; @@ -93,12 +92,12 @@ PLATFORM_EXPORT scoped_refptr<viz::RasterContextProvider> GetRasterContextProvider(); -// Creates a CanvasResourceProvider which is appropriate for drawing VideoFrame +// Creates a CanvasSnapshotProvider which is appropriate for drawing VideoFrame // objects into. Some callers to CreateImageFromVideoFrame() may choose to cache -// their resource providers. If |raster_context_provider| is null a software -// resource provider will be returned. -PLATFORM_EXPORT std::unique_ptr<CanvasResourceProvider> -CreateResourceProviderForVideoFrame( +// their snapshot providers. If |raster_context_provider| is null a software +// snapshot provider will be returned. +PLATFORM_EXPORT std::unique_ptr<CanvasSnapshotProvider> +CreateSnapshotProviderForVideoFrame( gfx::Size size, viz::SharedImageFormat format, SkAlphaType alpha_type,
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_image_util_test.cc b/third_party/blink/renderer/platform/graphics/video_frame_image_util_test.cc index af0b762..2717aafe 100644 --- a/third_party/blink/renderer/platform/graphics/video_frame_image_util_test.cc +++ b/third_party/blink/renderer/platform/graphics/video_frame_image_util_test.cc
@@ -105,7 +105,7 @@ scoped_refptr<StaticBitmapImage> DoCreateImageFromVideoFrame( scoped_refptr<media::VideoFrame> frame, - CanvasResourceProvider* resource_provider = nullptr, + CanvasSnapshotProvider* snapshot_provider = nullptr, media::PaintCanvasVideoRenderer* video_renderer = nullptr, bool prefer_tagged_orientation = true) { const auto transform = @@ -119,22 +119,22 @@ dest_rect.Transpose(); } - std::unique_ptr<CanvasResourceProvider> local_resource_provider; + std::unique_ptr<CanvasSnapshotProvider> local_snapshot_provider; - if (!resource_provider) { + if (!snapshot_provider) { auto frame_color_space = frame->CompatRGBColorSpace(); - local_resource_provider = CreateResourceProviderForVideoFrame( + local_snapshot_provider = CreateSnapshotProviderForVideoFrame( dest_rect.size(), GetN32FormatForCanvas(), kPremul_SkAlphaType, frame_color_space, raster_context_provider()); - if (!local_resource_provider) { + if (!local_snapshot_provider) { DLOG(ERROR) << "Failed to create CanvasResourceProvider."; return nullptr; } - resource_provider = local_resource_provider.get(); - CHECK(resource_provider); + snapshot_provider = local_snapshot_provider.get(); + CHECK(snapshot_provider); } - return CreateImageFromVideoFrame(std::move(frame), resource_provider, + return CreateImageFromVideoFrame(std::move(frame), snapshot_provider, video_renderer, prefer_tagged_orientation); } @@ -287,7 +287,7 @@ raster_context_provider(), kTestSize, gfx::Rect(kTestSize), base::DoNothing()); - auto provider = CreateResourceProviderForVideoFrame( + auto provider = CreateSnapshotProviderForVideoFrame( kTestSize, kTestFormat, kTestAlphaType, kTestColorSpace, raster_context_provider()); ASSERT_TRUE(provider); @@ -298,12 +298,10 @@ image = DoCreateImageFromVideoFrame(texture_frame, provider.get()); EXPECT_TRUE(image->IsTextureBacked()); - - ASSERT_FALSE(provider->Recorder().HasRecordedDrawOps()); } -TEST_P(VideoFrameImageUtilTest, CreateResourceProviderForVideoFrame) { - auto provider = CreateResourceProviderForVideoFrame( +TEST_P(VideoFrameImageUtilTest, CreateSnapshotProviderForVideoFrame) { + auto provider = CreateSnapshotProviderForVideoFrame( kTestSize, kTestFormat, kTestAlphaType, kTestColorSpace, raster_context_provider()); ASSERT_TRUE(provider);
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc index fcb5d9d0..c96b4f3 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc +++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
@@ -1515,10 +1515,6 @@ paint_params.transformation = pipeline_metadata_.video_decoder_config.video_transformation(); - // This class should only be used with raster context providers that - // support OOP-R. - CHECK(!raster_context_provider_ || - raster_context_provider_->ContextCapabilities().gpu_rasterization); video_renderer_.Paint(video_frame, canvas, flags, paint_params, raster_context_provider_.get()); }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index aa489c0..b113c2eb 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -4427,7 +4427,7 @@ // Spec: https://wicg.github.io/sanitizer-api/ // Tracking bug: crbug.com/356601280 name: "SanitizerAPI", - status: "test", + status: "experimental", }, { // https://wicg.github.io/webcomponents/proposals/Scoped-Custom-Element-Registries
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index f0d3355c..35ca1c47 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -5248,8 +5248,6 @@ # ====== Tests from enabling .any.js/.worker.js tests end here ======== -crbug.com/40551880 http/tests/devtools/sources/debugger/live-edit-no-reveal.js [ Crash Failure Pass Timeout ] - # ====== Begin of display: contents tests ====== crbug.com/181374 external/wpt/css/css-display/display-contents-dynamic-table-001-inline.html [ Failure ] @@ -5953,6 +5951,10 @@ crbug.com/41448929 http/tests/devtools/elements/styles-3/styles-add-new-rule.js [ Failure Pass Timeout ] crbug.com/41448929 http/tests/devtools/elements/styles-3/styles-change-node-while-editing.js [ Failure Pass ] +# For DevTools roll. +crbug.com/407751198 http/tests/devtools/console/console-dirxml.js [ Failure Pass ] +crbug.com/407751198 http/tests/devtools/console/console-xml-document.js [ Failure Pass ] + # Tests using testRunner.useUnfortunateSynchronousResizeMode occasionally timeout, # but the test coverage is still good. @@ -6298,7 +6300,6 @@ crbug.com/40728742 http/tests/devtools/sources/debugger-ui/continue-to-location-markers-in-top-level-function.js [ Failure Pass Timeout ] # Sheriff 2020-11-16 -crbug.com/40732030 http/tests/devtools/sources/debugger-ui/debugger-inline-values-frames.js [ Failure Pass Timeout ] crbug.com/40732030 http/tests/devtools/sources/debugger-ui/reveal-execution-line.js [ Failure Pass Timeout ] crbug.com/1150475 fast/dom/open-and-close-by-DOM.html [ Failure Pass ] @@ -6313,9 +6314,6 @@ #Sheriff 2020-11-26 crbug.com/931646 crbug.com/424347610 [ Mac ] virtual/viewport-and-meta-enabled/http/tests/preload/meta-viewport-link-headers-imagesrcset.php [ Failure Pass Timeout ] -# DevTools roll -crbug.com/40155405 http/tests/devtools/report-API-errors.js [ Crash Failure Pass Timeout ] - # Sheriff 2020-12-11 # Flaking on Linux crbug.com/40736669 http/tests/devtools/extensions/extensions-resources.js [ Failure Pass ] @@ -6423,9 +6421,6 @@ # Started failing after rolling new version of check-layout-th.js css3/flexbox/perpendicular-writing-modes-inside-flex-item.html [ Failure ] -# Sheriff 2021-11-15 -crbug.com/40205355 http/tests/devtools/sources/debugger-ui/debugger-inline-values.js [ Failure Pass Timeout ] - # The wpt_flags=h2 variants of these tests fail on content shell but pass on # headless shell. Use test expectations so that the results for headless shell # will be unexpected pass. @@ -7034,11 +7029,6 @@ crbug.com/366415131 external/wpt/html/semantics/forms/the-select-element/customizable-select/picker-and-slotted.html [ Failure ] -# Temporarily disabled to unblock DevTools roll. -crbug.com/407751574 http/tests/devtools/a11y-axe-core/sources/call-stack-a11y-test.js [ Failure Pass Timeout ] -crbug.com/407751574 http/tests/devtools/sources/debugger-ui/async-call-stack-async-function.js [ Failure Pass Timeout ] -crbug.com/407751574 http/tests/devtools/sources/debugger-ui/call-stack-show-more.js [ Failure Pass Timeout ] - crbug.com/357649033 virtual/customizable-select-in-page-disabled/external/wpt/html/semantics/forms/the-select-element/customizable-select-in-page/customizable-select-in-page-appearance.tentative.html [ Failure ] crbug.com/357649033 virtual/customizable-select-in-page-disabled/external/wpt/html/semantics/forms/the-select-element/customizable-select-in-page/customizable-select-in-page-keyboard-behavior.tentative.html [ Failure ] crbug.com/357649033 virtual/customizable-select-in-page-disabled/external/wpt/html/semantics/forms/the-select-element/customizable-select-in-page/customizable-select-in-page-mouse-behavior.tentative.html [ Failure ] @@ -8732,6 +8722,7 @@ crbug.com/356930166 [ Mac15 ] external/wpt/webrtc/RTCPeerConnection-perfect-negotiation.https.html [ Skip Timeout ] crbug.com/356930166 [ Mac15 ] external/wpt/webrtc/RTCPeerConnection-restartIce.https.html [ Timeout ] crbug.com/356930166 [ Mac15 ] external/wpt/webrtc/RTCPeerConnection-videoDetectorTest.html [ Skip Timeout ] +crbug.com/356930166 [ Mac15 ] external/wpt/webrtc/RTCPeerConnection-remote-track-mute.https.html [ Skip Timeout ] crbug.com/356930166 [ Mac15 ] external/wpt/webrtc/RTCRtpReceiver-getStats.https.html [ Skip Timeout ] crbug.com/356930166 [ Mac15 ] external/wpt/webrtc/RTCRtpSender-getStats.https.html [ Skip Timeout ] crbug.com/356930166 [ Mac15 ] external/wpt/webrtc/RTCRtpSender-replaceTrack.https.html [ Skip Timeout ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index b92076d..b4850131 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -2806,23 +2806,6 @@ ] }, { - "prefix": "sanitizer-api", - "platforms": [ - "Linux" - ], - "bases": [ - "external/wpt/sanitizer-api/" - ], - "args": [ - "--enable-features=SanitizerAPI" - ], - "expires": "Jan 18, 2026", - "owners": [ - "vogelheim@google.com" - ], - "exclusive_tests": "ALL" - }, - { "prefix": "scalefactor150", "platforms": [ "Linux",
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-getStats.https-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-getStats.https-expected.txt deleted file mode 100644 index 5a5ade0..0000000 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-getStats.https-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -[FAIL] getStats() on track associated with RTCRtpReceiver should return stats report containing inbound-rtp stats - assert_true: expected true got false -[FAIL] getStats() audio contains inbound-rtp stats - assert_true: expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-getStats.https-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-getStats.https-expected.txt index c15bf990..20f0e487 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-getStats.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-getStats.https-expected.txt
@@ -1,13 +1,5 @@ This is a testharness.js-based test. -[FAIL] receiver.getStats() via addTransceiver should return stats report containing inbound-rtp stats - assert_true: expected true got false -[FAIL] receiver.getStats() via addTrack should return stats report containing inbound-rtp stats - assert_true: expected true got false [FAIL] receiver.getStats() should work on a stopped transceiver but not have inbound-rtp objects - assert_true: expected true got false -[FAIL] receiver.getStats() should work with a closed PeerConnection but not have inbound-rtp objects - assert_true: expected true got false -[FAIL] receiver.getStats() should return stats report containing ICE candidate stats - assert_true: expected true got false + assert_false: expected false got true Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt index 3d45ac0..3661b1e2 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt
@@ -1,9 +1,5 @@ This is a testharness.js-based test. [FAIL] checkRemoveTrackNegotiation assert_equals: pc2.setRemoteDescription(offer) should've added 2 tracks to receive stream expected 2 but got 0 -[FAIL] track with audio is muted after SRD - assert_true: track is muted after SRD expected true got false -[FAIL] track with video is muted after SRD - assert_true: track is muted after SRD expected true got false Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html index f364753..7fc9c936 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html
@@ -2267,7 +2267,43 @@ await exchangeOfferAnswer(pc1, pc2); await waitUntilTrackEventWithTimeout(pc2.getReceivers()[0].track, 'unmute', t); assert_false(pc2.getReceivers()[0].track.muted, `track is unmuted`); - }, `track with ${kind} gets unmuted when setting the transceiver direction to 'sendrecv ' after 'inactive'`); + }, `track with ${kind} gets unmuted when setting the transceiver direction to 'sendrecv' after 'inactive'`); + + promise_test(async t => { + const pc1 = new RTCPeerConnection(); + const pc2 = new RTCPeerConnection(); + t.add_cleanup(() => pc1.close()); + t.add_cleanup(() => pc2.close()); + + let stream; + if (kind === 'audio') { + stream = await navigator.mediaDevices.getUserMedia({[kind]: true}); + } else { + stream = await getNoiseStream({[kind]: true}); + } + t.add_cleanup(() => stream.getTracks().forEach(t => t.stop())); + + pc1.addTrack(stream.getTracks()[0], stream); + pc2.ontrack = t.step_func(async e => { + assert_true(e.track.muted, `track is muted in ontrack`); + }); + + await exchangeIceCandidates(pc1, pc2); + await exchangeOfferAnswer(pc1, pc2); + await waitUntilTrackEventWithTimeout(pc2.getReceivers()[0].track, 'unmute', t); + assert_false(pc2.getReceivers()[0].track.muted, `track is unmuted`); + pc1.getSenders()[0].replaceTrack(null); + + pc1.getTransceivers()[0].direction = 'inactive'; + await exchangeOfferAnswer(pc1, pc2); + await waitUntilTrackEventWithTimeout(pc2.getReceivers()[0].track, 'mute', t); + assert_true(pc2.getReceivers()[0].track.muted, `track is muted`); + + pc1.getTransceivers()[0].direction = 'sendrecv'; + await exchangeOfferAnswer(pc1, pc2); + await waitUntilTrackEventWithTimeout(pc2.getReceivers()[0].track, 'unmute', t); + assert_true(pc2.getReceivers()[0].track.muted, `track remains muted`); + }, `track with ${kind} stays muted when setting the transceiver direction to 'sendrecv' after 'inactive' but no packets flow`); }); </script>
diff --git a/third_party/blink/web_tests/fast/borders/cornerShapeOutlineAuto-expected.png b/third_party/blink/web_tests/fast/borders/cornerShapeOutlineAuto-expected.png new file mode 100644 index 0000000..1c45638 --- /dev/null +++ b/third_party/blink/web_tests/fast/borders/cornerShapeOutlineAuto-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/fast/borders/cornerShapeOutlineAuto-offset-expected.png b/third_party/blink/web_tests/fast/borders/cornerShapeOutlineAuto-offset-expected.png new file mode 100644 index 0000000..df72209 --- /dev/null +++ b/third_party/blink/web_tests/fast/borders/cornerShapeOutlineAuto-offset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/fast/borders/cornerShapeOutlineAuto-offset.html b/third_party/blink/web_tests/fast/borders/cornerShapeOutlineAuto-offset.html new file mode 100644 index 0000000..f25b27f --- /dev/null +++ b/third_party/blink/web_tests/fast/borders/cornerShapeOutlineAuto-offset.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> + <head> + <style type="text/css"> + div { + width: 200px; + height: 200px; + outline: 15px auto purple; + outline-offset: 5px; + margin: 30px; + border-radius: 140px; + corner-shape: bevel notch squircle scoop; + background-color: green; + } + </style> + </head> + <body> + <div> </div> + </body> +</html>
diff --git a/third_party/blink/web_tests/fast/borders/cornerShapeOutlineAuto.html b/third_party/blink/web_tests/fast/borders/cornerShapeOutlineAuto.html new file mode 100644 index 0000000..c86f519 --- /dev/null +++ b/third_party/blink/web_tests/fast/borders/cornerShapeOutlineAuto.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <style type="text/css"> + div { + width: 200px; + height: 200px; + outline: 15px auto purple; + margin: 20px; + border-radius: 140px; + corner-shape: scoop bevel notch squircle; + background-color: green; + } + </style> + </head> + <body> + <div> </div> + </body> +</html>
diff --git a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/call-stack-a11y-test.js b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/call-stack-a11y-test.js index 816f482..ebadb37 100644 --- a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/call-stack-a11y-test.js +++ b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/call-stack-a11y-test.js
@@ -29,9 +29,9 @@ await SourcesTestRunner.startDebuggerTestPromise(/* quiet */ true); await SourcesTestRunner.runTestFunctionAndWaitUntilPausedPromise(); - await TestRunner.addSnifferPromise(SourcesModule.CallStackSidebarPane.CallStackSidebarPane.prototype, 'updatedForTest'); const callStackPane = SourcesModule.CallStackSidebarPane.CallStackSidebarPane.instance(); + await callStackPane.updateComplete; const callStackElement = callStackPane.contentElement; TestRunner.addResult(`Call stack pane content: ${TestRunner.clearSpecificInfoFromStackFrames(callStackElement.deepTextContent())}`); TestRunner.addResult('Running the axe-core linter on the call stack sidebar pane.');
diff --git a/third_party/blink/web_tests/http/tests/devtools/components/widget-events-expected.txt b/third_party/blink/web_tests/http/tests/devtools/components/widget-events-expected.txt deleted file mode 100644 index b33e832..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/components/widget-events-expected.txt +++ /dev/null
@@ -1,212 +0,0 @@ -This tests that events are properly propagated through Widget hierarchy. - - -Running: testShowWidget -Widget() -Widget.show() - Widget.wasShown() - Widget.onResize() -Widget.detach() - Widget.willHide() - -Running: testAttachToOrphanNode -Widget() -Widget.show() -Error: Attempt to attach widget to orphan node - -Running: testImmediateParent -Parent() -Child() -Child.show() -OK - -Running: testDistantParent -Parent() -Child() -Child.show() -OK - -Running: testEvents -Parent() -Child() -Parent.show() - Parent.wasShown() - Parent.onResize() -Parent.doResize() -Child.show() - Child.wasShown() - Child.onResize() -Parent.doResize() - Child.onResize() -Parent.detach() - Child.willHide() - Parent.willHide() -Parent.show() - Parent.wasShown() - Child.wasShown() - Parent.onResize() - Child.onResize() -Child.detach() - Child.willHide() -Parent.detach() - Parent.willHide() - -Running: testEventsHideOnDetach -Parent() -Child() -Parent.show() - Parent.wasShown() - Parent.onResize() -Parent.doResize() -Child.show() - Child.wasShown() - Child.onResize() -Parent.doResize() - Child.onResize() -Parent.detach() - Child.willHide() - Parent.willHide() -Parent.show() - Parent.wasShown() - Child.wasShown() - Parent.onResize() - Child.onResize() -Child.detach() - Child.willHide() -Parent.detach() - Parent.willHide() - -Running: testShowOnWasShown -Parent() -Child() -Parent.show() - Parent.wasShown() -Child.show() - Child.wasShown() - Parent.onResize() - Child.onResize() -Parent.detach() - Child.willHide() - Parent.willHide() - -Running: testShowNestedOnWasShown -Top() -Middle() -Bottom() -Middle.show() -Top.show() - Top.wasShown() -Bottom.show() - Middle.wasShown() - Bottom.wasShown() - Top.onResize() - Middle.onResize() - Bottom.onResize() -Top.detach() - Bottom.willHide() - Middle.willHide() - Top.willHide() - -Running: testDetachOnWasShown -Parent() -Child() -Child.show() -Parent.show() - Parent.wasShown() -Child.detach() - Parent.onResize() -Parent.detach() - Parent.willHide() - -Running: testShowOnWillHide -Parent() -Child() -Parent.show() - Parent.wasShown() - Parent.onResize() -Child.show() - Child.wasShown() - Child.onResize() -Parent.detach() - Child.willHide() - Parent.willHide() -Child.show() - -Running: testDetachOnWillHide -Parent() -Child() -Parent.show() - Parent.wasShown() - Parent.onResize() -Child.show() - Child.wasShown() - Child.onResize() -Parent.detach() - Child.willHide() - Parent.willHide() -Child.detach() - -Running: testShowDetachesFromPrevious -Parent1() -Parent2() -Child() -Parent1.show() - Parent1.wasShown() - Parent1.onResize() -Parent2.show() - Parent2.wasShown() - Parent2.onResize() -Child.show() - Child.wasShown() - Child.onResize() -Child.show() -Child.detach() - Child.willHide() - Child.wasShown() - Child.onResize() - -Running: testResizeOnWasShown -Parent() -Child() -Child.show() -Parent.show() - Parent.wasShown() -Child.doResize() - Child.wasShown() - Parent.onResize() - Child.onResize() -Parent.detach() - Child.willHide() - Parent.willHide() - -Running: testReparentWithinWidget -Parent() -Parent.show() - Parent.wasShown() - Parent.onResize() -Child() -Child.show() - Child.wasShown() - Child.onResize() -Child.show() - Child.onResize() - -Running: testDetachChildWidgetsRemovesHiddenChildren -Parent() -visibleChild() -hiddenChild() -Parent.show() - Parent.wasShown() - Parent.onResize() -visibleChild.show() - visibleChild.wasShown() - visibleChild.onResize() -hiddenChild.show() - hiddenChild.wasShown() - hiddenChild.onResize() - hiddenChild.willHide() -visibleChild.detach() - visibleChild.willHide() -hiddenChild.detach() -Parent element has 0 child elements -
diff --git a/third_party/blink/web_tests/http/tests/devtools/components/widget-events.js b/third_party/blink/web_tests/http/tests/devtools/components/widget-events.js deleted file mode 100644 index 1c73e0e..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/components/widget-events.js +++ /dev/null
@@ -1,244 +0,0 @@ -// Copyright 2017 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {TestRunner} from 'test_runner'; - -import * as UI from 'devtools/ui/legacy/legacy.js'; - -(async function() { - TestRunner.addResult(`This tests that events are properly propagated through Widget hierarchy.\n`); - - - var TestWidget = class extends UI.Widget.Widget { - constructor(widgetName) { - super(); - this.widgetName = widgetName; - this.processWillShowCount = 0; - this.processWasHiddenCount = 0; - TestRunner.addResult(this.widgetName + '()'); - } - - processWillShow() { - TestRunner.assertEquals(this.processWillShowCount, this.processWasHiddenCount); - super.processWillShow(); - ++this.processWillShowCount; - } - - processWasHidden() { - super.processWasHidden(); - ++this.processWasHiddenCount; - TestRunner.assertEquals(this.processWillShowCount, this.processWasHiddenCount); - } - - show(parentElement) { - TestRunner.addResult(this.widgetName + '.show()'); - super.show(parentElement); - } - - detach() { - TestRunner.addResult(this.widgetName + '.detach()'); - super.detach(); - } - - doResize() { - TestRunner.addResult(this.widgetName + '.doResize()'); - super.doResize(); - } - - wasShown() { - TestRunner.addResult(' ' + this.widgetName + '.wasShown()'); - if (this.showOnWasShown) - this.showOnWasShown.show(this.showRoot || this.element); - if (this.detachOnWasShown) - this.detachOnWasShown.detach(); - if (this.resizeOnWasShown) - this.resizeOnWasShown.doResize(); - } - - willHide() { - TestRunner.addResult(' ' + this.widgetName + '.willHide()'); - if (this.showOnWillHide) - this.showOnWillHide.show(this.element); - if (this.detachOnWillHide) - this.detachOnWillHide.detach(); - } - - onResize() { - TestRunner.addResult(' ' + this.widgetName + '.onResize()'); - } - }; - - TestRunner.runTestSuite([ - function testShowWidget(next) { - var widget = new TestWidget('Widget'); - widget.show(UI.InspectorView.InspectorView.instance().element); - widget.detach(); - next(); - }, - - function testAttachToOrphanNode(next) { - try { - var widget = new TestWidget('Widget'); - var div = document.createElement('div'); - widget.show(div); - } catch (e) { - TestRunner.addResult(e); - } - next(); - }, - - function testImmediateParent(next) { - var parentWidget = new TestWidget('Parent'); - var childWidget = new TestWidget('Child'); - childWidget.show(parentWidget.element); - if (childWidget.parentWidget() === parentWidget) - TestRunner.addResult('OK'); - else - TestRunner.addResult('FAILED'); - next(); - }, - - function testDistantParent(next) { - var parentWidget = new TestWidget('Parent'); - var div = document.createElement('div'); - parentWidget.element.appendChild(div); - var childWidget = new TestWidget('Child'); - childWidget.show(div); - - if (childWidget.parentWidget() === parentWidget) - TestRunner.addResult('OK'); - else - TestRunner.addResult('FAILED'); - next(); - }, - - function testEvents(next) { - var parentWidget = new TestWidget('Parent'); - parentWidget.markAsRoot(); - var childWidget = new TestWidget('Child'); - parentWidget.show(document.body); - - parentWidget.doResize(); - childWidget.show(parentWidget.element); - parentWidget.doResize(); - parentWidget.detach(); - parentWidget.show(document.body); - childWidget.detach(); - parentWidget.detach(); - next(); - }, - - function testEventsHideOnDetach(next) { - var parentWidget = new TestWidget('Parent'); - var childWidget = new TestWidget('Child'); - childWidget.setHideOnDetach(); - parentWidget.show(UI.InspectorView.InspectorView.instance().element); - - parentWidget.doResize(); - childWidget.show(parentWidget.element); - parentWidget.doResize(); - parentWidget.detach(); - parentWidget.show(UI.InspectorView.InspectorView.instance().element); - childWidget.detach(); - parentWidget.detach(); - next(); - }, - - function testShowOnWasShown(next) { - var parentWidget = new TestWidget('Parent'); - parentWidget.showOnWasShown = new TestWidget('Child'); - parentWidget.show(UI.InspectorView.InspectorView.instance().element); - parentWidget.detach(); - next(); - }, - - function testShowNestedOnWasShown(next) { - var topWidget = new TestWidget('Top'); - var middleWidget = new TestWidget('Middle'); - var bottomWidget = new TestWidget('Bottom'); - middleWidget.show(topWidget.element); - topWidget.showOnWasShown = bottomWidget; - topWidget.showRoot = middleWidget.element; - topWidget.show(UI.InspectorView.InspectorView.instance().element); - topWidget.detach(); - next(); - }, - - function testDetachOnWasShown(next) { - var parentWidget = new TestWidget('Parent'); - var childWidget = new TestWidget('Child'); - childWidget.show(parentWidget.element); - parentWidget.detachOnWasShown = childWidget; - parentWidget.show(UI.InspectorView.InspectorView.instance().element); - parentWidget.detach(); - next(); - }, - - function testShowOnWillHide(next) { - var parentWidget = new TestWidget('Parent'); - var childWidget = new TestWidget('Child'); - parentWidget.show(UI.InspectorView.InspectorView.instance().element); - childWidget.show(parentWidget.element); - parentWidget.showOnWillHide = childWidget; - parentWidget.detach(); - next(); - }, - - function testDetachOnWillHide(next) { - var parentWidget = new TestWidget('Parent'); - var childWidget = new TestWidget('Child'); - parentWidget.show(UI.InspectorView.InspectorView.instance().element); - childWidget.show(parentWidget.element); - parentWidget.detachOnWillHide = childWidget; - parentWidget.detach(); - next(); - }, - - function testShowDetachesFromPrevious(next) { - var parentWidget1 = new TestWidget('Parent1'); - var parentWidget2 = new TestWidget('Parent2'); - var childWidget = new TestWidget('Child'); - parentWidget1.show(UI.InspectorView.InspectorView.instance().element); - parentWidget2.show(UI.InspectorView.InspectorView.instance().element); - childWidget.show(parentWidget1.element); - childWidget.show(parentWidget2.element); - next(); - }, - - function testResizeOnWasShown(next) { - var parentWidget = new TestWidget('Parent'); - var childWidget = new TestWidget('Child'); - childWidget.show(parentWidget.element); - parentWidget.resizeOnWasShown = childWidget; - parentWidget.show(UI.InspectorView.InspectorView.instance().element); - parentWidget.detach(); - next(); - }, - - function testReparentWithinWidget(next) { - var parentWidget = new TestWidget('Parent'); - parentWidget.show(UI.InspectorView.InspectorView.instance().element); - var childWidget = new TestWidget('Child'); - var container1 = parentWidget.element.createChild('div'); - var container2 = parentWidget.element.createChild('div'); - childWidget.show(container1); - childWidget.show(container2); - next(); - }, - - function testDetachChildWidgetsRemovesHiddenChildren(next) { - var parentWidget = new TestWidget('Parent'); - var visibleChild = new TestWidget('visibleChild'); - var hiddenChild = new TestWidget('hiddenChild'); - parentWidget.show(UI.InspectorView.InspectorView.instance().element); - visibleChild.show(parentWidget.element); - hiddenChild.show(parentWidget.element); - hiddenChild.hideWidget(); - parentWidget.detachChildWidgets(); - var count = parentWidget.element.childElementCount; - TestRunner.addResult(`Parent element has ${count} child elements`); - next(); - } - ]); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/report-API-errors-expected.txt b/third_party/blink/web_tests/http/tests/devtools/report-API-errors-expected.txt deleted file mode 100644 index f129270e..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/report-API-errors-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -Tests that InspectorBackendStub is catching incorrect arguments. - -Protocol Error: Invalid type of argument 'userAgent' for method 'Network.setUserAgentOverride' call. It must be 'string' but it is 'number'. -Protocol Error: Invalid number of arguments for method 'Network.setUserAgentOverride' call. It must have the following arguments [{"name":"userAgent","type":"string","optional":false},{"name":"acceptLanguage","type":"string","optional":true},{"name":"platform","type":"string","optional":true},{"name":"userAgentMetadata","type":"object","optional":true}]'. -Protocol Error: Invalid type of argument 'includeCommandLineAPI' for method 'Runtime.evaluate' call. It must be 'boolean' but it is 'function'. -Protocol Error: Invalid type of argument 'silent' for method 'Runtime.evaluate' call. It must be 'boolean' but it is 'function'. -Protocol Error: the message wrongDomain.something-strange is for non-existing domain 'wrongDomain': {"method":"wrongDomain.something-strange","params":{}} -Protocol Error: Attempted to dispatch an unspecified method 'Inspector.something-strange': {"method":"Inspector.something-strange","params":{}} -
diff --git a/third_party/blink/web_tests/http/tests/devtools/report-API-errors.js b/third_party/blink/web_tests/http/tests/devtools/report-API-errors.js deleted file mode 100644 index f4d78a7..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/report-API-errors.js +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2017 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {TestRunner} from 'test_runner'; - -import * as Platform from 'devtools/core/platform/platform.js'; - -(async function() { - TestRunner.addResult(`Tests that InspectorBackendStub is catching incorrect arguments.\n`); - - - console.error = function() { - TestRunner.addResult(Platform.StringUtilities.sprintf.apply(this, arguments)); - }; - - TestRunner.NetworkAgent.invoke_setUserAgentOverride({userAgent: 1}); - TestRunner.NetworkAgent.invoke_setUserAgentOverride({}); - TestRunner.NetworkAgent.invoke_setUserAgentOverride({userAgent: '123', acceptLanguage: 'not a function'}); - TestRunner.NetworkAgent.invoke_setUserAgentOverride({userAgent: '123', acceptLanguage: undefined}); - TestRunner.RuntimeAgent.invoke_evaluate({expression: 'true', objectGroup: 'test'}); - TestRunner.RuntimeAgent.invoke_evaluate({expression: 'true', objectGroup: 'test', includeCommandLineAPI: function() {}}); - TestRunner.RuntimeAgent.invoke_evaluate({expression: 'true', objectGroup: 'test', includeCommandLineAPI: undefined, silent: function() {}}); - TestRunner.mainTarget._router._onMessage('{"method": "wrongDomain.something-strange", "params": {}}'); - TestRunner.mainTarget._router._onMessage('{"method": "Inspector.something-strange", "params": {}}'); - - TestRunner.completeTest(); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/async-call-stack-async-function.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/async-call-stack-async-function.js index 5b4ffd5..3bf5002 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/async-call-stack-async-function.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/async-call-stack-async-function.js
@@ -36,9 +36,7 @@ SourcesTestRunner.startDebuggerTestPromise(/* quiet */ true) .then(() => SourcesTestRunner.runTestFunctionAndWaitUntilPausedPromise()) - .then( - () => TestRunner.addSnifferPromise( - SourcesModule.CallStackSidebarPane.CallStackSidebarPane.prototype, 'updatedForTest')) + .then(() => SourcesModule.CallStackSidebarPane.CallStackSidebarPane.instance().updateComplete) .then(() => dumpCallStackSidebarPane()) .then(() => SourcesTestRunner.completeDebuggerTest());
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/call-stack-show-more.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/call-stack-show-more.js index 015e4bd..9f09de45 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/call-stack-show-more.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/call-stack-show-more.js
@@ -27,15 +27,13 @@ await SourcesTestRunner.startDebuggerTestPromise(/* quiet */ true); await SourcesTestRunner.runTestFunctionAndWaitUntilPausedPromise(); - await TestRunner.addSnifferPromise( - SourcesModule.CallStackSidebarPane.CallStackSidebarPane.prototype, 'updatedForTest'); + const pane = SourcesModule.CallStackSidebarPane.CallStackSidebarPane.instance(); + await pane.updateComplete; dumpCallStackSidebarPane(); TestRunner.addResult('\n---------------\nClicks show more..'); - const pane = SourcesModule.CallStackSidebarPane.CallStackSidebarPane.instance(); pane.contentElement.querySelector('.show-more-message > .link').click(); - await TestRunner.addSnifferPromise( - SourcesModule.CallStackSidebarPane.CallStackSidebarPane.prototype, 'updatedForTest'); + await pane.updateComplete; dumpCallStackSidebarPane(); SourcesTestRunner.completeDebuggerTest();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-inline-values-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-inline-values-expected.txt deleted file mode 100644 index d253eaa..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-inline-values-expected.txt +++ /dev/null
@@ -1,113 +0,0 @@ -Tests inline values rendering in the sources panel. - -=========== 11< ========== -[11] > debugger; -[12] var a = { k: 1 }; -[13] var b = [1, 2, 3, 4, 5]; -[14] var c = new Array(100); c[10] = 1; -[15] a.k = 2; -[16] a.l = window; -[17] b[1]++; -[18] b[2] = document.body; -[19] } -[20] -=========== 11< ========== -[11] debugger; -[12] > var a = { k: 1 }; -[13] var b = [1, 2, 3, 4, 5]; -[14] var c = new Array(100); c[10] = 1; -[15] a.k = 2; -[16] a.l = window; -[17] b[1]++; -[18] b[2] = document.body; -[19] } -[20] -=========== 11< ========== -[11] debugger; -[12] var a = { k: 1 }; a = {k: 1} -[13] > var b = [1, 2, 3, 4, 5]; -[14] var c = new Array(100); c[10] = 1; -[15] a.k = 2; -[16] a.l = window; -[17] b[1]++; -[18] b[2] = document.body; -[19] } -[20] -=========== 11< ========== -[11] debugger; -[12] var a = { k: 1 }; a = {k: 1} -[13] var b = [1, 2, 3, 4, 5]; b = (5) [1, 2, 3, 4, 5] -[14] > var c = new Array(100); c[10] = 1; -[15] a.k = 2; -[16] a.l = window; -[17] b[1]++; -[18] b[2] = document.body; -[19] } -[20] -=========== 11< ========== -[11] debugger; -[12] var a = { k: 1 }; a = {k: 1} -[13] var b = [1, 2, 3, 4, 5]; b = (5) [1, 2, 3, 4, 5] -[14] > var c = new Array(100); c[10] = 1; -[15] a.k = 2; -[16] a.l = window; -[17] b[1]++; -[18] b[2] = document.body; -[19] } -[20] -=========== 11< ========== -[11] debugger; -[12] var a = { k: 1 }; a = {k: 1} -[13] var b = [1, 2, 3, 4, 5]; b = (5) [1, 2, 3, 4, 5] -[14] var c = new Array(100); c[10] = 1; c = (100) [empty × 10, 1, empty × 89] -[15] > a.k = 2; -[16] a.l = window; -[17] b[1]++; -[18] b[2] = document.body; -[19] } -[20] -=========== 11< ========== -[11] debugger; -[12] var a = { k: 1 }; a = {k: 2} -[13] var b = [1, 2, 3, 4, 5]; b = (5) [1, 2, 3, 4, 5] -[14] var c = new Array(100); c[10] = 1; c = (100) [empty × 10, 1, empty × 89] -[15] a.k = 2; a = {k: 2} -[16] > a.l = window; -[17] b[1]++; -[18] b[2] = document.body; -[19] } -[20] -=========== 11< ========== -[11] debugger; -[12] var a = { k: 1 }; a = {k: 2, l: Window} -[13] var b = [1, 2, 3, 4, 5]; b = (5) [1, 2, 3, 4, 5] -[14] var c = new Array(100); c[10] = 1; c = (100) [empty × 10, 1, empty × 89] -[15] a.k = 2; a = {k: 2, l: Window} -[16] a.l = window; -[17] > b[1]++; -[18] b[2] = document.body; -[19] } -[20] -=========== 11< ========== -[11] debugger; -[12] var a = { k: 1 }; a = {k: 2, l: Window} -[13] var b = [1, 2, 3, 4, 5]; b = (5) [1, 3, 3, 4, 5] -[14] var c = new Array(100); c[10] = 1; c = (100) [empty × 10, 1, empty × 89] -[15] a.k = 2; a = {k: 2, l: Window} -[16] a.l = window; -[17] b[1]++; b = (5) [1, 3, 3, 4, 5] -[18] > b[2] = document.body; -[19] } -[20] -=========== 11< ========== -[11] debugger; -[12] var a = { k: 1 }; a = {k: 2, l: Window} -[13] var b = [1, 2, 3, 4, 5]; b = (5) [1, 3, body, 4, 5] -[14] var c = new Array(100); c[10] = 1; c = (100) [empty × 10, 1, empty × 89] -[15] a.k = 2; a = {k: 2, l: Window} -[16] a.l = window; -[17] b[1]++; b = (5) [1, 3, body, 4, 5] -[18] b[2] = document.body; -[19] > } -[20] -
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-inline-values-frames-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-inline-values-frames-expected.txt deleted file mode 100644 index 34f098f..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-inline-values-frames-expected.txt +++ /dev/null
@@ -1,57 +0,0 @@ -Tests inline values rendering while stepping between call frames. - -=========== 11< ========== -[11] > debugger; -[12] var sameName = 'foo'; -[13] innerFunction('not-foo'); -[14] } -[15] -[16] function innerFunction(sameName) { -[17] return; -[18] } -=========== 11< ========== -[11] debugger; -[12] > var sameName = 'foo'; -[13] innerFunction('not-foo'); -[14] } -[15] -[16] function innerFunction(sameName) { -[17] return; -[18] } -=========== 11< ========== -[11] debugger; -[12] var sameName = 'foo'; sameName = "foo" -[13] > innerFunction('not-foo'); -[14] } -[15] -[16] function innerFunction(sameName) { -[17] return; -[18] } -=========== 11< ========== -[11] debugger; -[12] var sameName = 'foo'; -[13] innerFunction('not-foo'); -[14] } -[15] -[16] function innerFunction(sameName) { sameName = "not-foo" -[17] > return; -[18] } -=========== 11< ========== -[11] debugger; -[12] var sameName = 'foo'; -[13] innerFunction('not-foo'); -[14] } -[15] -[16] function innerFunction(sameName) { sameName = "not-foo" -[17] > return; -[18] } -=========== 11< ========== -[11] debugger; -[12] var sameName = 'foo'; sameName = "foo" -[13] innerFunction('not-foo'); -[14] > } -[15] -[16] function innerFunction(sameName) { -[17] return; -[18] } -
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-inline-values-frames.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-inline-values-frames.js deleted file mode 100644 index da64885..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-inline-values-frames.js +++ /dev/null
@@ -1,65 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {TestRunner} from 'test_runner'; -import {SourcesTestRunner} from 'sources_test_runner'; - -import * as SourcesModule from 'devtools/panels/sources/sources.js'; - -(async function() { - TestRunner.addResult(`Tests inline values rendering while stepping between call frames.\n`); - await TestRunner.showPanel('sources'); - await TestRunner.evaluateInPagePromise(` - function testFunction() - { - debugger; - var sameName = 'foo'; - innerFunction('not-foo'); - } - - function innerFunction(sameName) { - return; - } - `); - - SourcesTestRunner.startDebuggerTest(runTestFunction); - SourcesTestRunner.setQuiet(true); - - var stepCount = 0; - - function runTestFunction() { - TestRunner.addSniffer( - SourcesModule.DebuggerPlugin.DebuggerPlugin.prototype, 'executionLineChanged', - onSetExecutionLocation); - TestRunner.evaluateInPage('setTimeout(testFunction, 0)'); - } - - async function onSetExecutionLocation(liveLocation) { - TestRunner.deprecatedRunAfterPendingDispatches(dumpAndContinue.bind( - null, this.textEditor, (await liveLocation.uiLocation()).lineNumber)); - } - - function dumpAndContinue(textEditor, lineNumber) { - var startLine = 11; - var endLine = 19; - TestRunner.addResult(`=========== ${startLine}< ==========`); - var lineCount = endLine - startLine; - for (var i = startLine; i < endLine; ++i) { - var output = ['[' + (i < lineCount ? ' ' : '') + i + ']']; - output.push(i == lineNumber ? '>' : ' '); - output.push(textEditor.line(i)); - output.push('\t'); - textEditor.decorations.get(i).forEach(decoration => output.push(decoration.element.deepTextContent())); - TestRunner.addResult(output.join(' ')); - } - - TestRunner.addSniffer( - SourcesModule.DebuggerPlugin.DebuggerPlugin.prototype, 'executionLineChanged', - onSetExecutionLocation); - if (++stepCount < 6) - SourcesTestRunner.stepInto(); - else - SourcesTestRunner.completeDebuggerTest(); - } -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-inline-values.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-inline-values.js deleted file mode 100644 index 5a88cb2..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-inline-values.js +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2017 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {TestRunner} from 'test_runner'; -import {SourcesTestRunner} from 'sources_test_runner'; - -import * as SourcesModule from 'devtools/panels/sources/sources.js'; - -(async function() { - TestRunner.addResult(`Tests inline values rendering in the sources panel.\n`); - await TestRunner.showPanel('sources'); - await TestRunner.evaluateInPagePromise(` - function testFunction() - { - debugger; - var a = { k: 1 }; - var b = [1, 2, 3, 4, 5]; - var c = new Array(100); c[10] = 1; - a.k = 2; - a.l = window; - b[1]++; - b[2] = document.body; - } - `); - - SourcesTestRunner.startDebuggerTest(runTestFunction); - SourcesTestRunner.setQuiet(true); - - var stepCount = 0; - - function runTestFunction() { - TestRunner.addSniffer( - SourcesModule.DebuggerPlugin.DebuggerPlugin.prototype, 'executionLineChanged', - onSetExecutionLocation); - TestRunner.evaluateInPage('setTimeout(testFunction, 0)'); - } - - async function onSetExecutionLocation(liveLocation) { - TestRunner.deprecatedRunAfterPendingDispatches(dumpAndContinue.bind( - null, this.textEditor, (await liveLocation.uiLocation()).lineNumber)); - } - - function dumpAndContinue(textEditor, lineNumber) { - TestRunner.addResult('=========== 11< =========='); - for (var i = 11; i < 21; ++i) { - var output = ['[' + (i < 10 ? ' ' : '') + i + ']']; - output.push(i == lineNumber ? '>' : ' '); - output.push(textEditor.line(i)); - output.push('\t'); - textEditor.decorations.get(i).forEach(decoration => output.push(decoration.element.deepTextContent())); - TestRunner.addResult(output.join(' ')); - } - - TestRunner.addSniffer( - SourcesModule.DebuggerPlugin.DebuggerPlugin.prototype, 'executionLineChanged', - onSetExecutionLocation); - if (++stepCount < 10) - SourcesTestRunner.stepOver(); - else - SourcesTestRunner.completeDebuggerTest(); - } -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/live-edit-no-reveal-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger/live-edit-no-reveal-expected.txt deleted file mode 100644 index 9e97d9e..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/live-edit-no-reveal-expected.txt +++ /dev/null
@@ -1,47 +0,0 @@ -Tests live edit feature. - - -Running: testLiveEditWithoutStepInWhenPausedThenStepIntoCausesCursorMove -Script execution paused. -Moving cursor to (0, 0). -Committing live edit. -Script execution paused. -Stepping into... -Did step into -Script execution resumed. -Script execution paused. -Script execution resumed. -Cursor position is: (2, 4). - -Running: testLiveEditWithStepInWhenPausedThenStepIntoCausesCursorMove -Script execution paused. -Moving cursor to (0, 0). -Committing live edit. -Did step into -Stepping into... -Did step into -Script execution resumed. -Script execution paused. -Script execution resumed. -Script execution paused. -Script execution resumed. -Cursor position is: (8, 4). - -Running: testLiveEditWithoutStepInWhenPausedDoesNotCauseCursorMove -Script execution paused. -Moving cursor to (0, 0). -Committing live edit. -Script execution paused. -Script execution resumed. -Cursor position is: (0, 0). - -Running: testLiveEditWithStepInWhenPausedDoesNotCauseCursorMove -Script execution paused. -Moving cursor to (0, 0). -Committing live edit. -Did step into -Script execution resumed. -Script execution paused. -Script execution resumed. -Cursor position is: (0, 0). -
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/live-edit-no-reveal.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger/live-edit-no-reveal.js deleted file mode 100644 index c7ab56ce..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/live-edit-no-reveal.js +++ /dev/null
@@ -1,116 +0,0 @@ -// Copyright 2017 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {TestRunner} from 'test_runner'; -import {SourcesTestRunner} from 'sources_test_runner'; - -import * as TextUtils from 'devtools/models/text_utils/text_utils.js'; -import * as Sources from 'devtools/panels/sources/sources.js'; - -(async function() { - TestRunner.addResult(`Tests live edit feature.\n`); - await TestRunner.showPanel('sources'); - await TestRunner.addScriptTag('resources/edit-me-when-paused-no-reveal.js'); - - var panel = Sources.SourcesPanel.SourcesPanel.instance(); - var sourceFrame; - - function didStepInto() { - TestRunner.addResult('Did step into'); - } - - TestRunner.addSniffer(TestRunner.debuggerModel, 'stepInto', didStepInto, true); - - function testLiveEditWhenPausedDoesNotCauseCursorMove(oldText, newText, next) { - SourcesTestRunner.showScriptSource('edit-me-when-paused-no-reveal.js', didShowScriptSource); - - async function didShowScriptSource(sourceFrame) { - SourcesTestRunner.waitUntilPaused(paused); - await SourcesTestRunner.setBreakpoint(sourceFrame, 8, '', true); - TestRunner.evaluateInPage('f1()', didEvaluateInPage); - } - - function paused(callFrames) { - sourceFrame = panel.visibleView; - SourcesTestRunner.removeBreakpoint(sourceFrame, 8); - TestRunner.addSniffer(TestRunner.debuggerModel, '_didEditScriptSource', didEditScriptSource); - panel._updateLastModificationTimeForTest(); - SourcesTestRunner.replaceInSource(sourceFrame, oldText, newText); - TestRunner.addResult('Moving cursor to (0, 0).'); - sourceFrame.setSelection(TextUtils.TextRange.TextRange.createFromLocation(0, 0)); - TestRunner.addResult('Committing live edit.'); - SourcesTestRunner.commitSource(sourceFrame); - } - - function didEditScriptSource() { - SourcesTestRunner.resumeExecution(); - } - - function didEvaluateInPage(result) { - panel._lastModificationTimeoutPassedForTest(); - var selection = sourceFrame.textEditor.selection(); - TestRunner.addResult('Cursor position is: (' + selection.startLine + ', ' + selection.startColumn + ').'); - TestRunner.assertEquals(sourceFrame, panel.visibleView, 'Another file editor is open.'); - next(); - } - } - - function testLiveEditWhenPausedThenStepIntoCausesCursorMove(oldText, newText, next) { - SourcesTestRunner.showScriptSource('edit-me-when-paused-no-reveal.js', didShowScriptSource); - - async function didShowScriptSource(sourceFrame) { - SourcesTestRunner.waitUntilPaused(paused); - await SourcesTestRunner.setBreakpoint(sourceFrame, 8, '', true); - TestRunner.evaluateInPage('f1()', didEvaluateInPage); - } - - function paused(callFrames) { - sourceFrame = panel.visibleView; - SourcesTestRunner.removeBreakpoint(sourceFrame, 8); - TestRunner.addSniffer(TestRunner.debuggerModel, '_didEditScriptSource', didEditScriptSource); - panel._lastModificationTimeoutPassedForTest(); - SourcesTestRunner.replaceInSource(sourceFrame, oldText, newText); - TestRunner.addResult('Moving cursor to (0, 0).'); - sourceFrame.setSelection(TextUtils.TextRange.TextRange.createFromLocation(0, 0)); - TestRunner.addResult('Committing live edit.'); - SourcesTestRunner.commitSource(sourceFrame); - } - - function didEditScriptSource() { - TestRunner.addResult('Stepping into...'); - TestRunner.addSniffer(Sources.SourcesView.SourcesView.prototype, 'showSourceLocation', didRevealAfterStepInto); - panel._lastModificationTimeoutPassedForTest(); - SourcesTestRunner.stepInto(); - } - - function didRevealAfterStepInto() { - SourcesTestRunner.resumeExecution(); - } - - function didEvaluateInPage(result) { - var selection = sourceFrame.textEditor.selection(); - TestRunner.addResult('Cursor position is: (' + selection.startLine + ', ' + selection.startColumn + ').'); - TestRunner.assertEquals(sourceFrame, panel.visibleView, 'Another file editor is open.'); - next(); - } - } - - SourcesTestRunner.runDebuggerTestSuite([ - function testLiveEditWithoutStepInWhenPausedThenStepIntoCausesCursorMove(next) { - testLiveEditWhenPausedThenStepIntoCausesCursorMove('function f2()', ' function f2()', next); - }, - - function testLiveEditWithStepInWhenPausedThenStepIntoCausesCursorMove(next) { - testLiveEditWhenPausedThenStepIntoCausesCursorMove('return x + f2();', 'return x + f2(); ', next); - }, - - function testLiveEditWithoutStepInWhenPausedDoesNotCauseCursorMove(next) { - testLiveEditWhenPausedDoesNotCauseCursorMove('function f2()', ' function f2()', next); - }, - - function testLiveEditWithStepInWhenPausedDoesNotCauseCursorMove(next) { - testLiveEditWhenPausedDoesNotCauseCursorMove('return x + f2();', 'return x + f2(); ', next); - } - ]); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/unit/object-events-expected.txt b/third_party/blink/web_tests/http/tests/devtools/unit/object-events-expected.txt deleted file mode 100644 index 83a54f5..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/unit/object-events-expected.txt +++ /dev/null
@@ -1,23 +0,0 @@ -The test verifies that DevTools events work. - -Adding a listener with this 'original listener' -Dispatching event with the data 'first event' -Heard event with the data 'first event' and this 'original listener' - -Adding a listener with this 'second listener' -Dispatching event with the data 'second event' -Heard event with the data 'second event' and this 'original listener' -Heard event with the data 'second event' and this 'second listener' - -Removing a listener with this 'second listener' -Dispatching event with the data 'third event' -Heard event with the data 'third event' and this 'original listener' - -Adding a listener that removes a later listener -Adding a listener with this 'later listener to be removed' -Dispatching event with the data 'fourth event' -Heard event with the data 'fourth event' and this 'original listener' -removing the listener during the event: fourth event -Removing a listener with this 'later listener to be removed' - -
diff --git a/third_party/blink/web_tests/http/tests/devtools/unit/object-events.js b/third_party/blink/web_tests/http/tests/devtools/unit/object-events.js deleted file mode 100644 index 6fac046..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/unit/object-events.js +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {TestRunner} from 'test_runner'; - -import * as Common from 'devtools/core/common/common.js'; - -(async function() { - TestRunner.addResult(`The test verifies that DevTools events work.\n`); - var object = new Common.ObjectWrapper.ObjectWrapper(); - var eventSymbol = Symbol('Event'); - - addListener('original listener'); - dispatch('first event'); - addListener('second listener'); - dispatch('second event'); - removeListener('second listener'); - dispatch('third event'); - - TestRunner.addResult('Adding a listener that removes a later listener') - object.addEventListener(eventSymbol, event => { - TestRunner.addResult(`removing the listener during the event: ${event.data} `); - removeListener('later listener to be removed'); - }); - addListener('later listener to be removed') - dispatch('fourth event'); - - TestRunner.completeTest(); - - function eventListener(event) { - TestRunner.addResult(`Heard event with the data '${event.data}' and this '${this}'`); - } - - function dispatch(data) { - TestRunner.addResult(`Dispatching event with the data '${data}'`); - object.dispatchEventToListeners(eventSymbol, data); - TestRunner.addResult(''); - } - - function addListener(thisValue) { - TestRunner.addResult(`Adding a listener with this '${thisValue}'`); - object.addEventListener(eventSymbol, eventListener, thisValue); - } - - function removeListener(thisValue) { - TestRunner.addResult(`Removing a listener with this '${thisValue}'`); - object.removeEventListener(eventSymbol, eventListener, thisValue); - - } - -})();
diff --git a/third_party/blink/web_tests/virtual/sanitizer-api/README.md b/third_party/blink/web_tests/virtual/sanitizer-api/README.md deleted file mode 100644 index 95a66a3..0000000 --- a/third_party/blink/web_tests/virtual/sanitizer-api/README.md +++ /dev/null
@@ -1,8 +0,0 @@ -= Sanitizer API Virtual Test Suite = - -We're removing and then re-implementing the Sanitizer API. In order to not have -to deal with failing sanitizer WPT tests in the mean time, this virtual test -suite is "stealing" all the WPT sanitizer tests. - -Note that the virtual test suite definition uses `exclusive_tests: ALL`, -which causes these tests to only be executed as part of this test suite.
diff --git a/third_party/dawn b/third_party/dawn index 23f08c7..d07825e 160000 --- a/third_party/dawn +++ b/third_party/dawn
@@ -1 +1 @@ -Subproject commit 23f08c798e68e28242fe3cd6990ec049695a930b +Subproject commit d07825efa003125c46a2819c37081dbde0528277
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index 60b8977..9d9a726 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit 60b8977eb329282198e284c76f6ac002f5320b45 +Subproject commit 9d9a7262df8a7db685524e449c0c08fc3f5f0e8c
diff --git a/third_party/fontconfig/BUILD.gn b/third_party/fontconfig/BUILD.gn index 76816f0..2ca2c39 100644 --- a/third_party/fontconfig/BUILD.gn +++ b/third_party/fontconfig/BUILD.gn
@@ -82,6 +82,7 @@ "BINDGEN_IGNORE_VISIBILITY=1", "FC_NO_MT=1", "FLEXIBLE_ARRAY_MEMBER=1", + "HAVE_VASPRINTF=1", ] } @@ -99,7 +100,6 @@ "src/src/fcdir.c", "src/src/fcfontations.c", "src/src/fcformat.c", - "src/src/fcfreetype.c", "src/src/fcfs.c", "src/src/fchash.c", "src/src/fcinit.c", @@ -118,8 +118,6 @@ "src/src/fcstr.c", "src/src/fcweight.c", "src/src/fcxml.c", - "src/src/ftglue.c", - "src/src/ftglue.h", ] include_dirs = [ @@ -143,7 +141,6 @@ deps = [ ":fontconfig_fontations_ffi", - "//build/config/freetype", "//third_party/libxml", "//third_party/zlib", ]
diff --git a/third_party/fontconfig/README.chromium b/third_party/fontconfig/README.chromium index 95605d24..dcd219a 100644 --- a/third_party/fontconfig/README.chromium +++ b/third_party/fontconfig/README.chromium
@@ -1,6 +1,6 @@ Name: fontconfig URL: http://www.freedesktop.org/wiki/Software/fontconfig/ -Version: 23b3fc6e58a13d126b9c30fafc9a16f8bd7143e9 +Version: d62c2ab268d1679335daa8fb0ea6970f35224a76 Update Mechanism: Manual CPEPrefix: cpe:/a:fontconfig_project:fontconfig:2.17.1 License: public-domain-md5, MIT-Modern-Variant, HPND-sell-variant, MIT @@ -12,7 +12,12 @@ Fontconfig is a library for configuring and customizing font access. Modifications: -- None +- We locally build FontConfig fully based on Fontations, and without FreeType. + We do that by removing ENABLE_FREETYPE from meson-config.h see + - https://gitlab.freedesktop.org/fontconfig/fontconfig/-/issues/502 + - https://gitlab.freedesktop.org/fontconfig/fontconfig/-/merge_requests/488 + - https://gitlab.freedesktop.org/fontconfig/fontconfig/-/merge_requests/490 + The update.sh script removes these lines from meson-config.h To import a new snapshot of fontconfig: Run update.sh
diff --git a/third_party/fontconfig/include/fcalias.h b/third_party/fontconfig/include/fcalias.h index dd87830d..33951c65 100644 --- a/third_party/fontconfig/include/fcalias.h +++ b/third_party/fontconfig/include/fcalias.h
@@ -162,10 +162,6 @@ #define FcDirCacheLoadFile IA__FcDirCacheLoadFile extern __typeof (FcDirCacheUnload) IA__FcDirCacheUnload FC_ATTRIBUTE_VISIBILITY_HIDDEN; #define FcDirCacheUnload IA__FcDirCacheUnload -extern __typeof (FcFreeTypeQuery) IA__FcFreeTypeQuery FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcFreeTypeQuery IA__FcFreeTypeQuery -extern __typeof (FcFreeTypeQueryAll) IA__FcFreeTypeQueryAll FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcFreeTypeQueryAll IA__FcFreeTypeQueryAll extern __typeof (FcFontSetCreate) IA__FcFontSetCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; #define FcFontSetCreate IA__FcFontSetCreate extern __typeof (FcFontSetDestroy) IA__FcFontSetDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; @@ -288,6 +284,8 @@ #define FcNameGetConstantFor IA__FcNameGetConstantFor extern __typeof (FcNameConstant) IA__FcNameConstant FC_ATTRIBUTE_VISIBILITY_HIDDEN; #define FcNameConstant IA__FcNameConstant +extern __typeof (FcNameGetConstantNameFrom) IA__FcNameGetConstantNameFrom FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcNameGetConstantNameFrom IA__FcNameGetConstantNameFrom extern __typeof (FcNameParse) IA__FcNameParse FC_ATTRIBUTE_VISIBILITY_HIDDEN; #define FcNameParse IA__FcNameParse extern __typeof (FcNameUnparse) IA__FcNameUnparse FC_ATTRIBUTE_VISIBILITY_HIDDEN; @@ -460,6 +458,8 @@ #define FcConfigParseAndLoad IA__FcConfigParseAndLoad extern __typeof (FcConfigParseAndLoadFromMemory) IA__FcConfigParseAndLoadFromMemory FC_ATTRIBUTE_VISIBILITY_HIDDEN; #define FcConfigParseAndLoadFromMemory IA__FcConfigParseAndLoadFromMemory +extern __typeof (FcConfigFileGenerate) IA__FcConfigFileGenerate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcConfigFileGenerate IA__FcConfigFileGenerate extern __typeof (FcConfigGetRescanInverval) IA__FcConfigGetRescanInverval FC_ATTRIBUTE_VISIBILITY_HIDDEN; #define FcConfigGetRescanInverval IA__FcConfigGetRescanInverval extern __typeof (FcConfigSetRescanInverval) IA__FcConfigSetRescanInverval FC_ATTRIBUTE_VISIBILITY_HIDDEN;
diff --git a/third_party/fontconfig/include/fcaliastail.h b/third_party/fontconfig/include/fcaliastail.h index 53ba175..e9b98e2 100644 --- a/third_party/fontconfig/include/fcaliastail.h +++ b/third_party/fontconfig/include/fcaliastail.h
@@ -183,12 +183,6 @@ # undef FcDirCacheUnload extern __typeof (FcDirCacheUnload) FcDirCacheUnload __attribute((alias("IA__FcDirCacheUnload"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; #endif /* __fccache__ */ -#ifdef __fcfreetype__ -# undef FcFreeTypeQuery -extern __typeof (FcFreeTypeQuery) FcFreeTypeQuery __attribute((alias("IA__FcFreeTypeQuery"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcFreeTypeQueryAll -extern __typeof (FcFreeTypeQueryAll) FcFreeTypeQueryAll __attribute((alias("IA__FcFreeTypeQueryAll"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -#endif /* __fcfreetype__ */ #ifdef __fcfs__ # undef FcFontSetCreate extern __typeof (FcFontSetCreate) FcFontSetCreate __attribute((alias("IA__FcFontSetCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; @@ -326,6 +320,8 @@ extern __typeof (FcNameGetConstantFor) FcNameGetConstantFor __attribute((alias("IA__FcNameGetConstantFor"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; # undef FcNameConstant extern __typeof (FcNameConstant) FcNameConstant __attribute((alias("IA__FcNameConstant"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcNameGetConstantNameFrom +extern __typeof (FcNameGetConstantNameFrom) FcNameGetConstantNameFrom __attribute((alias("IA__FcNameGetConstantNameFrom"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; # undef FcNameParse extern __typeof (FcNameParse) FcNameParse __attribute((alias("IA__FcNameParse"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; # undef FcNameUnparse @@ -513,6 +509,10 @@ # undef FcConfigParseAndLoadFromMemory extern __typeof (FcConfigParseAndLoadFromMemory) FcConfigParseAndLoadFromMemory __attribute((alias("IA__FcConfigParseAndLoadFromMemory"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; #endif /* __fcxml__ */ +#ifdef __fcconffile__ +# undef FcConfigFileGenerate +extern __typeof (FcConfigFileGenerate) FcConfigFileGenerate __attribute((alias("IA__FcConfigFileGenerate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +#endif /* __fcconffile__ */ #ifdef __fccfg__ # undef FcConfigGetRescanInverval extern __typeof (FcConfigGetRescanInverval) FcConfigGetRescanInverval __attribute((alias("IA__FcConfigGetRescanInverval"))) FC_ATTRIBUTE_VISIBILITY_EXPORT;
diff --git a/third_party/fontconfig/include/fcftalias.h b/third_party/fontconfig/include/fcftalias.h index 593e9977..4af6a68d6 100644 --- a/third_party/fontconfig/include/fcftalias.h +++ b/third_party/fontconfig/include/fcftalias.h
@@ -10,3 +10,7 @@ #define FcPatternAddFTFace IA__FcPatternAddFTFace extern __typeof (FcFreeTypeQueryFace) IA__FcFreeTypeQueryFace FC_ATTRIBUTE_VISIBILITY_HIDDEN; #define FcFreeTypeQueryFace IA__FcFreeTypeQueryFace +extern __typeof (FcFreeTypeQuery) IA__FcFreeTypeQuery FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFreeTypeQuery IA__FcFreeTypeQuery +extern __typeof (FcFreeTypeQueryAll) IA__FcFreeTypeQueryAll FC_ATTRIBUTE_VISIBILITY_HIDDEN; +#define FcFreeTypeQueryAll IA__FcFreeTypeQueryAll
diff --git a/third_party/fontconfig/include/fcftaliastail.h b/third_party/fontconfig/include/fcftaliastail.h index 3070746..8b1e04d 100644 --- a/third_party/fontconfig/include/fcftaliastail.h +++ b/third_party/fontconfig/include/fcftaliastail.h
@@ -16,5 +16,9 @@ #ifdef __fcfreetype__ # undef FcFreeTypeQueryFace extern __typeof (FcFreeTypeQueryFace) FcFreeTypeQueryFace __attribute((alias("IA__FcFreeTypeQueryFace"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFreeTypeQuery +extern __typeof (FcFreeTypeQuery) FcFreeTypeQuery __attribute((alias("IA__FcFreeTypeQuery"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +# undef FcFreeTypeQueryAll +extern __typeof (FcFreeTypeQueryAll) FcFreeTypeQueryAll __attribute((alias("IA__FcFreeTypeQueryAll"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; #endif /* __fcfreetype__ */ #endif /* HAVE_GNUC_ATTRIBUTE */
diff --git a/third_party/fontconfig/include/fontconfig/fontconfig.h b/third_party/fontconfig/include/fontconfig/fontconfig.h index 79e300f..3f014ac 100644 --- a/third_party/fontconfig/include/fontconfig/fontconfig.h +++ b/third_party/fontconfig/include/fontconfig/fontconfig.h
@@ -238,6 +238,8 @@ FcTypeRange } FcType; +typedef int FcObject; + typedef struct _FcMatrix { double xx, xy, yx, yy; } FcMatrix; @@ -312,9 +314,11 @@ } FcFontSet; typedef struct _FcObjectSet { - int nobject; + int nobject; /* deprecated */ int sobject; - const char **objects; + const char **objects; /* deprecated */ + int nobjIds; + FcObject *objIds; } FcObjectSet; typedef enum _FcMatchKind { @@ -680,13 +684,6 @@ FcPublic void FcDirCacheUnload (FcCache *cache); -/* fcfreetype.c */ -FcPublic FcPattern * -FcFreeTypeQuery (const FcChar8 *file, unsigned int id, FcBlanks *blanks, int *count); - -FcPublic unsigned int -FcFreeTypeQueryAll (const FcChar8 *file, unsigned int id, FcBlanks *blanks, int *count, FcFontSet *set); - /* fcfs.c */ FcPublic FcFontSet * @@ -909,6 +906,9 @@ FcPublic FcBool FcNameConstant (const FcChar8 *string, int *result); +FcPublic const FcChar8 * +FcNameGetConstantNameFrom (const char *object, int value); + FcPublic FcPattern * FcNameParse (const FcChar8 *name); @@ -1198,6 +1198,13 @@ const FcChar8 *buffer, FcBool complain); +/* fcconffile.c */ +FcPublic FcChar8 * +FcConfigFileGenerate (FcConfig *config, + FcPattern *pat, + const FcChar8 *font_path); + + _FCFUNCPROTOEND #undef FC_ATTRIBUTE_SENTINEL
diff --git a/third_party/fontconfig/include/meson-config.h b/third_party/fontconfig/include/meson-config.h index 7f6ee54..d9e3d64 100644 --- a/third_party/fontconfig/include/meson-config.h +++ b/third_party/fontconfig/include/meson-config.h
@@ -36,10 +36,10 @@ #define FONTCONFIG_PATH "/etc/fonts" -#define FREETYPE_PCF_LONG_FAMILY_NAMES - #define GETTEXT_PACKAGE "fontconfig" +#define HAVE_C99_VSNPRINTF 1 + #define HAVE_DCGETTEXT 1 #define HAVE_DIRENT_H 1 @@ -86,8 +86,6 @@ #define HAVE_MKDTEMP 1 -#define HAVE_MKOSTEMP 1 - #define HAVE_MKSTEMP 1 #define HAVE_MMAP 1 @@ -112,6 +110,8 @@ #define HAVE_STDLIB_H 1 +#define HAVE_STRDUP 1 + #define HAVE_STRERROR 1 #define HAVE_STRERROR_R 1 @@ -142,6 +142,8 @@ #define HAVE_UNISTD_H 1 +#define HAVE_VASPRINTF 1 + #define HAVE_VPRINTF 1 #define HAVE_VSNPRINTF 1
diff --git a/third_party/fontconfig/src b/third_party/fontconfig/src index 23b3fc6..d62c2ab 160000 --- a/third_party/fontconfig/src +++ b/third_party/fontconfig/src
@@ -1 +1 @@ -Subproject commit 23b3fc6e58a13d126b9c30fafc9a16f8bd7143e9 +Subproject commit d62c2ab268d1679335daa8fb0ea6970f35224a76
diff --git a/third_party/fontconfig/update.sh b/third_party/fontconfig/update.sh index 4ea8558e..7b9ab2e9 100755 --- a/third_party/fontconfig/update.sh +++ b/third_party/fontconfig/update.sh
@@ -6,8 +6,8 @@ SRC_DIR="$SCRIPT_DIR/../.." cd "$SCRIPT_DIR/src" -git fetch origin main -REVISION="$(git rev-parse origin/main)" +git fetch origin upstream/main +REVISION="$(git rev-parse origin/upstream/main)" cd "$SRC_DIR" roll-dep src/third_party/fontconfig/src --roll-to "$REVISION" "$@" @@ -20,6 +20,10 @@ # config.h has "#define _GNU_SOURCE" which would conflict with # our "#define _GNU_SOURCE 1". sed -i 's/_GNU_SOURCE$/_GNU_SOURCE 1/' ../include/meson-config.h +# Remove ENABLE_FREETYPE and related FreeType define from upstream, +# as locally we build without FreeType. +sed -i '/#define ENABLE_FREETYPE 1/{N;d}' ../include/meson-config.h +sed -i '/#define FREETYPE_PCF_LONG_FAMILY_NAMES/{N;d}' ../include/meson-config.h # Use libxml2 instead of libexpat. Currently, there's no way # to configure this with meson options. echo '#define ENABLE_LIBXML2 1' >>../include/config.h
diff --git a/third_party/perfetto b/third_party/perfetto index 8ab293d..ec42dd38 160000 --- a/third_party/perfetto +++ b/third_party/perfetto
@@ -1 +1 @@ -Subproject commit 8ab293da46a370dc17283a4d413242385e2033b1 +Subproject commit ec42dd387c2ab14c7369136e86898be936248315
diff --git a/third_party/webrtc b/third_party/webrtc index d80cfa2..bfe5317 160000 --- a/third_party/webrtc +++ b/third_party/webrtc
@@ -1 +1 @@ -Subproject commit d80cfa2a3d24618558f150bcca616a56cdca234a +Subproject commit bfe531707560d16644de452e51e2c4fe40c46b91
diff --git a/tools/metrics/histograms/metadata/signin/enums.xml b/tools/metrics/histograms/metadata/signin/enums.xml index 0bc75093..d61bd9e 100644 --- a/tools/metrics/histograms/metadata/signin/enums.xml +++ b/tools/metrics/histograms/metadata/signin/enums.xml
@@ -763,7 +763,7 @@ <int value="48" label="Edu Coexistence Login Handler"/> <int value="49" label="Edu Account Login Handler"/> <int value="50" label="Chromeos Family Link User Metrics provider"/> - <int value="51" label="Enterprise Identity Service"/> + <int value="51" label="Enterprise Identity Service (deprecated 12/2025)"/> <int value="52" label="Promotion Eligibility Checker"/> <int value="53" label="Password Manager Leak Detection"/> <int value="54" label="Android Management Client"/> @@ -792,6 +792,8 @@ <int value="77" label="YouTube Music"/> <int value="78" label="Contextual Tasks"/> <int value="79" label="Enterprise Plus Address"/> + <int value="80" label="Glic User Status"/> + <int value="81" label="Devtools Gdp"/> </enum> <!-- LINT.ThenChange(//components/signin/public/base/oauth_consumer_id.h:OAuthConsumerId) --> @@ -1371,6 +1373,16 @@ <int value="1" label="Finished"/> </enum> +<!-- LINT.IfChange(SigninTokenTableGetAllWrappedBindingKeysResult) --> + +<enum name="SigninTokenTableGetAllWrappedBindingKeysResult"> + <int value="0" label="Success"/> + <int value="1" label="SQL Invalid Statement"/> + <int value="2" label="SQL Failure"/> +</enum> + +<!-- LINT.ThenChange(//components/signin/public/webdata/token_service_table.cc:GetAllWrappedBindingKeysResult) --> + <enum name="SigninTokenTableReadTokenFromDBResult"> <int value="0" label="Success"/> <int value="1" label="Decrypt failed"/>
diff --git a/tools/metrics/histograms/metadata/signin/histograms.xml b/tools/metrics/histograms/metadata/signin/histograms.xml index 862d961..071e1efa 100644 --- a/tools/metrics/histograms/metadata/signin/histograms.xml +++ b/tools/metrics/histograms/metadata/signin/histograms.xml
@@ -3780,6 +3780,16 @@ </summary> </histogram> +<histogram name="Signin.TokenTable.GetAllWrappedBindingKeysResult" + enum="SigninTokenTableGetAllWrappedBindingKeysResult" + expires_after="2026-06-08"> + <owner>alexilin@chromium.org</owner> + <owner>chrome-signin-team@google.com</owner> + <summary> + Counts the results of loading wrapped binding keys from the token database. + </summary> +</histogram> + <histogram name="Signin.TokenTable.ReadTokenFromDBResult" enum="SigninTokenTableReadTokenFromDBResult" expires_after="never"> <!-- expires-never: This reports health status for loading authentication
diff --git a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc index e5f172b5..99e9e13 100644 --- a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc +++ b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc
@@ -68,8 +68,8 @@ CloseSession(); } -void GlobalAcceleratorListenerLinux::OnServiceStarted(bool service_started) { - service_started_ = service_started; +void GlobalAcceleratorListenerLinux::OnServiceStarted(uint32_t version) { + service_started_ = (version != 0); if (!*service_started_) { bound_commands_.clear();
diff --git a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.h b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.h index 3838de75..3fcfe9ab 100644 --- a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.h +++ b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.h
@@ -103,7 +103,7 @@ const std::string& signal_name, bool success); - void OnServiceStarted(bool service_started); + void OnServiceStarted(uint32_t version); void CreateSession();
diff --git a/ui/gtk/select_file_dialog_linux_gtk.h b/ui/gtk/select_file_dialog_linux_gtk.h index 213eaa5..740c8e25 100644 --- a/ui/gtk/select_file_dialog_linux_gtk.h +++ b/ui/gtk/select_file_dialog_linux_gtk.h
@@ -34,7 +34,6 @@ bool IsRunning(gfx::NativeWindow parent_window) const override; // SelectFileDialog implementation. - // |params| is unused and must be nullptr. void SelectFileImpl(Type type, const std::u16string& title, const base::FilePath& default_path,
diff --git a/ui/linux/linux_ui_factory.cc b/ui/linux/linux_ui_factory.cc index 9307de3..3f0a2e0 100644 --- a/ui/linux/linux_ui_factory.cc +++ b/ui/linux/linux_ui_factory.cc
@@ -15,7 +15,6 @@ #include "base/no_destructor.h" #include "base/strings/string_util.h" #include "base/task/sequenced_task_runner.h" -#include "build/chromecast_buildflags.h" #include "ui/base/buildflags.h" #include "ui/base/ui_base_switches.h" #include "ui/color/system_theme.h" @@ -31,10 +30,6 @@ #include "ui/qt/qt_ui.h" #endif -#if !BUILDFLAG(IS_CASTOS) -#include "ui/shell_dialogs/shell_dialog_linux.h" -#endif - namespace ui { namespace { @@ -162,15 +157,7 @@ } // namespace LinuxUi* GetDefaultLinuxUi() { - auto* linux_ui = GetDefaultLinuxUiAndTheme(); -#if !BUILDFLAG(IS_CASTOS) - // This may create an extra thread that may race against the LinuxUi instance - // initialization, GtkInitFromCommandLine, in GtkUi for example, so this must - // be done after the call to GetDefaultLinuxUiAndTheme above, so the race - // condition is avoided. - shell_dialog_linux::Initialize(); -#endif - return linux_ui; + return GetDefaultLinuxUiAndTheme(); } LinuxUiTheme* GetDefaultLinuxUiTheme() {
diff --git a/ui/shell_dialogs/BUILD.gn b/ui/shell_dialogs/BUILD.gn index 4535b46..819b8e5 100644 --- a/ui/shell_dialogs/BUILD.gn +++ b/ui/shell_dialogs/BUILD.gn
@@ -57,7 +57,6 @@ "select_file_dialog_linux.cc", "select_file_dialog_linux.h", "shell_dialog_linux.cc", - "shell_dialog_linux.h", ] deps += [ "//ui/linux:linux_ui" ] if (use_dbus) {
diff --git a/ui/shell_dialogs/select_file_dialog_linux_portal.cc b/ui/shell_dialogs/select_file_dialog_linux_portal.cc index 6430ef98..c66b8da5 100644 --- a/ui/shell_dialogs/select_file_dialog_linux_portal.cc +++ b/ui/shell_dialogs/select_file_dialog_linux_portal.cc
@@ -20,6 +20,7 @@ #include "base/time/time.h" #include "components/dbus/thread_linux/dbus_thread_linux.h" #include "components/dbus/xdg/portal.h" +#include "components/dbus/xdg/portal_constants.h" #include "components/dbus/xdg/request.h" #include "dbus/message.h" #include "dbus/object_path.h" @@ -27,6 +28,7 @@ #include "ui/aura/window_tree_host.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/native_ui_types.h" +#include "ui/linux/linux_ui.h" #include "ui/linux/linux_ui_delegate.h" #include "ui/shell_dialogs/selected_file_info.h" #include "ui/strings/grit/ui_strings.h" @@ -43,9 +45,6 @@ constexpr int kXdgPortalRequiredVersion = 3; -constexpr char kFileChooserInterfaceName[] = - "org.freedesktop.portal.FileChooser"; - constexpr char kFileChooserMethodOpenFile[] = "OpenFile"; constexpr char kFileChooserMethodSaveFile[] = "SaveFile"; @@ -62,57 +61,6 @@ constexpr char kFileUriPrefix[] = "file://"; -enum class ServiceAvailability { - kNotStarted, - kInProgress, - kNotAvailable, - kAvailable, -}; - -ServiceAvailability g_service_availability = ServiceAvailability::kNotStarted; - -scoped_refptr<base::SequencedTaskRunner>& GetMainTaskRunner() { - static base::NoDestructor<scoped_refptr<base::SequencedTaskRunner>> - main_task_runner; - return *main_task_runner; -} - -void OnGetPropertyReply(dbus::Response* response) { - if (!response) { - g_service_availability = ServiceAvailability::kNotAvailable; - return; - } - - uint32_t version = 0; - dbus::MessageReader reader(response); - if (!reader.PopVariantOfUint32(&version)) { - g_service_availability = ServiceAvailability::kNotAvailable; - return; - } - - g_service_availability = version >= kXdgPortalRequiredVersion - ? ServiceAvailability::kAvailable - : ServiceAvailability::kNotAvailable; -} - -void OnServiceStarted(bool service_started) { - if (!service_started) { - g_service_availability = ServiceAvailability::kNotAvailable; - return; - } - - dbus::ObjectProxy* portal = - dbus_thread_linux::GetSharedSessionBus()->GetObjectProxy( - kXdgPortalService, dbus::ObjectPath(kXdgPortalObject)); - - dbus::MethodCall get_property_call(DBUS_INTERFACE_PROPERTIES, "Get"); - dbus::MessageWriter get_property_writer(&get_property_call); - get_property_writer.AppendString(kFileChooserInterfaceName); - get_property_writer.AppendString("version"); - portal->CallMethod(&get_property_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, - base::BindOnce(&OnGetPropertyReply)); -} - std::vector<uint8_t> PathToByteArray(const base::FilePath& path) { std::vector<uint8_t> bytes(path.value().begin(), path.value().end()); // Null-terminate the array. @@ -154,36 +102,20 @@ } } -// static -void SelectFileDialogLinuxPortal::StartAvailabilityTestInBackground() { - if (g_service_availability != ServiceAvailability::kNotStarted) { - return; - } - g_service_availability = ServiceAvailability::kInProgress; - - GetMainTaskRunner() = base::SequencedTaskRunner::GetCurrentDefault(); - - dbus_xdg::RequestXdgDesktopPortal( - dbus_thread_linux::GetSharedSessionBus().get(), - base::BindOnce(&OnServiceStarted)); -} - -// static -bool SelectFileDialogLinuxPortal::IsPortalAvailable() { - if (g_service_availability == ServiceAvailability::kInProgress) { - LOG(WARNING) << "Portal availability checked before test was complete"; - } - - return g_service_availability == ServiceAvailability::kAvailable; -} - void SelectFileDialogLinuxPortal::ListenerDestroyed() { weak_factory_.InvalidateWeakPtrs(); + if (fallback_dialog_) { + fallback_dialog_->ListenerDestroyed(); + fallback_dialog_.reset(); + } SelectFileDialogLinux::ListenerDestroyed(); } bool SelectFileDialogLinuxPortal::IsRunning( gfx::NativeWindow parent_window) const { + if (fallback_dialog_) { + return fallback_dialog_->IsRunning(parent_window); + } return parent_window && host_ && host_.get() == parent_window->GetHost(); } @@ -196,7 +128,7 @@ const base::FilePath::StringType& default_extension, gfx::NativeWindow owning_window, const GURL* caller) { - type_ = type; + set_type(type); invoker_task_runner_ = base::SequencedTaskRunner::GetCurrentDefault(); if (owning_window) { @@ -214,6 +146,42 @@ set_file_type_index(file_type_index); + std::optional<GURL> caller_copy; + if (caller) { + caller_copy = *caller; + } + + dbus_xdg::RequestXdgDesktopPortal( + dbus_thread_linux::GetSharedSessionBus().get(), + base::BindOnce(&SelectFileDialogLinuxPortal::OnPortalAvailable, + weak_factory_.GetWeakPtr(), title, default_path, + default_extension, std::move(caller_copy))); +} + +void SelectFileDialogLinuxPortal::OnPortalAvailable( + std::u16string title, + base::FilePath default_path, + base::FilePath::StringType default_extension, + std::optional<GURL> caller, + uint32_t version) { + if (version < kXdgPortalRequiredVersion) { + gfx::NativeWindow owning_window = host_ ? host_->window() : nullptr; + if (auto* linux_ui = ui::LinuxUi::instance()) { + fallback_dialog_ = linux_ui->CreateSelectFileDialog(listener_, nullptr); + } + if (fallback_dialog_) { + fallback_dialog_->SelectFile( + type(), title, default_path, &file_types(), file_type_index(), + default_extension, owning_window, caller ? &caller.value() : nullptr); + return; + } + + if (listener_) { + listener_->FileSelectionCanceled(); + } + return; + } + PortalFilterSet filter_set = BuildFilterSet(); // Keep a copy of the filters so the index of the chosen one can be identified @@ -235,6 +203,9 @@ } bool SelectFileDialogLinuxPortal::HasMultipleFileTypeChoicesImpl() { + if (fallback_dialog_) { + return fallback_dialog_->HasMultipleFileTypeChoices(); + } return file_types().extensions.size() > 1; } @@ -318,7 +289,7 @@ base::FilePath::StringType default_extension, std::string parent_handle) { bool default_path_exists = CallDirectoryExistsOnUIThread(default_path); - GetMainTaskRunner()->PostTask( + invoker_task_runner_->PostTask( FROM_HERE, base::BindOnce(&SelectFileDialogLinuxPortal::SelectFileImplOnMainThread, this, std::move(title), std::move(default_path), @@ -333,10 +304,10 @@ PortalFilterSet filter_set, base::FilePath::StringType default_extension, std::string parent_handle) { - CHECK(GetMainTaskRunner()->RunsTasksInCurrentSequence()); + CHECK(invoker_task_runner_->RunsTasksInCurrentSequence()); std::string method; - switch (type_) { + switch (type()) { case SELECT_FOLDER: case SELECT_UPLOAD_FOLDER: case SELECT_EXISTING_FOLDER: @@ -356,9 +327,9 @@ utf8_title = base::UTF16ToUTF8(title); } else { int message_id = 0; - if (type_ == SELECT_SAVEAS_FILE) { + if (type() == SELECT_SAVEAS_FILE) { message_id = IDS_SAVEAS_ALL_FILES; - } else if (type_ == SELECT_OPEN_MULTI_FILE) { + } else if (type() == SELECT_OPEN_MULTI_FILE) { message_id = IDS_OPEN_FILES_DIALOG_TITLE; } else { message_id = IDS_OPEN_FILE_DIALOG_TITLE; @@ -378,7 +349,7 @@ const PortalFilterSet& filter_set) { dbus_xdg::Dictionary dict; - switch (type_) { + switch (type()) { case SelectFileDialog::SELECT_UPLOAD_FOLDER: dict[kFileChooserOptionAcceptLabel] = dbus_utils::Variant::Wrap<"s">(l10n_util::GetStringUTF8( @@ -410,7 +381,7 @@ // current_folder is supported by xdg-desktop-portal but current_name // is not - only try to set this when invoking a save file dialog. - if (type_ == SELECT_SAVEAS_FILE) { + if (type() == SELECT_SAVEAS_FILE) { dict[kFileChooserOptionCurrentName] = dbus_utils::Variant::Wrap<"s">(default_path.BaseName().value()); } @@ -451,7 +422,7 @@ const std::string& title, dbus_xdg::Dictionary options, std::string parent_handle) { - CHECK(GetMainTaskRunner()->RunsTasksInCurrentSequence()); + CHECK(invoker_task_runner_->RunsTasksInCurrentSequence()); scoped_refptr<dbus::Bus> bus = dbus_thread_linux::GetSharedSessionBus(); dbus::ObjectProxy* portal = bus->GetObjectProxy( kXdgPortalService, dbus::ObjectPath(kXdgPortalObject)); @@ -461,8 +432,8 @@ base::BindOnce(&SelectFileDialogLinuxPortal::OnFileChooserResponse, base::Unretained(this)); file_chooser_request_ = std::make_unique<dbus_xdg::Request>( - bus, portal, kFileChooserInterfaceName, method, std::move(options), - std::move(callback), std::move(parent_handle), title); + bus, portal, dbus_xdg::kFileChooserInterfaceName, method, + std::move(options), std::move(callback), std::move(parent_handle), title); invoker_task_runner_->PostTask( FROM_HERE, base::BindOnce(&SelectFileDialogLinuxPortal::DialogCreatedOnInvoker, @@ -471,7 +442,7 @@ void SelectFileDialogLinuxPortal::OnFileChooserResponse( base::expected<dbus_xdg::Dictionary, dbus_xdg::ResponseError> results) { - CHECK(GetMainTaskRunner()->RunsTasksInCurrentSequence()); + CHECK(invoker_task_runner_->RunsTasksInCurrentSequence()); file_chooser_request_.reset(); @@ -546,7 +517,7 @@ UnparentOnInvoker(); if (listener_) { - if (type_ == SELECT_OPEN_MULTI_FILE) { + if (type() == SELECT_OPEN_MULTI_FILE) { listener_->MultiFilesSelected(FilePathListToSelectedFileInfoList(paths)); } else if (paths.size() > 1) { LOG(ERROR) << "Got >1 file URI from a single-file chooser";
diff --git a/ui/shell_dialogs/select_file_dialog_linux_portal.h b/ui/shell_dialogs/select_file_dialog_linux_portal.h index 31b6709..af224fd 100644 --- a/ui/shell_dialogs/select_file_dialog_linux_portal.h +++ b/ui/shell_dialogs/select_file_dialog_linux_portal.h
@@ -19,6 +19,7 @@ #include "dbus/bus.h" #include "ui/shell_dialogs/select_file_dialog_linux.h" #include "ui/shell_dialogs/shell_dialogs_export.h" +#include "url/gurl.h" namespace ui { @@ -40,15 +41,6 @@ SelectFileDialogLinuxPortal& operator=( const SelectFileDialogLinuxPortal& other) = delete; - // Starts running a test to check for the presence of the file chooser portal. - // Must be called on the UI thread. This should only be called once, - // preferably around program start. - static void StartAvailabilityTestInBackground(); - - // Checks if the file chooser portal is available. Logs a warning if the - // availability test has not yet completed. - static bool IsPortalAvailable(); - protected: ~SelectFileDialogLinuxPortal() override; @@ -152,7 +144,11 @@ // Removes the DialogInfo parent. void UnparentOnInvoker(); - Type type_ = SELECT_NONE; + void OnPortalAvailable(std::u16string title, + base::FilePath default_path, + base::FilePath::StringType default_extension, + std::optional<GURL> caller, + uint32_t version); // The task runner the SelectFileImpl method was called on. scoped_refptr<base::SequencedTaskRunner> invoker_task_runner_; @@ -160,6 +156,9 @@ // This should be used by the invoker task runner. base::WeakPtr<aura::WindowTreeHost> host_; + // The fallback dialog to use if the portal is not available. + scoped_refptr<SelectFileDialog> fallback_dialog_; + std::vector<PortalFilter> filters_; // The Request representing an in-flight file chooser call, if any.
diff --git a/ui/shell_dialogs/shell_dialog_linux.cc b/ui/shell_dialogs/shell_dialog_linux.cc index 1a4daf4e..1546514 100644 --- a/ui/shell_dialogs/shell_dialog_linux.cc +++ b/ui/shell_dialogs/shell_dialog_linux.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/shell_dialogs/shell_dialog_linux.h" - #include "base/notreached.h" #include "build/config/linux/dbus/buildflags.h" #include "ui/linux/linux_ui.h" @@ -14,62 +12,20 @@ #include "ui/shell_dialogs/select_file_dialog_linux_portal.h" #endif -namespace shell_dialog_linux { - -void Initialize() { -#if BUILDFLAG(USE_DBUS) - ui::SelectFileDialogLinuxPortal::StartAvailabilityTestInBackground(); -#endif -} - -} // namespace shell_dialog_linux - namespace ui { -namespace { - -enum FileDialogChoice { - kUnknown, - kToolkit, -#if BUILDFLAG(USE_DBUS) - kPortal, -#endif -}; - -FileDialogChoice dialog_choice_ = kUnknown; - -FileDialogChoice GetFileDialogChoice() { -#if BUILDFLAG(USE_DBUS) - // Check to see if the portal is available. - if (SelectFileDialogLinuxPortal::IsPortalAvailable()) - return kPortal; -#endif - - return kToolkit; -} - -} // namespace - SelectFileDialog* CreateSelectFileDialog( SelectFileDialog::Listener* listener, std::unique_ptr<SelectFilePolicy> policy) { - if (dialog_choice_ == kUnknown) - dialog_choice_ = GetFileDialogChoice(); - - const LinuxUi* linux_ui = LinuxUi::instance(); - switch (dialog_choice_) { - case kToolkit: - if (!linux_ui) - break; - return linux_ui->CreateSelectFileDialog(listener, std::move(policy)); #if BUILDFLAG(USE_DBUS) - case kPortal: - return new SelectFileDialogLinuxPortal(listener, std::move(policy)); -#endif - case kUnknown: - NOTREACHED(); + return new SelectFileDialogLinuxPortal(listener, std::move(policy)); +#else + const LinuxUi* linux_ui = LinuxUi::instance(); + if (linux_ui) { + return linux_ui->CreateSelectFileDialog(listener, std::move(policy)); } return nullptr; +#endif } } // namespace ui
diff --git a/ui/shell_dialogs/shell_dialog_linux.h b/ui/shell_dialogs/shell_dialog_linux.h deleted file mode 100644 index 2888ae3..0000000 --- a/ui/shell_dialogs/shell_dialog_linux.h +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2013 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_SHELL_DIALOGS_SHELL_DIALOG_LINUX_H_ -#define UI_SHELL_DIALOGS_SHELL_DIALOG_LINUX_H_ - -#include "ui/shell_dialogs/shell_dialogs_export.h" - -namespace shell_dialog_linux { - -// TODO(thomasanderson): Remove Initialize(). - -// Should be called before the first call to CreateSelectFileDialog. -SHELL_DIALOGS_EXPORT void Initialize(); - -} // namespace shell_dialog_linux - -#endif // UI_SHELL_DIALOGS_SHELL_DIALOG_LINUX_H_
diff --git a/v8 b/v8 index 54df9a2..6e0661d6 160000 --- a/v8 +++ b/v8
@@ -1 +1 @@ -Subproject commit 54df9a2e6ec0f28a218491cf15a4d6841779b4cc +Subproject commit 6e0661d6b0f95270c198d690bb2c4f54ba2acf4d