Scope Android autofill candidates
ci / lint-test (pull_request) Successful in 5m45s
ci / build (pull_request) Successful in 6m19s

This commit is contained in:
Joe Julian
2026-04-27 19:50:55 -07:00
parent 586de0169d
commit d18627cda4
4 changed files with 196 additions and 30 deletions
@@ -10,6 +10,9 @@ public final class AutofillCacheStoreBehaviorTest {
testChooserCandidatesCollapseToExactAndroidAppMatch();
testChooserCandidatesStayScopedToExactHostMatches();
testChooserCandidatesStayScopedToParentHostMatches();
testCacheStoreChooserCandidatesStayScopedToExactHostMatches();
testCacheStoreChooserCandidatesFallBackToAllEntriesOnlyWhenUnrelated();
testCacheStoreRelevantCandidatesDoNotFallBackToAllEntries();
}
private static void testFindBestMatchUsesAndroidAppTargets() {
@@ -128,6 +131,103 @@ public final class AutofillCacheStoreBehaviorTest {
}
}
private static void testCacheStoreChooserCandidatesStayScopedToExactHostMatches() {
List<AutofillCacheStore.Entry> entries = new ArrayList<>();
entries.add(new AutofillCacheStore.Entry(
"bellagio-primary",
"Bellagio Primary",
"dannyocean",
"vault-code",
"bellagio.example.invalid",
"https://bellagio.example.invalid/login",
Arrays.asList("https://bellagio.example.invalid/login"),
Arrays.asList("Crew", "Internet")
));
entries.add(new AutofillCacheStore.Entry(
"bellagio-backup",
"Bellagio Backup",
"rustyryan",
"backup-code",
"bellagio.example.invalid",
"https://bellagio.example.invalid/admin",
Arrays.asList("https://bellagio.example.invalid/admin"),
Arrays.asList("Crew", "Internet")
));
entries.add(new AutofillCacheStore.Entry(
"night-fox-entry",
"Night Fox",
"nightfox",
"vault-code",
"gitlab.com",
"https://gitlab.com",
Arrays.asList("https://gitlab.com"),
Arrays.asList("Crew", "Internet")
));
List<AutofillCacheStore.Entry> got = AutofillCacheStore.chooserCandidatesFromEntries(entries, "https://bellagio.example.invalid/security");
if (got.size() != 2 || !containsStoreIDs(got, "bellagio-primary", "bellagio-backup")) {
throw new AssertionError("AutofillCacheStore chooser candidates = " + describeStore(got) + ", want only Bellagio entries");
}
}
private static void testCacheStoreChooserCandidatesFallBackToAllEntriesOnlyWhenUnrelated() {
List<AutofillCacheStore.Entry> entries = new ArrayList<>();
entries.add(new AutofillCacheStore.Entry(
"bellagio-primary",
"Bellagio Primary",
"dannyocean",
"vault-code",
"bellagio.example.invalid",
"https://bellagio.example.invalid/login",
Arrays.asList("https://bellagio.example.invalid/login"),
Arrays.asList("Crew", "Internet")
));
entries.add(new AutofillCacheStore.Entry(
"night-fox-entry",
"Night Fox",
"nightfox",
"vault-code",
"gitlab.com",
"https://gitlab.com",
Arrays.asList("https://gitlab.com"),
Arrays.asList("Crew", "Internet")
));
List<AutofillCacheStore.Entry> got = AutofillCacheStore.chooserCandidatesFromEntries(entries, "https://tessio.example.invalid/login");
if (got.size() != 2 || !containsStoreIDs(got, "bellagio-primary", "night-fox-entry")) {
throw new AssertionError("AutofillCacheStore unrelated chooser candidates = " + describeStore(got) + ", want full fallback list");
}
}
private static void testCacheStoreRelevantCandidatesDoNotFallBackToAllEntries() {
List<AutofillCacheStore.Entry> entries = new ArrayList<>();
entries.add(new AutofillCacheStore.Entry(
"bellagio-primary",
"Bellagio Primary",
"dannyocean",
"vault-code",
"bellagio.example.invalid",
"https://bellagio.example.invalid/login",
Arrays.asList("https://bellagio.example.invalid/login"),
Arrays.asList("Crew", "Internet")
));
entries.add(new AutofillCacheStore.Entry(
"night-fox-entry",
"Night Fox",
"nightfox",
"vault-code",
"gitlab.com",
"https://gitlab.com",
Arrays.asList("https://gitlab.com"),
Arrays.asList("Crew", "Internet")
));
List<AutofillCacheStore.Entry> got = AutofillCacheStore.relevantCandidatesFromEntries(entries, "https://tessio.example.invalid/login");
if (!got.isEmpty()) {
throw new AssertionError("AutofillCacheStore relevant unrelated candidates = " + describeStore(got) + ", want []");
}
}
private static String describe(AutofillTargetMatcher.Entry entry) {
if (entry == null) {
return "null";
@@ -150,4 +250,20 @@ public final class AutofillCacheStoreBehaviorTest {
}
return ids.containsAll(Arrays.asList(wantIDs)) && ids.size() == wantIDs.length;
}
private static String describeStore(List<AutofillCacheStore.Entry> entries) {
List<String> ids = new ArrayList<>();
for (AutofillCacheStore.Entry entry : entries) {
ids.add(entry.id);
}
return ids.toString();
}
private static boolean containsStoreIDs(List<AutofillCacheStore.Entry> entries, String... wantIDs) {
List<String> ids = new ArrayList<>();
for (AutofillCacheStore.Entry entry : entries) {
ids.add(entry.id);
}
return ids.containsAll(Arrays.asList(wantIDs)) && ids.size() == wantIDs.length;
}
}