# Policy Update Policy configuration is complicated and have a deep stack. To understand how policy is/should be updated, let's roam around the related codes. ## Notify updates [PolicyService](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/common/policy_service.h;l=38;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5) is a class responsible for merging policies from all sources. This lives as a singleton. On production, [PolicyServiceImpl](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/common/policy_service_impl.h;l=36;drc=133b2d903fa57cfda1317bc589b349cf4c284b7c) is the actual implementation. [RefreshPolicies](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/common/policy_service_impl.cc;l=212;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5) will post [MergeAndTriggerUpdates](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/common/policy_service_impl.cc;l=354;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5) which complets immediately if there is no policy provbiders. As the method name says, it merges the policies from multiple sources such [`chrome_policies`](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/common/policy_service_impl.cc;l=366;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5) from POLICY_DOMAIN_CHROME, PolicyBundle provided via registered [ConfigurationPolicyProvider](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/common/configuration_policy_provider.h;l=23;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5). [PolicyService::Observer](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/common/policy_service.h;l=40;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5) observes the policy update. [PolicyNamespace](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/common/policy_namespace.h;l=39;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5) represents a policy domain. We have 4 [PolicyDomain](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/common/policy_namespace.h;l=21;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5). CHROME, EXTENSIONS and SIGNIN_EXTENSIONS are the domains here. Then it passes `previous` map and `current` map so that we can take the diff. This notifies many classes such as [ArcPolicyBridge](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ash/arc/policy/arc_policy_bridge.cc;l=630;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5). This is used when the policy should be controlled by ARC. ## Policy entry [kSimplePolicyMap](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/policy/configuration_policy_handler_list_factory.cc;l=283;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5) contains a list of policy including kArcEnabled. Each entry is [PolicyToPreferenceMapEntry](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/browser/configuration_policy_handler.h;l=32;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5) struct. ```cpp= struct POLICY_EXPORT PolicyToPreferenceMapEntry { const char* const policy_name; const char* const preference_path; const base::Value::Type value_type; }; ... { key::kArcEnabled, arc::prefs::kArcEnabled, base::Value::Type::BOOLEAN }, ... ``` These entries are mapped via [SimplePolicyHandler](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/browser/configuration_policy_handler.h;l=221;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5). Here's the only meaningful method for SimplePolicyHandler. ```cpp= void SimplePolicyHandler::ApplyPolicySettings(const PolicyMap& policies, PrefValueMap* prefs) { const base::Value* value = policies.GetValueUnsafe(policy_name()); if (value) prefs->SetValue(pref_path_, value->Clone()); } ``` PrefValueMap is a mapping of the preferences and when given PolicyMap `policies` it extracts the policy value corresponding to `policy_name` and set it to `prefs`. The policy is applied on [CreatePreferencesFromPolicies](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/browser/configuration_policy_pref_store.cc;l=143-145;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5), called on [Refresh](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/browser/configuration_policy_pref_store.cc;l=118;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5). We need to Refresh the policy to apply the up-to-date policies. ### Configuration Policy Pref Store The method mentioned above is in [ConfigurationPolicyPrefStore](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/browser/configuration_policy_pref_store.h;l=30;drc=894b522cbf353e182bef8c9e1a53e1342fa0d825). [ConfigurationPolicyPrefStore](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/browser/configuration_policy_pref_store.h;l=30;drc=894b522cbf353e182bef8c9e1a53e1342fa0d825) is an implementation of PrefStore that bridges policy settings as read from the PolicyService to preferences. On refresh, it calculates the prefs which is different from the existing one by [GetDifferingKeys](https://source.chromium.org/chromium/chromium/src/+/main:components/prefs/pref_value_map.cc;l=135;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5) and then send [OnPrefValueChanged](https://source.chromium.org/chromium/chromium/src/+/main:components/policy/core/browser/configuration_policy_pref_store.cc;l=127;drc=c3a520cd08d04365a91c6837b947dfa714cfbfd5) notification only for changed prefs.