0

Remove bootstrapping for AutofillAi

The current iteration of AutofillAi only contains data that is not
already contained in "classic" Autofill sources. Therefore
bootstrapping no longer makes sense.

Bug: 395555410
Change-Id: I05368bbc273766426e265c202a922137ba5cb775
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6252831
Reviewed-by: Demetrios Papadopoulos <dpapad@chromium.org>
Commit-Queue: Jan Keitel <jkeitel@google.com>
Reviewed-by: Devlin Cronin <rdevlin.cronin@chromium.org>
Reviewed-by: Justin Lulejian <jlulejian@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1419712}
This commit is contained in:
Jan Keitel
2025-02-12 22:47:37 -08:00
committed by Chromium LUCI CQ
parent b6775457d1
commit a6e998da2b
15 changed files with 3 additions and 337 deletions
chrome
components/autofill_ai/core/browser
extensions/browser
tools
metrics
histograms
metadata
extensions
typescript

@ -1047,62 +1047,6 @@ void AutofillPrivateDeleteUserAnnotationsEntryFunction::OnEntryDeleted() {
Respond(NoArguments());
}
// Triggers bootstrapping using `UserAnnotationsService`. On completion if
// entries were added returns `true` and triggers `maybeShowHelpBubble`,
// otherwise return `false`.
ExtensionFunction::ResponseAction
AutofillPrivateTriggerAnnotationsBootstrappingFunction::Run() {
AddressDataManager* adm = address_data_manager();
if (!adm || !adm->has_initial_load_finished()) {
return RespondNow(Error(kErrorDataUnavailable));
}
std::vector<const autofill::AutofillProfile*> autofill_profiles =
adm->GetProfiles(
autofill::AddressDataManager::ProfileOrder::kHighestFrecencyDesc);
if (autofill_profiles.size() == 0u) {
return RespondNow(WithArguments(false));
}
Profile* profile =
Profile::FromBrowserContext(GetSenderWebContents()->GetBrowserContext());
user_annotations::UserAnnotationsService* user_annotations_service =
profile ? UserAnnotationsServiceFactory::GetForProfile(profile) : nullptr;
if (!user_annotations_service) {
return RespondNow(WithArguments(false));
}
user_annotations_service->SaveAutofillProfile(
*autofill_profiles[0],
base::BindOnce(&AutofillPrivateTriggerAnnotationsBootstrappingFunction::
OnBootstrappingComplete,
this));
return did_respond() ? AlreadyResponded() : RespondLater();
}
void AutofillPrivateTriggerAnnotationsBootstrappingFunction::MaybeShowIPH() {
if (auto* const interface =
BrowserUserEducationInterface::MaybeGetForWebContentsInTab(
GetSenderWebContents())) {
interface->MaybeShowFeaturePromo(
feature_engagement::
kIPHAutofillPredictionImprovementsBootstrappingFeature);
}
}
void AutofillPrivateTriggerAnnotationsBootstrappingFunction::
OnBootstrappingComplete(
user_annotations::UserAnnotationsExecutionResult result) {
if (result == user_annotations::UserAnnotationsExecutionResult::kSuccess) {
// When the new data was added to memories, notify user with the IPH.
MaybeShowIPH();
Respond(WithArguments(true));
return;
}
Respond(WithArguments(false));
}
////////////////////////////////////////////////////////////////////////////////
// AutofillPrivateHasUserAnnotationsEntriesFunction

