blob: 1c0c2619656d8a7b387514cbf95a2d85ce955bdb [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.base.shared_preferences;
import com.google.common.collect.Sets;
import org.chromium.base.ResettersForTesting;
import org.chromium.build.BuildConfig;
import org.chromium.build.annotations.CheckDiscard;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Ensures that all {@link PreferenceKeyRegistry}s used are known.
*
* A complement to ChromePreferenceKeysTest, which ensures that preference keys across all known
* registries are unique.
*
* This checking is done in tests in which |initializeKnownRegistries()| is called, which happens
* during browser process initialization.
*/
@CheckDiscard("Preference key checking should only happen on build with asserts")
public class KnownPreferenceKeyRegistries {
private static Set<PreferenceKeyRegistry> sKnownRegistries;
private static Set<PreferenceKeyRegistry> sRegistriesUsedBeforeInitialization = new HashSet<>();
public static void onRegistryUsed(PreferenceKeyRegistry registry) {
if (!BuildConfig.ENABLE_ASSERTS) {
return;
}
if (sKnownRegistries == null) {
// Before initialization, keep track of registries used.
sRegistriesUsedBeforeInitialization.add(registry);
} else {
// After initialization, check if registry is known.
if (!sKnownRegistries.contains(registry)) {
String message =
"An unknown registry was used, PreferenceKeyRegistries must be declared as "
+ "known in AllPreferenceKeyRegistries: "
+ String.join(",", registry.toDebugString());
assert false : message;
}
}
}
public static void initializeKnownRegistries(Set<PreferenceKeyRegistry> knownRegistries) {
if (!BuildConfig.ENABLE_ASSERTS) {
return;
}
if (sKnownRegistries != null) {
// Double initialization; make sure new known registries are the same.
assert sKnownRegistries.equals(knownRegistries);
return;
}
// Check that each registry already used is known; assert otherwise.
Set<PreferenceKeyRegistry> unknownRegistries =
Sets.difference(sRegistriesUsedBeforeInitialization, knownRegistries);
if (!unknownRegistries.isEmpty()) {
List<String> unknownRegistryNames = new ArrayList<>();
for (PreferenceKeyRegistry unknownRegistry : unknownRegistries) {
unknownRegistryNames.add(unknownRegistry.toDebugString());
}
String message =
"Unknown registries were used, PreferenceKeyRegistries must be declared as "
+ "known in AllPreferenceKeyRegistries: "
+ String.join(",", unknownRegistryNames);
assert false : message;
}
sKnownRegistries = knownRegistries;
sRegistriesUsedBeforeInitialization = null;
}
static void clearForTesting() {
Set<PreferenceKeyRegistry> previousKnownRegistries = sKnownRegistries;
Set<PreferenceKeyRegistry> registriesUsedBeforeInitialization =
sRegistriesUsedBeforeInitialization;
ResettersForTesting.register(
() -> {
sKnownRegistries = previousKnownRegistries;
sRegistriesUsedBeforeInitialization = registriesUsedBeforeInitialization;
});
sKnownRegistries = null;
sRegistriesUsedBeforeInitialization = new HashSet<>();
}
}