[Android] Allow multiple --install in bb_device_steps.py.
[chromium-blink-merge.git] / chrome / browser / chromeos / settings / device_settings_provider.cc
blob7c2196f563169d377d386ca0f534efcb83240d41
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 kAppPack,
57 kAttestationForContentProtectionEnabled,
58 kDeviceAttestationEnabled,
59 kDeviceOwner,
60 kIdleLogoutTimeout,
61 kIdleLogoutWarningDuration,
62 kPolicyMissingMitigationMode,
63 kReleaseChannel,
64 kReleaseChannelDelegated,
65 kReportDeviceActivityTimes,
66 kReportDeviceBootMode,
67 kReportDeviceLocation,
68 kReportDeviceNetworkInterfaces,
69 kReportDeviceUsers,
70 kReportDeviceVersionInfo,
71 kScreenSaverExtensionId,
72 kScreenSaverTimeout,
73 kServiceAccountIdentity,
74 kSignedDataRoamingEnabled,
75 kStartUpFlags,
76 kStartUpUrls,
77 kStatsReportingPref,
78 kSystemTimezonePolicy,
79 kSystemUse24HourClock,
80 kUpdateDisabled,
81 kVariationsRestrictParameter,
82 kDeviceDisabled,
83 kDeviceDisabledMessage,
86 bool HasOldMetricsFile() {
87 // TODO(pastarmovj): Remove this once migration is not needed anymore.
88 // If the value is not set we should try to migrate legacy consent file.
89 // Loading consent file state causes us to do blocking IO on UI thread.
90 // Temporarily allow it until we fix http://crbug.com/62626
91 base::ThreadRestrictions::ScopedAllowIO allow_io;
92 return GoogleUpdateSettings::GetCollectStatsConsent();
95 void DecodeLoginPolicies(
96 const em::ChromeDeviceSettingsProto& policy,
97 PrefValueMap* new_values_cache) {
98 // For all our boolean settings the following is applicable:
99 // true is default permissive value and false is safe prohibitive value.
100 // Exceptions:
101 // kAccountsPrefEphemeralUsersEnabled has a default value of false.
102 // kAccountsPrefSupervisedUsersEnabled has a default value of false
103 // for enterprise devices and true for consumer devices.
104 // kAccountsPrefTransferSAMLCookies has a default value of false.
105 if (policy.has_allow_new_users() &&
106 policy.allow_new_users().has_allow_new_users()) {
107 if (policy.allow_new_users().allow_new_users()) {
108 // New users allowed, user whitelist ignored.
109 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true);
110 } else {
111 // New users not allowed, enforce user whitelist if present.
112 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser,
113 !policy.has_user_whitelist());
115 } else {
116 // No configured allow-new-users value, enforce whitelist if non-empty.
117 new_values_cache->SetBoolean(
118 kAccountsPrefAllowNewUser,
119 policy.user_whitelist().user_whitelist_size() == 0);
122 new_values_cache->SetBoolean(
123 kAccountsPrefAllowGuest,
124 !policy.has_guest_mode_enabled() ||
125 !policy.guest_mode_enabled().has_guest_mode_enabled() ||
126 policy.guest_mode_enabled().guest_mode_enabled());
128 policy::BrowserPolicyConnectorChromeOS* connector =
129 g_browser_process->platform_part()->browser_policy_connector_chromeos();
130 bool supervised_users_enabled = false;
131 if (connector->IsEnterpriseManaged()) {
132 supervised_users_enabled =
133 policy.has_supervised_users_settings() &&
134 policy.supervised_users_settings().has_supervised_users_enabled() &&
135 policy.supervised_users_settings().supervised_users_enabled();
136 } else {
137 supervised_users_enabled =
138 !policy.has_supervised_users_settings() ||
139 !policy.supervised_users_settings().has_supervised_users_enabled() ||
140 policy.supervised_users_settings().supervised_users_enabled();
142 new_values_cache->SetBoolean(
143 kAccountsPrefSupervisedUsersEnabled, supervised_users_enabled);
145 new_values_cache->SetBoolean(
146 kAccountsPrefShowUserNamesOnSignIn,
147 !policy.has_show_user_names() ||
148 !policy.show_user_names().has_show_user_names() ||
149 policy.show_user_names().show_user_names());
151 new_values_cache->SetBoolean(
152 kAccountsPrefEphemeralUsersEnabled,
153 policy.has_ephemeral_users_enabled() &&
154 policy.ephemeral_users_enabled().has_ephemeral_users_enabled() &&
155 policy.ephemeral_users_enabled().ephemeral_users_enabled());
157 base::ListValue* list = new base::ListValue();
158 const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist();
159 const RepeatedPtrField<std::string>& whitelist =
160 whitelist_proto.user_whitelist();
161 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin();
162 it != whitelist.end(); ++it) {
163 list->Append(new base::StringValue(*it));
165 new_values_cache->SetValue(kAccountsPrefUsers, list);
167 scoped_ptr<base::ListValue> account_list(new base::ListValue());
168 const em::DeviceLocalAccountsProto device_local_accounts_proto =
169 policy.device_local_accounts();
170 const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts =
171 device_local_accounts_proto.account();
172 RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry;
173 for (entry = accounts.begin(); entry != accounts.end(); ++entry) {
174 scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue());
175 if (entry->has_type()) {
176 if (entry->has_account_id()) {
177 entry_dict->SetStringWithoutPathExpansion(
178 kAccountsPrefDeviceLocalAccountsKeyId, entry->account_id());
180 entry_dict->SetIntegerWithoutPathExpansion(
181 kAccountsPrefDeviceLocalAccountsKeyType, entry->type());
182 if (entry->kiosk_app().has_app_id()) {
183 entry_dict->SetStringWithoutPathExpansion(
184 kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
185 entry->kiosk_app().app_id());
187 if (entry->kiosk_app().has_update_url()) {
188 entry_dict->SetStringWithoutPathExpansion(
189 kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL,
190 entry->kiosk_app().update_url());
192 } else if (entry->has_deprecated_public_session_id()) {
193 // Deprecated public session specification.
194 entry_dict->SetStringWithoutPathExpansion(
195 kAccountsPrefDeviceLocalAccountsKeyId,
196 entry->deprecated_public_session_id());
197 entry_dict->SetIntegerWithoutPathExpansion(
198 kAccountsPrefDeviceLocalAccountsKeyType,
199 policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION);
201 account_list->Append(entry_dict.release());
203 new_values_cache->SetValue(kAccountsPrefDeviceLocalAccounts,
204 account_list.release());
206 if (policy.has_device_local_accounts()) {
207 if (policy.device_local_accounts().has_auto_login_id()) {
208 new_values_cache->SetString(
209 kAccountsPrefDeviceLocalAccountAutoLoginId,
210 policy.device_local_accounts().auto_login_id());
212 if (policy.device_local_accounts().has_auto_login_delay()) {
213 new_values_cache->SetInteger(
214 kAccountsPrefDeviceLocalAccountAutoLoginDelay,
215 policy.device_local_accounts().auto_login_delay());
219 new_values_cache->SetBoolean(
220 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
221 policy.device_local_accounts().enable_auto_login_bailout());
222 new_values_cache->SetBoolean(
223 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline,
224 policy.device_local_accounts().prompt_for_network_when_offline());
226 if (policy.has_start_up_flags()) {
227 base::ListValue* list = new base::ListValue();
228 const em::StartUpFlagsProto& flags_proto = policy.start_up_flags();
229 const RepeatedPtrField<std::string>& flags = flags_proto.flags();
230 for (RepeatedPtrField<std::string>::const_iterator it = flags.begin();
231 it != flags.end(); ++it) {
232 list->Append(new base::StringValue(*it));
234 new_values_cache->SetValue(kStartUpFlags, list);
237 if (policy.has_saml_settings()) {
238 new_values_cache->SetBoolean(
239 kAccountsPrefTransferSAMLCookies,
240 policy.saml_settings().transfer_saml_cookies());
244 void DecodeKioskPolicies(
245 const em::ChromeDeviceSettingsProto& policy,
246 PrefValueMap* new_values_cache) {
247 if (policy.has_forced_logout_timeouts()) {
248 if (policy.forced_logout_timeouts().has_idle_logout_timeout()) {
249 new_values_cache->SetInteger(
250 kIdleLogoutTimeout,
251 policy.forced_logout_timeouts().idle_logout_timeout());
254 if (policy.forced_logout_timeouts().has_idle_logout_warning_duration()) {
255 new_values_cache->SetInteger(
256 kIdleLogoutWarningDuration,
257 policy.forced_logout_timeouts().idle_logout_warning_duration());
261 if (policy.has_login_screen_saver()) {
262 if (policy.login_screen_saver().has_screen_saver_timeout()) {
263 new_values_cache->SetInteger(
264 kScreenSaverTimeout,
265 policy.login_screen_saver().screen_saver_timeout());
268 if (policy.login_screen_saver().has_screen_saver_extension_id()) {
269 new_values_cache->SetString(
270 kScreenSaverExtensionId,
271 policy.login_screen_saver().screen_saver_extension_id());
275 if (policy.has_app_pack()) {
276 typedef RepeatedPtrField<em::AppPackEntryProto> proto_type;
277 base::ListValue* list = new base::ListValue;
278 const proto_type& app_pack = policy.app_pack().app_pack();
279 for (proto_type::const_iterator it = app_pack.begin();
280 it != app_pack.end(); ++it) {
281 base::DictionaryValue* entry = new base::DictionaryValue;
282 if (it->has_extension_id()) {
283 entry->SetStringWithoutPathExpansion(kAppPackKeyExtensionId,
284 it->extension_id());
286 if (it->has_update_url()) {
287 entry->SetStringWithoutPathExpansion(kAppPackKeyUpdateUrl,
288 it->update_url());
290 list->Append(entry);
292 new_values_cache->SetValue(kAppPack, list);
295 if (policy.has_start_up_urls()) {
296 base::ListValue* list = new base::ListValue();
297 const em::StartUpUrlsProto& urls_proto = policy.start_up_urls();
298 const RepeatedPtrField<std::string>& urls = urls_proto.start_up_urls();
299 for (RepeatedPtrField<std::string>::const_iterator it = urls.begin();
300 it != urls.end(); ++it) {
301 list->Append(new base::StringValue(*it));
303 new_values_cache->SetValue(kStartUpUrls, list);
307 void DecodeNetworkPolicies(
308 const em::ChromeDeviceSettingsProto& policy,
309 PrefValueMap* new_values_cache) {
310 // kSignedDataRoamingEnabled has a default value of false.
311 new_values_cache->SetBoolean(
312 kSignedDataRoamingEnabled,
313 policy.has_data_roaming_enabled() &&
314 policy.data_roaming_enabled().has_data_roaming_enabled() &&
315 policy.data_roaming_enabled().data_roaming_enabled());
318 void DecodeAutoUpdatePolicies(
319 const em::ChromeDeviceSettingsProto& policy,
320 PrefValueMap* new_values_cache) {
321 if (policy.has_auto_update_settings()) {
322 const em::AutoUpdateSettingsProto& au_settings_proto =
323 policy.auto_update_settings();
324 if (au_settings_proto.has_update_disabled()) {
325 new_values_cache->SetBoolean(kUpdateDisabled,
326 au_settings_proto.update_disabled());
328 const RepeatedField<int>& allowed_connection_types =
329 au_settings_proto.allowed_connection_types();
330 base::ListValue* list = new base::ListValue();
331 for (RepeatedField<int>::const_iterator i(allowed_connection_types.begin());
332 i != allowed_connection_types.end(); ++i) {
333 list->Append(new base::FundamentalValue(*i));
335 new_values_cache->SetValue(kAllowedConnectionTypesForUpdate, list);
339 void DecodeReportingPolicies(
340 const em::ChromeDeviceSettingsProto& policy,
341 PrefValueMap* new_values_cache) {
342 if (policy.has_device_reporting()) {
343 const em::DeviceReportingProto& reporting_policy =
344 policy.device_reporting();
345 if (reporting_policy.has_report_version_info()) {
346 new_values_cache->SetBoolean(
347 kReportDeviceVersionInfo,
348 reporting_policy.report_version_info());
350 if (reporting_policy.has_report_activity_times()) {
351 new_values_cache->SetBoolean(
352 kReportDeviceActivityTimes,
353 reporting_policy.report_activity_times());
355 if (reporting_policy.has_report_boot_mode()) {
356 new_values_cache->SetBoolean(
357 kReportDeviceBootMode,
358 reporting_policy.report_boot_mode());
360 if (reporting_policy.has_report_network_interfaces()) {
361 new_values_cache->SetBoolean(
362 kReportDeviceNetworkInterfaces,
363 reporting_policy.report_network_interfaces());
365 if (reporting_policy.has_report_users()) {
366 new_values_cache->SetBoolean(
367 kReportDeviceUsers,
368 reporting_policy.report_users());
373 void DecodeGenericPolicies(
374 const em::ChromeDeviceSettingsProto& policy,
375 PrefValueMap* new_values_cache) {
376 if (policy.has_metrics_enabled()) {
377 new_values_cache->SetBoolean(kStatsReportingPref,
378 policy.metrics_enabled().metrics_enabled());
379 } else {
380 new_values_cache->SetBoolean(kStatsReportingPref, HasOldMetricsFile());
383 if (!policy.has_release_channel() ||
384 !policy.release_channel().has_release_channel()) {
385 // Default to an invalid channel (will be ignored).
386 new_values_cache->SetString(kReleaseChannel, "");
387 } else {
388 new_values_cache->SetString(kReleaseChannel,
389 policy.release_channel().release_channel());
392 new_values_cache->SetBoolean(
393 kReleaseChannelDelegated,
394 policy.has_release_channel() &&
395 policy.release_channel().has_release_channel_delegated() &&
396 policy.release_channel().release_channel_delegated());
398 if (policy.has_system_timezone()) {
399 if (policy.system_timezone().has_timezone()) {
400 new_values_cache->SetString(
401 kSystemTimezonePolicy,
402 policy.system_timezone().timezone());
406 if (policy.has_use_24hour_clock()) {
407 if (policy.use_24hour_clock().has_use_24hour_clock()) {
408 new_values_cache->SetBoolean(
409 kSystemUse24HourClock, policy.use_24hour_clock().use_24hour_clock());
413 if (policy.has_allow_redeem_offers()) {
414 new_values_cache->SetBoolean(
415 kAllowRedeemChromeOsRegistrationOffers,
416 policy.allow_redeem_offers().allow_redeem_offers());
417 } else {
418 new_values_cache->SetBoolean(
419 kAllowRedeemChromeOsRegistrationOffers,
420 true);
423 if (policy.has_variations_parameter()) {
424 new_values_cache->SetString(
425 kVariationsRestrictParameter,
426 policy.variations_parameter().parameter());
429 new_values_cache->SetBoolean(
430 kDeviceAttestationEnabled,
431 policy.attestation_settings().attestation_enabled());
433 if (policy.has_attestation_settings() &&
434 policy.attestation_settings().has_content_protection_enabled()) {
435 new_values_cache->SetBoolean(
436 kAttestationForContentProtectionEnabled,
437 policy.attestation_settings().content_protection_enabled());
438 } else {
439 new_values_cache->SetBoolean(kAttestationForContentProtectionEnabled, true);
443 void DecodeDeviceState(const em::PolicyData& policy_data,
444 PrefValueMap* new_values_cache) {
445 if (!policy_data.has_device_state())
446 return;
448 const em::DeviceState& device_state = policy_data.device_state();
450 if (device_state.device_mode() == em::DeviceState::DEVICE_MODE_DISABLED)
451 new_values_cache->SetBoolean(kDeviceDisabled, true);
452 if (device_state.has_disabled_state() &&
453 device_state.disabled_state().has_message()) {
454 new_values_cache->SetString(kDeviceDisabledMessage,
455 device_state.disabled_state().message());
459 } // namespace
461 DeviceSettingsProvider::DeviceSettingsProvider(
462 const NotifyObserversCallback& notify_cb,
463 DeviceSettingsService* device_settings_service)
464 : CrosSettingsProvider(notify_cb),
465 device_settings_service_(device_settings_service),
466 trusted_status_(TEMPORARILY_UNTRUSTED),
467 ownership_status_(device_settings_service_->GetOwnershipStatus()),
468 store_callback_factory_(this) {
469 device_settings_service_->AddObserver(this);
470 if (!UpdateFromService()) {
471 // Make sure we have at least the cache data immediately.
472 RetrieveCachedData();
476 DeviceSettingsProvider::~DeviceSettingsProvider() {
477 if (device_settings_service_->GetOwnerSettingsService())
478 device_settings_service_->GetOwnerSettingsService()->RemoveObserver(this);
479 device_settings_service_->RemoveObserver(this);
482 // static
483 bool DeviceSettingsProvider::IsDeviceSetting(const std::string& name) {
484 const char* const* end = kKnownSettings + arraysize(kKnownSettings);
485 return std::find(kKnownSettings, end, name) != end;
488 void DeviceSettingsProvider::DoSet(const std::string& path,
489 const base::Value& in_value) {
490 // Make sure that either the current user is the device owner or the
491 // device doesn't have an owner yet.
492 if (!(device_settings_service_->HasPrivateOwnerKey() ||
493 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)) {
494 LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
496 // Revert UI change.
497 NotifyObservers(path);
498 return;
501 if (!IsDeviceSetting(path)) {
502 NOTREACHED() << "Try to set unhandled cros setting " << path;
503 return;
506 if (device_settings_service_->HasPrivateOwnerKey()) {
507 // Directly set setting through OwnerSettingsService.
508 ownership::OwnerSettingsService* service =
509 device_settings_service_->GetOwnerSettingsService();
510 if (!service->Set(path, in_value)) {
511 NotifyObservers(path);
512 return;
514 } else {
515 // Temporary store new setting in
516 // |device_settings_|. |device_settings_| will be stored on a disk
517 // as soon as an ownership of device the will be taken.
518 OwnerSettingsServiceChromeOS::UpdateDeviceSettings(
519 path, in_value, device_settings_);
520 em::PolicyData data;
521 data.set_username(device_settings_service_->GetUsername());
522 CHECK(device_settings_.SerializeToString(data.mutable_policy_value()));
524 // Set the cache to the updated value.
525 UpdateValuesCache(data, device_settings_, TEMPORARILY_UNTRUSTED);
527 if (!device_settings_cache::Store(data, g_browser_process->local_state())) {
528 LOG(ERROR) << "Couldn't store to the temp storage.";
529 NotifyObservers(path);
530 return;
534 bool metrics_value;
535 if (path == kStatsReportingPref && in_value.GetAsBoolean(&metrics_value))
536 ApplyMetricsSetting(false, metrics_value);
539 void DeviceSettingsProvider::OwnershipStatusChanged() {
540 DeviceSettingsService::OwnershipStatus new_ownership_status =
541 device_settings_service_->GetOwnershipStatus();
543 if (device_settings_service_->GetOwnerSettingsService())
544 device_settings_service_->GetOwnerSettingsService()->AddObserver(this);
546 // If the device just became owned, write the settings accumulated in the
547 // cache to device settings proper. It is important that writing only happens
548 // in this case, as during normal operation, the contents of the cache should
549 // never overwrite actual device settings.
550 if (new_ownership_status == DeviceSettingsService::OWNERSHIP_TAKEN &&
551 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE &&
552 device_settings_service_->HasPrivateOwnerKey()) {
553 // There shouldn't be any pending writes, since the cache writes are all
554 // immediate.
555 DCHECK(!store_callback_factory_.HasWeakPtrs());
557 trusted_status_ = TEMPORARILY_UNTRUSTED;
558 // Apply the locally-accumulated device settings on top of the initial
559 // settings from the service and write back the result.
560 if (device_settings_service_->device_settings()) {
561 em::ChromeDeviceSettingsProto new_settings(
562 *device_settings_service_->device_settings());
563 new_settings.MergeFrom(device_settings_);
564 device_settings_.Swap(&new_settings);
567 scoped_ptr<em::PolicyData> policy(new em::PolicyData());
568 policy->set_username(device_settings_service_->GetUsername());
569 CHECK(device_settings_.SerializeToString(policy->mutable_policy_value()));
570 if (!device_settings_service_->GetOwnerSettingsService()
571 ->CommitTentativeDeviceSettings(policy.Pass())) {
572 LOG(ERROR) << "Can't store policy";
576 // The owner key might have become available, allowing migration to happen.
577 AttemptMigration();
579 ownership_status_ = new_ownership_status;
582 void DeviceSettingsProvider::DeviceSettingsUpdated() {
583 if (!store_callback_factory_.HasWeakPtrs())
584 UpdateAndProceedStoring();
587 void DeviceSettingsProvider::OnDeviceSettingsServiceShutdown() {
588 device_settings_service_ = nullptr;
591 void DeviceSettingsProvider::OnTentativeChangesInPolicy(
592 const em::PolicyData& policy_data) {
593 em::ChromeDeviceSettingsProto device_settings;
594 CHECK(device_settings.ParseFromString(policy_data.policy_value()));
595 UpdateValuesCache(policy_data, device_settings, TEMPORARILY_UNTRUSTED);
598 void DeviceSettingsProvider::RetrieveCachedData() {
599 em::PolicyData policy_data;
600 if (!device_settings_cache::Retrieve(&policy_data,
601 g_browser_process->local_state()) ||
602 !device_settings_.ParseFromString(policy_data.policy_value())) {
603 VLOG(1) << "Can't retrieve temp store, possibly not created yet.";
606 UpdateValuesCache(policy_data, device_settings_, trusted_status_);
609 void DeviceSettingsProvider::UpdateValuesCache(
610 const em::PolicyData& policy_data,
611 const em::ChromeDeviceSettingsProto& settings,
612 TrustedStatus trusted_status) {
613 PrefValueMap new_values_cache;
615 // If the device is not managed, or is consumer-managed, we set the device
616 // owner value.
617 if (policy_data.has_username() &&
618 (policy::GetManagementMode(policy_data) ==
619 policy::MANAGEMENT_MODE_LOCAL_OWNER ||
620 policy::GetManagementMode(policy_data) ==
621 policy::MANAGEMENT_MODE_CONSUMER_MANAGED)) {
622 new_values_cache.SetString(kDeviceOwner, policy_data.username());
625 if (policy_data.has_service_account_identity()) {
626 new_values_cache.SetString(kServiceAccountIdentity,
627 policy_data.service_account_identity());
630 DecodeLoginPolicies(settings, &new_values_cache);
631 DecodeKioskPolicies(settings, &new_values_cache);
632 DecodeNetworkPolicies(settings, &new_values_cache);
633 DecodeAutoUpdatePolicies(settings, &new_values_cache);
634 DecodeReportingPolicies(settings, &new_values_cache);
635 DecodeGenericPolicies(settings, &new_values_cache);
636 DecodeDeviceState(policy_data, &new_values_cache);
638 // Collect all notifications but send them only after we have swapped the
639 // cache so that if somebody actually reads the cache will be already valid.
640 std::vector<std::string> notifications;
641 // Go through the new values and verify in the old ones.
642 PrefValueMap::iterator iter = new_values_cache.begin();
643 for (; iter != new_values_cache.end(); ++iter) {
644 const base::Value* old_value;
645 if (!values_cache_.GetValue(iter->first, &old_value) ||
646 !old_value->Equals(iter->second)) {
647 notifications.push_back(iter->first);
650 // Now check for values that have been removed from the policy blob.
651 for (iter = values_cache_.begin(); iter != values_cache_.end(); ++iter) {
652 const base::Value* value;
653 if (!new_values_cache.GetValue(iter->first, &value))
654 notifications.push_back(iter->first);
656 // Swap and notify.
657 values_cache_.Swap(&new_values_cache);
658 trusted_status_ = trusted_status;
659 for (size_t i = 0; i < notifications.size(); ++i)
660 NotifyObservers(notifications[i]);
663 void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file,
664 bool new_value) {
665 // TODO(pastarmovj): Remove this once migration is not needed anymore.
666 // If the value is not set we should try to migrate legacy consent file.
667 if (use_file) {
668 new_value = HasOldMetricsFile();
669 // Make sure the values will get eventually written to the policy file.
670 migration_values_.SetBoolean(kStatsReportingPref, new_value);
671 AttemptMigration();
672 VLOG(1) << "No metrics policy set will revert to checking "
673 << "consent file which is "
674 << (new_value ? "on." : "off.");
675 UMA_HISTOGRAM_COUNTS("DeviceSettings.MetricsMigrated", 1);
677 VLOG(1) << "Metrics policy is being set to : " << new_value
678 << "(use file : " << use_file << ")";
679 // TODO(pastarmovj): Remove this once we don't need to regenerate the
680 // consent file for the GUID anymore.
681 InitiateMetricsReportingChange(new_value, OnMetricsReportingCallbackType());
684 void DeviceSettingsProvider::ApplySideEffects(
685 const em::ChromeDeviceSettingsProto& settings) {
686 // First migrate metrics settings as needed.
687 if (settings.has_metrics_enabled())
688 ApplyMetricsSetting(false, settings.metrics_enabled().metrics_enabled());
689 else
690 ApplyMetricsSetting(true, false);
693 bool DeviceSettingsProvider::MitigateMissingPolicy() {
694 // First check if the device has been owned already and if not exit
695 // immediately.
696 policy::BrowserPolicyConnectorChromeOS* connector =
697 g_browser_process->platform_part()->browser_policy_connector_chromeos();
698 if (connector->GetDeviceMode() != policy::DEVICE_MODE_CONSUMER)
699 return false;
701 // If we are here the policy file were corrupted or missing. This can happen
702 // because we are migrating Pre R11 device to the new secure policies or there
703 // was an attempt to circumvent policy system. In this case we should populate
704 // the policy cache with "safe-mode" defaults which should allow the owner to
705 // log in but lock the device for anyone else until the policy blob has been
706 // recreated by the session manager.
707 LOG(ERROR) << "Corruption of the policy data has been detected."
708 << "Switching to \"safe-mode\" policies until the owner logs in "
709 << "to regenerate the policy data.";
711 device_settings_.Clear();
712 device_settings_.mutable_allow_new_users()->set_allow_new_users(true);
713 device_settings_.mutable_guest_mode_enabled()->set_guest_mode_enabled(true);
714 em::PolicyData empty_policy_data;
715 UpdateValuesCache(empty_policy_data, device_settings_, TRUSTED);
716 values_cache_.SetBoolean(kPolicyMissingMitigationMode, true);
718 return true;
721 const base::Value* DeviceSettingsProvider::Get(const std::string& path) const {
722 if (IsDeviceSetting(path)) {
723 const base::Value* value;
724 if (values_cache_.GetValue(path, &value))
725 return value;
726 } else {
727 NOTREACHED() << "Trying to get non cros setting.";
730 return NULL;
733 DeviceSettingsProvider::TrustedStatus
734 DeviceSettingsProvider::PrepareTrustedValues(const base::Closure& cb) {
735 TrustedStatus status = RequestTrustedEntity();
736 if (status == TEMPORARILY_UNTRUSTED && !cb.is_null())
737 callbacks_.push_back(cb);
738 return status;
741 bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const {
742 return IsDeviceSetting(path);
745 DeviceSettingsProvider::TrustedStatus
746 DeviceSettingsProvider::RequestTrustedEntity() {
747 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)
748 return TRUSTED;
749 return trusted_status_;
752 void DeviceSettingsProvider::UpdateAndProceedStoring() {
753 // Re-sync the cache from the service.
754 UpdateFromService();
757 bool DeviceSettingsProvider::UpdateFromService() {
758 bool settings_loaded = false;
759 switch (device_settings_service_->status()) {
760 case DeviceSettingsService::STORE_SUCCESS: {
761 const em::PolicyData* policy_data =
762 device_settings_service_->policy_data();
763 const em::ChromeDeviceSettingsProto* device_settings =
764 device_settings_service_->device_settings();
765 if (policy_data && device_settings) {
766 if (!device_settings_cache::Store(*policy_data,
767 g_browser_process->local_state())) {
768 LOG(ERROR) << "Couldn't update the local state cache.";
770 UpdateValuesCache(*policy_data, *device_settings, TRUSTED);
771 device_settings_ = *device_settings;
773 // TODO(pastarmovj): Make those side effects responsibility of the
774 // respective subsystems.
775 ApplySideEffects(*device_settings);
777 settings_loaded = true;
778 } else {
779 // Initial policy load is still pending.
780 trusted_status_ = TEMPORARILY_UNTRUSTED;
782 break;
784 case DeviceSettingsService::STORE_NO_POLICY:
785 if (MitigateMissingPolicy())
786 break;
787 // fall through.
788 case DeviceSettingsService::STORE_KEY_UNAVAILABLE:
789 VLOG(1) << "No policies present yet, will use the temp storage.";
790 trusted_status_ = PERMANENTLY_UNTRUSTED;
791 break;
792 case DeviceSettingsService::STORE_POLICY_ERROR:
793 case DeviceSettingsService::STORE_VALIDATION_ERROR:
794 case DeviceSettingsService::STORE_INVALID_POLICY:
795 case DeviceSettingsService::STORE_OPERATION_FAILED:
796 LOG(ERROR) << "Failed to retrieve cros policies. Reason: "
797 << device_settings_service_->status();
798 trusted_status_ = PERMANENTLY_UNTRUSTED;
799 break;
800 case DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR:
801 // The policy has failed to validate due to temporary error but it might
802 // take a long time until we recover so behave as it is a permanent error.
803 LOG(ERROR) << "Failed to retrieve cros policies because a temporary "
804 << "validation error has occurred. Retrying might succeed.";
805 trusted_status_ = PERMANENTLY_UNTRUSTED;
806 break;
809 // Notify the observers we are done.
810 std::vector<base::Closure> callbacks;
811 callbacks.swap(callbacks_);
812 for (size_t i = 0; i < callbacks.size(); ++i)
813 callbacks[i].Run();
815 return settings_loaded;
818 void DeviceSettingsProvider::AttemptMigration() {
819 if (device_settings_service_->HasPrivateOwnerKey()) {
820 PrefValueMap::const_iterator i;
821 for (i = migration_values_.begin(); i != migration_values_.end(); ++i)
822 DoSet(i->first, *i->second);
823 migration_values_.Clear();
827 } // namespace chromeos