[ios][apcv2] Graft xorigin frames [chromium/src : main]

0 views
Skip to first unread message

Vincent Boisselle (Gerrit)

unread,
Nov 28, 2025, 2:21:10 PM11/28/25
to Nicolas MacBeth, Chromium LUCI CQ, chromium...@chromium.org, browser-comp...@chromium.org, chrome-intell...@chromium.org, chrome-intelligence-te...@google.com, ios-revie...@chromium.org, ios-r...@chromium.org, marq+...@chromium.org, tmartino+tran...@chromium.org
Attention needed from Nicolas MacBeth

Vincent Boisselle voted Commit-Queue+1

Commit-Queue+1
Open in Gerrit

Related details

Attention is currently required from:
  • Nicolas MacBeth
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I7c5c481d4c18bed78c1bbb7022ac2ab04fd5d085
Gerrit-Change-Number: 7205479
Gerrit-PatchSet: 5
Gerrit-Owner: Vincent Boisselle <vi...@google.com>
Gerrit-Reviewer: Nicolas MacBeth <nicolas...@google.com>
Gerrit-Reviewer: Vincent Boisselle <vi...@google.com>
Gerrit-Attention: Nicolas MacBeth <nicolas...@google.com>
Gerrit-Comment-Date: Fri, 28 Nov 2025 19:21:06 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
satisfied_requirement
unsatisfied_requirement
open
diffy

Nicolas MacBeth (Gerrit)

unread,
Jan 2, 2026, 4:10:43 PMJan 2
to Vincent Boisselle, Code Review Nudger, Chromium LUCI CQ, chromium...@chromium.org, browser-comp...@chromium.org, chrome-intell...@chromium.org, chrome-intelligence-te...@google.com, ios-revie...@chromium.org, ios-r...@chromium.org, marq+...@chromium.org, tmartino+tran...@chromium.org
Attention needed from Vincent Boisselle

Nicolas MacBeth added 34 comments

Patchset-level comments
File-level comment, Patchset 5 (Latest):
Nicolas MacBeth . resolved

thanks so so much Vince! this is looking really great, and very sorry for the delay in reviewing

Note: I quickly glossed over the unittest diff because it is quite hard to review

Commit Message
Line 7, Patchset 5 (Latest):[ios][apcv2] Graft xorigin frames
Nicolas MacBeth . unresolved

Can we add some comprehensive information to this commit message?

File components/autofill/ios/form_util/child_frame_registrar.h
Line 53, Patchset 5 (Latest): // Maps from local to remote token.
Nicolas MacBeth . unresolved

question: do you think it's worth it documentation-wise to copy the information above about remote and local frames? or should it move to something more generic that encompasses these two methods?

