the Chromium logo

The Chromium Projects

Preferences and policies

Preferences

What are Preferences?

A Preference is a mechanism to store values across reboots and optionally sync to a profile. We typically use Preferences if we want to store a user selected setting and preserve that across system reboots. Note that these are not the same as a C++ global/singleton variable as those are tied to the lifetime of the program (i.e. Chrome).

There are two forms of preferences, profile and local state.

Profile Preferences - The value is attached to a specific user profile and can be optionally synced. These values are only applied and changed by the current signed in profile. If the preference is synced, it will be available in any device the User signs into. If the profile preference is not synced it stays local to the device.

Local State Preferences - The value is attached to the machine and is not synced to a profile. Since these are not tied to a profile, Local State Preferences are applied to all session states of the device, such as the login screen, and are applied to all signed in profiles.

Tip: If there is a device setting that you only want the device owner (i.e. first user to be added to the device) to change, consider using a CrosSetting. More details on the ownership model here.

Which Preference should I use?

When adding a Preference check on what are the parameters for the value you're storing.

If the value is useful only for a signed in user and makes sense to be synced across different devices (e.g. Wallpaper), then a Profile Preference is probably ideal. If the value is only useful for the current session (e.g. tracking if the user has recently did an action), then it should probably not be a Preference.

If you have a value that you want to preserve across reboots and available in all session states, then a Local State Preference is preferred. Keep in mind that this preference will also be available for all profiles that sign into the device, so please do not store any profile-tied values to a local state pref (some exceptions may apply such as parent-child accounts).

Bottom line is that if there's a value that you want to store and keep across system reboots then Preferences are your best bet, but be sure to pick the correct Preference for your use case.

Preference Implementation

Tip: The following code examples are specific for Ash. Browser based prefs can be seen here. Further documentation on prefs can be found here.

Step 1: Define the preference name

Step 2: Register the Preference

// Static:
void AshAcceleratorConfiguration::RegisterProfilePrefs(
    PrefRegistrySimple* registry) {
  // Local profile pref.
  registry->RegisterDictionaryPref(prefs::kAcceleratorOverrides);

  // Synced profile pref.
  registry->RegisterBooleanPref(
      prefs::kAccessibilityAutoclickStabilizePosition, false,
      user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF)
}
void RegisterProfilePrefs(PrefRegistrySimple* registry, bool for_test) {
  ...
AshAcceleratorConfiguration::RegisterProfilePrefs(registry);
  ...
}

Step 3: Set and Retrieve the Preference

Tip: Preferences store base::Value types, which includes your primitive types but also data structures such as Dictionaries and List.

Retrieving Preference values
// Since this is a Profile pref, we need the active signed in user ID.
AccountId GetActiveAccountId() {
  return ash::Shell::Get()->session_controller()->GetActiveAccountId();
}

// Get the associated PrefService for the current signed in account.
PrefService* GetUserPrefService(const AccountId& account_id) {
  return ash::Shell::Get()->session_controller()->GetUserPrefServiceForUser(
      account_id);
}

// Fetch the pref value.
auto* pref_service = GetUserPrefService(GetActiveAccountId());
const base::Value::Dict& override_prefs =
    pref_service->GetDict(prefs::kAcceleratorOverrides);
Setting Preference values
// Helper function to convert a std::map<T,T> to base::Value::Dict<T,T>
base::Value::Dict CreateAcceleratorOverrides() { ... }

auto* pref_service = GetUserPrefService(GetActiveAccountId());
pref_service->SetDict(prefs::kAcceleratorOverrides,
                      CreateAcceleratorOverrideDict());

Policy

What is a Policy?

A Policy is a configuration rule set that an administrator can enforce to their managed devices. Policies are typically used in either a enterprise or education setting.

In ChromeOS, a device can be managed by an administrator so that they can set specific settings that the user may or may not be able to modify. An infamous example is that there is a policy to disable the Chrome Dinosaur game, which we see used for Chromebooks in education.

Using Policies

Before implementing a policy, please ensure that a policy is required. Also please keep in mind that policies will be reviewed by the enterprise/edu team.

Policies are typically backed by a Preference. A Policy itself will not do anything until you attach it to a Preference.

There are existing documentation on implementing a Policy here.

Example of adding a simple policy here.

Additional tips:

 // TypeScript WebUI:
 // Check if a pref in OSSettings that is used in the UI is enforced
 // (i.e. policy configured).
 private isDefaultSearchEngineEnforced_(
     pref: chrome.settingsPrivate.PrefObject): boolean {
   return pref.enforcement === chrome.settingsPrivate.Enforcement.ENFORCED;
 };