Get rid of excessive CrosSettings::Get()->Set*() usage, mostly in tests.
[chromium-blink-merge.git] / chrome / browser / chromeos / settings / device_settings_provider.cc
blob05fe7685787a0ef60137c7d61d47656e164ad463
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/settings/device_settings_provider.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/logging.h"
11 #include "base/metrics/histogram.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/threading/thread_restrictions.h"
14 #include "base/values.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
17 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
18 #include "chrome/browser/chromeos/policy/device_local_account.h"
19 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
20 #include "chrome/browser/chromeos/settings/cros_settings.h"
21 #include "chrome/browser/chromeos/settings/device_settings_cache.h"
22 #include "chrome/browser/metrics/metrics_reporting_state.h"
23 #include "chrome/installer/util/google_update_settings.h"
24 #include "chromeos/chromeos_switches.h"
25 #include "chromeos/dbus/cryptohome_client.h"
26 #include "chromeos/dbus/dbus_thread_manager.h"
27 #include "chromeos/settings/cros_settings_names.h"
28 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
29 #include "policy/proto/device_management_backend.pb.h"
31 using google::protobuf::RepeatedField;
32 using google::protobuf::RepeatedPtrField;
34 namespace em = enterprise_management;
36 namespace chromeos {
38 namespace {
40 // List of settings handled by the DeviceSettingsProvider.
41 const char* const kKnownSettings[] = {
42 kAccountsPrefAllowGuest,
43 kAccountsPrefAllowNewUser,
44 kAccountsPrefDeviceLocalAccounts,
45 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
46 kAccountsPrefDeviceLocalAccountAutoLoginDelay,
47 kAccountsPrefDeviceLocalAccountAutoLoginId,
48 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline,
49 kAccountsPrefEphemeralUsersEnabled,
50 kAccountsPrefShowUserNamesOnSignIn,
51 kAccountsPrefSupervisedUsersEnabled,
52 kAccountsPrefTransferSAMLCookies,
53 kAccountsPrefUsers,
54 kAccountsPrefLoginScreenDomainAutoComplete,
55 kAllowRedeemChromeOsRegistrationOffers,
56 kAllowedConnectionTypesForUpdate,
57 kAttestationForContentProtectionEnabled,
58 kDeviceAttestationEnabled,
59 kDeviceDisabled,
60 kDeviceDisabledMessage,
61 kDeviceOwner,
62 kExtensionCacheSize,
63 kHeartbeatEnabled,
64 kHeartbeatFrequency,
65 kPolicyMissingMitigationMode,
66 kRebootOnShutdown,
67 kReleaseChannel,
68 kReleaseChannelDelegated,
69 kReportDeviceActivityTimes,
70 kReportDeviceBootMode,
71 kReportDeviceHardwareStatus,
72 kReportDeviceLocation,
73 kReportDeviceNetworkInterfaces,
74 kReportDeviceSessionStatus,
75 kReportDeviceUsers,
76 kReportDeviceVersionInfo,
77 kReportUploadFrequency,
78 kServiceAccountIdentity,
79 kSignedDataRoamingEnabled,
80 kStartUpFlags,
81 kStatsReportingPref,
82 kSystemTimezonePolicy,
83 kSystemUse24HourClock,
84 kUpdateDisabled,
85 kVariationsRestrictParameter,
88 bool HasOldMetricsFile() {
89 // TODO(pastarmovj): Remove this once migration is not needed anymore.
90 // If the value is not set we should try to migrate legacy consent file.
91 // Loading consent file state causes us to do blocking IO on UI thread.
92 // Temporarily allow it until we fix http://crbug.com/62626
93 base::ThreadRestrictions::ScopedAllowIO allow_io;
94 return GoogleUpdateSettings::GetCollectStatsConsent();
97 void DecodeLoginPolicies(
98 const em::ChromeDeviceSettingsProto& policy,
99 PrefValueMap* new_values_cache) {
100 // For all our boolean settings the following is applicable:
101 // true is default permissive value and false is safe prohibitive value.
102 // Exceptions:
103 // kAccountsPrefEphemeralUsersEnabled has a default value of false.
104 // kAccountsPrefSupervisedUsersEnabled has a default value of false
105 // for enterprise devices and true for consumer devices.
106 // kAccountsPrefTransferSAMLCookies has a default value of false.
107 if (policy.has_allow_new_users() &&
108 policy.allow_new_users().has_allow_new_users()) {
109 if (policy.allow_new_users().allow_new_users()) {
110 // New users allowed, user whitelist ignored.
111 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true);
112 } else {
113 // New users not allowed, enforce user whitelist if present.
114 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser,
115 !policy.has_user_whitelist());
117 } else {
118 // No configured allow-new-users value, enforce whitelist if non-empty.
119 new_values_cache->SetBoolean(
120 kAccountsPrefAllowNewUser,
121 policy.user_whitelist().user_whitelist_size() == 0);
124 new_values_cache->SetBoolean(
125 kRebootOnShutdown,
126 policy.has_reboot_on_shutdown() &&
127 policy.reboot_on_shutdown().has_reboot_on_shutdown() &&
128 policy.reboot_on_shutdown().reboot_on_shutdown());
130 new_values_cache->SetBoolean(
131 kAccountsPrefAllowGuest,
132 !policy.has_guest_mode_enabled() ||
133 !policy.guest_mode_enabled().has_guest_mode_enabled() ||
134 policy.guest_mode_enabled().guest_mode_enabled());
136 policy::BrowserPolicyConnectorChromeOS* connector =
137 g_browser_process->platform_part()->browser_policy_connector_chromeos();
138 bool supervised_users_enabled = false;
139 if (connector->IsEnterpriseManaged()) {
140 supervised_users_enabled =
141 policy.has_supervised_users_settings() &&
142 policy.supervised_users_settings().has_supervised_users_enabled() &&
143 policy.supervised_users_settings().supervised_users_enabled();
144 } else {
145 supervised_users_enabled =
146 !policy.has_supervised_users_settings() ||
147 !policy.supervised_users_settings().has_supervised_users_enabled() ||
148 policy.supervised_users_settings().supervised_users_enabled();
150 new_values_cache->SetBoolean(
151 kAccountsPrefSupervisedUsersEnabled, supervised_users_enabled);
153 new_values_cache->SetBoolean(
154 kAccountsPrefShowUserNamesOnSignIn,
155 !policy.has_show_user_names() ||
156 !policy.show_user_names().has_show_user_names() ||
157 policy.show_user_names().show_user_names());
159 new_values_cache->SetBoolean(
160 kAccountsPrefEphemeralUsersEnabled,
161 policy.has_ephemeral_users_enabled() &&
162 policy.ephemeral_users_enabled().has_ephemeral_users_enabled() &&
163 policy.ephemeral_users_enabled().ephemeral_users_enabled());
165 base::ListValue* list = new base::ListValue();
166 const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist();
167 const RepeatedPtrField<std::string>& whitelist =
168 whitelist_proto.user_whitelist();
169 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin();
170 it != whitelist.end(); ++it) {
171 list->Append(new base::StringValue(*it));
173 new_values_cache->SetValue(kAccountsPrefUsers, list);
175 scoped_ptr<base::ListValue> account_list(new base::ListValue());
176 const em::DeviceLocalAccountsProto device_local_accounts_proto =
177 policy.device_local_accounts();
178 const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts =
179 device_local_accounts_proto.account();
180 RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry;
181 for (entry = accounts.begin(); entry != accounts.end(); ++entry) {
182 scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue());
183 if (entry->has_type()) {
184 if (entry->has_account_id()) {
185 entry_dict->SetStringWithoutPathExpansion(
186 kAccountsPrefDeviceLocalAccountsKeyId, entry->account_id());
188 entry_dict->SetIntegerWithoutPathExpansion(
189 kAccountsPrefDeviceLocalAccountsKeyType, entry->type());
190 if (entry->kiosk_app().has_app_id()) {
191 entry_dict->SetStringWithoutPathExpansion(
192 kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
193 entry->kiosk_app().app_id());
195 if (entry->kiosk_app().has_update_url()) {
196 entry_dict->SetStringWithoutPathExpansion(
197 kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL,
198 entry->kiosk_app().update_url());
200 } else if (entry->has_deprecated_public_session_id()) {
201 // Deprecated public session specification.
202 entry_dict->SetStringWithoutPathExpansion(
203 kAccountsPrefDeviceLocalAccountsKeyId,
204 entry->deprecated_public_session_id());
205 entry_dict->SetIntegerWithoutPathExpansion(
206 kAccountsPrefDeviceLocalAccountsKeyType,
207 policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION);
209 account_list->Append(entry_dict.release());
211 new_values_cache->SetValue(kAccountsPrefDeviceLocalAccounts,
212 account_list.release());
214 if (policy.has_device_local_accounts()) {
215 if (policy.device_local_accounts().has_auto_login_id()) {
216 new_values_cache->SetString(
217 kAccountsPrefDeviceLocalAccountAutoLoginId,
218 policy.device_local_accounts().auto_login_id());
220 if (policy.device_local_accounts().has_auto_login_delay()) {
221 new_values_cache->SetInteger(
222 kAccountsPrefDeviceLocalAccountAutoLoginDelay,
223 policy.device_local_accounts().auto_login_delay());
227 new_values_cache->SetBoolean(
228 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
229 policy.device_local_accounts().enable_auto_login_bailout());
230 new_values_cache->SetBoolean(
231 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline,
232 policy.device_local_accounts().prompt_for_network_when_offline());
234 if (policy.has_start_up_flags()) {
235 base::ListValue* list = new base::ListValue();
236 const em::StartUpFlagsProto& flags_proto = policy.start_up_flags();
237 const RepeatedPtrField<std::string>& flags = flags_proto.flags();
238 for (RepeatedPtrField<std::string>::const_iterator it = flags.begin();
239 it != flags.end(); ++it) {
240 list->Append(new base::StringValue(*it));
242 new_values_cache->SetValue(kStartUpFlags, list);
245 if (policy.has_saml_settings()) {
246 new_values_cache->SetBoolean(
247 kAccountsPrefTransferSAMLCookies,
248 policy.saml_settings().transfer_saml_cookies());
251 // The behavior when policy is not set and when it is set to an empty string
252 // is the same. Thus lets add policy only if it is set and its value is not
253 // an empty string.
254 if (policy.has_login_screen_domain_auto_complete() &&
255 policy.login_screen_domain_auto_complete()
256 .has_login_screen_domain_auto_complete() &&
257 !policy.login_screen_domain_auto_complete()
258 .login_screen_domain_auto_complete()
259 .empty()) {
260 new_values_cache->SetString(kAccountsPrefLoginScreenDomainAutoComplete,
261 policy.login_screen_domain_auto_complete()
262 .login_screen_domain_auto_complete());
266 void DecodeNetworkPolicies(
267 const em::ChromeDeviceSettingsProto& policy,
268 PrefValueMap* new_values_cache) {
269 // kSignedDataRoamingEnabled has a default value of false.
270 new_values_cache->SetBoolean(
271 kSignedDataRoamingEnabled,
272 policy.has_data_roaming_enabled() &&
273 policy.data_roaming_enabled().has_data_roaming_enabled() &&
274 policy.data_roaming_enabled().data_roaming_enabled());
277 void DecodeAutoUpdatePolicies(
278 const em::ChromeDeviceSettingsProto& policy,
279 PrefValueMap* new_values_cache) {
280 if (policy.has_auto_update_settings()) {
281 const em::AutoUpdateSettingsProto& au_settings_proto =
282 policy.auto_update_settings();
283 if (au_settings_proto.has_update_disabled()) {
284 new_values_cache->SetBoolean(kUpdateDisabled,
285 au_settings_proto.update_disabled());
287 const RepeatedField<int>& allowed_connection_types =
288 au_settings_proto.allowed_connection_types();
289 base::ListValue* list = new base::ListValue();
290 for (RepeatedField<int>::const_iterator i(allowed_connection_types.begin());
291 i != allowed_connection_types.end(); ++i) {
292 list->Append(new base::FundamentalValue(*i));
294 new_values_cache->SetValue(kAllowedConnectionTypesForUpdate, list);
298 void DecodeReportingPolicies(
299 const em::ChromeDeviceSettingsProto& policy,
300 PrefValueMap* new_values_cache) {
301 if (policy.has_device_reporting()) {
302 const em::DeviceReportingProto& reporting_policy =
303 policy.device_reporting();
304 if (reporting_policy.has_report_version_info()) {
305 new_values_cache->SetBoolean(
306 kReportDeviceVersionInfo,
307 reporting_policy.report_version_info());
309 if (reporting_policy.has_report_activity_times()) {
310 new_values_cache->SetBoolean(
311 kReportDeviceActivityTimes,
312 reporting_policy.report_activity_times());
314 if (reporting_policy.has_report_boot_mode()) {
315 new_values_cache->SetBoolean(
316 kReportDeviceBootMode,
317 reporting_policy.report_boot_mode());
319 if (reporting_policy.has_report_network_interfaces()) {
320 new_values_cache->SetBoolean(
321 kReportDeviceNetworkInterfaces,
322 reporting_policy.report_network_interfaces());
324 if (reporting_policy.has_report_users()) {
325 new_values_cache->SetBoolean(
326 kReportDeviceUsers,
327 reporting_policy.report_users());
329 if (reporting_policy.has_report_hardware_status()) {
330 new_values_cache->SetBoolean(
331 kReportDeviceHardwareStatus,
332 reporting_policy.report_hardware_status());
334 if (reporting_policy.has_report_session_status()) {
335 new_values_cache->SetBoolean(
336 kReportDeviceSessionStatus,
337 reporting_policy.report_session_status());
339 if (reporting_policy.has_device_status_frequency()) {
340 new_values_cache->SetInteger(
341 kReportUploadFrequency,
342 reporting_policy.device_status_frequency());
347 void DecodeHeartbeatPolicies(
348 const em::ChromeDeviceSettingsProto& policy,
349 PrefValueMap* new_values_cache) {
350 if (!policy.has_device_heartbeat_settings())
351 return;
353 const em::DeviceHeartbeatSettingsProto& heartbeat_policy =
354 policy.device_heartbeat_settings();
355 if (heartbeat_policy.has_heartbeat_enabled()) {
356 new_values_cache->SetBoolean(
357 kHeartbeatEnabled,
358 heartbeat_policy.heartbeat_enabled());
360 if (heartbeat_policy.has_heartbeat_frequency()) {
361 new_values_cache->SetInteger(
362 kHeartbeatFrequency,
363 heartbeat_policy.heartbeat_frequency());
367 void DecodeGenericPolicies(
368 const em::ChromeDeviceSettingsProto& policy,
369 PrefValueMap* new_values_cache) {
370 if (policy.has_metrics_enabled()) {
371 new_values_cache->SetBoolean(kStatsReportingPref,
372 policy.metrics_enabled().metrics_enabled());
373 } else {
374 new_values_cache->SetBoolean(kStatsReportingPref, HasOldMetricsFile());
377 if (!policy.has_release_channel() ||
378 !policy.release_channel().has_release_channel()) {
379 // Default to an invalid channel (will be ignored).
380 new_values_cache->SetString(kReleaseChannel, "");
381 } else {
382 new_values_cache->SetString(kReleaseChannel,
383 policy.release_channel().release_channel());
386 new_values_cache->SetBoolean(
387 kReleaseChannelDelegated,
388 policy.has_release_channel() &&
389 policy.release_channel().has_release_channel_delegated() &&
390 policy.release_channel().release_channel_delegated());
392 if (policy.has_system_timezone()) {
393 if (policy.system_timezone().has_timezone()) {
394 new_values_cache->SetString(
395 kSystemTimezonePolicy,
396 policy.system_timezone().timezone());
400 if (policy.has_use_24hour_clock()) {
401 if (policy.use_24hour_clock().has_use_24hour_clock()) {
402 new_values_cache->SetBoolean(
403 kSystemUse24HourClock, policy.use_24hour_clock().use_24hour_clock());
407 if (policy.has_allow_redeem_offers()) {
408 new_values_cache->SetBoolean(
409 kAllowRedeemChromeOsRegistrationOffers,
410 policy.allow_redeem_offers().allow_redeem_offers());
411 } else {
412 new_values_cache->SetBoolean(
413 kAllowRedeemChromeOsRegistrationOffers,
414 true);
417 if (policy.has_variations_parameter()) {
418 new_values_cache->SetString(
419 kVariationsRestrictParameter,
420 policy.variations_parameter().parameter());
423 new_values_cache->SetBoolean(
424 kDeviceAttestationEnabled,
425 policy.attestation_settings().attestation_enabled());
427 if (policy.has_attestation_settings() &&
428 policy.attestation_settings().has_content_protection_enabled()) {
429 new_values_cache->SetBoolean(
430 kAttestationForContentProtectionEnabled,
431 policy.attestation_settings().content_protection_enabled());
432 } else {
433 new_values_cache->SetBoolean(kAttestationForContentProtectionEnabled, true);
436 if (policy.has_extension_cache_size() &&
437 policy.extension_cache_size().has_extension_cache_size()) {
438 new_values_cache->SetInteger(
439 kExtensionCacheSize,
440 policy.extension_cache_size().extension_cache_size());
444 void DecodeDeviceState(const em::PolicyData& policy_data,
445 PrefValueMap* new_values_cache) {
446 if (!policy_data.has_device_state())
447 return;
449 const em::DeviceState& device_state = policy_data.device_state();
451 if (device_state.device_mode() == em::DeviceState::DEVICE_MODE_DISABLED)
452 new_values_cache->SetBoolean(kDeviceDisabled, true);
453 if (device_state.has_disabled_state() &&
454 device_state.disabled_state().has_message()) {
455 new_values_cache->SetString(kDeviceDisabledMessage,
456 device_state.disabled_state().message());
460 } // namespace
462 DeviceSettingsProvider::DeviceSettingsProvider(
463 const NotifyObserversCallback& notify_cb,
464 DeviceSettingsService* device_settings_service)
465 : CrosSettingsProvider(notify_cb),
466 device_settings_service_(device_settings_service),
467 trusted_status_(TEMPORARILY_UNTRUSTED),
468 ownership_status_(device_settings_service_->GetOwnershipStatus()),
469 store_callback_factory_(this) {
470 device_settings_service_->AddObserver(this);
471 if (!UpdateFromService()) {
472 // Make sure we have at least the cache data immediately.
473 RetrieveCachedData();
477 DeviceSettingsProvider::~DeviceSettingsProvider() {
478 if (device_settings_service_->GetOwnerSettingsService())
479 device_settings_service_->GetOwnerSettingsService()->RemoveObserver(this);
480 device_settings_service_->RemoveObserver(this);
483 // static
484 bool DeviceSettingsProvider::IsDeviceSetting(const std::string& name) {
485 const char* const* end = kKnownSettings + arraysize(kKnownSettings);
486 return std::find(kKnownSettings, end, name) != end;
489 void DeviceSettingsProvider::DoSet(const std::string& path,
490 const base::Value& in_value) {
491 // Make sure that either the current user is the device owner or the
492 // device doesn't have an owner yet.
493 if (!(device_settings_service_->HasPrivateOwnerKey() ||
494 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)) {
495 LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
497 // Revert UI change.
498 NotifyObservers(path);
499 return;
502 if (!IsDeviceSetting(path)) {
503 NOTREACHED() << "Try to set unhandled cros setting " << path;
504 return;
507 if (device_settings_service_->HasPrivateOwnerKey()) {
508 // Directly set setting through OwnerSettingsService.
509 ownership::OwnerSettingsService* service =
510 device_settings_service_->GetOwnerSettingsService();
511 if (!service->Set(path, in_value)) {
512 NotifyObservers(path);
513 return;
515 } else {
516 // Temporary store new setting in
517 // |device_settings_|. |device_settings_| will be stored on a disk
518 // as soon as an ownership of device the will be taken.
519 OwnerSettingsServiceChromeOS::UpdateDeviceSettings(
520 path, in_value, device_settings_);
521 em::PolicyData data;
522 data.set_username(device_settings_service_->GetUsername());
523 CHECK(device_settings_.SerializeToString(data.mutable_policy_value()));
525 // Set the cache to the updated value.
526 UpdateValuesCache(data, device_settings_, TEMPORARILY_UNTRUSTED);
528 if (!device_settings_cache::Store(data, g_browser_process->local_state())) {
529 LOG(ERROR) << "Couldn't store to the temp storage.";
530 NotifyObservers(path);
531 return;
535 bool metrics_value;
536 if (path == kStatsReportingPref && in_value.GetAsBoolean(&metrics_value))
537 ApplyMetricsSetting(false, metrics_value);
540 void DeviceSettingsProvider::OwnershipStatusChanged() {
541 DeviceSettingsService::OwnershipStatus new_ownership_status =
542 device_settings_service_->GetOwnershipStatus();
544 if (device_settings_service_->GetOwnerSettingsService())
545 device_settings_service_->GetOwnerSettingsService()->AddObserver(this);
547 // If the device just became owned, write the settings accumulated in the
548 // cache to device settings proper. It is important that writing only happens
549 // in this case, as during normal operation, the contents of the cache should
550 // never overwrite actual device settings.
551 if (new_ownership_status == DeviceSettingsService::OWNERSHIP_TAKEN &&
552 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE &&
553 device_settings_service_->HasPrivateOwnerKey()) {
554 // There shouldn't be any pending writes, since the cache writes are all
555 // immediate.
556 DCHECK(!store_callback_factory_.HasWeakPtrs());
558 trusted_status_ = TEMPORARILY_UNTRUSTED;
559 // Apply the locally-accumulated device settings on top of the initial
560 // settings from the service and write back the result.
561 if (device_settings_service_->device_settings()) {
562 em::ChromeDeviceSettingsProto new_settings(
563 *device_settings_service_->device_settings());
564 new_settings.MergeFrom(device_settings_);
565 device_settings_.Swap(&new_settings);
568 scoped_ptr<em::PolicyData> policy(new em::PolicyData());
569 policy->set_username(device_settings_service_->GetUsername());
570 CHECK(device_settings_.SerializeToString(policy->mutable_policy_value()));
571 if (!device_settings_service_->GetOwnerSettingsService()
572 ->CommitTentativeDeviceSettings(policy.Pass())) {
573 LOG(ERROR) << "Can't store policy";
577 // The owner key might have become available, allowing migration to happen.
578 AttemptMigration();
580 ownership_status_ = new_ownership_status;
583 void DeviceSettingsProvider::DeviceSettingsUpdated() {
584 if (!store_callback_factory_.HasWeakPtrs())
585 UpdateAndProceedStoring();
588 void DeviceSettingsProvider::OnDeviceSettingsServiceShutdown() {
589 device_settings_service_ = nullptr;
592 void DeviceSettingsProvider::OnTentativeChangesInPolicy(
593 const em::PolicyData& policy_data) {
594 em::ChromeDeviceSettingsProto device_settings;
595 CHECK(device_settings.ParseFromString(policy_data.policy_value()));
596 UpdateValuesCache(policy_data, device_settings, TEMPORARILY_UNTRUSTED);
599 void DeviceSettingsProvider::RetrieveCachedData() {
600 em::PolicyData policy_data;
601 if (!device_settings_cache::Retrieve(&policy_data,
602 g_browser_process->local_state()) ||
603 !device_settings_.ParseFromString(policy_data.policy_value())) {
604 VLOG(1) << "Can't retrieve temp store, possibly not created yet.";
607 UpdateValuesCache(policy_data, device_settings_, trusted_status_);
610 void DeviceSettingsProvider::UpdateValuesCache(
611 const em::PolicyData& policy_data,
612 const em::ChromeDeviceSettingsProto& settings,
613 TrustedStatus trusted_status) {
614 PrefValueMap new_values_cache;
616 // If the device is not managed, or is consumer-managed, we set the device
617 // owner value.
618 if (policy_data.has_username() &&
619 (policy::GetManagementMode(policy_data) ==
620 policy::MANAGEMENT_MODE_LOCAL_OWNER ||
621 policy::GetManagementMode(policy_data) ==
622 policy::MANAGEMENT_MODE_CONSUMER_MANAGED)) {
623 new_values_cache.SetString(kDeviceOwner, policy_data.username());
626 if (policy_data.has_service_account_identity()) {
627 new_values_cache.SetString(kServiceAccountIdentity,
628 policy_data.service_account_identity());
631 DecodeLoginPolicies(settings, &new_values_cache);
632 DecodeNetworkPolicies(settings, &new_values_cache);
633 DecodeAutoUpdatePolicies(settings, &new_values_cache);
634 DecodeReportingPolicies(settings, &new_values_cache);
635 DecodeHeartbeatPolicies(settings, &new_values_cache);
636 DecodeGenericPolicies(settings, &new_values_cache);
637 DecodeDeviceState(policy_data, &new_values_cache);
639 // Collect all notifications but send them only after we have swapped the
640 // cache so that if somebody actually reads the cache will be already valid.
641 std::vector<std::string> notifications;
642 // Go through the new values and verify in the old ones.
643 PrefValueMap::iterator iter = new_values_cache.begin();
644 for (; iter != new_values_cache.end(); ++iter) {
645 const base::Value* old_value;
646 if (!values_cache_.GetValue(iter->first, &old_value) ||
647 !old_value->Equals(iter->second)) {
648 notifications.push_back(iter->first);
651 // Now check for values that have been removed from the policy blob.
652 for (iter = values_cache_.begin(); iter != values_cache_.end(); ++iter) {
653 const base::Value* value;
654 if (!new_values_cache.GetValue(iter->first, &value))
655 notifications.push_back(iter->first);
657 // Swap and notify.
658 values_cache_.Swap(&new_values_cache);
659 trusted_status_ = trusted_status;
660 for (size_t i = 0; i < notifications.size(); ++i)
661 NotifyObservers(notifications[i]);
664 void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file,
665 bool new_value) {
666 // TODO(pastarmovj): Remove this once migration is not needed anymore.
667 // If the value is not set we should try to migrate legacy consent file.
668 if (use_file) {
669 new_value = HasOldMetricsFile();
670 // Make sure the values will get eventually written to the policy file.
671 migration_values_.SetBoolean(kStatsReportingPref, new_value);
672 AttemptMigration();
673 VLOG(1) << "No metrics policy set will revert to checking "
674 << "consent file which is "
675 << (new_value ? "on." : "off.");
676 UMA_HISTOGRAM_COUNTS("DeviceSettings.MetricsMigrated", 1);
678 VLOG(1) << "Metrics policy is being set to : " << new_value
679 << "(use file : " << use_file << ")";
680 // TODO(pastarmovj): Remove this once we don't need to regenerate the
681 // consent file for the GUID anymore.
682 InitiateMetricsReportingChange(new_value, OnMetricsReportingCallbackType());
685 void DeviceSettingsProvider::ApplySideEffects(
686 const em::ChromeDeviceSettingsProto& settings) {
687 // First migrate metrics settings as needed.
688 if (settings.has_metrics_enabled())
689 ApplyMetricsSetting(false, settings.metrics_enabled().metrics_enabled());
690 else
691 ApplyMetricsSetting(true, false);
694 bool DeviceSettingsProvider::MitigateMissingPolicy() {
695 // First check if the device has been owned already and if not exit
696 // immediately.
697 policy::BrowserPolicyConnectorChromeOS* connector =
698 g_browser_process->platform_part()->browser_policy_connector_chromeos();
699 if (connector->GetDeviceMode() != policy::DEVICE_MODE_CONSUMER)
700 return false;
702 // If we are here the policy file were corrupted or missing. This can happen
703 // because we are migrating Pre R11 device to the new secure policies or there
704 // was an attempt to circumvent policy system. In this case we should populate
705 // the policy cache with "safe-mode" defaults which should allow the owner to
706 // log in but lock the device for anyone else until the policy blob has been
707 // recreated by the session manager.
708 LOG(ERROR) << "Corruption of the policy data has been detected."
709 << "Switching to \"safe-mode\" policies until the owner logs in "
710 << "to regenerate the policy data.";
712 device_settings_.Clear();
713 device_settings_.mutable_allow_new_users()->set_allow_new_users(true);
714 device_settings_.mutable_guest_mode_enabled()->set_guest_mode_enabled(true);
715 em::PolicyData empty_policy_data;
716 UpdateValuesCache(empty_policy_data, device_settings_, TRUSTED);
717 values_cache_.SetBoolean(kPolicyMissingMitigationMode, true);
719 return true;
722 const base::Value* DeviceSettingsProvider::Get(const std::string& path) const {
723 if (IsDeviceSetting(path)) {
724 const base::Value* value;
725 if (values_cache_.GetValue(path, &value))
726 return value;
727 } else {
728 NOTREACHED() << "Trying to get non cros setting.";
731 return NULL;
734 DeviceSettingsProvider::TrustedStatus
735 DeviceSettingsProvider::PrepareTrustedValues(const base::Closure& cb) {
736 TrustedStatus status = RequestTrustedEntity();
737 if (status == TEMPORARILY_UNTRUSTED && !cb.is_null())
738 callbacks_.push_back(cb);
739 return status;
742 bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const {
743 return IsDeviceSetting(path);
746 DeviceSettingsProvider::TrustedStatus
747 DeviceSettingsProvider::RequestTrustedEntity() {
748 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)
749 return TRUSTED;
750 return trusted_status_;
753 void DeviceSettingsProvider::UpdateAndProceedStoring() {
754 // Re-sync the cache from the service.
755 UpdateFromService();
758 bool DeviceSettingsProvider::UpdateFromService() {
759 bool settings_loaded = false;
760 switch (device_settings_service_->status()) {
761 case DeviceSettingsService::STORE_SUCCESS: {
762 const em::PolicyData* policy_data =
763 device_settings_service_->policy_data();
764 const em::ChromeDeviceSettingsProto* device_settings =
765 device_settings_service_->device_settings();
766 if (policy_data && device_settings) {
767 if (!device_settings_cache::Store(*policy_data,
768 g_browser_process->local_state())) {
769 LOG(ERROR) << "Couldn't update the local state cache.";
771 UpdateValuesCache(*policy_data, *device_settings, TRUSTED);
772 device_settings_ = *device_settings;
774 // TODO(pastarmovj): Make those side effects responsibility of the
775 // respective subsystems.
776 ApplySideEffects(*device_settings);
778 settings_loaded = true;
779 } else {
780 // Initial policy load is still pending.
781 trusted_status_ = TEMPORARILY_UNTRUSTED;
783 break;
785 case DeviceSettingsService::STORE_NO_POLICY:
786 if (MitigateMissingPolicy())
787 break;
788 // fall through.
789 case DeviceSettingsService::STORE_KEY_UNAVAILABLE:
790 VLOG(1) << "No policies present yet, will use the temp storage.";
791 trusted_status_ = PERMANENTLY_UNTRUSTED;
792 break;
793 case DeviceSettingsService::STORE_POLICY_ERROR:
794 case DeviceSettingsService::STORE_VALIDATION_ERROR:
795 case DeviceSettingsService::STORE_INVALID_POLICY:
796 case DeviceSettingsService::STORE_OPERATION_FAILED:
797 LOG(ERROR) << "Failed to retrieve cros policies. Reason: "
798 << device_settings_service_->status();
799 trusted_status_ = PERMANENTLY_UNTRUSTED;
800 break;
801 case DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR:
802 // The policy has failed to validate due to temporary error but it might
803 // take a long time until we recover so behave as it is a permanent error.
804 LOG(ERROR) << "Failed to retrieve cros policies because a temporary "
805 << "validation error has occurred. Retrying might succeed.";
806 trusted_status_ = PERMANENTLY_UNTRUSTED;
807 break;
810 // Notify the observers we are done.
811 std::vector<base::Closure> callbacks;
812 callbacks.swap(callbacks_);
813 for (size_t i = 0; i < callbacks.size(); ++i)
814 callbacks[i].Run();
816 return settings_loaded;
819 void DeviceSettingsProvider::AttemptMigration() {
820 if (device_settings_service_->HasPrivateOwnerKey()) {
821 PrefValueMap::const_iterator i;
822 for (i = migration_values_.begin(); i != migration_values_.end(); ++i)
823 DoSet(i->first, *i->second);
824 migration_values_.Clear();
828 } // namespace chromeos