Add suggestion interaction callbacks in FilterTabController. [chromium/src : main]

0 views
Skip to first unread message

Aditya Gupta (Gerrit)

unread,
Jul 9, 2026, 9:53:31 AM (21 hours ago) Jul 9
to chromium...@chromium.org, droger+w...@chromium.org

Aditya Gupta has uploaded the change for review

Commit message

Add suggestion interaction callbacks in FilterTabController.

This CL adds SuggestionInteractionCallbacks in MultistepFilterUiDelegate and passes the SuggestionInteractionCallbacks to FilterUiController in OnSuggestionGenerated method. This decouples MultistepFilterService depedency from FilterUiController and makes FilterTabController the source of truth for all future metrics tracking.
Bug: b:531724639
Change-Id: If38b1936d05d8117109da96ed055d35a0c0eb8c0

Change diff


Change information

Files:
  • M chrome/browser/multistep_filter/BUILD.gn
  • M chrome/browser/multistep_filter/chrome_filter_navigation_observer_unittest.cc
  • M chrome/browser/multistep_filter/multistep_filter_ui_delegate_impl.cc
  • M chrome/browser/multistep_filter/multistep_filter_ui_delegate_impl.h
  • M chrome/browser/multistep_filter/multistep_filter_ui_delegate_impl_unittest.cc
  • M chrome/browser/multistep_filter/ui/filter_ui_controller.cc
  • M chrome/browser/multistep_filter/ui/filter_ui_controller.h
  • M chrome/browser/multistep_filter/ui/filter_ui_controller_test_api.h
  • M chrome/browser/multistep_filter/ui/filter_ui_controller_unittest.cc
  • M components/multistep_filter/content/content_filter_navigation_observer_unittest.cc
  • M components/multistep_filter/core/filter_tab_controller.cc
  • M components/multistep_filter/core/filter_tab_controller.h
  • M components/multistep_filter/core/filter_tab_controller_unittest.cc
  • M components/multistep_filter/core/multistep_filter_ui_delegate.h
Change size: L
Delta: 14 files changed, 313 insertions(+), 187 deletions(-)
Open in Gerrit

Related details

Attention set is empty
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: newchange
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: If38b1936d05d8117109da96ed055d35a0c0eb8c0
Gerrit-Change-Number: 8065259
Gerrit-PatchSet: 1
Gerrit-Owner: Aditya Gupta <adi...@google.com>
satisfied_requirement
unsatisfied_requirement
open
diffy

Dominic Battré (Gerrit)

unread,
Jul 9, 2026, 11:20:21 AM (20 hours ago) Jul 9
to Aditya Gupta, Chromium LUCI CQ, chromium...@chromium.org, droger+w...@chromium.org
Attention needed from Aditya Gupta

Dominic Battré added 11 comments

File chrome/browser/multistep_filter/chrome_filter_navigation_observer_unittest.cc
Line 187, Patchset 4: OnSuggestionGenerated(testing::Optional(suggestion), testing::_));
Dominic Battré . unresolved
```suggestion
OnSuggestionGenerated(testing::Optional(suggestion), _));
```
File chrome/browser/multistep_filter/multistep_filter_ui_delegate_impl.h
Line 25, Patchset 4: ~MultistepFilterUiDelegateImpl() override = default;
Dominic Battré . unresolved

The `= default` should go back to the .cc file.

File chrome/browser/multistep_filter/ui/filter_ui_controller.h
Line 86, Patchset 4: // Callbacks to notify the core of user interactions with this suggestion.
Dominic Battré . unresolved

about