File components/autofill/ios/form_util/child_frame_registrar.mm
Line 25, Patchset 5 (Latest):std::optional<RemoteFrameToken> ChildFrameRegistrar::LookupLocalFrame(
Nicolas MacBeth . unresolved

I defer to you and Tommy as local owners here, but do you think it's worthwhile to maintain a reverse lookup map instead of iterating over all the tokens at every lookup here? WDYT? if we do this operation often in the page context extraction, we may be introducing some latency here

at the very least I think we should document this in the header!

File ios/chrome/browser/intelligence/proto_wrappers/frame_grafter.h
Line 29, Patchset 5 (Latest): // grafting. Content is cached if there is no claim to fulfil immediately.
Nicolas MacBeth . unresolved

type: `fulfill`

Line 21, Patchset 5 (Latest): // Claims a frame's content for grafting. Puts the `placeholder` in a waitlist
Nicolas MacBeth . unresolved

the claim / give terminology is quite confusing to me throughout this file. do you think it's clear enough for future readers? WDYT instead of something like `RegisterPlaceholder`, `FulfillPlaceholder` and `FulfillUnresolvedPlaceholders`?

Line 14, Patchset 5 (Latest):// Grafter that receives claims on frame content and frame content to construct
// the frame tree.
Nicolas MacBeth . unresolved

do you mind adding a comment that explains the overview of the algorithm? (especially given the terminology used below in methods/comments). maybe we can also link to the DD tree grafting section?

Line 11, Patchset 5 (Latest):#import "components/autofill/core/common/unique_ids.h"
Nicolas MacBeth . unresolved

nit: can we add a TODO to do the migration off of `components/autofill`?

File-level comment, Patchset 5 (Latest):
Nicolas MacBeth . unresolved

what do you think about making the tree grafter more self-contained, and reusable? ideally this would work for any node grafting impl, and token/ID types. for the types, we can use a template, and we pass callbacks to the grafter which take a node as param (similar to your `PlaceUnclaimedFrames` impl).

something like (code example created through prompting - definitely needs rework, but just to illustrate what I mean): https://paste.googleplex.com/5323044430151680

File ios/chrome/browser/intelligence/proto_wrappers/frame_grafter.mm
Line 18, Patchset 5 (Latest): // Can't claim content for the `token` more than once.
Nicolas MacBeth . unresolved

this shouldn't ever happen right? assuming no single frame should get an extraction pass more than once, this shouldn't be called twice. can we log a metric here (or add a TODO for that)

Line 36, Patchset 5 (Latest): // Can't give give frame content for the `token` more than once.
Nicolas MacBeth . unresolved

ditto

Line 58, Patchset 5 (Latest): for (auto& [_, o] : unclaimed_frame_content_) {
Nicolas MacBeth . unresolved

can we add a TODO here to log how often this happens? a overall TODO for metrics in this file would be helpful too I think

File ios/chrome/browser/intelligence/proto_wrappers/page_context_extractor_java_script_feature.h
Line 48, Patchset 5 (Latest): bool include_xorigin_frames,
Nicolas MacBeth . unresolved

I'm not sure the name for this parameter is totally accurate, since this frame can't see x-origin frames. instead maybe something like `include_cross_origin_frame_tokens`? can we add a small blurb about it in the comment above?

File ios/chrome/browser/intelligence/proto_wrappers/page_context_extractor_java_script_feature_unittest.mm
File-level comment, Patchset 5 (Latest):
Nicolas MacBeth . unresolved

should this file include new tests for `include_xorigin_frames`?

File ios/chrome/browser/intelligence/proto_wrappers/page_context_utils.h
Line 22, Patchset 5 (Latest):// Deserializes a string frame ID into a LocalFrameToken.
Nicolas MacBeth . unresolved

IIUC this to go from JS frame ID to base::UnguessableToken to autofill::LocalFrameToken ? there isn't a more direct way of achieving this? and if not, can we document that in the comment?

Line 11, Patchset 5 (Latest):#import "components/autofill/core/common/unique_ids.h"
Nicolas MacBeth . unresolved

nit: add todo to cleanup dep on `components/autofill`

File ios/chrome/browser/intelligence/proto_wrappers/page_context_utils.mm
Line 7, Patchset 5 (Latest):#import "components/autofill/ios/browser/autofill_util.h"
Nicolas MacBeth . unresolved

ditto

File ios/chrome/browser/intelligence/proto_wrappers/page_context_wrapper.mm
Line 703, Patchset 5 (Latest): // children of the main frame node since they couldn't be grafted at
Nicolas MacBeth . unresolved

super nit: `by` instead of `at`?

Line 813, Patchset 5 (Latest): frameId:
Nicolas MacBeth . unresolved

do you think `localFrameId` would be an improvement to make this clearer?

Line 854, Patchset 5 (Latest): valueAsDict.FindBool(kRemoteFrameTokenKey)) {
Nicolas MacBeth . unresolved

I don't think this should be `bool`

Line 876, Patchset 5 (Latest): if (frameId) {
Nicolas MacBeth . unresolved

if there is no frameId, we would lose this frame. could we handle this more gracefully?

Line 899, Patchset 5 (Latest): // for any of the main WebFrame's children iframes. Children can be remote
// or same origin frames.
Nicolas MacBeth . unresolved

mismatch between terminologies (remote/local, same/cross origin)

Line 900, Patchset 5 (Latest): // or same origin frames.
Nicolas MacBeth . unresolved

super nit: extra space

Line 1023, Patchset 5 (Latest): if (const std::string* token_string =
value.FindString(kRemoteFrameTokenKey)) {
Nicolas MacBeth . unresolved

can we extract the assignment from the `if` for legibility? and early return instead of nesting `if`s

Line 1028, Patchset 5 (Latest): if (std::optional<autofill::RemoteFrameToken> remote =
DeserializeFrameIdAsRemoteFrameToken(*token_string)) {
Nicolas MacBeth . unresolved

ditto

Line 1031, Patchset 5 (Latest): if (std::optional<autofill::LocalFrameToken> local =
[self frameRegistrar]->LookupChildFrame(*remote)) {
Nicolas MacBeth . unresolved

ditto

Line 1083, Patchset 5 (Latest): return;
Nicolas MacBeth . unresolved

is this return useful?

File ios/chrome/browser/intelligence/proto_wrappers/page_context_wrapper_config.h
Line 20, Patchset 5 (Latest): // True to graft cross-origin frames.
bool graft_xorigin_frames() const;
Nicolas MacBeth . unresolved

nit: could you elaborate on the comment here

File ios/chrome/browser/intelligence/proto_wrappers/page_context_wrapper_unittest.mm
Line 22, Patchset 5 (Latest):#import "components/autofill/core/common/unique_ids.h"
#import "components/autofill/ios/form_util/child_frame_registrar.h"
Nicolas MacBeth . unresolved

TODO for removing the dep

Line 80, Patchset 5 (Latest):constexpr base::TimeDelta kRegistrationTimeout = base::Seconds(5);
Nicolas MacBeth . unresolved

this feels long, can it be reduced without introducing flakiness?

Line 1399, Patchset 5 (Latest): u"__gCrWeb.getRegisteredApi('pageContextWrapperTest')"
".getFunction('registerAllRemoteFrames')()");
Nicolas MacBeth . unresolved

can we make this a const since I think I see it used multiple times in this file. even as a const, is this maintainable in case the original lib changes?

File ios/chrome/browser/intelligence/proto_wrappers/resources/page_context_extractor.ts
Line 21, Patchset 5 (Latest):// Data extracted on remote frames (other than the main frame) on the same
// or different origin.
type RemoteFrameData = SameOriginFrameData|CrossOriginFrameData;
Nicolas MacBeth . unresolved

nit: can you move this below the definitions of SameOriginFrameData and CrossOriginFrameData?

Line 90, Patchset 5 (Latest): if (!contentDoc) {
Nicolas MacBeth . unresolved

is this the most idiomatic way of knowing that this is a cross-origin frame?

Line 144, Patchset 5 (Latest): keepXoriginFrames: boolean): ExtractionResult {
Nicolas MacBeth . unresolved

similar to above, can we have a naming closer to including cross origin frame tokens?

Open in Gerrit

Related details

Attention is currently required from:
  • Vincent Boisselle
Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I7c5c481d4c18bed78c1bbb7022ac2ab04fd5d085
    Gerrit-Change-Number: 7205479
    Gerrit-PatchSet: 5
    Gerrit-Owner: Vincent Boisselle <vi...@google.com>
    Gerrit-Reviewer: Nicolas MacBeth <nicolas...@google.com>
    Gerrit-Reviewer: Vincent Boisselle <vi...@google.com>
    Gerrit-CC: Code Review Nudger <android-build...@prod.google.com>
    Gerrit-Attention: Vincent Boisselle <vi...@google.com>
    Gerrit-Comment-Date: Fri, 02 Jan 2026 21:10:37 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Nicolas MacBeth (Gerrit)

    unread,
    Jan 2, 2026, 4:21:44 PMJan 2
    to Vincent Boisselle, Code Review Nudger, Chromium LUCI CQ, chromium...@chromium.org, browser-comp...@chromium.org, chrome-intell...@chromium.org, chrome-intelligence-te...@google.com, ios-revie...@chromium.org, ios-r...@chromium.org, marq+...@chromium.org, tmartino+tran...@chromium.org
    Attention needed from Vincent Boisselle

    Nicolas MacBeth added 7 comments

    File components/autofill/ios/form_util/child_frame_registrar.mm
    Line 27, Patchset 5 (Latest): for (auto [r, l] : lookup_map_) {
    Nicolas MacBeth . unresolved

    AI suggestion: use `const auto& [r, l]` to remove unnecessary copying

    File ios/chrome/browser/intelligence/proto_wrappers/frame_grafter.h
    Line 49, Patchset 5 (Latest): std::map<autofill::LocalFrameToken, optimization_guide::proto::ContentNode>
    unclaimed_frame_content_;
    // Frame content that is claimed but wasn't yet available.
    std::map<autofill::LocalFrameToken, optimization_guide::proto::ContentNode*>
    claims_;
    Nicolas MacBeth . unresolved

    can the content nodes here be unique pointers, for better lifecycle destruction of any remaining pointers and explicit ownership?

    File ios/chrome/browser/intelligence/proto_wrappers/frame_grafter.mm
    Line 56, Patchset 5 (Latest):
    Nicolas MacBeth . unresolved

    do we want to post a task on the main thread here just to give it the change to maybe finish some extractions or registrations?

    Line 65, Patchset 5 (Latest): for (auto& [ot, _] : unclaimed_frame_content_) {
    for (auto& [at, _] : claims_) {
    if (ot == at) {
    return true;
    }
    }
    }
    Nicolas MacBeth . unresolved

    instead of nested loops, we can probably just iterate over one map and check for existence in the other, this would be more efficient

    File ios/chrome/browser/intelligence/proto_wrappers/page_context_wrapper.mm
    Line 229, Patchset 5 (Latest): FrameGrafter _grafter;
    Nicolas MacBeth . unresolved

    can we make this a unique pointer, for its lifecycle to be tied to the page context wrapper?

    Line 1025, Patchset 5 (Latest): // TODO(crbug.com/460823916): The grafter should re-attempt claim upon
    Nicolas MacBeth . unresolved

    this is an important TODO, I fear there will be quite some unfinished registrations

    File ios/chrome/browser/intelligence/proto_wrappers/resources/page_context_extractor.ts
    Line 99, Patchset 5 (Latest): return null;
    Nicolas MacBeth . unresolved

    would it make sense to return a `CrossOriginFrameData` with a remote frame registration in this catch, if `keepXoriginFrames` is true?

    Gerrit-Comment-Date: Fri, 02 Jan 2026 21:21:38 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Vincent Boisselle (Gerrit)

    unread,
    Jan 7, 2026, 10:56:49 AMJan 7
    to Code Review Nudger, Nicolas MacBeth, Chromium LUCI CQ, chromium...@chromium.org, browser-comp...@chromium.org, chrome-intell...@chromium.org, chrome-intelligence-te...@google.com, ios-revie...@chromium.org, ios-r...@chromium.org, marq+...@chromium.org, tmartino+tran...@chromium.org
    Attention needed from Nicolas MacBeth

    Vincent Boisselle added 41 comments

    Patchset-level comments
    File-level comment, Patchset 8 (Latest):
    Vincent Boisselle . resolved

    I still need to change the license years

    Commit Message
    Line 7, Patchset 5:[ios][apcv2] Graft xorigin frames
    Nicolas MacBeth . resolved

    Can we add some comprehensive information to this commit message?

    Vincent Boisselle

    Done

    File components/autofill/ios/form_util/child_frame_registrar.h
    Line 53, Patchset 5: // Maps from local to remote token.
    Nicolas MacBeth . resolved

    question: do you think it's worth it documentation-wise to copy the information above about remote and local frames? or should it move to something more generic that encompasses these two methods?

    Vincent Boisselle

    Done

    File components/autofill/ios/form_util/child_frame_registrar.mm
    Line 25, Patchset 5:std::optional<RemoteFrameToken> ChildFrameRegistrar::LookupLocalFrame(
    Nicolas MacBeth . resolved

    I defer to you and Tommy as local owners here, but do you think it's worthwhile to maintain a reverse lookup map instead of iterating over all the tokens at every lookup here? WDYT? if we do this operation often in the page context extraction, we may be introducing some latency here

    at the very least I think we should document this in the header!

    Vincent Boisselle

    I changed the logic to not have to do that

    Line 27, Patchset 5: for (auto [r, l] : lookup_map_) {
    Nicolas MacBeth . resolved

    AI suggestion: use `const auto& [r, l]` to remove unnecessary copying

    Vincent Boisselle

    those are relatively small structures

    File ios/chrome/browser/intelligence/proto_wrappers/frame_grafter.h
    Line 49, Patchset 5: std::map<autofill::LocalFrameToken, optimization_guide::proto::ContentNode>

    unclaimed_frame_content_;
    // Frame content that is claimed but wasn't yet available.
    std::map<autofill::LocalFrameToken, optimization_guide::proto::ContentNode*>
    claims_;
    Nicolas MacBeth . unresolved

    can the content nodes here be unique pointers, for better lifecycle destruction of any remaining pointers and explicit ownership?

    Vincent Boisselle

    unclaimed_frame_content_ has its own optimization_guide::proto::ContentNode objects, which is moved there, then moved back to the placeholder when the fulfilling the claim.

    For the claims_ since we populate empty placeholders in the apc tree, we need a pointer to it. The grafter itself doesn't own the tree.

    Or we could use callbacks instead, not sure it would be better

    OR we make some sort of weakptr wrapper around the content pointers

    ----
    Regarding memory management

    If the wrapper can only be used once, should be fine

    It looks like the wrapper was mad to be only used once

    Line 29, Patchset 5: // grafting. Content is cached if there is no claim to fulfil immediately.
    Nicolas MacBeth . resolved

    type: `fulfill`

    Vincent Boisselle

    Done

    Line 21, Patchset 5: // Claims a frame's content for grafting. Puts the `placeholder` in a waitlist
    Nicolas MacBeth . resolved

    the claim / give terminology is quite confusing to me throughout this file. do you think it's clear enough for future readers? WDYT instead of something like `RegisterPlaceholder`, `FulfillPlaceholder` and `FulfillUnresolvedPlaceholders`?

    Vincent Boisselle

    sure

    Line 14, Patchset 5:// Grafter that receives claims on frame content and frame content to construct
    // the frame tree.
    Nicolas MacBeth . resolved

    do you mind adding a comment that explains the overview of the algorithm? (especially given the terminology used below in methods/comments). maybe we can also link to the DD tree grafting section?

    Vincent Boisselle

    Done

    Line 11, Patchset 5:#import "components/autofill/core/common/unique_ids.h"
    Nicolas MacBeth . resolved

    nit: can we add a TODO to do the migration off of `components/autofill`?

    Vincent Boisselle

    Done

    File-level comment, Patchset 5:
    Nicolas MacBeth . resolved

    what do you think about making the tree grafter more self-contained, and reusable? ideally this would work for any node grafting impl, and token/ID types. for the types, we can use a template, and we pass callbacks to the grafter which take a node as param (similar to your `PlaceUnclaimedFrames` impl).

    something like (code example created through prompting - definitely needs rework, but just to illustrate what I mean): https://paste.googleplex.com/5323044430151680

    Vincent Boisselle

    I don't see any use case other than frames.

    I would keep it specialized for now,

    if we need that elsewhere we can then generalize

    File ios/chrome/browser/intelligence/proto_wrappers/frame_grafter.mm
    Line 18, Patchset 5: // Can't claim content for the `token` more than once.
    Nicolas MacBeth . resolved

    this shouldn't ever happen right? assuming no single frame should get an extraction pass more than once, this shouldn't be called twice. can we log a metric here (or add a TODO for that)

    Vincent Boisselle

    Nothing is impossible but will likely not happen.

    Line 36, Patchset 5: // Can't give give frame content for the `token` more than once.
    Nicolas MacBeth . resolved

    ditto

    Vincent Boisselle

    Done

    Line 56, Patchset 5:
    Nicolas MacBeth . resolved

    do we want to post a task on the main thread here just to give it the change to maybe finish some extractions or registrations?

    Vincent Boisselle

    I reworked the logic to wait on registration

    Line 58, Patchset 5: for (auto& [_, o] : unclaimed_frame_content_) {
    Nicolas MacBeth . resolved

    can we add a TODO here to log how often this happens? a overall TODO for metrics in this file would be helpful too I think

    Vincent Boisselle

    Done

    Line 65, Patchset 5: for (auto& [ot, _] : unclaimed_frame_content_) {

    for (auto& [at, _] : claims_) {
    if (ot == at) {
    return true;
    }
    }
    }
    Nicolas MacBeth . resolved

    instead of nested loops, we can probably just iterate over one map and check for existence in the other, this would be more efficient

    Vincent Boisselle

    ah yeah, there was time it wasn't possible but now that I use the local frame token in both we can just do that.

    File ios/chrome/browser/intelligence/proto_wrappers/page_context_extractor_java_script_feature.h
    Line 48, Patchset 5: bool include_xorigin_frames,
    Nicolas MacBeth . resolved

    I'm not sure the name for this parameter is totally accurate, since this frame can't see x-origin frames. instead maybe something like `include_cross_origin_frame_tokens`? can we add a small blurb about it in the comment above?

    Vincent Boisselle

    `include_cross_origin_frame_content`

    this goes beyond the tokens where the content is grafted to the apc tree

    File ios/chrome/browser/intelligence/proto_wrappers/page_context_extractor_java_script_feature_unittest.mm
    File-level comment, Patchset 5:
    Nicolas MacBeth . resolved

    should this file include new tests for `include_xorigin_frames`?

    Vincent Boisselle

    Done

    File ios/chrome/browser/intelligence/proto_wrappers/page_context_utils.h
    Line 22, Patchset 5:// Deserializes a string frame ID into a LocalFrameToken.
    Nicolas MacBeth . unresolved

    IIUC this to go from JS frame ID to base::UnguessableToken to autofill::LocalFrameToken ? there isn't a more direct way of achieving this? and if not, can we document that in the comment?

    Vincent Boisselle

    there is no other way to go from a string to base::UnguessableToken

    what extra documentation do we need ?

    Line 11, Patchset 5:#import "components/autofill/core/common/unique_ids.h"
    Nicolas MacBeth . resolved

    nit: add todo to cleanup dep on `components/autofill`

    Vincent Boisselle

    Done

    File ios/chrome/browser/intelligence/proto_wrappers/page_context_utils.mm
    Line 7, Patchset 5:#import "components/autofill/ios/browser/autofill_util.h"
    Nicolas MacBeth . resolved

    ditto

    Vincent Boisselle

    Done

    adding the todo to the header will be sufficient

    File ios/chrome/browser/intelligence/proto_wrappers/page_context_wrapper.mm
    Line 229, Patchset 5: FrameGrafter _grafter;
    Nicolas MacBeth . resolved

    can we make this a unique pointer, for its lifecycle to be tied to the page context wrapper?

    Vincent Boisselle

    its lifecycle is already ties to the wrapper

    I will be deleted first , before other _pageContext so there is less risk of dangling content pointers.

    Line 703, Patchset 5: // children of the main frame node since they couldn't be grafted at
    Nicolas MacBeth . resolved

    super nit: `by` instead of `at`?

    Vincent Boisselle

    Done

    Line 813, Patchset 5: frameId:
    Nicolas MacBeth . resolved

    do you think `localFrameId` would be an improvement to make this clearer?

    Vincent Boisselle

    Done

    Line 854, Patchset 5: valueAsDict.FindBool(kRemoteFrameTokenKey)) {
    Nicolas MacBeth . resolved

    I don't think this should be `bool`

    Vincent Boisselle

    I guess no tests hit that case lol

    A string indeed

    Line 876, Patchset 5: if (frameId) {
    Nicolas MacBeth . unresolved

    if there is no frameId, we would lose this frame. could we handle this more gracefully?

    Vincent Boisselle

    One thing we could do is to put that in the list of unregistered content then autoplace the content at the end of extraction

    but note that this should be rare as registration isn't needed to give frame content.

    Line 900, Patchset 5: // or same origin frames.
    Nicolas MacBeth . resolved

    super nit: extra space

    Vincent Boisselle

    Done

    Line 899, Patchset 5: // for any of the main WebFrame's children iframes. Children can be remote

    // or same origin frames.
    Nicolas MacBeth . resolved

    mismatch between terminologies (remote/local, same/cross origin)

    Vincent Boisselle

    Done

    Line 1023, Patchset 5: if (const std::string* token_string =
    value.FindString(kRemoteFrameTokenKey)) {
    Nicolas MacBeth . resolved

    can we extract the assignment from the `if` for legibility? and early return instead of nesting `if`s

    Vincent Boisselle

    we dont want to early return if there is remote frame token

    I managed to remove one level of nesting.

    Line 1025, Patchset 5: // TODO(crbug.com/460823916): The grafter should re-attempt claim upon
    Nicolas MacBeth . resolved

    this is an important TODO, I fear there will be quite some unfinished registrations

    Vincent Boisselle

    yup, but the solution isn't that trivial so I prefer having it as a next step

    Line 1028, Patchset 5: if (std::optional<autofill::RemoteFrameToken> remote =
    DeserializeFrameIdAsRemoteFrameToken(*token_string)) {
    Nicolas MacBeth . resolved

    ditto

    Vincent Boisselle

    Done

    Line 1031, Patchset 5: if (std::optional<autofill::LocalFrameToken> local =
    [self frameRegistrar]->LookupChildFrame(*remote)) {
    Nicolas MacBeth . resolved

    ditto

    Vincent Boisselle

    Done

    Line 1083, Patchset 5: return;
    Nicolas MacBeth . resolved

    is this return useful?

    Vincent Boisselle

    the finest return

    File ios/chrome/browser/intelligence/proto_wrappers/page_context_wrapper_config.h
    Line 20, Patchset 5: // True to graft cross-origin frames.
    bool graft_xorigin_frames() const;
    Nicolas MacBeth . resolved

    nit: could you elaborate on the comment here

    Vincent Boisselle

    Done

    File ios/chrome/browser/intelligence/proto_wrappers/page_context_wrapper_unittest.mm
    Line 22, Patchset 5:#import "components/autofill/core/common/unique_ids.h"
    #import "components/autofill/ios/form_util/child_frame_registrar.h"
    Nicolas MacBeth . resolved

    TODO for removing the dep

    Vincent Boisselle

    If we change the tested file, we will have to change this file, so I think one comment per module is sufficient.

    Line 80, Patchset 5:constexpr base::TimeDelta kRegistrationTimeout = base::Seconds(5);
    Nicolas MacBeth . resolved

    this feels long, can it be reduced without introducing flakiness?

    Vincent Boisselle

    Done

    Line 1399, Patchset 5: u"__gCrWeb.getRegisteredApi('pageContextWrapperTest')"
    ".getFunction('registerAllRemoteFrames')()");
    Nicolas MacBeth . resolved

    can we make this a const since I think I see it used multiple times in this file. even as a const, is this maintainable in case the original lib changes?

    Vincent Boisselle

    Done

    File ios/chrome/browser/intelligence/proto_wrappers/resources/page_context_extractor.ts
    Line 21, Patchset 5:// Data extracted on remote frames (other than the main frame) on the same

    // or different origin.
    type RemoteFrameData = SameOriginFrameData|CrossOriginFrameData;
    Nicolas MacBeth . resolved

    nit: can you move this below the definitions of SameOriginFrameData and CrossOriginFrameData?

    Vincent Boisselle

    Done

    Line 90, Patchset 5: if (!contentDoc) {
    Nicolas MacBeth . resolved

    is this the most idiomatic way of knowing that this is a cross-origin frame?

    Vincent Boisselle

    I think so

    and also probably the only way

    Nicolas MacBeth . unresolved

    would it make sense to return a `CrossOriginFrameData` with a remote frame registration in this catch, if `keepXoriginFrames` is true?

    Vincent Boisselle

    I did a few tests and I have never seen cases where an exception is thrown if contentDocument can't be access. Have you seen that ?

    There is a console log error message but no exception is thrown

    I think we could remove this try/catch altogether

    ----

    I reworked the logic to return on both an exception and a null content node

    Line 144, Patchset 5: keepXoriginFrames: boolean): ExtractionResult {
    Nicolas MacBeth . resolved

    similar to above, can we have a naming closer to including cross origin frame tokens?

    Vincent Boisselle

    idk, I could use `keepCrossOriginFrameData` but I would not refer to token which is a bit too narrow IMO

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Nicolas MacBeth
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I7c5c481d4c18bed78c1bbb7022ac2ab04fd5d085
    Gerrit-Change-Number: 7205479
    Gerrit-PatchSet: 8
    Gerrit-Owner: Vincent Boisselle <vi...@google.com>
    Gerrit-Reviewer: Nicolas MacBeth <nicolas...@google.com>
    Gerrit-Reviewer: Vincent Boisselle <vi...@google.com>
    Gerrit-CC: Code Review Nudger <android-build...@prod.google.com>
    Gerrit-Attention: Nicolas MacBeth <nicolas...@google.com>
    Gerrit-Comment-Date: Wed, 07 Jan 2026 15:56:43 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Nicolas MacBeth <nicolas...@google.com>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Nicolas MacBeth (Gerrit)

    unread,
    Jan 13, 2026, 3:52:31 PM (8 days ago) Jan 13
    to Vincent Boisselle, Code Review Nudger, Chromium LUCI CQ, chromium...@chromium.org, browser-comp...@chromium.org, chrome-intell...@chromium.org, chrome-intelligence-te...@google.com, ios-revie...@chromium.org, ios-r...@chromium.org, marq+...@chromium.org, tmartino+tran...@chromium.org
    Attention needed from Vincent Boisselle

    Nicolas MacBeth voted and added 12 comments

    Votes added by Nicolas MacBeth

    Code-Review+1

    12 comments

    Patchset-level comments
    File-level comment, Patchset 10 (Latest):
    Nicolas MacBeth . resolved

    waiting for registration at the end of the tree walking as an approach to fix the inter-frame messaging wait delay sgtm! thanks Vince!

    File ios/chrome/browser/intelligence/proto_wrappers/frame_grafter.h
    Line 53, Patchset 10 (Latest): // not match a placeholder. Call this function when it is determined that (1)
    Nicolas MacBeth . unresolved

    nit: you can remote "not" I think given you have "doesn't"

    Line 49, Patchset 5: std::map<autofill::LocalFrameToken, optimization_guide::proto::ContentNode>
    unclaimed_frame_content_;
    // Frame content that is claimed but wasn't yet available.
    std::map<autofill::LocalFrameToken, optimization_guide::proto::ContentNode*>
    claims_;
    Nicolas MacBeth . resolved

    can the content nodes here be unique pointers, for better lifecycle destruction of any remaining pointers and explicit ownership?

    Vincent Boisselle

    unclaimed_frame_content_ has its own optimization_guide::proto::ContentNode objects, which is moved there, then moved back to the placeholder when the fulfilling the claim.

    For the claims_ since we populate empty placeholders in the apc tree, we need a pointer to it. The grafter itself doesn't own the tree.

    Or we could use callbacks instead, not sure it would be better

    OR we make some sort of weakptr wrapper around the content pointers

    ----
    Regarding memory management

    If the wrapper can only be used once, should be fine

    It looks like the wrapper was mad to be only used once

    Nicolas MacBeth

    Acknowledged

    File ios/chrome/browser/intelligence/proto_wrappers/page_context_utils.h
    Line 22, Patchset 5:// Deserializes a string frame ID into a LocalFrameToken.
    Nicolas MacBeth . resolved

    IIUC this to go from JS frame ID to base::UnguessableToken to autofill::LocalFrameToken ? there isn't a more direct way of achieving this? and if not, can we document that in the comment?

    Vincent Boisselle

    there is no other way to go from a string to base::UnguessableToken

    what extra documentation do we need ?

    Nicolas MacBeth

    Acknowledged

    File ios/chrome/browser/intelligence/proto_wrappers/page_context_utils.mm
    Line 25, Patchset 10 (Latest):std::optional<autofill::LocalFrameToken> DeserializeFrameIdAsLocalFrameToken(
    Nicolas MacBeth . unresolved

    AI suggestion:

    You are attempting to static_cast a std::optional<base::UnguessableToken> (returned by DeserializeJavaScriptFrameId) to std::optional<autofill::LocalFrameToken>. static_cast cannot convert between distinct template instantiations of std::optional even if the underlying types are convertible or aliases. Suggestion: Unwrap the optional and construct the token explicitly.

    ```
    auto token = autofill::DeserializeJavaScriptFrameId(serialized_id);
    return token ? std::make_optional(autofill::LocalFrameToken(*token)) : std::nullopt;
    ```

    File ios/chrome/browser/intelligence/proto_wrappers/page_context_wrapper.mm
    Line 357, Patchset 10 (Latest):- (void)stopRegistrationTimer {
    Nicolas MacBeth . unresolved

    nit: comment

    Line 361, Patchset 10 (Latest):- (void)completeRegistrationWaitWithBarrier:(base::RepeatingClosure)barrier {
    Nicolas MacBeth . unresolved

    nit: comment

    Line 876, Patchset 5: if (frameId) {
    Nicolas MacBeth . resolved

    if there is no frameId, we would lose this frame. could we handle this more gracefully?

    Vincent Boisselle

    One thing we could do is to put that in the list of unregistered content then autoplace the content at the end of extraction

    but note that this should be rare as registration isn't needed to give frame content.

    Nicolas MacBeth

    I think the former sgtm

    Line 979, Patchset 10 (Latest): _registrationTimer.Start(FROM_HERE, kRegistrationTimeout, run_barrier_once);
    Nicolas MacBeth . unresolved

    As we spoke offline: Let's add a TODO for a metric to see how often the registration timeout occurs

    Nicolas MacBeth . unresolved

    is this return useful?

    Vincent Boisselle

    the finest return

    Nicolas MacBeth

    kept by mistake?

    Line 1112, Patchset 10 (Latest): _discoveredRemoteTokens.push_back(*remote);
    Nicolas MacBeth . unresolved

    can we use the grafter as a source of truth instead of maintaining both the grafter and _discoveredRemoteTokens?

    File ios/chrome/browser/intelligence/proto_wrappers/resources/page_context_extractor.ts
    Nicolas MacBeth . resolved

    would it make sense to return a `CrossOriginFrameData` with a remote frame registration in this catch, if `keepXoriginFrames` is true?

    Vincent Boisselle

    I did a few tests and I have never seen cases where an exception is thrown if contentDocument can't be access. Have you seen that ?

    There is a console log error message but no exception is thrown

    I think we could remove this try/catch altogether

    ----

    I reworked the logic to return on both an exception and a null content node

    Nicolas MacBeth

    Acknowledged

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Vincent Boisselle
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I7c5c481d4c18bed78c1bbb7022ac2ab04fd5d085
    Gerrit-Change-Number: 7205479
    Gerrit-PatchSet: 10
    Gerrit-Owner: Vincent Boisselle <vi...@google.com>
    Gerrit-Reviewer: Nicolas MacBeth <nicolas...@google.com>
    Gerrit-Reviewer: Vincent Boisselle <vi...@google.com>
    Gerrit-CC: Code Review Nudger <android-build...@prod.google.com>
    Gerrit-Attention: Vincent Boisselle <vi...@google.com>
    Gerrit-Comment-Date: Tue, 13 Jan 2026 20:52:20 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    Comment-In-Reply-To: Nicolas MacBeth <nicolas...@google.com>
    Comment-In-Reply-To: Vincent Boisselle <vi...@google.com>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Vincent Boisselle (Gerrit)

    unread,
    Jan 14, 2026, 4:40:55 PM (7 days ago) Jan 14
    to Nicolas MacBeth, Code Review Nudger, Chromium LUCI CQ, chromium...@chromium.org, browser-comp...@chromium.org, chrome-intell...@chromium.org, chrome-intelligence-te...@google.com, ios-revie...@chromium.org, ios-r...@chromium.org, marq+...@chromium.org, tmartino+tran...@chromium.org
    Attention needed from Nicolas MacBeth

    Vincent Boisselle added 7 comments

    File ios/chrome/browser/intelligence/proto_wrappers/frame_grafter.h
    Line 53, Patchset 10: // not match a placeholder. Call this function when it is determined that (1)
    Nicolas MacBeth . resolved

    nit: you can remote "not" I think given you have "doesn't"

    Vincent Boisselle

    Done

    File ios/chrome/browser/intelligence/proto_wrappers/page_context_utils.mm
    Line 25, Patchset 10:std::optional<autofill::LocalFrameToken> DeserializeFrameIdAsLocalFrameToken(
    Nicolas MacBeth . resolved

    AI suggestion:

    You are attempting to static_cast a std::optional<base::UnguessableToken> (returned by DeserializeJavaScriptFrameId) to std::optional<autofill::LocalFrameToken>. static_cast cannot convert between distinct template instantiations of std::optional even if the underlying types are convertible or aliases. Suggestion: Unwrap the optional and construct the token explicitly.

    ```
    auto token = autofill::DeserializeJavaScriptFrameId(serialized_id);
    return token ? std::make_optional(autofill::LocalFrameToken(*token)) : std::nullopt;
    ```

    Vincent Boisselle

    Done

    File ios/chrome/browser/intelligence/proto_wrappers/page_context_wrapper.mm
    Line 357, Patchset 10:- (void)stopRegistrationTimer {
    Nicolas MacBeth . resolved

    nit: comment

    Vincent Boisselle

    Done

    Line 361, Patchset 10:- (void)completeRegistrationWaitWithBarrier:(base::RepeatingClosure)barrier {
    Nicolas MacBeth . resolved

    nit: comment

    Vincent Boisselle

    Done

    Line 979, Patchset 10: _registrationTimer.Start(FROM_HERE, kRegistrationTimeout, run_barrier_once);
    Nicolas MacBeth . resolved

    As we spoke offline: Let's add a TODO for a metric to see how often the registration timeout occurs

    Vincent Boisselle

    Done

    Nicolas MacBeth . resolved

    is this return useful?

    Vincent Boisselle

    the finest return

    Nicolas MacBeth

    kept by mistake?

    Vincent Boisselle

    the finest

    Line 1112, Patchset 10: _discoveredRemoteTokens.push_back(*remote);
    Nicolas MacBeth . resolved

    can we use the grafter as a source of truth instead of maintaining both the grafter and _discoveredRemoteTokens?

    Vincent Boisselle

    Done

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Nicolas MacBeth
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I7c5c481d4c18bed78c1bbb7022ac2ab04fd5d085
    Gerrit-Change-Number: 7205479
    Gerrit-PatchSet: 11
    Gerrit-Owner: Vincent Boisselle <vi...@google.com>
    Gerrit-Reviewer: Nicolas MacBeth <nicolas...@google.com>
    Gerrit-Reviewer: Vincent Boisselle <vi...@google.com>
    Gerrit-CC: Code Review Nudger <android-build...@prod.google.com>
    Gerrit-Attention: Nicolas MacBeth <nicolas...@google.com>
    Gerrit-Comment-Date: Wed, 14 Jan 2026 21:40:48 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Nicolas MacBeth (Gerrit)

    unread,
    Jan 20, 2026, 12:21:15 AM (yesterday) Jan 20
    to Vincent Boisselle, Code Review Nudger, Chromium LUCI CQ, chromium...@chromium.org, browser-comp...@chromium.org, chrome-intell...@chromium.org, chrome-intelligence-te...@google.com, ios-revie...@chromium.org, ios-r...@chromium.org, marq+...@chromium.org, tmartino+tran...@chromium.org
    Attention needed from Vincent Boisselle

    Nicolas MacBeth voted Code-Review+1

    Code-Review+1
    Open in Gerrit

    Related details

    Attention is currently required from:
    • Vincent Boisselle
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement satisfiedCode-Review
    • requirement satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I7c5c481d4c18bed78c1bbb7022ac2ab04fd5d085
    Gerrit-Change-Number: 7205479
    Gerrit-PatchSet: 13
    Gerrit-Owner: Vincent Boisselle <vi...@google.com>
    Gerrit-Reviewer: Nicolas MacBeth <nicolas...@google.com>
    Gerrit-Reviewer: Vincent Boisselle <vi...@google.com>
    Gerrit-CC: Code Review Nudger <android-build...@prod.google.com>
    Gerrit-Attention: Vincent Boisselle <vi...@google.com>
    Gerrit-Comment-Date: Tue, 20 Jan 2026 05:21:07 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    satisfied_requirement
    open
    diffy

    Nicolas MacBeth (Gerrit)

    unread,
    Jan 20, 2026, 12:21:53 AM (yesterday) Jan 20
    to Vincent Boisselle, Code Review Nudger, Chromium LUCI CQ, chromium...@chromium.org, browser-comp...@chromium.org, chrome-intell...@chromium.org, chrome-intelligence-te...@google.com, ios-revie...@chromium.org, ios-r...@chromium.org, marq+...@chromium.org, tmartino+tran...@chromium.org
    Attention needed from Vincent Boisselle

    Nicolas MacBeth voted and added 2 comments

    Votes added by Nicolas MacBeth

    Commit-Queue+1

    2 comments

    Patchset-level comments
    File-level comment, Patchset 13 (Latest):
    Nicolas MacBeth . resolved

    looks great, thanks!

    Commit Message
    Line 20, Patchset 13 (Latest):Doesn't solve the registration racing problem yet.
    Nicolas MacBeth . unresolved

    Can you update the commit message, thanks!

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Vincent Boisselle
    Submit Requirements:
      • requirement satisfiedCode-Coverage
      • requirement satisfiedCode-Owners
      • requirement satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement satisfiedReview-Enforcement
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: chromium/src
      Gerrit-Branch: main
      Gerrit-Change-Id: I7c5c481d4c18bed78c1bbb7022ac2ab04fd5d085
      Gerrit-Change-Number: 7205479
      Gerrit-PatchSet: 13
      Gerrit-Owner: Vincent Boisselle <vi...@google.com>
      Gerrit-Reviewer: Nicolas MacBeth <nicolas...@google.com>
      Gerrit-Reviewer: Vincent Boisselle <vi...@google.com>
      Gerrit-CC: Code Review Nudger <android-build...@prod.google.com>
      Gerrit-Attention: Vincent Boisselle <vi...@google.com>
      Gerrit-Comment-Date: Tue, 20 Jan 2026 05:21:38 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: Yes
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Vincent Boisselle (Gerrit)

      unread,
      10:38 AM (2 hours ago) 10:38 AM
      to Nicolas MacBeth, Code Review Nudger, Chromium LUCI CQ, chromium...@chromium.org, browser-comp...@chromium.org, chrome-intell...@chromium.org, chrome-intelligence-te...@google.com, ios-revie...@chromium.org, ios-r...@chromium.org, marq+...@chromium.org, tmartino+tran...@chromium.org
      Attention needed from Nicolas MacBeth and Vincent Boisselle

      Message from Vincent Boisselle

      Set Ready For Review

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Nicolas MacBeth
      • Vincent Boisselle
      Submit Requirements:
      • requirement satisfiedCode-Coverage
      • requirement satisfiedCode-Owners
      • requirement satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement satisfiedReview-Enforcement
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: chromium/src
      Gerrit-Branch: main
      Gerrit-Change-Id: I7c5c481d4c18bed78c1bbb7022ac2ab04fd5d085
      Gerrit-Change-Number: 7205479
      Gerrit-PatchSet: 17
      Gerrit-Owner: Vincent Boisselle <vi...@google.com>
      Gerrit-Reviewer: Nicolas MacBeth <nicolas...@google.com>
      Gerrit-Reviewer: Vincent Boisselle <vi...@google.com>
      Gerrit-CC: Code Review Nudger <android-build...@prod.google.com>
      Gerrit-Attention: Nicolas MacBeth <nicolas...@google.com>
      Gerrit-Attention: Vincent Boisselle <vi...@google.com>
      Gerrit-Comment-Date: Wed, 21 Jan 2026 15:38:01 +0000
      Gerrit-HasComments: No
      Gerrit-Has-Labels: No
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Vincent Boisselle (Gerrit)

      unread,
      10:38 AM (2 hours ago) 10:38 AM
      to Nicolas MacBeth, Code Review Nudger, Chromium LUCI CQ, chromium...@chromium.org, browser-comp...@chromium.org, chrome-intell...@chromium.org, chrome-intelligence-te...@google.com, ios-revie...@chromium.org, ios-r...@chromium.org, marq+...@chromium.org, tmartino+tran...@chromium.org
      Attention needed from Nicolas MacBeth

      Vincent Boisselle voted and added 1 comment

      Votes added by Vincent Boisselle

      Commit-Queue+1

      1 comment

      Commit Message
      Line 20, Patchset 13:Doesn't solve the registration racing problem yet.
      Nicolas MacBeth . resolved

      Can you update the commit message, thanks!

      Vincent Boisselle

      Done

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Nicolas MacBeth
      Submit Requirements:
        • requirement satisfiedCode-Coverage
        • requirement satisfiedCode-Owners
        • requirement satisfiedCode-Review
        • requirement satisfiedReview-Enforcement
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: chromium/src
        Gerrit-Branch: main
        Gerrit-Change-Id: I7c5c481d4c18bed78c1bbb7022ac2ab04fd5d085
        Gerrit-Change-Number: 7205479
        Gerrit-PatchSet: 17
        Gerrit-Owner: Vincent Boisselle <vi...@google.com>
        Gerrit-Reviewer: Nicolas MacBeth <nicolas...@google.com>
        Gerrit-Reviewer: Vincent Boisselle <vi...@google.com>
        Gerrit-CC: Code Review Nudger <android-build...@prod.google.com>
        Gerrit-Attention: Nicolas MacBeth <nicolas...@google.com>
        Gerrit-Comment-Date: Wed, 21 Jan 2026 15:38:06 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: Yes
        Comment-In-Reply-To: Nicolas MacBeth <nicolas...@google.com>
        satisfied_requirement
        open
        diffy
        Reply all
        Reply to author
        Forward
        0 new messages