Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / settings / device_settings_provider.cc
blob6cf0395485a6cc6e2900f7767c1291ebe3acea8b
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 kSystemLogUploadEnabled,
66 kPolicyMissingMitigationMode,
67 kRebootOnShutdown,
68 kReleaseChannel,
69 kReleaseChannelDelegated,
70 kReportDeviceActivityTimes,
71 kReportDeviceBootMode,
72 kReportDeviceHardwareStatus,
73 kReportDeviceLocation,
74 kReportDeviceNetworkInterfaces,
75 kReportDeviceSessionStatus,
76 kReportDeviceUsers,
77 kReportDeviceVersionInfo,
78 kReportUploadFrequency,
79 kServiceAccountIdentity,
80 kSignedDataRoamingEnabled,
81 kStartUpFlags,
82 kStatsReportingPref,
83 kSystemTimezonePolicy,
84 kSystemUse24HourClock,
85 kUpdateDisabled,
86 kVariationsRestrictParameter,
89 bool HasOldMetricsFile() {
90 // TODO(pastarmovj): Remove this once migration is not needed anymore.
91 // If the value is not set we should try to migrate legacy consent file.
92 // Loading consent file state causes us to do blocking IO on UI thread.
93 // Temporarily allow it until we fix http://crbug.com/62626
94 base::ThreadRestrictions::ScopedAllowIO allow_io;
95 return GoogleUpdateSettings::GetCollectStatsConsent();
98 void DecodeLoginPolicies(
99 const em::ChromeDeviceSettingsProto& policy,
100 PrefValueMap* new_values_cache) {
101 // For all our boolean settings the following is applicable:
102 // true is default permissive value and false is safe prohibitive value.
103 // Exceptions:
104 // kAccountsPrefEphemeralUsersEnabled has a default value of false.
105 // kAccountsPrefSupervisedUsersEnabled has a default value of false
106 // for enterprise devices and true for consumer devices.
107 // kAccountsPrefTransferSAMLCookies has a default value of false.
108 if (policy.has_allow_new_users() &&
109 policy.allow_new_users().has_allow_new_users()) {
110 if (policy.allow_new_users().allow_new_users()) {
111 // New users allowed, user whitelist ignored.
112 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true);
113 } else {
114 // New users not allowed, enforce user whitelist if present.
115 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser,
116 !policy.has_user_whitelist());
118 } else {
119 // No configured allow-new-users value, enforce whitelist if non-empty.
120 new_values_cache->SetBoolean(
121 kAccountsPrefAllowNewUser,
122 policy.user_whitelist().user_whitelist_size() == 0);
125 new_values_cache->SetBoolean(
126 kRebootOnShutdown,
127 policy.has_reboot_on_shutdown() &&
128 policy.reboot_on_shutdown().has_reboot_on_shutdown() &&
129 policy.reboot_on_shutdown().reboot_on_shutdown());
131 new_values_cache->SetBoolean(
132 kAccountsPrefAllowGuest,
133 !policy.has_guest_mode_enabled() ||
134 !policy.guest_mode_enabled().has_guest_mode_enabled() ||
135 policy.guest_mode_enabled().guest_mode_enabled());
137 policy::BrowserPolicyConnectorChromeOS* connector =
138 g_browser_process->platform_part()->browser_policy_connector_chromeos();
139 bool supervised_users_enabled = false;
140 if (connector->IsEnterpriseManaged()) {
141 supervised_users_enabled =
142 policy.has_supervised_users_settings() &&
143 policy.supervised_users_settings().has_supervised_users_enabled() &&
144 policy.supervised_users_settings().supervised_users_enabled();
145 } else {
146 supervised_users_enabled =
147 !policy.has_supervised_users_settings() ||
148 !policy.supervised_users_settings().has_supervised_users_enabled() ||
149 policy.supervised_users_settings().supervised_users_enabled();
151 new_values_cache->SetBoolean(
152 kAccountsPrefSupervisedUsersEnabled, supervised_users_enabled);
154 new_values_cache->SetBoolean(
155 kAccountsPrefShowUserNamesOnSignIn,
156 !policy.has_show_user_names() ||
157 !policy.show_user_names().has_show_user_names() ||
158 policy.show_user_names().show_user_names());
160 new_values_cache->SetBoolean(
161 kAccountsPrefEphemeralUsersEnabled,
162 policy.has_ephemeral_users_enabled() &&
163 policy.ephemeral_users_enabled().has_ephemeral_users_enabled() &&
164 policy.ephemeral_users_enabled().ephemeral_users_enabled());
166 scoped_ptr<base::ListValue> list(new base::ListValue());
167 const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist();
168 const RepeatedPtrField<std::string>& whitelist =
169 whitelist_proto.user_whitelist();
170 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin();
171 it != whitelist.end(); ++it) {
172 list->Append(new base::StringValue(*it));
174 new_values_cache->SetValue(kAccountsPrefUsers, list.Pass());
176 scoped_ptr<base::ListValue> account_list(new base::ListValue());
177 const em::DeviceLocalAccountsProto device_local_accounts_proto =
178 policy.device_local_accounts();
179 const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts =
180 device_local_accounts_proto.account();
181 RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry;
182 for (entry = accounts.begin(); entry != accounts.end(); ++entry) {
183 scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue());
184 if (entry->has_type()) {
185 if (entry->has_account_id()) {
186 entry_dict->SetStringWithoutPathExpansion(
187 kAccountsPrefDeviceLocalAccountsKeyId, entry->account_id());
189 entry_dict->SetIntegerWithoutPathExpansion(
190 kAccountsPrefDeviceLocalAccountsKeyType, entry->type());
191 if (entry->kiosk_app().has_app_id()) {
192 entry_dict->SetStringWithoutPathExpansion(
193 kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
194 entry->kiosk_app().app_id());
196 if (entry->kiosk_app().has_update_url()) {
197 entry_dict->SetStringWithoutPathExpansion(
198 kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL,
199 entry->kiosk_app().update_url());
201 } else if (entry->has_deprecated_public_session_id()) {
202 // Deprecated public session specification.
203 entry_dict->SetStringWithoutPathExpansion(
204 kAccountsPrefDeviceLocalAccountsKeyId,
205 entry->deprecated_public_session_id());
206 entry_dict->SetIntegerWithoutPathExpansion(
207 kAccountsPrefDeviceLocalAccountsKeyType,
208 policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION);
210 account_list->Append(entry_dict.Pass());
212 new_values_cache->SetValue(kAccountsPrefDeviceLocalAccounts,
213 account_list.Pass());
215 if (policy.has_device_local_accounts()) {
216 if (policy.device_local_accounts().has_auto_login_id()) {
217 new_values_cache->SetString(
218 kAccountsPrefDeviceLocalAccountAutoLoginId,
219 policy.device_local_accounts().auto_login_id());
221 if (policy.device_local_accounts().has_auto_login_delay()) {
222 new_values_cache->SetInteger(
223 kAccountsPrefDeviceLocalAccountAutoLoginDelay,
224 policy.device_local_accounts().auto_login_delay());
228 new_values_cache->SetBoolean(
229 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
230 policy.device_local_accounts().enable_auto_login_bailout());
231 new_values_cache->SetBoolean(
232 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline,
233 policy.device_local_accounts().prompt_for_network_when_offline());
235 if (policy.has_start_up_flags()) {
236 scoped_ptr<base::ListValue> list(new base::ListValue());
237 const em::StartUpFlagsProto& flags_proto = policy.start_up_flags();
238 const RepeatedPtrField<std::string>& flags = flags_proto.flags();
239 for (RepeatedPtrField<std::string>::const_iterator it = flags.begin();
240 it != flags.end(); ++it) {
241 list->Append(new base::StringValue(*it));
243 new_values_cache->SetValue(kStartUpFlags, list.Pass());
246 if (policy.has_saml_settings()) {
247 new_values_cache->SetBoolean(
248 kAccountsPrefTransferSAMLCookies,
249 policy.saml_settings().transfer_saml_cookies());
252 // The behavior when policy is not set and when it is set to an empty string
253 // is the same. Thus lets add policy only if it is set and its value is not
254 // an empty string.
255 if (policy.has_login_screen_domain_auto_complete() &&
256 policy.login_screen_domain_auto_complete()
257 .has_login_screen_domain_auto_complete() &&
258 !policy.login_screen_domain_auto_complete()
259 .login_screen_domain_auto_complete()
260 .empty()) {
261 new_values_cache->SetString(kAccountsPrefLoginScreenDomainAutoComplete,
262 policy.login_screen_domain_auto_complete()
263 .login_screen_domain_auto_complete());
267 void DecodeNetworkPolicies(
268 const em::ChromeDeviceSettingsProto& policy,
269 PrefValueMap* new_values_cache) {
270 // kSignedDataRoamingEnabled has a default value of false.
271 new_values_cache->SetBoolean(
272 kSignedDataRoamingEnabled,
273 policy.has_data_roaming_enabled() &&
274 policy.data_roaming_enabled().has_data_roaming_enabled() &&
275 policy.data_roaming_enabled().data_roaming_enabled());
278 void DecodeAutoUpdatePolicies(
279 const em::ChromeDeviceSettingsProto& policy,
280 PrefValueMap* new_values_cache) {
281 if (policy.has_auto_update_settings()) {
282 const em::AutoUpdateSettingsProto& au_settings_proto =
283 policy.auto_update_settings();
284 if (au_settings_proto.has_update_disabled()) {
285 new_values_cache->SetBoolean(kUpdateDisabled,
286 au_settings_proto.update_disabled());
288 const RepeatedField<int>& allowed_connection_types =
289 au_settings_proto.allowed_connection_types();
290 scoped_ptr<base::ListValue> list(new base::ListValue());
291 for (RepeatedField<int>::const_iterator i(allowed_connection_types.begin());
292 i != allowed_connection_types.end(); ++i) {
293 list->Append(new base::FundamentalValue(*i));
295 new_values_cache->SetValue(kAllowedConnectionTypesForUpdate, list.Pass());
299 void DecodeReportingPolicies(
300 const em::ChromeDeviceSettingsProto& policy,
301 PrefValueMap* new_values_cache) {
302 if (policy.has_device_reporting()) {
303 const em::DeviceReportingProto& reporting_policy =
304 policy.device_reporting();
305 if (reporting_policy.has_report_version_info()) {
306 new_values_cache->SetBoolean(
307 kReportDeviceVersionInfo,
308 reporting_policy.report_version_info());
310 if (reporting_policy.has_report_activity_times()) {
311 new_values_cache->SetBoolean(
312 kReportDeviceActivityTimes,
313 reporting_policy.report_activity_times());
315 if (reporting_policy.has_report_boot_mode()) {
316 new_values_cache->SetBoolean(
317 kReportDeviceBootMode,
318 reporting_policy.report_boot_mode());
320 if (reporting_policy.has_report_network_interfaces()) {
321 new_values_cache->SetBoolean(
322 kReportDeviceNetworkInterfaces,
323 reporting_policy.report_network_interfaces());
325 if (reporting_policy.has_report_users()) {
326 new_values_cache->SetBoolean(
327 kReportDeviceUsers,
328 reporting_policy.report_users());
330 if (reporting_policy.has_report_hardware_status()) {
331 new_values_cache->SetBoolean(
332 kReportDeviceHardwareStatus,
333 reporting_policy.report_hardware_status());
335 if (reporting_policy.has_report_session_status()) {
336 new_values_cache->SetBoolean(
337 kReportDeviceSessionStatus,
338 reporting_policy.report_session_status());
340 if (reporting_policy.has_device_status_frequency()) {
341 new_values_cache->SetInteger(
342 kReportUploadFrequency,
343 reporting_policy.device_status_frequency());
348 void DecodeHeartbeatPolicies(
349 const em::ChromeDeviceSettingsProto& policy,
350 PrefValueMap* new_values_cache) {
351 if (!policy.has_device_heartbeat_settings())
352 return;
354 const em::DeviceHeartbeatSettingsProto& heartbeat_policy =
355 policy.device_heartbeat_settings();
356 if (heartbeat_policy.has_heartbeat_enabled()) {
357 new_values_cache->SetBoolean(
358 kHeartbeatEnabled,
359 heartbeat_policy.heartbeat_enabled());
361 if (heartbeat_policy.has_heartbeat_frequency()) {
362 new_values_cache->SetInteger(
363 kHeartbeatFrequency,
364 heartbeat_policy.heartbeat_frequency());
368 void DecodeGenericPolicies(
369 const em::ChromeDeviceSettingsProto& policy,
370 PrefValueMap* new_values_cache) {
371 if (policy.has_metrics_enabled()) {
372 new_values_cache->SetBoolean(kStatsReportingPref,
373 policy.metrics_enabled().metrics_enabled());
374 } else {
375 new_values_cache->SetBoolean(kStatsReportingPref, HasOldMetricsFile());
378 if (!policy.has_release_channel() ||
379 !policy.release_channel().has_release_channel()) {
380 // Default to an invalid channel (will be ignored).
381 new_values_cache->SetString(kReleaseChannel, "");
382 } else {
383 new_values_cache->SetString(kReleaseChannel,
384 policy.release_channel().release_channel());
387 new_values_cache->SetBoolean(
388 kReleaseChannelDelegated,
389 policy.has_release_channel() &&
390 policy.release_channel().has_release_channel_delegated() &&
391 policy.release_channel().release_channel_delegated());
393 if (policy.has_system_timezone()) {
394 if (policy.system_timezone().has_timezone()) {
395 new_values_cache->SetString(
396 kSystemTimezonePolicy,
397 policy.system_timezone().timezone());
401 if (policy.has_use_24hour_clock()) {
402 if (policy.use_24hour_clock().has_use_24hour_clock()) {
403 new_values_cache->SetBoolean(
404 kSystemUse24HourClock, policy.use_24hour_clock().use_24hour_clock());
408 if (policy.has_allow_redeem_offers()) {
409 new_values_cache->SetBoolean(
410 kAllowRedeemChromeOsRegistrationOffers,
411 policy.allow_redeem_offers().allow_redeem_offers());
412 } else {
413 new_values_cache->SetBoolean(
414 kAllowRedeemChromeOsRegistrationOffers,
415 true);
418 if (policy.has_variations_parameter()) {
419 new_values_cache->SetString(
420 kVariationsRestrictParameter,
421 policy.variations_parameter().parameter());
424 new_values_cache->SetBoolean(
425 kDeviceAttestationEnabled,
426 policy.attestation_settings().attestation_enabled());
428 if (policy.has_attestation_settings() &&
429 policy.attestation_settings().has_content_protection_enabled()) {
430 new_values_cache->SetBoolean(
431 kAttestationForContentProtectionEnabled,
432 policy.attestation_settings().content_protection_enabled());
433 } else {
434 new_values_cache->SetBoolean(kAttestationForContentProtectionEnabled, true);
437 if (policy.has_extension_cache_size() &&
438 policy.extension_cache_size().has_extension_cache_size()) {
439 new_values_cache->SetInteger(
440 kExtensionCacheSize,
441 policy.extension_cache_size().extension_cache_size());
445 void DecodeLogUploadPolicies(const em::ChromeDeviceSettingsProto& policy,
446 PrefValueMap* new_values_cache) {
447 if (!policy.has_device_log_upload_settings())
448 return;
450 const em::DeviceLogUploadSettingsProto& log_upload_policy =
451 policy.device_log_upload_settings();
452 if (log_upload_policy.has_system_log_upload_enabled()) {
453 new_values_cache->SetBoolean(kSystemLogUploadEnabled,
454 log_upload_policy.system_log_upload_enabled());
458 void DecodeDeviceState(const em::PolicyData& policy_data,
459 PrefValueMap* new_values_cache) {
460 if (!policy_data.has_device_state())
461 return;
463 const em::DeviceState& device_state = policy_data.device_state();
465 if (device_state.device_mode() == em::DeviceState::DEVICE_MODE_DISABLED)
466 new_values_cache->SetBoolean(kDeviceDisabled, true);
467 if (device_state.has_disabled_state() &&
468 device_state.disabled_state().has_message()) {
469 new_values_cache->SetString(kDeviceDisabledMessage,
470 device_state.disabled_state().message());
474 } // namespace
476 DeviceSettingsProvider::DeviceSettingsProvider(
477 const NotifyObserversCallback& notify_cb,
478 DeviceSettingsService* device_settings_service)
479 : CrosSettingsProvider(notify_cb),
480 device_settings_service_(device_settings_service),
481 trusted_status_(TEMPORARILY_UNTRUSTED),
482 ownership_status_(device_settings_service_->GetOwnershipStatus()),
483 store_callback_factory_(this) {
484 device_settings_service_->AddObserver(this);
485 if (!UpdateFromService()) {
486 // Make sure we have at least the cache data immediately.
487 RetrieveCachedData();
491 DeviceSettingsProvider::~DeviceSettingsProvider() {
492 if (device_settings_service_->GetOwnerSettingsService())
493 device_settings_service_->GetOwnerSettingsService()->RemoveObserver(this);
494 device_settings_service_->RemoveObserver(this);
497 // static
498 bool DeviceSettingsProvider::IsDeviceSetting(const std::string& name) {
499 const char* const* end = kKnownSettings + arraysize(kKnownSettings);
500 return std::find(kKnownSettings, end, name) != end;
503 void DeviceSettingsProvider::DoSet(const std::string& path,
504 const base::Value& in_value) {
505 // Make sure that either the current user is the device owner or the
506 // device doesn't have an owner yet.
507 if (!(device_settings_service_->HasPrivateOwnerKey() ||
508 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)) {
509 LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
511 // Revert UI change.
512 NotifyObservers(path);
513 return;
516 if (!IsDeviceSetting(path)) {
517 NOTREACHED() << "Try to set unhandled cros setting " << path;
518 return;
521 if (device_settings_service_->HasPrivateOwnerKey()) {
522 // Directly set setting through OwnerSettingsService.
523 ownership::OwnerSettingsService* service =
524 device_settings_service_->GetOwnerSettingsService();
525 if (!service->Set(path, in_value)) {
526 NotifyObservers(path);
527 return;
529 } else {
530 // Temporary store new setting in
531 // |device_settings_|. |device_settings_| will be stored on a disk
532 // as soon as an ownership of device the will be taken.
533 OwnerSettingsServiceChromeOS::UpdateDeviceSettings(
534 path, in_value, device_settings_);
535 em::PolicyData data;
536 data.set_username(device_settings_service_->GetUsername());
537 CHECK(device_settings_.SerializeToString(data.mutable_policy_value()));
539 // Set the cache to the updated value.
540 UpdateValuesCache(data, device_settings_, TEMPORARILY_UNTRUSTED);
542 if (!device_settings_cache::Store(data, g_browser_process->local_state())) {
543 LOG(ERROR) << "Couldn't store to the temp storage.";
544 NotifyObservers(path);
545 return;
549 bool metrics_value;
550 if (path == kStatsReportingPref && in_value.GetAsBoolean(&metrics_value))
551 ApplyMetricsSetting(false, metrics_value);
554 void DeviceSettingsProvider::OwnershipStatusChanged() {
555 DeviceSettingsService::OwnershipStatus new_ownership_status =
556 device_settings_service_->GetOwnershipStatus();
558 if (device_settings_service_->GetOwnerSettingsService())
559 device_settings_service_->GetOwnerSettingsService()->AddObserver(this);
561 // If the device just became owned, write the settings accumulated in the
562 // cache to device settings proper. It is important that writing only happens
563 // in this case, as during normal operation, the contents of the cache should
564 // never overwrite actual device settings.
565 if (new_ownership_status == DeviceSettingsService::OWNERSHIP_TAKEN &&
566 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE &&
567 device_settings_service_->HasPrivateOwnerKey()) {
568 // There shouldn't be any pending writes, since the cache writes are all
569 // immediate.
570 DCHECK(!store_callback_factory_.HasWeakPtrs());
572 trusted_status_ = TEMPORARILY_UNTRUSTED;
573 // Apply the locally-accumulated device settings on top of the initial
574 // settings from the service and write back the result.
575 if (device_settings_service_->device_settings()) {
576 em::ChromeDeviceSettingsProto new_settings(
577 *device_settings_service_->device_settings());
578 new_settings.MergeFrom(device_settings_);
579 device_settings_.Swap(&new_settings);
582 scoped_ptr<em::PolicyData> policy(new em::PolicyData());
583 policy->set_username(device_settings_service_->GetUsername());
584 CHECK(device_settings_.SerializeToString(policy->mutable_policy_value()));
585 if (!device_settings_service_->GetOwnerSettingsService()
586 ->CommitTentativeDeviceSettings(policy.Pass())) {
587 LOG(ERROR) << "Can't store policy";
591 // The owner key might have become available, allowing migration to happen.
592 AttemptMigration();
594 ownership_status_ = new_ownership_status;
597 void DeviceSettingsProvider::DeviceSettingsUpdated() {
598 if (!store_callback_factory_.HasWeakPtrs())
599 UpdateAndProceedStoring();
602 void DeviceSettingsProvider::OnDeviceSettingsServiceShutdown() {
603 device_settings_service_ = nullptr;
606 void DeviceSettingsProvider::OnTentativeChangesInPolicy(
607 const em::PolicyData& policy_data) {
608 em::ChromeDeviceSettingsProto device_settings;
609 CHECK(device_settings.ParseFromString(policy_data.policy_value()));
610 UpdateValuesCache(policy_data, device_settings, TEMPORARILY_UNTRUSTED);
613 void DeviceSettingsProvider::RetrieveCachedData() {
614 em::PolicyData policy_data;
615 if (!device_settings_cache::Retrieve(&policy_data,
616 g_browser_process->local_state()) ||
617 !device_settings_.ParseFromString(policy_data.policy_value())) {
618 VLOG(1) << "Can't retrieve temp store, possibly not created yet.";
621 UpdateValuesCache(policy_data, device_settings_, trusted_status_);
624 void DeviceSettingsProvider::UpdateValuesCache(
625 const em::PolicyData& policy_data,
626 const em::ChromeDeviceSettingsProto& settings,
627 TrustedStatus trusted_status) {
628 PrefValueMap new_values_cache;
630 // If the device is not managed, or is consumer-managed, we set the device
631 // owner value.
632 if (policy_data.has_username() &&
633 (policy::GetManagementMode(policy_data) ==
634 policy::MANAGEMENT_MODE_LOCAL_OWNER ||
635 policy::GetManagementMode(policy_data) ==
636 policy::MANAGEMENT_MODE_CONSUMER_MANAGED)) {
637 new_values_cache.SetString(kDeviceOwner, policy_data.username());
640 if (policy_data.has_service_account_identity()) {
641 new_values_cache.SetString(kServiceAccountIdentity,
642 policy_data.service_account_identity());
645 DecodeLoginPolicies(settings, &new_values_cache);
646 DecodeNetworkPolicies(settings, &new_values_cache);
647 DecodeAutoUpdatePolicies(settings, &new_values_cache);
648 DecodeReportingPolicies(settings, &new_values_cache);
649 DecodeHeartbeatPolicies(settings, &new_values_cache);
650 DecodeGenericPolicies(settings, &new_values_cache);
651 DecodeLogUploadPolicies(settings, &new_values_cache);
652 DecodeDeviceState(policy_data, &new_values_cache);
654 // Collect all notifications but send them only after we have swapped the
655 // cache so that if somebody actually reads the cache will be already valid.
656 std::vector<std::string> notifications;
657 // Go through the new values and verify in the old ones.
658 PrefValueMap::iterator iter = new_values_cache.begin();
659 for (; iter != new_values_cache.end(); ++iter) {
660 const base::Value* old_value;
661 if (!values_cache_.GetValue(iter->first, &old_value) ||
662 !old_value->Equals(iter->second)) {
663 notifications.push_back(iter->first);
666 // Now check for values that have been removed from the policy blob.
667 for (iter = values_cache_.begin(); iter != values_cache_.end(); ++iter) {
668 const base::Value* value;
669 if (!new_values_cache.GetValue(iter->first, &value))
670 notifications.push_back(iter->first);
672 // Swap and notify.
673 values_cache_.Swap(&new_values_cache);
674 trusted_status_ = trusted_status;
675 for (size_t i = 0; i < notifications.size(); ++i)
676 NotifyObservers(notifications[i]);
679 void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file,
680 bool new_value) {
681 // TODO(pastarmovj): Remove this once migration is not needed anymore.
682 // If the value is not set we should try to migrate legacy consent file.
683 if (use_file) {
684 new_value = HasOldMetricsFile();
685 // Make sure the values will get eventually written to the policy file.
686 migration_values_.SetBoolean(kStatsReportingPref, new_value);
687 AttemptMigration();
688 VLOG(1) << "No metrics policy set will revert to checking "
689 << "consent file which is "
690 << (new_value ? "on." : "off.");
691 UMA_HISTOGRAM_COUNTS("DeviceSettings.MetricsMigrated", 1);
693 VLOG(1) << "Metrics policy is being set to : " << new_value
694 << "(use file : " << use_file << ")";
695 // TODO(pastarmovj): Remove this once we don't need to regenerate the
696 // consent file for the GUID anymore.
697 InitiateMetricsReportingChange(new_value, OnMetricsReportingCallbackType());
700 void DeviceSettingsProvider::ApplySideEffects(
701 const em::ChromeDeviceSettingsProto& settings) {
702 // First migrate metrics settings as needed.
703 if (settings.has_metrics_enabled())
704 ApplyMetricsSetting(false, settings.metrics_enabled().metrics_enabled());
705 else
706 ApplyMetricsSetting(true, false);
709 bool DeviceSettingsProvider::MitigateMissingPolicy() {
710 // First check if the device has been owned already and if not exit
711 // immediately.
712 policy::BrowserPolicyConnectorChromeOS* connector =
713 g_browser_process->platform_part()->browser_policy_connector_chromeos();
714 if (connector->GetDeviceMode() != policy::DEVICE_MODE_CONSUMER)
715 return false;
717 // If we are here the policy file were corrupted or missing. This can happen
718 // because we are migrating Pre R11 device to the new secure policies or there
719 // was an attempt to circumvent policy system. In this case we should populate
720 // the policy cache with "safe-mode" defaults which should allow the owner to
721 // log in but lock the device for anyone else until the policy blob has been
722 // recreated by the session manager.
723 LOG(ERROR) << "Corruption of the policy data has been detected."
724 << "Switching to \"safe-mode\" policies until the owner logs in "
725 << "to regenerate the policy data.";
727 device_settings_.Clear();
728 device_settings_.mutable_allow_new_users()->set_allow_new_users(true);
729 device_settings_.mutable_guest_mode_enabled()->set_guest_mode_enabled(true);
730 em::PolicyData empty_policy_data;
731 UpdateValuesCache(empty_policy_data, device_settings_, TRUSTED);
732 values_cache_.SetBoolean(kPolicyMissingMitigationMode, true);
734 return true;
737 const base::Value* DeviceSettingsProvider::Get(const std::string& path) const {
738 if (IsDeviceSetting(path)) {
739 const base::Value* value;
740 if (values_cache_.GetValue(path, &value))
741 return value;
742 } else {
743 NOTREACHED() << "Trying to get non cros setting.";
746 return NULL;
749 DeviceSettingsProvider::TrustedStatus
750 DeviceSettingsProvider::PrepareTrustedValues(const base::Closure& cb) {
751 TrustedStatus status = RequestTrustedEntity();
752 if (status == TEMPORARILY_UNTRUSTED && !cb.is_null())
753 callbacks_.push_back(cb);
754 return status;
757 bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const {
758 return IsDeviceSetting(path);
761 DeviceSettingsProvider::TrustedStatus
762 DeviceSettingsProvider::RequestTrustedEntity() {
763 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)
764 return TRUSTED;
765 return trusted_status_;
768 void DeviceSettingsProvider::UpdateAndProceedStoring() {
769 // Re-sync the cache from the service.
770 UpdateFromService();
773 bool DeviceSettingsProvider::UpdateFromService() {
774 bool settings_loaded = false;
775 switch (device_settings_service_->status()) {
776 case DeviceSettingsService::STORE_SUCCESS: {
777 const em::PolicyData* policy_data =
778 device_settings_service_->policy_data();
779 const em::ChromeDeviceSettingsProto* device_settings =
780 device_settings_service_->device_settings();
781 if (policy_data && device_settings) {
782 if (!device_settings_cache::Store(*policy_data,
783 g_browser_process->local_state())) {
784 LOG(ERROR) << "Couldn't update the local state cache.";
786 UpdateValuesCache(*policy_data, *device_settings, TRUSTED);
787 device_settings_ = *device_settings;
789 // TODO(pastarmovj): Make those side effects responsibility of the
790 // respective subsystems.
791 ApplySideEffects(*device_settings);
793 settings_loaded = true;
794 } else {
795 // Initial policy load is still pending.
796 trusted_status_ = TEMPORARILY_UNTRUSTED;
798 break;
800 case DeviceSettingsService::STORE_NO_POLICY:
801 if (MitigateMissingPolicy())
802 break;
803 // fall through.
804 case DeviceSettingsService::STORE_KEY_UNAVAILABLE:
805 VLOG(1) << "No policies present yet, will use the temp storage.";
806 trusted_status_ = PERMANENTLY_UNTRUSTED;
807 break;
808 case DeviceSettingsService::STORE_POLICY_ERROR:
809 case DeviceSettingsService::STORE_VALIDATION_ERROR:
810 case DeviceSettingsService::STORE_INVALID_POLICY:
811 case DeviceSettingsService::STORE_OPERATION_FAILED:
812 LOG(ERROR) << "Failed to retrieve cros policies. Reason: "
813 << device_settings_service_->status();
814 trusted_status_ = PERMANENTLY_UNTRUSTED;
815 break;
816 case DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR:
817 // The policy has failed to validate due to temporary error but it might
818 // take a long time until we recover so behave as it is a permanent error.
819 LOG(ERROR) << "Failed to retrieve cros policies because a temporary "
820 << "validation error has occurred. Retrying might succeed.";
821 trusted_status_ = PERMANENTLY_UNTRUSTED;
822 break;
825 // Notify the observers we are done.
826 std::vector<base::Closure> callbacks;
827 callbacks.swap(callbacks_);
828 for (size_t i = 0; i < callbacks.size(); ++i)
829 callbacks[i].Run();
831 return settings_loaded;
834 void DeviceSettingsProvider::AttemptMigration() {
835 if (device_settings_service_->HasPrivateOwnerKey()) {
836 PrefValueMap::const_iterator i;
837 for (i = migration_values_.begin(); i != migration_values_.end(); ++i)
838 DoSet(i->first, *i->second);
839 migration_values_.Clear();
843 } // namespace chromeos