File chrome/browser/multistep_filter/ui/filter_ui_controller.cc
Line 419, Patchset 4: case SuggestionViewState::kInactive: {
Dominic Battré . unresolved

here and below: these {} are not needed, right?

Line 431, Patchset 4: if (suggestion_state_->callbacks.on_suggestion_shown) {
std::move(suggestion_state_->callbacks.on_suggestion_shown).Run();
}
Dominic Battré . unresolved

in the `case` below you first do the logging and then the callback. Is there a reason not to have a consistent order?

File components/multistep_filter/core/filter_tab_controller.h
Line 96, Patchset 4: // Called when the user interacts with a suggestion.
Dominic Battré . unresolved

"the suggestion UI."?

File components/multistep_filter/core/multistep_filter_ui_delegate.h
Line 38, Patchset 4: virtual void OnSuggestionGenerated(
Dominic Battré . unresolved

I think that if you rename this to "ShowSuggestions" the whole concept with the callbacks becomes a bit more obvious.

Line 28, Patchset 4: base::OnceCallback<void(SuggestionUserDecision)> on_suggestion_interaction;
Dominic Battré . unresolved

base::RepeatedCallback?

Line 28, Patchset 4: base::OnceCallback<void(SuggestionUserDecision)> on_suggestion_interaction;
Dominic Battré . unresolved

on_user_iteraction?

Line 27, Patchset 4: base::OnceClosure on_suggestion_reopened;
Dominic Battré . unresolved

Is this a onetime callback or can this happen multiple times, which would mean 1) `base::RepeatedCallback` and 2) no use of `std::move(...)`?

