blob: 770b1f39f07586756bcc3d83edb1dbc7ce1a6404 [file] [log] [blame]
// 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.
#include "chrome/browser/autofill/manual_filling_controller_impl.h"
#include <map>
#include <memory>
#include <string>
#include <utility>
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "chrome/browser/autofill/accessory_controller.h"
#include "chrome/browser/autofill/manual_filling_view_interface.h"
#include "chrome/browser/autofill/mock_address_accessory_controller.h"
#include "chrome/browser/autofill/mock_credit_card_accessory_controller.h"
#include "chrome/browser/autofill/mock_manual_filling_view.h"
#include "chrome/browser/autofill/mock_password_accessory_controller.h"
#include "chrome/browser/password_manager/android/password_accessory_controller.h"
#include "chrome/test/base/testing_profile.h"
#include "components/autofill/core/browser/ui/accessory_sheet_data.h"
#include "components/autofill/core/browser/ui/accessory_sheet_enums.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/password_manager/core/common/password_manager_features.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_web_contents_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace {
using autofill::AccessoryAction;
using autofill::AccessorySheetData;
using autofill::AccessoryTabType;
using autofill::mojom::FocusedFieldType;
using testing::_;
using testing::AnyNumber;
using testing::AtLeast;
using testing::NiceMock;
using testing::Return;
using testing::SaveArg;
using testing::StrictMock;
using testing::WithArgs;
using FillingSource = ManualFillingController::FillingSource;
using IsFillingSourceAvailable = AccessoryController::IsFillingSourceAvailable;
using WaitForKeyboard = ManualFillingViewInterface::WaitForKeyboard;
using ShouldShowAction = ManualFillingController::ShouldShowAction;
AccessorySheetData empty_passwords_sheet() {
constexpr char16_t kTitle[] = u"Example title";
return AccessorySheetData(AccessoryTabType::PASSWORDS, kTitle);
}
AccessorySheetData filled_passwords_sheet() {
return AccessorySheetData::Builder(AccessoryTabType::PASSWORDS, u"Pwds")
.AddUserInfo("example.com", autofill::UserInfo::IsExactMatch(true))
.AppendField(u"Ben", u"Ben", false, true)
.AppendField(u"S3cur3", u"Ben's PW", true, false)
.Build();
}
AccessorySheetData populate_sheet(AccessoryTabType type) {
constexpr char16_t kTitle[] = u"Suggestions available!";
return AccessorySheetData::Builder(type, kTitle).AddUserInfo().Build();
}
constexpr autofill::FieldRendererId kFocusedFieldId(123);
} // namespace
// Fixture that tests the manual filling experience with the most recent version
// of the keyboard accessory and all its fallback sheets.
class ManualFillingControllerTest : public testing::Test {
public:
ManualFillingControllerTest() = default;
void SetUp() override {
scoped_feature_list_.InitWithFeatures(
/*enabled_features=*/
{autofill::features::kAutofillKeyboardAccessory,
autofill::features::kAutofillManualFallbackAndroid},
/*disabled_features=*/{});
ON_CALL(mock_pwd_controller_, RegisterFillingSourceObserver(_))
.WillByDefault(SaveArg<0>(&pwd_source_observer_));
ON_CALL(mock_cc_controller_, RegisterFillingSourceObserver(_))
.WillByDefault(SaveArg<0>(&cc_source_observer_));
ON_CALL(mock_address_controller_, RegisterFillingSourceObserver(_))
.WillByDefault(SaveArg<0>(&address_source_observer_));
ManualFillingControllerImpl::CreateForWebContentsForTesting(
web_contents(), mock_pwd_controller_.AsWeakPtr(),
mock_address_controller_.AsWeakPtr(), mock_cc_controller_.AsWeakPtr(),
std::make_unique<NiceMock<MockManualFillingView>>());
}
void FocusFieldAndClearExpectations(FocusedFieldType fieldType) {
// Depending on |fieldType|, different calls can be expected. All of them
// are irrelevant during setup.
controller()->NotifyFocusedInputChanged(kFocusedFieldId, fieldType);
testing::Mock::VerifyAndClearExpectations(view());
}
ManualFillingControllerImpl* controller() {
return ManualFillingControllerImpl::FromWebContents(web_contents());
}
content::WebContents* web_contents() { return web_contents_; }
MockManualFillingView* view() {
return static_cast<MockManualFillingView*>(controller()->view());
}
void NotifyPasswordSourceObserver(IsFillingSourceAvailable source_available) {
pwd_source_observer_.Run(&mock_pwd_controller_, source_available);
}
void NotifyCreditCardSourceObserver(
IsFillingSourceAvailable source_available) {
cc_source_observer_.Run(&mock_cc_controller_, source_available);
}
void NotifyAddressSourceObserver(IsFillingSourceAvailable source_available) {
address_source_observer_.Run(&mock_address_controller_, source_available);
}
protected:
base::test::ScopedFeatureList scoped_feature_list_;
content::BrowserTaskEnvironment task_environment_;
TestingProfile profile_;
content::TestWebContentsFactory web_contents_factory_;
raw_ptr<content::WebContents> web_contents_ =
web_contents_factory_.CreateWebContents(&profile_);
NiceMock<MockPasswordAccessoryController> mock_pwd_controller_;
NiceMock<MockAddressAccessoryController> mock_address_controller_;
NiceMock<MockCreditCardAccessoryController> mock_cc_controller_;
AccessoryController::FillingSourceObserver pwd_source_observer_;
AccessoryController::FillingSourceObserver cc_source_observer_;
AccessoryController::FillingSourceObserver address_source_observer_;
};
// Fixture for tests that the old but widely used legacy behavior of the manual
// filling experience. It doesn't expect autofill suggestions and uses only the
// fallback sheets for passwords.
class ManualFillingControllerLegacyTest : public ManualFillingControllerTest {
public:
ManualFillingControllerLegacyTest() = default;
void SetUp() override {
scoped_feature_list_.InitWithFeatures(
/*enabled_features=*/{},
/*disabled_features=*/{
autofill::features::kAutofillEnableManualFallbackForVirtualCards,
autofill::features::kAutofillKeyboardAccessory,
autofill::features::kAutofillManualFallbackAndroid});
ManualFillingControllerImpl::CreateForWebContentsForTesting(
web_contents(), mock_pwd_controller_.AsWeakPtr(),
mock_address_controller_.AsWeakPtr(), mock_cc_controller_.AsWeakPtr(),
std::make_unique<NiceMock<MockManualFillingView>>());
}
};
TEST_F(ManualFillingControllerLegacyTest, IsNotRecreatedForSameWebContents) {
ManualFillingController* initial_controller =
ManualFillingControllerImpl::FromWebContents(web_contents());
EXPECT_NE(nullptr, initial_controller);
ManualFillingControllerImpl::CreateForWebContents(web_contents());
EXPECT_EQ(ManualFillingControllerImpl::FromWebContents(web_contents()),
initial_controller);
}
TEST_F(ManualFillingControllerLegacyTest,
ClosesSheetWhenFocusingUnfillableField) {
EXPECT_CALL(*view(), CloseAccessorySheet());
EXPECT_CALL(*view(), SwapSheetWithKeyboard()).Times(0);
controller()->NotifyFocusedInputChanged(kFocusedFieldId,
FocusedFieldType::kUnfillableElement);
}
TEST_F(ManualFillingControllerLegacyTest,
SwapsWithKeyboardWhenFocusingFillableFields) {
EXPECT_CALL(*view(), CloseAccessorySheet()).Times(0);
EXPECT_CALL(*view(), SwapSheetWithKeyboard());
controller()->NotifyFocusedInputChanged(
kFocusedFieldId, FocusedFieldType::kFillablePasswordField);
}
TEST_F(ManualFillingControllerLegacyTest, ClosesSheetWhenFocusingSearchField) {
EXPECT_CALL(*view(), CloseAccessorySheet());
EXPECT_CALL(*view(), SwapSheetWithKeyboard()).Times(0);
controller()->NotifyFocusedInputChanged(
kFocusedFieldId, FocusedFieldType::kFillableSearchField);
}
TEST_F(ManualFillingControllerLegacyTest, ClosesSheetWhenFocusingTextArea) {
EXPECT_CALL(*view(), CloseAccessorySheet());
EXPECT_CALL(*view(), SwapSheetWithKeyboard()).Times(0);
controller()->NotifyFocusedInputChanged(kFocusedFieldId,
FocusedFieldType::kFillableTextArea);
}
TEST_F(ManualFillingControllerLegacyTest,
AlwaysShowsAccessoryForPasswordFields) {
controller()->RefreshSuggestions(empty_passwords_sheet());
EXPECT_CALL(*view(), Show(WaitForKeyboard(true)));
FocusFieldAndClearExpectations(FocusedFieldType::kFillablePasswordField);
}
TEST_F(ManualFillingControllerTest, ShowsAccessoryForAutofillOnSearchField) {
FocusFieldAndClearExpectations(FocusedFieldType::kFillableSearchField);
EXPECT_CALL(*view(), Show(WaitForKeyboard(true)));
controller()->UpdateSourceAvailability(FillingSource::PASSWORD_FALLBACKS,
/*has_suggestions=*/true);
controller()->UpdateSourceAvailability(FillingSource::AUTOFILL,
/*has_suggestions=*/true);
testing::Mock::VerifyAndClearExpectations(view());
// Hiding autofill hides the accessory because fallbacks alone don't provide
// sufficient value and might be confusing.
EXPECT_CALL(*view(), Hide()).Times(1);
controller()->UpdateSourceAvailability(FillingSource::AUTOFILL,
/*has_suggestions=*/false);
}
TEST_F(ManualFillingControllerLegacyTest, ShowsAccessoryWithSuggestions) {
FocusFieldAndClearExpectations(FocusedFieldType::kFillableUsernameField);
EXPECT_CALL(*view(), Show(WaitForKeyboard(true)));
controller()->RefreshSuggestions(populate_sheet(AccessoryTabType::PASSWORDS));
}
TEST_F(ManualFillingControllerLegacyTest,
ShowsAccessoryForUsernameFieldsEvenWithoutPasswordSuggestions) {
EXPECT_CALL(*view(), Show(WaitForKeyboard(true)));
FocusFieldAndClearExpectations(FocusedFieldType::kFillableUsernameField);
EXPECT_CALL(*view(), Hide()).Times(0);
controller()->RefreshSuggestions(empty_passwords_sheet());
}
TEST_F(ManualFillingControllerLegacyTest,
DoesntShowFallbacksOutsideUsernameInV1) {
FocusFieldAndClearExpectations(FocusedFieldType::kFillableNonSearchField);
EXPECT_CALL(*view(), Hide());
controller()->RefreshSuggestions(populate_sheet(AccessoryTabType::PASSWORDS));
}
TEST_F(ManualFillingControllerTest, ShowsFallbacksOutsideUsernameInV2) {
FocusFieldAndClearExpectations(FocusedFieldType::kFillableNonSearchField);
EXPECT_CALL(*view(), Show(WaitForKeyboard(true)));
controller()->RefreshSuggestions(populate_sheet(AccessoryTabType::PASSWORDS));
}
// TODO(fhorschig): Check for recorded metrics here or similar to this.
TEST_F(ManualFillingControllerLegacyTest,
ShowsAccessoryWhenRefreshingSuggestions) {
FocusFieldAndClearExpectations(FocusedFieldType::kFillableUsernameField);
EXPECT_CALL(*view(), Show(WaitForKeyboard(true)));
controller()->RefreshSuggestions(populate_sheet(AccessoryTabType::PASSWORDS));
}
TEST_F(ManualFillingControllerLegacyTest, ShowsAndHidesAccessoryForPasswords) {
EXPECT_CALL(*view(), Show(WaitForKeyboard(true)));
FocusFieldAndClearExpectations(FocusedFieldType::kFillableUsernameField);
controller()->UpdateSourceAvailability(FillingSource::PASSWORD_FALLBACKS,
/*has_suggestions=*/true);
EXPECT_CALL(*view(), Hide()).Times(0);
controller()->UpdateSourceAvailability(FillingSource::PASSWORD_FALLBACKS,
/*has_suggestions=*/false);
}
TEST_F(ManualFillingControllerTest,
ShowsAccessoryForPasswordsTriggeredByObserver) {
// TODO(crbug.com/1169167): Because the data isn't cached, test that only one
// call to `GetSheetData()` happens.
EXPECT_CALL(mock_pwd_controller_, GetSheetData)
.Times(AtLeast(1))
.WillRepeatedly(Return(filled_passwords_sheet()));
EXPECT_CALL(*view(), OnItemsAvailable(filled_passwords_sheet()))
.Times(AnyNumber());
EXPECT_CALL(*view(), Show(WaitForKeyboard(true)));
NotifyPasswordSourceObserver(IsFillingSourceAvailable(true));
FocusFieldAndClearExpectations(FocusedFieldType::kFillableUsernameField);
EXPECT_CALL(*view(), Hide());
NotifyPasswordSourceObserver(IsFillingSourceAvailable(false));
}
TEST_F(ManualFillingControllerTest,
ShowsAccessoryForAddressesTriggeredByObserver) {
const AccessorySheetData kTestAddressSheet =
populate_sheet(AccessoryTabType::ADDRESSES);
// TODO(crbug.com/1169167): Because the data isn't cached, test that only one
// call to `GetSheetData()` happens.
EXPECT_CALL(mock_address_controller_, GetSheetData)
.Times(AtLeast(1))
.WillRepeatedly(Return(kTestAddressSheet));
EXPECT_CALL(*view(), OnItemsAvailable(kTestAddressSheet)).Times(AnyNumber());
EXPECT_CALL(*view(), Show(WaitForKeyboard(true)));
NotifyAddressSourceObserver(IsFillingSourceAvailable(true));
FocusFieldAndClearExpectations(FocusedFieldType::kFillableNonSearchField);
EXPECT_CALL(*view(), Hide());
NotifyAddressSourceObserver(IsFillingSourceAvailable(false));
}
TEST_F(ManualFillingControllerTest,
ShowsAccessoryForCreditCardsTriggeredByObserver) {
const AccessorySheetData kTestCreditCardSheet =
populate_sheet(AccessoryTabType::CREDIT_CARDS);
// TODO(crbug.com/1169167): Because the data isn't cached, test that only one
// call to `GetSheetData()` happens.
EXPECT_CALL(mock_cc_controller_, GetSheetData)
.Times(AtLeast(1))
.WillRepeatedly(Return(kTestCreditCardSheet));
EXPECT_CALL(*view(), OnItemsAvailable(kTestCreditCardSheet))
.Times(AnyNumber());
EXPECT_CALL(*view(), Show(WaitForKeyboard(true)));
NotifyCreditCardSourceObserver(IsFillingSourceAvailable(true));
FocusFieldAndClearExpectations(FocusedFieldType::kFillableNonSearchField);
EXPECT_CALL(*view(), Hide());
NotifyCreditCardSourceObserver(IsFillingSourceAvailable(false));
}
TEST_F(ManualFillingControllerTest,
ShowsAccessoryForCreditCardsWhenManualFallbackEnabledForVirtualCards) {
base::test::ScopedFeatureList features;
features.InitWithFeatures(/*enabled_features=*/
{autofill::features::
kAutofillEnableManualFallbackForVirtualCards},
/*disabled_features=*/{
autofill::features::kAutofillKeyboardAccessory,
autofill::features::
kAutofillManualFallbackAndroid});
const AccessorySheetData kTestCreditCardSheet =
populate_sheet(AccessoryTabType::CREDIT_CARDS);
// TODO(crbug.com/1169167): Because the data isn't cached, test that only one
// call to `GetSheetData()` happens.
EXPECT_CALL(mock_cc_controller_, GetSheetData)
.Times(AtLeast(1))
.WillRepeatedly(Return(kTestCreditCardSheet));
EXPECT_CALL(*view(), OnItemsAvailable(kTestCreditCardSheet))
.Times(AnyNumber());
EXPECT_CALL(*view(), Show(WaitForKeyboard(true)));
NotifyCreditCardSourceObserver(IsFillingSourceAvailable(true));
FocusFieldAndClearExpectations(FocusedFieldType::kFillableNonSearchField);
EXPECT_CALL(*view(), Hide());
NotifyCreditCardSourceObserver(IsFillingSourceAvailable(false));
}
TEST_F(ManualFillingControllerLegacyTest,
UpdatesCreditCardControllerOnFocusChange) {
EXPECT_CALL(mock_cc_controller_, RefreshSuggestions);
FocusFieldAndClearExpectations(FocusedFieldType::kFillableUsernameField);
}
TEST_F(ManualFillingControllerTest, HidesAccessoryWithoutAvailableSources) {
FocusFieldAndClearExpectations(FocusedFieldType::kFillableNonSearchField);
EXPECT_CALL(*view(), Show(WaitForKeyboard(true))).Times(2);
controller()->UpdateSourceAvailability(FillingSource::PASSWORD_FALLBACKS,
/*has_suggestions=*/true);
controller()->UpdateSourceAvailability(FillingSource::AUTOFILL,
/*has_suggestions=*/true);
// This duplicate call is a noop.
controller()->UpdateSourceAvailability(FillingSource::PASSWORD_FALLBACKS,
/*has_suggestions=*/true);
testing::Mock::VerifyAndClearExpectations(view());
// Hiding just one of two active filling sources won't have any effect at all.
EXPECT_CALL(*view(), Hide()).Times(0);
EXPECT_CALL(*view(), Show(WaitForKeyboard(true))).Times(0);
controller()->UpdateSourceAvailability(FillingSource::PASSWORD_FALLBACKS,
/*has_suggestions=*/false);
testing::Mock::VerifyAndClearExpectations(view());
EXPECT_CALL(*view(), Hide());
controller()->UpdateSourceAvailability(FillingSource::AUTOFILL,
/*has_suggestions=*/false);
}
TEST_F(ManualFillingControllerLegacyTest,
OnAccessoryActionAvailabilityChanged) {
EXPECT_CALL(*view(), OnAccessoryActionAvailabilityChanged(
ShouldShowAction(true),
AccessoryAction::GENERATE_PASSWORD_AUTOMATIC));
controller()->OnAccessoryActionAvailabilityChanged(
ShouldShowAction(true), AccessoryAction::GENERATE_PASSWORD_AUTOMATIC);
EXPECT_CALL(*view(), OnAccessoryActionAvailabilityChanged(
ShouldShowAction(false),
AccessoryAction::GENERATE_PASSWORD_AUTOMATIC));
controller()->OnAccessoryActionAvailabilityChanged(
ShouldShowAction(false), AccessoryAction::GENERATE_PASSWORD_AUTOMATIC);
}
TEST_F(ManualFillingControllerLegacyTest,
OnFillingTriggeredFillsAndClosesSheet) {
const char16_t kTextToFill[] = u"TextToFill";
const std::u16string text_to_fill(kTextToFill);
const autofill::AccessorySheetField field(
/*display_text=*/text_to_fill, /*text_to_fill=*/text_to_fill,
/*a11y_description=*/text_to_fill, /*id=*/"", /*is_obfuscated=*/false,
/*selectable=*/true);
EXPECT_CALL(mock_pwd_controller_,
OnFillingTriggered(autofill::FieldGlobalId(), field));
EXPECT_CALL(*view(), SwapSheetWithKeyboard());
controller()->OnFillingTriggered(AccessoryTabType::PASSWORDS, field);
autofill::FieldGlobalId field_id{autofill::LocalFrameToken(),
kFocusedFieldId};
EXPECT_CALL(mock_pwd_controller_, OnFillingTriggered(field_id, field));
EXPECT_CALL(*view(), SwapSheetWithKeyboard());
controller()->NotifyFocusedInputChanged(
kFocusedFieldId, autofill::mojom::FocusedFieldType::kUnknown);
controller()->OnFillingTriggered(AccessoryTabType::PASSWORDS, field);
}
TEST_F(ManualFillingControllerLegacyTest, RefreshingUpdatesCache) {
// First, focus a field for which suggestions exist.
FocusFieldAndClearExpectations(FocusedFieldType::kFillableUsernameField);
controller()->RefreshSuggestions(populate_sheet(AccessoryTabType::PASSWORDS));
// Now, focus a field (e.g. in an iframe) with different suggestions.
FocusFieldAndClearExpectations(FocusedFieldType::kFillablePasswordField);
controller()->RefreshSuggestions(filled_passwords_sheet());
// Triggering a subsequent (independent) update must reuse the latest sheet.
AccessorySheetData cached(AccessoryTabType::PASSWORDS, std::u16string());
EXPECT_CALL(*view(), OnItemsAvailable).WillOnce(SaveArg<0>(&cached));
FocusFieldAndClearExpectations(FocusedFieldType::kFillablePasswordField);
EXPECT_EQ(cached, filled_passwords_sheet());
}
TEST_F(ManualFillingControllerLegacyTest,
ForwardsPasswordManagingToController) {
EXPECT_CALL(mock_pwd_controller_,
OnOptionSelected(AccessoryAction::MANAGE_PASSWORDS));
controller()->OnOptionSelected(AccessoryAction::MANAGE_PASSWORDS);
}
TEST_F(ManualFillingControllerLegacyTest,
ForwardsPasswordGenerationToController) {
EXPECT_CALL(mock_pwd_controller_,
OnOptionSelected(AccessoryAction::GENERATE_PASSWORD_MANUAL));
controller()->OnOptionSelected(AccessoryAction::GENERATE_PASSWORD_MANUAL);
}
TEST_F(ManualFillingControllerLegacyTest, ForwardsAddressManagingToController) {
EXPECT_CALL(mock_address_controller_,
OnOptionSelected(AccessoryAction::MANAGE_ADDRESSES));
controller()->OnOptionSelected(AccessoryAction::MANAGE_ADDRESSES);
}
TEST_F(ManualFillingControllerLegacyTest,
ForwardsCreditCardManagingToController) {
EXPECT_CALL(mock_cc_controller_,
OnOptionSelected(AccessoryAction::MANAGE_CREDIT_CARDS));
controller()->OnOptionSelected(AccessoryAction::MANAGE_CREDIT_CARDS);
}
TEST_F(ManualFillingControllerLegacyTest, OnAutomaticGenerationRequested) {
EXPECT_CALL(mock_pwd_controller_,
OnOptionSelected(AccessoryAction::GENERATE_PASSWORD_AUTOMATIC));
controller()->OnOptionSelected(AccessoryAction::GENERATE_PASSWORD_AUTOMATIC);
}
TEST_F(ManualFillingControllerLegacyTest, OnManualGenerationRequested) {
EXPECT_CALL(mock_pwd_controller_,
OnOptionSelected(AccessoryAction::GENERATE_PASSWORD_MANUAL));
controller()->OnOptionSelected(AccessoryAction::GENERATE_PASSWORD_MANUAL);
}
TEST_F(ManualFillingControllerLegacyTest, OnSavePasswordsToggledTrue) {
EXPECT_CALL(mock_pwd_controller_,
OnToggleChanged(AccessoryAction::TOGGLE_SAVE_PASSWORDS, true));
controller()->OnToggleChanged(AccessoryAction::TOGGLE_SAVE_PASSWORDS, true);
}
TEST_F(ManualFillingControllerLegacyTest, OnSavePasswordsToggledFalse) {
EXPECT_CALL(mock_pwd_controller_,
OnToggleChanged(AccessoryAction::TOGGLE_SAVE_PASSWORDS, false));
controller()->OnToggleChanged(AccessoryAction::TOGGLE_SAVE_PASSWORDS, false);
}
TEST_F(ManualFillingControllerTest,
ShowsAccessoryWhenAutofillSourceAvailableOnUnknownField) {
FocusFieldAndClearExpectations(FocusedFieldType::kUnknown);
EXPECT_CALL(*view(), Show(WaitForKeyboard(false)));
controller()->UpdateSourceAvailability(FillingSource::AUTOFILL,
/*has_suggestions=*/true);
// Noop duplicate call.
controller()->UpdateSourceAvailability(FillingSource::AUTOFILL,
/*has_suggestions=*/true);
testing::Mock::VerifyAndClearExpectations(view());
EXPECT_CALL(*view(), Hide());
controller()->UpdateSourceAvailability(FillingSource::AUTOFILL,
/*has_suggestions=*/false);
}