@ -485,29 +485,6 @@ class AutofillPrivateHasUserAnnotationsEntriesFunction
void OnEntriesRetrieved(user_annotations::UserAnnotationsEntries results);
};
class AutofillPrivateTriggerAnnotationsBootstrappingFunction
: public AutofillPrivateExtensionFunction {
public:
AutofillPrivateTriggerAnnotationsBootstrappingFunction() = default;
AutofillPrivateTriggerAnnotationsBootstrappingFunction(
const AutofillPrivateTriggerAnnotationsBootstrappingFunction&) = delete;
AutofillPrivateTriggerAnnotationsBootstrappingFunction& operator=(
const AutofillPrivateTriggerAnnotationsBootstrappingFunction&) = delete;
DECLARE_EXTENSION_FUNCTION("autofillPrivate.triggerAnnotationsBootstrapping",
AUTOFILLPRIVATE_TRIGGERANNOTATIONSBOOTSTRAPPING)
protected:
~AutofillPrivateTriggerAnnotationsBootstrappingFunction() override = default;
// ExtensionFunction overrides.
ResponseAction Run() override;
private:
void OnBootstrappingComplete(
user_annotations::UserAnnotationsExecutionResult result);
void MaybeShowIPH();
};
class AutofillPrivateIsUserEligibleForAutofillImprovementsFunction
: public AutofillPrivateExtensionFunction {
public:

@ -445,34 +445,5 @@ IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest, AddVirtualCard) {
EXPECT_TRUE(RunAutofillSubtest("addVirtualCard")) << message_;
}
IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest,
TriggerAnnotationsBootstrapping_Success) {
autofill::TestPersonalDataManager& test_personal_data_manager =
static_cast<autofill::TestPersonalDataManager&>(
autofill_client()->GetPersonalDataManager());
autofill::TestAddressDataManager& test_address_data_manager =
test_personal_data_manager.test_address_data_manager();
autofill::AutofillProfile profile = autofill::test::GetFullProfile();
test_address_data_manager.AddProfile(profile);
EXPECT_TRUE(RunAutofillSubtest("TriggerAnnotationsBootstrapping_Success"))
<< message_;
}
IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest,
TriggerAnnotationsBootstrapping_Failure) {
autofill::TestPersonalDataManager& test_personal_data_manager =
static_cast<autofill::TestPersonalDataManager&>(
autofill_client()->GetPersonalDataManager());
autofill::TestAddressDataManager& test_address_data_manager =
test_personal_data_manager.test_address_data_manager();
test_address_data_manager.ClearProfiles();
EXPECT_TRUE(RunAutofillSubtest("TriggerAnnotationsBootstrapping_Failure"))
<< message_;
}
} // namespace
} // namespace extensions

@ -114,29 +114,6 @@ export class SettingsAutofillAiSectionElement extends
private onPrefToggleChanged_() {
this.userAnnotationsManager_.predictionImprovementsIphFeatureUsed();
this.maybeTriggerBootstrapping_();
}
private async maybeTriggerBootstrapping_() {
const bootstrappingDisabled =
!loadTimeData.getBoolean('autofillAiBootstrappingEnabled');
const toggleDisabled = !this.$.prefToggle.checked;
const hasEntries = await this.userAnnotationsManager_.hasEntries();
// Only trigger bootstrapping if the pref was just enabled and there are no
// entries yet.
if (bootstrappingDisabled || this.disabled || toggleDisabled ||
hasEntries) {
return;
}
const entriesAdded =
await this.userAnnotationsManager_.triggerBootstrapping();
// Refresh the list if bootstrapping resulted in new entries being added.
if (entriesAdded) {
this.userAnnotationsEntries_ =
await this.userAnnotationsManager_.getEntries();
}
}
private onDeleteEntryCick_(e: DomRepeatEvent<UserAnnotationsEntry>): void {

@ -38,17 +38,6 @@ export interface UserAnnotationsManagerProxy {
* Notifies user education that the user used the pref.
*/
predictionImprovementsIphFeatureUsed(): void;
/**
* Starts the bootstrapping process for user annotations.
*
* This method is called when the user enables the prediction improvements. It
* will only start the bootstrapping process if the user is eligible and
* doesn't have existing user annotation entries. *
* @return `true` when the bootstrapping process resulted in user annotations
* being added, `false` otherwise.
*/
triggerBootstrapping(): Promise<boolean>;
}
export class UserAnnotationsManagerProxyImpl implements
@ -77,10 +66,6 @@ export class UserAnnotationsManagerProxyImpl implements
chrome.autofillPrivate.predictionImprovementsIphFeatureUsed();
}
triggerBootstrapping(): Promise<boolean> {
return chrome.autofillPrivate.triggerAnnotationsBootstrapping();
}
static getInstance(): UserAnnotationsManagerProxy {
return instance || (instance = new UserAnnotationsManagerProxyImpl());
}