Line 25, Patchset 4: struct SuggestionInteractionCallbacks {
Dominic Battré . unresolved

SuggestionUiCallbacks?

Open in Gerrit

Related details

Attention is currently required from:
  • Aditya Gupta
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: If38b1936d05d8117109da96ed055d35a0c0eb8c0
    Gerrit-Change-Number: 8065259
    Gerrit-PatchSet: 4
    Gerrit-Owner: Aditya Gupta <adi...@google.com>
    Gerrit-Reviewer: Aditya Gupta <adi...@google.com>
    Gerrit-Reviewer: Dominic Battré <bat...@chromium.org>
    Gerrit-Attention: Aditya Gupta <adi...@google.com>
    Gerrit-Comment-Date: Thu, 09 Jul 2026 15:20:05 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Dominic Battré (Gerrit)

    unread,
    Jul 9, 2026, 11:30:14 AM (20 hours ago) Jul 9
    to Aditya Gupta, Chromium LUCI CQ, chromium...@chromium.org, droger+w...@chromium.org
    Attention needed from Aditya Gupta

    Dominic Battré added 2 comments

    File components/multistep_filter/core/filter_tab_controller_unittest.cc
    Line 583, Patchset 5 (Latest): .WillOnce(
    [&captured_callbacks](
    std::optional<UrlFilterSuggestion> suggestion,
    MultistepFilterUiDelegate::SuggestionInteractionCallbacks
    callbacks) { captured_callbacks = std::move(callbacks); });
    Dominic Battré . unresolved

    How about this:

    ```suggestion
    .WillOnce(SaveArgByMove<1>(&captured_callbacks));
    ```

    Maybe you could also use a TestFuture... something like the following (I am not sure if I got the syntax right).

    ```
    base::TestFuture<void, std::optional<UrlFilterSuggestion>,
    MultistepFilterUiDelegate::SuggestionInteractionCallbacks> future.
    EXPECT_CALL(*mock_delegate_,
    OnSuggestionGenerated(std::optional(expected_suggestion), _))
    .WillOnce(InvokeFuture(future));

    ...

    std::move(future.Get<2>().on_suggestion_shown).Run();
    ```

    Line 603, Patchset 5 (Latest): std::move(captured_callbacks.on_suggestion_shown).Run();
    Dominic Battré . unresolved

    This crashes the entire test process in case the callback did not happen.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Aditya Gupta
    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: If38b1936d05d8117109da96ed055d35a0c0eb8c0
    Gerrit-Change-Number: 8065259
    Gerrit-PatchSet: 5
    Gerrit-Owner: Aditya Gupta <adi...@google.com>
    Gerrit-Reviewer: Aditya Gupta <adi...@google.com>
    Gerrit-Reviewer: Dominic Battré <bat...@chromium.org>
    Gerrit-Attention: Aditya Gupta <adi...@google.com>
    Gerrit-Comment-Date: Thu, 09 Jul 2026 15:29:58 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Aditya Gupta (Gerrit)

    unread,
    Jul 9, 2026, 12:00:29 PM (19 hours ago) Jul 9
    to Dominic Battré, Chromium LUCI CQ, chromium...@chromium.org, droger+w...@chromium.org
    Attention needed from Dominic Battré

    Aditya Gupta voted and added 13 comments

    Votes added by Aditya Gupta

    Commit-Queue+1

    13 comments

    File chrome/browser/multistep_filter/chrome_filter_navigation_observer_unittest.cc
    Line 187, Patchset 4: OnSuggestionGenerated(testing::Optional(suggestion), testing::_));
    Dominic Battré . resolved
    ```suggestion
    OnSuggestionGenerated(testing::Optional(suggestion), _));
    ```
    Aditya Gupta

    Done

    File chrome/browser/multistep_filter/multistep_filter_ui_delegate_impl.h
    Line 25, Patchset 4: ~MultistepFilterUiDelegateImpl() override = default;
    Dominic Battré . resolved

    The `= default` should go back to the .cc file.

    Aditya Gupta

    Done

    File chrome/browser/multistep_filter/ui/filter_ui_controller.h
    Line 86, Patchset 4: // Callbacks to notify the core of user interactions with this suggestion.
    Dominic Battré . resolved

    about

    Aditya Gupta

    Done

    File chrome/browser/multistep_filter/ui/filter_ui_controller.cc
    Line 419, Patchset 4: case SuggestionViewState::kInactive: {
    Dominic Battré . resolved

    here and below: these {} are not needed, right?

    Aditya Gupta

    Done

    Line 431, Patchset 4: if (suggestion_state_->callbacks.on_suggestion_shown) {
    std::move(suggestion_state_->callbacks.on_suggestion_shown).Run();
    }
    Dominic Battré . resolved

    in the `case` below you first do the logging and then the callback. Is there a reason not to have a consistent order?

    Aditya Gupta

    Done

    File components/multistep_filter/core/filter_tab_controller.h
    Line 96, Patchset 4: // Called when the user interacts with a suggestion.
    Dominic Battré . resolved

    "the suggestion UI."?

    Aditya Gupta

    Done

    File components/multistep_filter/core/filter_tab_controller_unittest.cc

    [&captured_callbacks](
    std::optional<UrlFilterSuggestion> suggestion,
    MultistepFilterUiDelegate::SuggestionInteractionCallbacks
    callbacks) { captured_callbacks = std::move(callbacks); });
    Dominic Battré . resolved

    How about this:

    ```suggestion
    .WillOnce(SaveArgByMove<1>(&captured_callbacks));
    ```

    Maybe you could also use a TestFuture... something like the following (I am not sure if I got the syntax right).

    ```
    base::TestFuture<void, std::optional<UrlFilterSuggestion>,
    MultistepFilterUiDelegate::SuggestionInteractionCallbacks> future.
    EXPECT_CALL(*mock_delegate_,
    OnSuggestionGenerated(std::optional(expected_suggestion), _))
    .WillOnce(InvokeFuture(future));

    ...

    std::move(future.Get<2>().on_suggestion_shown).Run();
    ```

    Aditya Gupta

    Done

    Line 603, Patchset 5: std::move(captured_callbacks.on_suggestion_shown).Run();
    Dominic Battré . unresolved

    This crashes the entire test process in case the callback did not happen.

    Aditya Gupta

    Added ASSERT_FALSE(captured_callbacks.on_suggestion_shown.is_null()); before triggering the callback,

    File components/multistep_filter/core/multistep_filter_ui_delegate.h
    Line 38, Patchset 4: virtual void OnSuggestionGenerated(
    Dominic Battré . resolved

    I think that if you rename this to "ShowSuggestions" the whole concept with the callbacks becomes a bit more obvious.

    Aditya Gupta

    I will do that in a separate CL else this CL will add a lot of noise of the renaming.

    Line 28, Patchset 4: base::OnceCallback<void(SuggestionUserDecision)> on_suggestion_interaction;
    Dominic Battré . resolved

    on_user_iteraction?

    Aditya Gupta

    Done

    Line 28, Patchset 4: base::OnceCallback<void(SuggestionUserDecision)> on_suggestion_interaction;
    Dominic Battré . unresolved

    base::RepeatedCallback?

    Aditya Gupta

    Same as above but if you think this is not correct I am happy to set up some time to go over this.

    Line 27, Patchset 4: base::OnceClosure on_suggestion_reopened;
    Dominic Battré . unresolved

    Is this a onetime callback or can this happen multiple times, which would mean 1) `base::RepeatedCallback` and 2) no use of `std::move(...)`?

    Aditya Gupta

    No since we only want to record the metrics once, I choose to make them all OnceCallback, verified that if the callback is null (after making the first call), the check is in place to not call it again. This way I could be confident that the callbacks will be only triggered once for a suggesiton.

    Line 25, Patchset 4: struct SuggestionInteractionCallbacks {
    Dominic Battré . resolved

    SuggestionUiCallbacks?

    Aditya Gupta

    Done

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Dominic Battré
    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: If38b1936d05d8117109da96ed055d35a0c0eb8c0
    Gerrit-Change-Number: 8065259
    Gerrit-PatchSet: 5
    Gerrit-Owner: Aditya Gupta <adi...@google.com>
    Gerrit-Reviewer: Aditya Gupta <adi...@google.com>
    Gerrit-Reviewer: Dominic Battré <bat...@chromium.org>
    Gerrit-Attention: Dominic Battré <bat...@chromium.org>
    Gerrit-Comment-Date: Thu, 09 Jul 2026 16:00:07 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    Comment-In-Reply-To: Dominic Battré <bat...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Dominic Battré (Gerrit)

    unread,
    6:06 AM (1 hour ago) 6:06 AM
    to Aditya Gupta, Chromium LUCI CQ, chromium...@chromium.org, droger+w...@chromium.org
    Attention needed from Aditya Gupta

    Dominic Battré voted and added 6 comments

    Votes added by Dominic Battré

    Code-Review+1

    6 comments

    File components/multistep_filter/core/filter_tab_controller_unittest.cc
    Line 603, Patchset 5: std::move(captured_callbacks.on_suggestion_shown).Run();
    Dominic Battré . resolved

    This crashes the entire test process in case the callback did not happen.

    Aditya Gupta

    Added ASSERT_FALSE(captured_callbacks.on_suggestion_shown.is_null()); before triggering the callback,

    Dominic Battré

    Acknowledged

    File components/multistep_filter/core/multistep_filter_ui_delegate.h
    Line 28, Patchset 7: base::OnceCallback<void(SuggestionUserDecision)> on_user_interaction;
    Dominic Battré . unresolved

    // Called with the final interaction by the user. This can mean for example accepting a suggestion or to ignore it. Unless the user accepts the suggestion or opens settings, the reporting happens when the tab is closed.

    please verify this is correct or fix it.

    Line 27, Patchset 7: base::OnceClosure on_suggestion_reopened;
    Dominic Battré . unresolved

    // Called the first time a suggestion UI is shown after being dismissed/timing out before.

    Line 26, Patchset 7: base::OnceClosure on_suggestion_shown;
    Dominic Battré . unresolved

    // Called the first time a suggestion UI is shown after pageload.

    Line 28, Patchset 4: base::OnceCallback<void(SuggestionUserDecision)> on_suggestion_interaction;
    Dominic Battré . resolved

    base::RepeatedCallback?

    Aditya Gupta

    Same as above but if you think this is not correct I am happy to set up some time to go over this.

    Dominic Battré

    Acknowledged

    Line 27, Patchset 4: base::OnceClosure on_suggestion_reopened;
    Dominic Battré . resolved

    Is this a onetime callback or can this happen multiple times, which would mean 1) `base::RepeatedCallback` and 2) no use of `std::move(...)`?

    Aditya Gupta

    No since we only want to record the metrics once, I choose to make them all OnceCallback, verified that if the callback is null (after making the first call), the check is in place to not call it again. This way I could be confident that the callbacks will be only triggered once for a suggesiton.

    Dominic Battré

    Acknowledged, let's document this.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Aditya Gupta
    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: If38b1936d05d8117109da96ed055d35a0c0eb8c0
    Gerrit-Change-Number: 8065259
    Gerrit-PatchSet: 7
    Gerrit-Owner: Aditya Gupta <adi...@google.com>
    Gerrit-Reviewer: Aditya Gupta <adi...@google.com>
    Gerrit-Reviewer: Dominic Battré <bat...@chromium.org>
    Gerrit-Attention: Aditya Gupta <adi...@google.com>
    Gerrit-Comment-Date: Fri, 10 Jul 2026 10:05:43 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    Comment-In-Reply-To: Dominic Battré <bat...@chromium.org>
    Comment-In-Reply-To: Aditya Gupta <adi...@google.com>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Dominic Battré (Gerrit)

    unread,
    6:14 AM (1 hour ago) 6:14 AM
    to Aditya Gupta, Chromium LUCI CQ, chromium...@chromium.org, droger+w...@chromium.org
    Attention needed from Aditya Gupta

    Dominic Battré voted and added 1 comment

    Votes added by Dominic Battré

    Code-Review+1

    1 comment

    File components/multistep_filter/core/filter_tab_controller_unittest.cc
    Line 606, Patchset 8 (Latest): // 2. Verify on_suggestion_interaction callback.
    Dominic Battré . unresolved

    on_user_interaction

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Aditya Gupta
    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: If38b1936d05d8117109da96ed055d35a0c0eb8c0
    Gerrit-Change-Number: 8065259
    Gerrit-PatchSet: 8
    Gerrit-Owner: Aditya Gupta <adi...@google.com>
    Gerrit-Reviewer: Aditya Gupta <adi...@google.com>
    Gerrit-Reviewer: Dominic Battré <bat...@chromium.org>
    Gerrit-Attention: Aditya Gupta <adi...@google.com>
    Gerrit-Comment-Date: Fri, 10 Jul 2026 10:14:03 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Dominic Battré (Gerrit)

    unread,
    7:09 AM (10 minutes ago) 7:09 AM
    to Aditya Gupta, Chromium LUCI CQ, chromium...@chromium.org, droger+w...@chromium.org
    Attention needed from Aditya Gupta

    Dominic Battré added 1 comment

    File chrome/browser/multistep_filter/multistep_filter_ui_delegate_impl_unittest.cc
    Line 97, Patchset 8 (Latest): OnSuggestionGenerated(testing::Optional(suggestion), testing::_));
    Dominic Battré . unresolved

    delete

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Aditya Gupta
    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: If38b1936d05d8117109da96ed055d35a0c0eb8c0
    Gerrit-Change-Number: 8065259
    Gerrit-PatchSet: 8
    Gerrit-Owner: Aditya Gupta <adi...@google.com>
    Gerrit-Reviewer: Aditya Gupta <adi...@google.com>
    Gerrit-Reviewer: Dominic Battré <bat...@chromium.org>
    Gerrit-Attention: Aditya Gupta <adi...@google.com>
    Gerrit-Comment-Date: Fri, 10 Jul 2026 11:08:54 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy
    Reply all
    Reply to author
    Forward
    0 new messages