Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / chromeos / settings / device_settings_provider.cc
blob02bb836d980022db8a2b9daf7871ef30528fcb7d
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 kAllowRedeemChromeOsRegistrationOffers,
55 kAllowedConnectionTypesForUpdate,
56 kAttestationForContentProtectionEnabled,
57 kDeviceAttestationEnabled,
58 kDeviceOwner,
59 kHeartbeatEnabled,
60 kHeartbeatFrequency,
61 kPolicyMissingMitigationMode,
62 kReleaseChannel,
63 kReleaseChannelDelegated,
64 kReportDeviceActivityTimes,
65 kReportDeviceBootMode,
66 kReportDeviceHardwareStatus,
67 kReportDeviceLocation,
68 kReportDeviceNetworkInterfaces,
69 kReportDeviceSessionStatus,
70 kReportDeviceUsers,
71 kReportDeviceVersionInfo,
72 kReportUploadFrequency,
73 kServiceAccountIdentity,
74 kSignedDataRoamingEnabled,
75 kStartUpFlags,
76 kStatsReportingPref,
77 kSystemTimezonePolicy,
78 kSystemUse24HourClock,
79 kUpdateDisabled,
80 kVariationsRestrictParameter,
81 kDeviceDisabled,
82 kDeviceDisabledMessage,
83 kRebootOnShutdown,
84 kExtensionCacheSize,
87 bool HasOldMetricsFile() {
88 // TODO(pastarmovj): Remove this once migration is not needed anymore.
89 // If the value is not set we should try to migrate legacy consent file.
90 // Loading consent file state causes us to do blocking IO on UI thread.
91 // Temporarily allow it until we fix http://crbug.com/62626
92 base::ThreadRestrictions::ScopedAllowIO allow_io;
93 return GoogleUpdateSettings::GetCollectStatsConsent();
96 void DecodeLoginPolicies(
97 const em::ChromeDeviceSettingsProto& policy,
98 PrefValueMap* new_values_cache) {
99 // For all our boolean settings the following is applicable:
100 // true is default permissive value and false is safe prohibitive value.
101 // Exceptions:
102 // kAccountsPrefEphemeralUsersEnabled has a default value of false.
103 // kAccountsPrefSupervisedUsersEnabled has a default value of false
104 // for enterprise devices and true for consumer devices.
105 // kAccountsPrefTransferSAMLCookies has a default value of false.
106 if (policy.has_allow_new_users() &&
107 policy.allow_new_users().has_allow_new_users()) {
108 if (policy.allow_new_users().allow_new_users()) {
109 // New users allowed, user whitelist ignored.
110 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true);
111 } else {
112 // New users not allowed, enforce user whitelist if present.
113 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser,
114 !policy.has_user_whitelist());
116 } else {
117 // No configured allow-new-users value, enforce whitelist if non-empty.
118 new_values_cache->SetBoolean(
119 kAccountsPrefAllowNewUser,
120 policy.user_whitelist().user_whitelist_size() == 0);
123 new_values_cache->SetBoolean(
124 kRebootOnShutdown,
125 policy.has_reboot_on_shutdown() &&
126 policy.reboot_on_shutdown().has_reboot_on_shutdown() &&
127 policy.reboot_on_shutdown().reboot_on_shutdown());
129 new_values_cache->SetBoolean(
130 kAccountsPrefAllowGuest,
131 !policy.has_guest_mode_enabled() ||
132 !policy.guest_mode_enabled().has_guest_mode_enabled() ||
133 policy.guest_mode_enabled().guest_mode_enabled());
135 policy::BrowserPolicyConnectorChromeOS* connector =
136 g_browser_process->platform_part()->browser_policy_connector_chromeos();
137 bool supervised_users_enabled = false;
138 if (connector->IsEnterpriseManaged()) {
139 supervised_users_enabled =
140 policy.has_supervised_users_settings() &&
141 policy.supervised_users_settings().has_supervised_users_enabled() &&
142 policy.supervised_users_settings().supervised_users_enabled();
143 } else {
144 supervised_users_enabled =
145 !policy.has_supervised_users_settings() ||
146 !policy.supervised_users_settings().has_supervised_users_enabled() ||
147 policy.supervised_users_settings().supervised_users_enabled();
149 new_values_cache->SetBoolean(
150 kAccountsPrefSupervisedUsersEnabled, supervised_users_enabled);
152 new_values_cache->SetBoolean(
153 kAccountsPrefShowUserNamesOnSignIn,
154 !policy.has_show_user_names() ||
155 !policy.show_user_names().has_show_user_names() ||
156 policy.show_user_names().show_user_names());
158 new_values_cache->SetBoolean(
159 kAccountsPrefEphemeralUsersEnabled,
160 policy.has_ephemeral_users_enabled() &&
161 policy.ephemeral_users_enabled().has_ephemeral_users_enabled() &&
162 policy.ephemeral_users_enabled().ephemeral_users_enabled());
164 base::ListValue* list = new base::ListValue();
165 const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist();
166 const RepeatedPtrField<std::string>& whitelist =
167 whitelist_proto.user_whitelist();
168 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin();
169 it != whitelist.end(); ++it) {
170 list->Append(new base::StringValue(*it));
172 new_values_cache->SetValue(kAccountsPrefUsers, list);
174 scoped_ptr<base::ListValue> account_list(new base::ListValue());
175 const em::DeviceLocalAccountsProto device_local_accounts_proto =
176 policy.device_local_accounts();
177 const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts =
178 device_local_accounts_proto.account();
179 RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry;
180 for (entry = accounts.begin(); entry != accounts.end(); ++entry) {
181 scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue());
182 if (entry->has_type()) {
183 if (entry->has_account_id()) {
184 entry_dict->SetStringWithoutPathExpansion(
185 kAccountsPrefDeviceLocalAccountsKeyId, entry->account_id());
187 entry_dict->SetIntegerWithoutPathExpansion(
188 kAccountsPrefDeviceLocalAccountsKeyType, entry->type());
189 if (entry->kiosk_app().has_app_id()) {
190 entry_dict->SetStringWithoutPathExpansion(
191 kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
192 entry->kiosk_app().app_id());
194 if (entry->kiosk_app().has_update_url()) {
195 entry_dict->SetStringWithoutPathExpansion(
196 kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL,
197 entry->kiosk_app().update_url());
199 } else if (entry->has_deprecated_public_session_id()) {
200 // Deprecated public session specification.
201 entry_dict->SetStringWithoutPathExpansion(
202 kAccountsPrefDeviceLocalAccountsKeyId,
203 entry->deprecated_public_session_id());
204 entry_dict->SetIntegerWithoutPathExpansion(
205 kAccountsPrefDeviceLocalAccountsKeyType,
206 policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION);
208 account_list->Append(entry_dict.release());
210 new_values_cache->SetValue(kAccountsPrefDeviceLocalAccounts,
211 account_list.release());
213 if (policy.has_device_local_accounts()) {
214 if (policy.device_local_accounts().has_auto_login_id()) {
215 new_values_cache->SetString(
216 kAccountsPrefDeviceLocalAccountAutoLoginId,
217 policy.device_local_accounts().auto_login_id());
219 if (policy.device_local_accounts().has_auto_login_delay()) {
220 new_values_cache->SetInteger(
221 kAccountsPrefDeviceLocalAccountAutoLoginDelay,
222 policy.device_local_accounts().auto_login_delay());
226 new_values_cache->SetBoolean(
227 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
228 policy.device_local_accounts().enable_auto_login_bailout());
229 new_values_cache->SetBoolean(
230 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline,
231 policy.device_local_accounts().prompt_for_network_when_offline());
233 if (policy.has_start_up_flags()) {
234 base::ListValue* list = new base::ListValue();
235 const em::StartUpFlagsProto& flags_proto = policy.start_up_flags();
236 const RepeatedPtrField<std::string>& flags = flags_proto.flags();
237 for (RepeatedPtrField<std::string>::const_iterator it = flags.begin();
238 it != flags.end(); ++it) {
239 list->Append(new base::StringValue(*it));
241 new_values_cache->SetValue(kStartUpFlags, list);
244 if (policy.has_saml_settings()) {
245 new_values_cache->SetBoolean(
246 kAccountsPrefTransferSAMLCookies,
247 policy.saml_settings().transfer_saml_cookies());
251 void DecodeNetworkPolicies(
252 const em::ChromeDeviceSettingsProto& policy,
253 PrefValueMap* new_values_cache) {
254 // kSignedDataRoamingEnabled has a default value of false.
255 new_values_cache->SetBoolean(
256 kSignedDataRoamingEnabled,
257 policy.has_data_roaming_enabled() &&
258 policy.data_roaming_enabled().has_data_roaming_enabled() &&
259 policy.data_roaming_enabled().data_roaming_enabled());
262 void DecodeAutoUpdatePolicies(
263 const em::ChromeDeviceSettingsProto& policy,
264 PrefValueMap* new_values_cache) {
265 if (policy.has_auto_update_settings()) {
266 const em::AutoUpdateSettingsProto& au_settings_proto =
267 policy.auto_update_settings();
268 if (au_settings_proto.has_update_disabled()) {
269 new_values_cache->SetBoolean(kUpdateDisabled,
270 au_settings_proto.update_disabled());
272 const RepeatedField<int>& allowed_connection_types =
273 au_settings_proto.allowed_connection_types();
274 base::ListValue* list = new base::ListValue();
275 for (RepeatedField<int>::const_iterator i(allowed_connection_types.begin());
276 i != allowed_connection_types.end(); ++i) {
277 list->Append(new base::FundamentalValue(*i));
279 new_values_cache->SetValue(kAllowedConnectionTypesForUpdate, list);
283 void DecodeReportingPolicies(
284 const em::ChromeDeviceSettingsProto& policy,
285 PrefValueMap* new_values_cache) {
286 if (policy.has_device_reporting()) {
287 const em::DeviceReportingProto& reporting_policy =
288 policy.device_reporting();
289 if (reporting_policy.has_report_version_info()) {
290 new_values_cache->SetBoolean(
291 kReportDeviceVersionInfo,
292 reporting_policy.report_version_info());
294 if (reporting_policy.has_report_activity_times()) {
295 new_values_cache->SetBoolean(
296 kReportDeviceActivityTimes,
297 reporting_policy.report_activity_times());
299 if (reporting_policy.has_report_boot_mode()) {
300 new_values_cache->SetBoolean(
301 kReportDeviceBootMode,
302 reporting_policy.report_boot_mode());
304 if (reporting_policy.has_report_network_interfaces()) {
305 new_values_cache->SetBoolean(
306 kReportDeviceNetworkInterfaces,
307 reporting_policy.report_network_interfaces());
309 if (reporting_policy.has_report_users()) {
310 new_values_cache->SetBoolean(
311 kReportDeviceUsers,
312 reporting_policy.report_users());
314 if (reporting_policy.has_report_hardware_status()) {
315 new_values_cache->SetBoolean(
316 kReportDeviceHardwareStatus,
317 reporting_policy.report_hardware_status());
319 if (reporting_policy.has_report_session_status()) {
320 new_values_cache->SetBoolean(
321 kReportDeviceSessionStatus,
322 reporting_policy.report_session_status());
324 if (reporting_policy.has_device_status_frequency()) {
325 new_values_cache->SetInteger(
326 kReportUploadFrequency,
327 reporting_policy.device_status_frequency());
332 void DecodeHeartbeatPolicies(
333 const em::ChromeDeviceSettingsProto& policy,
334 PrefValueMap* new_values_cache) {
335 if (!policy.has_device_heartbeat_settings())
336 return;
338 const em::DeviceHeartbeatSettingsProto& heartbeat_policy =
339 policy.device_heartbeat_settings();
340 if (heartbeat_policy.has_heartbeat_enabled()) {
341 new_values_cache->SetBoolean(
342 kHeartbeatEnabled,
343 heartbeat_policy.heartbeat_enabled());
345 if (heartbeat_policy.has_heartbeat_frequency()) {
346 new_values_cache->SetInteger(
347 kHeartbeatFrequency,
348 heartbeat_policy.heartbeat_frequency());
352 void DecodeGenericPolicies(
353 const em::ChromeDeviceSettingsProto& policy,
354 PrefValueMap* new_values_cache) {
355 if (policy.has_metrics_enabled()) {
356 new_values_cache->SetBoolean(kStatsReportingPref,
357 policy.metrics_enabled().metrics_enabled());
358 } else {
359 new_values_cache->SetBoolean(kStatsReportingPref, HasOldMetricsFile());
362 if (!policy.has_release_channel() ||
363 !policy.release_channel().has_release_channel()) {
364 // Default to an invalid channel (will be ignored).
365 new_values_cache->SetString(kReleaseChannel, "");
366 } else {
367 new_values_cache->SetString(kReleaseChannel,
368 policy.release_channel().release_channel());
371 new_values_cache->SetBoolean(
372 kReleaseChannelDelegated,
373 policy.has_release_channel() &&
374 policy.release_channel().has_release_channel_delegated() &&
375 policy.release_channel().release_channel_delegated());
377 if (policy.has_system_timezone()) {
378 if (policy.system_timezone().has_timezone()) {
379 new_values_cache->SetString(
380 kSystemTimezonePolicy,
381 policy.system_timezone().timezone());
385 if (policy.has_use_24hour_clock()) {
386 if (policy.use_24hour_clock().has_use_24hour_clock()) {
387 new_values_cache->SetBoolean(
388 kSystemUse24HourClock, policy.use_24hour_clock().use_24hour_clock());
392 if (policy.has_allow_redeem_offers()) {
393 new_values_cache->SetBoolean(
394 kAllowRedeemChromeOsRegistrationOffers,
395 policy.allow_redeem_offers().allow_redeem_offers());
396 } else {
397 new_values_cache->SetBoolean(
398 kAllowRedeemChromeOsRegistrationOffers,
399 true);
402 if (policy.has_variations_parameter()) {
403 new_values_cache->SetString(
404 kVariationsRestrictParameter,
405 policy.variations_parameter().parameter());
408 new_values_cache->SetBoolean(
409 kDeviceAttestationEnabled,
410 policy.attestation_settings().attestation_enabled());
412 if (policy.has_attestation_settings() &&
413 policy.attestation_settings().has_content_protection_enabled()) {
414 new_values_cache->SetBoolean(
415 kAttestationForContentProtectionEnabled,
416 policy.attestation_settings().content_protection_enabled());
417 } else {
418 new_values_cache->SetBoolean(kAttestationForContentProtectionEnabled, true);
421 if (policy.has_extension_cache_size() &&
422 policy.extension_cache_size().has_extension_cache_size()) {
423 new_values_cache->SetInteger(
424 kExtensionCacheSize,
425 policy.extension_cache_size().extension_cache_size());
429 void DecodeDeviceState(const em::PolicyData& policy_data,
430 PrefValueMap* new_values_cache) {
431 if (!policy_data.has_device_state())
432 return;
434 const em::DeviceState& device_state = policy_data.device_state();
436 if (device_state.device_mode() == em::DeviceState::DEVICE_MODE_DISABLED)
437 new_values_cache->SetBoolean(kDeviceDisabled, true);
438 if (device_state.has_disabled_state() &&
439 device_state.disabled_state().has_message()) {
440 new_values_cache->SetString(kDeviceDisabledMessage,
441 device_state.disabled_state().message());
445 } // namespace
447 DeviceSettingsProvider::DeviceSettingsProvider(
448 const NotifyObserversCallback& notify_cb,
449 DeviceSettingsService* device_settings_service)
450 : CrosSettingsProvider(notify_cb),
451 device_settings_service_(device_settings_service),
452 trusted_status_(TEMPORARILY_UNTRUSTED),
453 ownership_status_(device_settings_service_->GetOwnershipStatus()),
454 store_callback_factory_(this) {
455 device_settings_service_->AddObserver(this);
456 if (!UpdateFromService()) {
457 // Make sure we have at least the cache data immediately.
458 RetrieveCachedData();
462 DeviceSettingsProvider::~DeviceSettingsProvider() {
463 if (device_settings_service_->GetOwnerSettingsService())
464 device_settings_service_->GetOwnerSettingsService()->RemoveObserver(this);
465 device_settings_service_->RemoveObserver(this);
468 // static
469 bool DeviceSettingsProvider::IsDeviceSetting(const std::string& name) {
470 const char* const* end = kKnownSettings + arraysize(kKnownSettings);
471 return std::find(kKnownSettings, end, name) != end;
474 void DeviceSettingsProvider::DoSet(const std::string& path,
475 const base::Value& in_value) {
476 // Make sure that either the current user is the device owner or the
477 // device doesn't have an owner yet.
478 if (!(device_settings_service_->HasPrivateOwnerKey() ||
479 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)) {
480 LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
482 // Revert UI change.
483 NotifyObservers(path);
484 return;
487 if (!IsDeviceSetting(path)) {
488 NOTREACHED() << "Try to set unhandled cros setting " << path;
489 return;
492 if (device_settings_service_->HasPrivateOwnerKey()) {
493 // Directly set setting through OwnerSettingsService.
494 ownership::OwnerSettingsService* service =
495 device_settings_service_->GetOwnerSettingsService();
496 if (!service->Set(path, in_value)) {
497 NotifyObservers(path);
498 return;
500 } else {
501 // Temporary store new setting in
502 // |device_settings_|. |device_settings_| will be stored on a disk
503 // as soon as an ownership of device the will be taken.
504 OwnerSettingsServiceChromeOS::UpdateDeviceSettings(
505 path, in_value, device_settings_);
506 em::PolicyData data;
507 data.set_username(device_settings_service_->GetUsername());
508 CHECK(device_settings_.SerializeToString(data.mutable_policy_value()));
510 // Set the cache to the updated value.
511 UpdateValuesCache(data, device_settings_, TEMPORARILY_UNTRUSTED);
513 if (!device_settings_cache::Store(data, g_browser_process->local_state())) {
514 LOG(ERROR) << "Couldn't store to the temp storage.";
515 NotifyObservers(path);
516 return;
520 bool metrics_value;
521 if (path == kStatsReportingPref && in_value.GetAsBoolean(&metrics_value))
522 ApplyMetricsSetting(false, metrics_value);
525 void DeviceSettingsProvider::OwnershipStatusChanged() {
526 DeviceSettingsService::OwnershipStatus new_ownership_status =
527 device_settings_service_->GetOwnershipStatus();
529 if (device_settings_service_->GetOwnerSettingsService())
530 device_settings_service_->GetOwnerSettingsService()->AddObserver(this);
532 // If the device just became owned, write the settings accumulated in the
533 // cache to device settings proper. It is important that writing only happens
534 // in this case, as during normal operation, the contents of the cache should
535 // never overwrite actual device settings.
536 if (new_ownership_status == DeviceSettingsService::OWNERSHIP_TAKEN &&
537 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE &&
538 device_settings_service_->HasPrivateOwnerKey()) {
539 // There shouldn't be any pending writes, since the cache writes are all
540 // immediate.
541 DCHECK(!store_callback_factory_.HasWeakPtrs());
543 trusted_status_ = TEMPORARILY_UNTRUSTED;
544 // Apply the locally-accumulated device settings on top of the initial
545 // settings from the service and write back the result.
546 if (device_settings_service_->device_settings()) {
547 em::ChromeDeviceSettingsProto new_settings(
548 *device_settings_service_->device_settings());
549 new_settings.MergeFrom(device_settings_);
550 device_settings_.Swap(&new_settings);
553 scoped_ptr<em::PolicyData> policy(new em::PolicyData());
554 policy->set_username(device_settings_service_->GetUsername());
555 CHECK(device_settings_.SerializeToString(policy->mutable_policy_value()));
556 if (!device_settings_service_->GetOwnerSettingsService()
557 ->CommitTentativeDeviceSettings(policy.Pass())) {
558 LOG(ERROR) << "Can't store policy";
562 // The owner key might have become available, allowing migration to happen.
563 AttemptMigration();
565 ownership_status_ = new_ownership_status;
568 void DeviceSettingsProvider::DeviceSettingsUpdated() {
569 if (!store_callback_factory_.HasWeakPtrs())
570 UpdateAndProceedStoring();
573 void DeviceSettingsProvider::OnDeviceSettingsServiceShutdown() {
574 device_settings_service_ = nullptr;
577 void DeviceSettingsProvider::OnTentativeChangesInPolicy(
578 const em::PolicyData& policy_data) {
579 em::ChromeDeviceSettingsProto device_settings;
580 CHECK(device_settings.ParseFromString(policy_data.policy_value()));
581 UpdateValuesCache(policy_data, device_settings, TEMPORARILY_UNTRUSTED);
584 void DeviceSettingsProvider::RetrieveCachedData() {
585 em::PolicyData policy_data;
586 if (!device_settings_cache::Retrieve(&policy_data,
587 g_browser_process->local_state()) ||
588 !device_settings_.ParseFromString(policy_data.policy_value())) {
589 VLOG(1) << "Can't retrieve temp store, possibly not created yet.";
592 UpdateValuesCache(policy_data, device_settings_, trusted_status_);
595 void DeviceSettingsProvider::UpdateValuesCache(
596 const em::PolicyData& policy_data,
597 const em::ChromeDeviceSettingsProto& settings,
598 TrustedStatus trusted_status) {
599 PrefValueMap new_values_cache;
601 // If the device is not managed, or is consumer-managed, we set the device
602 // owner value.
603 if (policy_data.has_username() &&
604 (policy::GetManagementMode(policy_data) ==
605 policy::MANAGEMENT_MODE_LOCAL_OWNER ||
606 policy::GetManagementMode(policy_data) ==
607 policy::MANAGEMENT_MODE_CONSUMER_MANAGED)) {
608 new_values_cache.SetString(kDeviceOwner, policy_data.username());
611 if (policy_data.has_service_account_identity()) {
612 new_values_cache.SetString(kServiceAccountIdentity,
613 policy_data.service_account_identity());
616 DecodeLoginPolicies(settings, &new_values_cache);
617 DecodeNetworkPolicies(settings, &new_values_cache);
618 DecodeAutoUpdatePolicies(settings, &new_values_cache);
619 DecodeReportingPolicies(settings, &new_values_cache);
620 DecodeHeartbeatPolicies(settings, &new_values_cache);
621 DecodeGenericPolicies(settings, &new_values_cache);
622 DecodeDeviceState(policy_data, &new_values_cache);
624 // Collect all notifications but send them only after we have swapped the
625 // cache so that if somebody actually reads the cache will be already valid.
626 std::vector<std::string> notifications;
627 // Go through the new values and verify in the old ones.
628 PrefValueMap::iterator iter = new_values_cache.begin();
629 for (; iter != new_values_cache.end(); ++iter) {
630 const base::Value* old_value;
631 if (!values_cache_.GetValue(iter->first, &old_value) ||
632 !old_value->Equals(iter->second)) {
633 notifications.push_back(iter->first);
636 // Now check for values that have been removed from the policy blob.
637 for (iter = values_cache_.begin(); iter != values_cache_.end(); ++iter) {
638 const base::Value* value;
639 if (!new_values_cache.GetValue(iter->first, &value))
640 notifications.push_back(iter->first);
642 // Swap and notify.
643 values_cache_.Swap(&new_values_cache);
644 trusted_status_ = trusted_status;
645 for (size_t i = 0; i < notifications.size(); ++i)
646 NotifyObservers(notifications[i]);
649 void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file,
650 bool new_value) {
651 // TODO(pastarmovj): Remove this once migration is not needed anymore.
652 // If the value is not set we should try to migrate legacy consent file.
653 if (use_file) {
654 new_value = HasOldMetricsFile();
655 // Make sure the values will get eventually written to the policy file.
656 migration_values_.SetBoolean(kStatsReportingPref, new_value);
657 AttemptMigration();
658 VLOG(1) << "No metrics policy set will revert to checking "
659 << "consent file which is "
660 << (new_value ? "on." : "off.");
661 UMA_HISTOGRAM_COUNTS("DeviceSettings.MetricsMigrated", 1);
663 VLOG(1) << "Metrics policy is being set to : " << new_value
664 << "(use file : " << use_file << ")";
665 // TODO(pastarmovj): Remove this once we don't need to regenerate the
666 // consent file for the GUID anymore.
667 InitiateMetricsReportingChange(new_value, OnMetricsReportingCallbackType());
670 void DeviceSettingsProvider::ApplySideEffects(
671 const em::ChromeDeviceSettingsProto& settings) {
672 // First migrate metrics settings as needed.
673 if (settings.has_metrics_enabled())
674 ApplyMetricsSetting(false, settings.metrics_enabled().metrics_enabled());
675 else
676 ApplyMetricsSetting(true, false);
679 bool DeviceSettingsProvider::MitigateMissingPolicy() {
680 // First check if the device has been owned already and if not exit
681 // immediately.
682 policy::BrowserPolicyConnectorChromeOS* connector =
683 g_browser_process->platform_part()->browser_policy_connector_chromeos();
684 if (connector->GetDeviceMode() != policy::DEVICE_MODE_CONSUMER)
685 return false;
687 // If we are here the policy file were corrupted or missing. This can happen
688 // because we are migrating Pre R11 device to the new secure policies or there
689 // was an attempt to circumvent policy system. In this case we should populate
690 // the policy cache with "safe-mode" defaults which should allow the owner to
691 // log in but lock the device for anyone else until the policy blob has been
692 // recreated by the session manager.
693 LOG(ERROR) << "Corruption of the policy data has been detected."
694 << "Switching to \"safe-mode\" policies until the owner logs in "
695 << "to regenerate the policy data.";
697 device_settings_.Clear();
698 device_settings_.mutable_allow_new_users()->set_allow_new_users(true);
699 device_settings_.mutable_guest_mode_enabled()->set_guest_mode_enabled(true);
700 em::PolicyData empty_policy_data;
701 UpdateValuesCache(empty_policy_data, device_settings_, TRUSTED);
702 values_cache_.SetBoolean(kPolicyMissingMitigationMode, true);
704 return true;
707 const base::Value* DeviceSettingsProvider::Get(const std::string& path) const {
708 if (IsDeviceSetting(path)) {
709 const base::Value* value;
710 if (values_cache_.GetValue(path, &value))
711 return value;
712 } else {
713 NOTREACHED() << "Trying to get non cros setting.";
716 return NULL;
719 DeviceSettingsProvider::TrustedStatus
720 DeviceSettingsProvider::PrepareTrustedValues(const base::Closure& cb) {
721 TrustedStatus status = RequestTrustedEntity();
722 if (status == TEMPORARILY_UNTRUSTED && !cb.is_null())
723 callbacks_.push_back(cb);
724 return status;
727 bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const {
728 return IsDeviceSetting(path);
731 DeviceSettingsProvider::TrustedStatus
732 DeviceSettingsProvider::RequestTrustedEntity() {
733 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)
734 return TRUSTED;
735 return trusted_status_;
738 void DeviceSettingsProvider::UpdateAndProceedStoring() {
739 // Re-sync the cache from the service.
740 UpdateFromService();
743 bool DeviceSettingsProvider::UpdateFromService() {
744 bool settings_loaded = false;
745 switch (device_settings_service_->status()) {
746 case DeviceSettingsService::STORE_SUCCESS: {
747 const em::PolicyData* policy_data =
748 device_settings_service_->policy_data();
749 const em::ChromeDeviceSettingsProto* device_settings =
750 device_settings_service_->device_settings();
751 if (policy_data && device_settings) {
752 if (!device_settings_cache::Store(*policy_data,
753 g_browser_process->local_state())) {
754 LOG(ERROR) << "Couldn't update the local state cache.";
756 UpdateValuesCache(*policy_data, *device_settings, TRUSTED);
757 device_settings_ = *device_settings;
759 // TODO(pastarmovj): Make those side effects responsibility of the
760 // respective subsystems.
761 ApplySideEffects(*device_settings);
763 settings_loaded = true;
764 } else {
765 // Initial policy load is still pending.
766 trusted_status_ = TEMPORARILY_UNTRUSTED;
768 break;
770 case DeviceSettingsService::STORE_NO_POLICY:
771 if (MitigateMissingPolicy())
772 break;
773 // fall through.
774 case DeviceSettingsService::STORE_KEY_UNAVAILABLE:
775 VLOG(1) << "No policies present yet, will use the temp storage.";
776 trusted_status_ = PERMANENTLY_UNTRUSTED;
777 break;
778 case DeviceSettingsService::STORE_POLICY_ERROR:
779 case DeviceSettingsService::STORE_VALIDATION_ERROR:
780 case DeviceSettingsService::STORE_INVALID_POLICY:
781 case DeviceSettingsService::STORE_OPERATION_FAILED:
782 LOG(ERROR) << "Failed to retrieve cros policies. Reason: "
783 << device_settings_service_->status();
784 trusted_status_ = PERMANENTLY_UNTRUSTED;
785 break;
786 case DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR:
787 // The policy has failed to validate due to temporary error but it might
788 // take a long time until we recover so behave as it is a permanent error.
789 LOG(ERROR) << "Failed to retrieve cros policies because a temporary "
790 << "validation error has occurred. Retrying might succeed.";
791 trusted_status_ = PERMANENTLY_UNTRUSTED;
792 break;
795 // Notify the observers we are done.
796 std::vector<base::Closure> callbacks;
797 callbacks.swap(callbacks_);
798 for (size_t i = 0; i < callbacks.size(); ++i)
799 callbacks[i].Run();
801 return settings_loaded;
804 void DeviceSettingsProvider::AttemptMigration() {
805 if (device_settings_service_->HasPrivateOwnerKey()) {
806 PrefValueMap::const_iterator i;
807 for (i = migration_values_.begin(); i != migration_values_.end(); ++i)
808 DoSet(i->first, *i->second);
809 migration_values_.Clear();
813 } // namespace chromeos