@ -1470,10 +1470,6 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
"autofillAiEnabled",
autofill_ai::IsAutofillAiSupported(profile->GetPrefs()));
html_source->AddBoolean(
"autofillAiBootstrappingEnabled",
base::FeatureList::IsEnabled(autofill_ai::kAutofillAiBootstrapping));
html_source->AddString(
"autofillAiToggleSubLabel",
l10n_util::GetStringFUTF16(

@ -328,7 +328,6 @@ namespace autofillPrivate {
callback GetUserAnnotationsEntriesCallback = void(UserAnnotationsEntry[] items);
callback hasUserAnnotationsEntriesCallback = void(boolean hasEntries);
callback isUserEligibleForAutofillImprovementsCallback = void(boolean eligible);
callback annotationsBootstrappingCallback = void(boolean bootstrapped);
interface Functions {
// Gets currently signed-in user profile info, no value is returned if
@ -462,10 +461,6 @@ namespace autofillPrivate {
// Notifies autofill client about the prediction improvements pre changing.
static void predictionImprovementsIphFeatureUsed();
// Triggers bootstrapping of user annotations. Returns true if
// bootstrapping was successful (entries were added), false otherwise.
static void triggerAnnotationsBootstrapping(annotationsBootstrappingCallback callback);
};
interface Events {

@ -887,20 +887,6 @@ var availableTests = [
chrome.test.succeed();
},
function triggerAnnotationsBootstrapping_ExpectTrue() {
chrome.autofillPrivate.triggerAnnotationsBootstrapping(function(success) {
chrome.test.assertTrue(success, 'Expected bootstrapping to succeed');
chrome.test.succeed();
});
},
function triggerAnnotationsBootstrapping_ExpectFalse() {
chrome.autofillPrivate.triggerAnnotationsBootstrapping(function(success) {
chrome.test.assertFalse(success, 'Expected bootstrapping to fail');
chrome.test.succeed();
});
},
function logServerIbanLinkClicked() {
chrome.autofillPrivate.logServerIbanLinkClicked();
chrome.test.assertNoLastError();
@ -961,10 +947,6 @@ var TESTS_FOR_CONFIG = {
'addVirtualCard': ['addVirtualCard'],
'removeVirtualCard': ['removeVirtualCard'],
'setAutofillSyncToggleEnabled': ['setAutofillSyncToggleEnabled'],
'TriggerAnnotationsBootstrapping_Success':
['triggerAnnotationsBootstrapping_ExpectTrue'],
'TriggerAnnotationsBootstrapping_Failure':
['triggerAnnotationsBootstrapping_ExpectFalse'],
'logServerIbanLinkClicked': ['logServerIbanLinkClicked'],
};

@ -5,7 +5,6 @@
// clang-format off
import 'chrome://settings/settings.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
import {assertTrue, assertEquals} from 'chrome://webui-test/chai_assert.js';
import type {SettingsSimpleConfirmationDialogElement, SettingsAutofillAiSectionElement} from 'chrome://settings/lazy_load.js';
@ -215,144 +214,3 @@ suite('AutofillAiSectionUiTest', function() {
'The "no entries" message shows up when the list is empty');
});
});
suite('AutofillAiSectionToggleTest', function() {
let section: SettingsAutofillAiSectionElement;
let userAnnotationManager: TestUserAnnotationsManagerProxyImpl;
setup(async function() {
document.body.innerHTML = window.trustedTypes!.emptyHTML;
loadTimeData.overrideValues({autofillAiBootstrappingEnabled: true});
userAnnotationManager = new TestUserAnnotationsManagerProxyImpl();
UserAnnotationsManagerProxyImpl.setInstance(userAnnotationManager);
section = document.createElement('settings-autofill-ai-section');
section.prefs = {
autofill: {
prediction_improvements: {
enabled: {
key: 'autofill.prediction_improvements.enabled',
type: chrome.settingsPrivate.PrefType.BOOLEAN,
value: false,
},
},
},
};
document.body.appendChild(section);
await flushTasks();
});
test('testTriggerBootstrappingCalledWhenConditionsMet', async function() {
loadTimeData.overrideValues({autofillAiBootstrappingEnabled: true});
userAnnotationManager.setEntries([]);
userAnnotationManager.reset();
section.$.prefToggle.click();
await flushTasks();
await userAnnotationManager.whenCalled('hasEntries');
await userAnnotationManager.whenCalled('triggerBootstrapping');
assertEquals(
1, userAnnotationManager.getCallCount('triggerBootstrapping'),
'triggerBootstrapping should be called when all conditions are met');
});
test(
'testTriggerBootstrappingNotCalledWhenBootstrappingDisabled',
async function() {
loadTimeData.overrideValues({autofillAiBootstrappingEnabled: false});
userAnnotationManager.setEntries([]);
userAnnotationManager.reset();
section.$.prefToggle.click();
await flushTasks();
await userAnnotationManager.whenCalled('hasEntries');
assertEquals(
0, userAnnotationManager.getCallCount('triggerBootstrapping'),
'triggerBootstrapping shouldn\'t be called if feature is disabled');
});
test('testTriggerBootstrappingNotCalledWhenToggleDisabled', async function() {
loadTimeData.overrideValues({autofillAiBootstrappingEnabled: true});
userAnnotationManager.setEntries([]);
userAnnotationManager.reset();
section.setPrefValue('autofill.prediction_improvements.enabled', true);
await flushTasks();
section.$.prefToggle.click();
await flushTasks();
await userAnnotationManager.whenCalled('hasEntries');
assertEquals(
0, userAnnotationManager.getCallCount('triggerBootstrapping'),
'triggerBootstrapping should not be called when toggle is disabled');
});
test('testTriggerBootstrappingNotCalledWhenHasEntries', async function() {
loadTimeData.overrideValues({autofillAiBootstrappingEnabled: true});
userAnnotationManager.setEntries([
{
entryId: 1,
key: 'Test Key',
value: 'Test Value',
},
]);
userAnnotationManager.reset();
section.$.prefToggle.click();
await flushTasks();
await userAnnotationManager.whenCalled('hasEntries');
assertEquals(
0, userAnnotationManager.getCallCount('triggerBootstrapping'),
'triggerBootstrapping should not be called when entries exist');
});
test('testTriggerBootstrappingNotCalledWhenComponentDisabled', async function() {
loadTimeData.overrideValues({autofillAiBootstrappingEnabled: true});
userAnnotationManager.setEntries([]);
userAnnotationManager.reset();
section.disabled = true;
section.$.prefToggle.click();
await flushTasks();
assertEquals(
0, userAnnotationManager.getCallCount('triggerBootstrapping'),
'triggerBootstrapping should not be called when component is disabled');
});
test('testGetEntriesCalledWhenBootstrappingAddsEntries', async function() {
loadTimeData.overrideValues({autofillAiBootstrappingEnabled: true});
userAnnotationManager.setEntries([]);
userAnnotationManager.setEntriesBootstrapped(true);
userAnnotationManager.reset();
section.$.prefToggle.click();
await flushTasks();
await userAnnotationManager.whenCalled('hasEntries');
await userAnnotationManager.whenCalled('triggerBootstrapping');
await userAnnotationManager.whenCalled('getEntries');
assertEquals(
1, userAnnotationManager.getCallCount('getEntries'),
'getEntries should be called if bootstrapping added entries');
});
});

@ -8,7 +8,6 @@ import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
export class TestUserAnnotationsManagerProxyImpl extends TestBrowserProxy
implements UserAnnotationsManagerProxy {
private entries_: chrome.autofillPrivate.UserAnnotationsEntry[] = [];
private entriesBootstrapped_: boolean = false;
private eligible_: boolean = true;
constructor() {
@ -16,7 +15,6 @@ export class TestUserAnnotationsManagerProxyImpl extends TestBrowserProxy
'getEntries',
'deleteEntry',
'deleteAllEntries',
'triggerBootstrapping',
'hasEntries',
'isUserEligible',
'predictionImprovementsIphFeatureUsed',
@ -27,10 +25,6 @@ export class TestUserAnnotationsManagerProxyImpl extends TestBrowserProxy
this.entries_ = entries;
}
setEntriesBootstrapped(entriesBootstrapped: boolean): void {
this.entriesBootstrapped_ = entriesBootstrapped;
}
setEligibility(isEligible: boolean): void {
this.eligible_ = isEligible;
}
@ -48,11 +42,6 @@ export class TestUserAnnotationsManagerProxyImpl extends TestBrowserProxy
this.methodCalled('deleteAllEntries');
}
triggerBootstrapping(): Promise<boolean> {
this.methodCalled('triggerBootstrapping');
return Promise.resolve(this.entriesBootstrapped_);
}
hasEntries(): Promise<boolean> {
this.methodCalled('hasEntries');
return Promise.resolve(this.entries_.length > 0);

@ -18,11 +18,6 @@ namespace autofill_ai {
// predicted.
BASE_FEATURE(kAutofillAi, "AutofillAi", base::FEATURE_DISABLED_BY_DEFAULT);
// Bootstrap autofill prediction while opt-ing in for improvements.
BASE_FEATURE(kAutofillAiBootstrapping,
"AutofillAiBootstrapping",
base::FEATURE_DISABLED_BY_DEFAULT);
bool IsAutofillAiSupported(const PrefService* prefs) {
constexpr bool is_supported_platform = BUILDFLAG(IS_CHROMEOS) ||
BUILDFLAG(IS_LINUX) ||

@ -16,9 +16,6 @@ namespace autofill_ai {
// TODO(crbug.com/395555410): Remove.
BASE_DECLARE_FEATURE(kAutofillAi);
// TODO(crbug.com/395555410): Remove.
BASE_DECLARE_FEATURE(kAutofillAiBootstrapping);
inline constexpr base::FeatureParam<base::TimeDelta> kExecutionTimeout{
&kAutofillAi, /*name=*/"execution_timeout",
/*default_value=*/base::Seconds(10)};

@ -1969,7 +1969,7 @@ enum HistogramValue {
AUTOFILLPRIVATE_HASUSERANNOTATIONSENTRIES = 1907,
AUTOFILLPRIVATE_ISUSERELIGIBLEFORAUTOFILLIMPROVEMENTS = 1908,
AUTOFILLPRIVATE_PREDICTIONIMPROVEMENTSIPHFFEATUREUSED = 1909,
AUTOFILLPRIVATE_TRIGGERANNOTATIONSBOOTSTRAPPING = 1910,
DELETED_AUTOFILLPRIVATE_TRIGGERANNOTATIONSBOOTSTRAPPING = 1910,
ACCESSIBILITY_PRIVATE_ENABLEDRAGEVENTREWRITER = 1911,
TTSENGINE_UPDATELANGUAGE = 1912,
ODFSCONFIGPRIVATE_OPENINOFFICEAPP = 1913,

@ -2780,7 +2780,8 @@ Called by update_extension_histograms.py.-->
label="AUTOFILLPRIVATE_ISUSERELIGIBLEFORAUTOFILLIMPROVEMENTS"/>
<int value="1909"
label="AUTOFILLPRIVATE_PREDICTIONIMPROVEMENTSIPHFFEATUREUSED"/>
<int value="1910" label="AUTOFILLPRIVATE_TRIGGERANNOTATIONSBOOTSTRAPPING"/>
<int value="1910"
label="DELETED_AUTOFILLPRIVATE_TRIGGERANNOTATIONSBOOTSTRAPPING"/>
<int value="1911" label="ACCESSIBILITY_PRIVATE_ENABLEDRAGEVENTREWRITER"/>
<int value="1912" label="TTSENGINE_UPDATELANGUAGE"/>
<int value="1913" label="ODFSCONFIGPRIVATE_OPENINOFFICEAPP"/>

@ -229,7 +229,6 @@ declare global {
export function bulkDeleteAllCvcs(): void;
export function setAutofillSyncToggleEnabled(enabled: boolean): void;
export function hasUserAnnotationsEntries(): Promise<boolean>;
export function triggerAnnotationsBootstrapping(): Promise<boolean>;
export function isUserEligibleForAutofillImprovements(): Promise<boolean>;
export function getUserAnnotationsEntries():
Promise<UserAnnotationsEntry[]>;