Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(233)

Side by Side Diff: chrome/browser/chromeos/device_settings_provider.cc

Issue 10824112: Move Chrome OS device settings stuff to chrome/browser/chromeos/settings. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/chromeos/device_settings_provider.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/file_util.h"
11 #include "base/logging.h"
12 #include "base/string_util.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/cros/cros_library.h"
17 #include "chrome/browser/chromeos/cros/network_library.h"
18 #include "chrome/browser/chromeos/cros_settings.h"
19 #include "chrome/browser/chromeos/cros_settings_names.h"
20 #include "chrome/browser/chromeos/login/signed_settings_cache.h"
21 #include "chrome/browser/chromeos/login/signed_settings_helper.h"
22 #include "chrome/browser/chromeos/login/user_manager.h"
23 #include "chrome/browser/policy/app_pack_updater.h"
24 #include "chrome/browser/policy/browser_policy_connector.h"
25 #include "chrome/browser/policy/cloud_policy_constants.h"
26 #include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
27 #include "chrome/browser/ui/options/options_util.h"
28 #include "chrome/common/chrome_notification_types.h"
29 #include "chrome/installer/util/google_update_settings.h"
30 #include "content/public/browser/notification_service.h"
31
32 using google::protobuf::RepeatedPtrField;
33
34 namespace em = enterprise_management;
35
36 namespace chromeos {
37
38 namespace {
39
40 // List of settings handled by the DeviceSettingsProvider.
41 const char* kKnownSettings[] = {
42 kAccountsPrefAllowGuest,
43 kAccountsPrefAllowNewUser,
44 kAccountsPrefEphemeralUsersEnabled,
45 kAccountsPrefShowUserNamesOnSignIn,
46 kAccountsPrefUsers,
47 kAppPack,
48 kDeviceOwner,
49 kIdleLogoutTimeout,
50 kIdleLogoutWarningDuration,
51 kPolicyMissingMitigationMode,
52 kReleaseChannel,
53 kReleaseChannelDelegated,
54 kReportDeviceActivityTimes,
55 kReportDeviceBootMode,
56 kReportDeviceLocation,
57 kReportDeviceVersionInfo,
58 kScreenSaverExtensionId,
59 kScreenSaverTimeout,
60 kSettingProxyEverywhere,
61 kSignedDataRoamingEnabled,
62 kStartUpUrls,
63 kStatsReportingPref,
64 };
65
66 // Upper bound for number of retries to fetch a signed setting.
67 static const int kNumRetriesLimit = 9;
68
69 // Legacy policy file location. Used to detect migration from pre v12 ChromeOS.
70 const char kLegacyPolicyFile[] = "/var/lib/whitelist/preferences";
71
72 bool IsControlledSetting(const std::string& pref_path) {
73 const char** end = kKnownSettings + arraysize(kKnownSettings);
74 return std::find(kKnownSettings, end, pref_path) != end;
75 }
76
77 bool HasOldMetricsFile() {
78 // TODO(pastarmovj): Remove this once migration is not needed anymore.
79 // If the value is not set we should try to migrate legacy consent file.
80 // Loading consent file state causes us to do blocking IO on UI thread.
81 // Temporarily allow it until we fix http://crbug.com/62626
82 base::ThreadRestrictions::ScopedAllowIO allow_io;
83 return GoogleUpdateSettings::GetCollectStatsConsent();
84 }
85
86 } // namespace
87
88 DeviceSettingsProvider::DeviceSettingsProvider(
89 const NotifyObserversCallback& notify_cb,
90 SignedSettingsHelper* signed_settings_helper)
91 : CrosSettingsProvider(notify_cb),
92 signed_settings_helper_(signed_settings_helper),
93 ownership_status_(OwnershipService::GetSharedInstance()->GetStatus(true)),
94 migration_helper_(new SignedSettingsMigrationHelper()),
95 retries_left_(kNumRetriesLimit),
96 trusted_status_(TEMPORARILY_UNTRUSTED) {
97 // Register for notification when ownership is taken so that we can update
98 // the |ownership_status_| and reload if needed.
99 registrar_.Add(this, chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED,
100 content::NotificationService::AllSources());
101 // Make sure we have at least the cache data immediately.
102 RetrieveCachedData();
103 // Start prefetching preferences.
104 Reload();
105 }
106
107 DeviceSettingsProvider::~DeviceSettingsProvider() {
108 }
109
110 void DeviceSettingsProvider::Reload() {
111 // While fetching we can't trust the cache anymore.
112 trusted_status_ = TEMPORARILY_UNTRUSTED;
113 if (ownership_status_ == OwnershipService::OWNERSHIP_NONE) {
114 RetrieveCachedData();
115 } else {
116 // Retrieve the real data.
117 signed_settings_helper_->StartRetrievePolicyOp(
118 base::Bind(&DeviceSettingsProvider::OnRetrievePolicyCompleted,
119 base::Unretained(this)));
120 }
121 }
122
123 void DeviceSettingsProvider::DoSet(const std::string& path,
124 const base::Value& in_value) {
125 if (!UserManager::Get()->IsCurrentUserOwner() &&
126 ownership_status_ != OwnershipService::OWNERSHIP_NONE) {
127 LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
128
129 // Revert UI change.
130 NotifyObservers(path);
131 return;
132 }
133
134 if (IsControlledSetting(path)) {
135 pending_changes_.push_back(PendingQueueElement(path, in_value.DeepCopy()));
136 if (pending_changes_.size() == 1)
137 SetInPolicy();
138 } else {
139 NOTREACHED() << "Try to set unhandled cros setting " << path;
140 }
141 }
142
143 void DeviceSettingsProvider::Observe(
144 int type,
145 const content::NotificationSource& source,
146 const content::NotificationDetails& details) {
147 if (type == chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED) {
148 // Reload the policy blob once the owner key has been loaded or updated.
149 ownership_status_ = OwnershipService::OWNERSHIP_TAKEN;
150 Reload();
151 }
152 }
153
154 const em::PolicyData DeviceSettingsProvider::policy() const {
155 return policy_;
156 }
157
158 void DeviceSettingsProvider::RetrieveCachedData() {
159 // If there is no owner yet, this function will pull the policy cache from the
160 // temp storage and use that instead.
161 em::PolicyData policy;
162 if (!signed_settings_cache::Retrieve(&policy,
163 g_browser_process->local_state())) {
164 VLOG(1) << "Can't retrieve temp store possibly not created yet.";
165 // Prepare empty data for the case we don't have temp cache yet.
166 policy.set_policy_type(kDevicePolicyType);
167 em::ChromeDeviceSettingsProto pol;
168 policy.set_policy_value(pol.SerializeAsString());
169 }
170
171 policy_ = policy;
172 UpdateValuesCache();
173 }
174
175 void DeviceSettingsProvider::SetInPolicy() {
176 if (pending_changes_.empty()) {
177 NOTREACHED();
178 return;
179 }
180
181 const std::string& prop = pending_changes_[0].first;
182 base::Value* value = pending_changes_[0].second;
183 if (prop == kDeviceOwner) {
184 // Just store it in the memory cache without trusted checks or persisting.
185 std::string owner;
186 if (value->GetAsString(&owner)) {
187 policy_.set_username(owner);
188 // In this case the |value_cache_| takes the ownership of |value|.
189 values_cache_.SetValue(prop, value);
190 NotifyObservers(prop);
191 // We can't trust this value anymore until we reload the real username.
192 trusted_status_ = TEMPORARILY_UNTRUSTED;
193 pending_changes_.erase(pending_changes_.begin());
194 if (!pending_changes_.empty())
195 SetInPolicy();
196 } else {
197 NOTREACHED();
198 }
199 return;
200 }
201
202 if (RequestTrustedEntity() != TRUSTED) {
203 // Otherwise we should first reload and apply on top of that.
204 signed_settings_helper_->StartRetrievePolicyOp(
205 base::Bind(&DeviceSettingsProvider::FinishSetInPolicy,
206 base::Unretained(this)));
207 return;
208 }
209
210 trusted_status_ = TEMPORARILY_UNTRUSTED;
211 em::PolicyData data = policy();
212 em::ChromeDeviceSettingsProto pol;
213 pol.ParseFromString(data.policy_value());
214 if (prop == kAccountsPrefAllowNewUser) {
215 em::AllowNewUsersProto* allow = pol.mutable_allow_new_users();
216 bool allow_value;
217 if (value->GetAsBoolean(&allow_value))
218 allow->set_allow_new_users(allow_value);
219 else
220 NOTREACHED();
221 } else if (prop == kAccountsPrefAllowGuest) {
222 em::GuestModeEnabledProto* guest = pol.mutable_guest_mode_enabled();
223 bool guest_value;
224 if (value->GetAsBoolean(&guest_value))
225 guest->set_guest_mode_enabled(guest_value);
226 else
227 NOTREACHED();
228 } else if (prop == kAccountsPrefShowUserNamesOnSignIn) {
229 em::ShowUserNamesOnSigninProto* show = pol.mutable_show_user_names();
230 bool show_value;
231 if (value->GetAsBoolean(&show_value))
232 show->set_show_user_names(show_value);
233 else
234 NOTREACHED();
235 } else if (prop == kSignedDataRoamingEnabled) {
236 em::DataRoamingEnabledProto* roam = pol.mutable_data_roaming_enabled();
237 bool roaming_value = false;
238 if (value->GetAsBoolean(&roaming_value))
239 roam->set_data_roaming_enabled(roaming_value);
240 else
241 NOTREACHED();
242 ApplyRoamingSetting(roaming_value);
243 } else if (prop == kSettingProxyEverywhere) {
244 // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed.
245 std::string proxy_value;
246 if (value->GetAsString(&proxy_value)) {
247 bool success =
248 pol.mutable_device_proxy_settings()->ParseFromString(proxy_value);
249 DCHECK(success);
250 } else {
251 NOTREACHED();
252 }
253 } else if (prop == kReleaseChannel) {
254 em::ReleaseChannelProto* release_channel = pol.mutable_release_channel();
255 std::string channel_value;
256 if (value->GetAsString(&channel_value))
257 release_channel->set_release_channel(channel_value);
258 else
259 NOTREACHED();
260 } else if (prop == kStatsReportingPref) {
261 em::MetricsEnabledProto* metrics = pol.mutable_metrics_enabled();
262 bool metrics_value = false;
263 if (value->GetAsBoolean(&metrics_value))
264 metrics->set_metrics_enabled(metrics_value);
265 else
266 NOTREACHED();
267 ApplyMetricsSetting(false, metrics_value);
268 } else if (prop == kAccountsPrefUsers) {
269 em::UserWhitelistProto* whitelist_proto = pol.mutable_user_whitelist();
270 whitelist_proto->clear_user_whitelist();
271 base::ListValue& users = static_cast<base::ListValue&>(*value);
272 for (base::ListValue::const_iterator i = users.begin();
273 i != users.end(); ++i) {
274 std::string email;
275 if ((*i)->GetAsString(&email))
276 whitelist_proto->add_user_whitelist(email.c_str());
277 }
278 } else if (prop == kAccountsPrefEphemeralUsersEnabled) {
279 em::EphemeralUsersEnabledProto* ephemeral_users_enabled =
280 pol.mutable_ephemeral_users_enabled();
281 bool ephemeral_users_enabled_value = false;
282 if (value->GetAsBoolean(&ephemeral_users_enabled_value))
283 ephemeral_users_enabled->set_ephemeral_users_enabled(
284 ephemeral_users_enabled_value);
285 else
286 NOTREACHED();
287 } else {
288 // The remaining settings don't support Set(), since they are not
289 // intended to be customizable by the user:
290 // kAppPack
291 // kIdleLogoutTimeout
292 // kIdleLogoutWarningDuration
293 // kReleaseChannelDelegated
294 // kReportDeviceVersionInfo
295 // kReportDeviceActivityTimes
296 // kReportDeviceBootMode
297 // kReportDeviceLocation
298 // kScreenSaverExtensionId
299 // kScreenSaverTimeout
300 // kStartUpUrls
301
302 NOTREACHED();
303 }
304 data.set_policy_value(pol.SerializeAsString());
305 // Set the cache to the updated value.
306 policy_ = data;
307 UpdateValuesCache();
308
309 if (!signed_settings_cache::Store(data, g_browser_process->local_state()))
310 LOG(ERROR) << "Couldn't store to the temp storage.";
311
312 if (ownership_status_ == OwnershipService::OWNERSHIP_TAKEN) {
313 em::PolicyFetchResponse policy_envelope;
314 policy_envelope.set_policy_data(policy_.SerializeAsString());
315 signed_settings_helper_->StartStorePolicyOp(
316 policy_envelope,
317 base::Bind(&DeviceSettingsProvider::OnStorePolicyCompleted,
318 base::Unretained(this)));
319 } else {
320 // OnStorePolicyCompleted won't get called in this case so proceed with any
321 // pending operations immediately.
322 delete pending_changes_[0].second;
323 pending_changes_.erase(pending_changes_.begin());
324 if (!pending_changes_.empty())
325 SetInPolicy();
326 }
327 }
328
329 void DeviceSettingsProvider::FinishSetInPolicy(
330 SignedSettings::ReturnCode code,
331 const em::PolicyFetchResponse& policy) {
332 if (code != SignedSettings::SUCCESS) {
333 LOG(ERROR) << "Can't serialize to policy error code: " << code;
334 Reload();
335 return;
336 }
337 // Update the internal caches and set the trusted flag to true so that we
338 // can pass the trustedness check in the second call to SetInPolicy.
339 OnRetrievePolicyCompleted(code, policy);
340
341 SetInPolicy();
342 }
343
344 void DeviceSettingsProvider::DecodeLoginPolicies(
345 const em::ChromeDeviceSettingsProto& policy,
346 PrefValueMap* new_values_cache) const {
347 // For all our boolean settings the following is applicable:
348 // true is default permissive value and false is safe prohibitive value.
349 // Exceptions:
350 // kSignedDataRoamingEnabled has a default value of false.
351 // kAccountsPrefEphemeralUsersEnabled has a default value of false.
352 if (policy.has_allow_new_users() &&
353 policy.allow_new_users().has_allow_new_users() &&
354 policy.allow_new_users().allow_new_users()) {
355 // New users allowed, user_whitelist() ignored.
356 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true);
357 } else if (!policy.has_user_whitelist()) {
358 // If we have the allow_new_users bool, and it is true, we honor that above.
359 // In all other cases (don't have it, have it and it is set to false, etc),
360 // We will honor the user_whitelist() if it is there and populated.
361 // Otherwise we default to allowing new users.
362 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true);
363 } else {
364 new_values_cache->SetBoolean(
365 kAccountsPrefAllowNewUser,
366 policy.user_whitelist().user_whitelist_size() == 0);
367 }
368
369 new_values_cache->SetBoolean(
370 kAccountsPrefAllowGuest,
371 !policy.has_guest_mode_enabled() ||
372 !policy.guest_mode_enabled().has_guest_mode_enabled() ||
373 policy.guest_mode_enabled().guest_mode_enabled());
374
375 new_values_cache->SetBoolean(
376 kAccountsPrefShowUserNamesOnSignIn,
377 !policy.has_show_user_names() ||
378 !policy.show_user_names().has_show_user_names() ||
379 policy.show_user_names().show_user_names());
380
381 new_values_cache->SetBoolean(
382 kAccountsPrefEphemeralUsersEnabled,
383 policy.has_ephemeral_users_enabled() &&
384 policy.ephemeral_users_enabled().has_ephemeral_users_enabled() &&
385 policy.ephemeral_users_enabled().ephemeral_users_enabled());
386
387 base::ListValue* list = new base::ListValue();
388 const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist();
389 const RepeatedPtrField<std::string>& whitelist =
390 whitelist_proto.user_whitelist();
391 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin();
392 it != whitelist.end(); ++it) {
393 list->Append(base::Value::CreateStringValue(*it));
394 }
395 new_values_cache->SetValue(kAccountsPrefUsers, list);
396 }
397
398 void DeviceSettingsProvider::DecodeKioskPolicies(
399 const em::ChromeDeviceSettingsProto& policy,
400 PrefValueMap* new_values_cache) const {
401 if (policy.has_forced_logout_timeouts()) {
402 if (policy.forced_logout_timeouts().has_idle_logout_timeout()) {
403 new_values_cache->SetInteger(
404 kIdleLogoutTimeout,
405 policy.forced_logout_timeouts().idle_logout_timeout());
406 }
407
408 if (policy.forced_logout_timeouts().has_idle_logout_warning_duration()) {
409 new_values_cache->SetInteger(
410 kIdleLogoutWarningDuration,
411 policy.forced_logout_timeouts().idle_logout_warning_duration());
412 }
413 }
414
415 if (policy.has_login_screen_saver()) {
416 if (policy.login_screen_saver().has_screen_saver_timeout()) {
417 new_values_cache->SetInteger(
418 kScreenSaverTimeout,
419 policy.login_screen_saver().screen_saver_timeout());
420 }
421
422 if (policy.login_screen_saver().has_screen_saver_extension_id()) {
423 new_values_cache->SetString(
424 kScreenSaverExtensionId,
425 policy.login_screen_saver().screen_saver_extension_id());
426 }
427 }
428
429 if (policy.has_app_pack()) {
430 typedef RepeatedPtrField<em::AppPackEntryProto> proto_type;
431 base::ListValue* list = new base::ListValue;
432 const proto_type& app_pack = policy.app_pack().app_pack();
433 for (proto_type::const_iterator it = app_pack.begin();
434 it != app_pack.end(); ++it) {
435 base::DictionaryValue* entry = new base::DictionaryValue;
436 if (it->has_extension_id()) {
437 entry->SetString(policy::AppPackUpdater::kExtensionId,
438 it->extension_id());
439 }
440 if (it->has_update_url())
441 entry->SetString(policy::AppPackUpdater::kUpdateUrl, it->update_url());
442 list->Append(entry);
443 }
444 new_values_cache->SetValue(kAppPack, list);
445 }
446
447 if (policy.has_start_up_urls()) {
448 base::ListValue* list = new base::ListValue();
449 const em::StartUpUrlsProto& urls_proto = policy.start_up_urls();
450 const RepeatedPtrField<std::string>& urls = urls_proto.start_up_urls();
451 for (RepeatedPtrField<std::string>::const_iterator it = urls.begin();
452 it != urls.end(); ++it) {
453 list->Append(base::Value::CreateStringValue(*it));
454 }
455 new_values_cache->SetValue(kStartUpUrls, list);
456 }
457 }
458
459 void DeviceSettingsProvider::DecodeNetworkPolicies(
460 const em::ChromeDeviceSettingsProto& policy,
461 PrefValueMap* new_values_cache) const {
462 new_values_cache->SetBoolean(
463 kSignedDataRoamingEnabled,
464 policy.has_data_roaming_enabled() &&
465 policy.data_roaming_enabled().has_data_roaming_enabled() &&
466 policy.data_roaming_enabled().data_roaming_enabled());
467
468 // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed.
469 std::string serialized;
470 if (policy.has_device_proxy_settings() &&
471 policy.device_proxy_settings().SerializeToString(&serialized)) {
472 new_values_cache->SetString(kSettingProxyEverywhere, serialized);
473 }
474 }
475
476 void DeviceSettingsProvider::DecodeReportingPolicies(
477 const em::ChromeDeviceSettingsProto& policy,
478 PrefValueMap* new_values_cache) const {
479 if (policy.has_device_reporting()) {
480 if (policy.device_reporting().has_report_version_info()) {
481 new_values_cache->SetBoolean(
482 kReportDeviceVersionInfo,
483 policy.device_reporting().report_version_info());
484 }
485 if (policy.device_reporting().has_report_activity_times()) {
486 new_values_cache->SetBoolean(
487 kReportDeviceActivityTimes,
488 policy.device_reporting().report_activity_times());
489 }
490 if (policy.device_reporting().has_report_boot_mode()) {
491 new_values_cache->SetBoolean(
492 kReportDeviceBootMode,
493 policy.device_reporting().report_boot_mode());
494 }
495 // Device location reporting needs to pass privacy review before it can be
496 // enabled. crosbug.com/24681
497 // if (policy.device_reporting().has_report_location()) {
498 // new_values_cache->SetBoolean(
499 // kReportDeviceLocation,
500 // policy.device_reporting().report_location());
501 // }
502 }
503 }
504
505 void DeviceSettingsProvider::DecodeGenericPolicies(
506 const em::ChromeDeviceSettingsProto& policy,
507 PrefValueMap* new_values_cache) const {
508 if (policy.has_metrics_enabled()) {
509 new_values_cache->SetBoolean(kStatsReportingPref,
510 policy.metrics_enabled().metrics_enabled());
511 } else {
512 new_values_cache->SetBoolean(kStatsReportingPref, HasOldMetricsFile());
513 }
514
515 if (!policy.has_release_channel() ||
516 !policy.release_channel().has_release_channel()) {
517 // Default to an invalid channel (will be ignored).
518 new_values_cache->SetString(kReleaseChannel, "");
519 } else {
520 new_values_cache->SetString(kReleaseChannel,
521 policy.release_channel().release_channel());
522 }
523
524 new_values_cache->SetBoolean(
525 kReleaseChannelDelegated,
526 policy.has_release_channel() &&
527 policy.release_channel().has_release_channel_delegated() &&
528 policy.release_channel().release_channel_delegated());
529 }
530
531 void DeviceSettingsProvider::UpdateValuesCache() {
532 const em::PolicyData data = policy();
533 PrefValueMap new_values_cache;
534
535 if (data.has_username() && !data.has_request_token())
536 new_values_cache.SetString(kDeviceOwner, data.username());
537
538 em::ChromeDeviceSettingsProto pol;
539 pol.ParseFromString(data.policy_value());
540
541 DecodeLoginPolicies(pol, &new_values_cache);
542 DecodeKioskPolicies(pol, &new_values_cache);
543 DecodeNetworkPolicies(pol, &new_values_cache);
544 DecodeReportingPolicies(pol, &new_values_cache);
545 DecodeGenericPolicies(pol, &new_values_cache);
546
547 // Collect all notifications but send them only after we have swapped the
548 // cache so that if somebody actually reads the cache will be already valid.
549 std::vector<std::string> notifications;
550 // Go through the new values and verify in the old ones.
551 PrefValueMap::iterator iter = new_values_cache.begin();
552 for (; iter != new_values_cache.end(); ++iter) {
553 const base::Value* old_value;
554 if (!values_cache_.GetValue(iter->first, &old_value) ||
555 !old_value->Equals(iter->second)) {
556 notifications.push_back(iter->first);
557 }
558 }
559 // Now check for values that have been removed from the policy blob.
560 for (iter = values_cache_.begin(); iter != values_cache_.end(); ++iter) {
561 const base::Value* value;
562 if (!new_values_cache.GetValue(iter->first, &value))
563 notifications.push_back(iter->first);
564 }
565 // Swap and notify.
566 values_cache_.Swap(&new_values_cache);
567 for (size_t i = 0; i < notifications.size(); ++i)
568 NotifyObservers(notifications[i]);
569 }
570
571 void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file,
572 bool new_value) const {
573 // TODO(pastarmovj): Remove this once migration is not needed anymore.
574 // If the value is not set we should try to migrate legacy consent file.
575 if (use_file) {
576 new_value = HasOldMetricsFile();
577 // Make sure the values will get eventually written to the policy file.
578 migration_helper_->AddMigrationValue(
579 kStatsReportingPref, base::Value::CreateBooleanValue(new_value));
580 migration_helper_->MigrateValues();
581 LOG(INFO) << "No metrics policy set will revert to checking "
582 << "consent file which is "
583 << (new_value ? "on." : "off.");
584 }
585 VLOG(1) << "Metrics policy is being set to : " << new_value
586 << "(use file : " << use_file << ")";
587 // TODO(pastarmovj): Remove this once we don't need to regenerate the
588 // consent file for the GUID anymore.
589 OptionsUtil::ResolveMetricsReportingEnabled(new_value);
590 }
591
592 void DeviceSettingsProvider::ApplyRoamingSetting(bool new_value) const {
593 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
594 const NetworkDevice* cellular = cros->FindCellularDevice();
595 if (cellular) {
596 bool device_value = cellular->data_roaming_allowed();
597 if (!device_value && cros->IsCellularAlwaysInRoaming()) {
598 // If operator requires roaming always enabled, ignore supplied value
599 // and set data roaming allowed in true always.
600 cros->SetCellularDataRoamingAllowed(true);
601 } else if (device_value != new_value) {
602 cros->SetCellularDataRoamingAllowed(new_value);
603 }
604 }
605 }
606
607 void DeviceSettingsProvider::ApplySideEffects() const {
608 const em::PolicyData data = policy();
609 em::ChromeDeviceSettingsProto pol;
610 pol.ParseFromString(data.policy_value());
611 // First migrate metrics settings as needed.
612 if (pol.has_metrics_enabled())
613 ApplyMetricsSetting(false, pol.metrics_enabled().metrics_enabled());
614 else
615 ApplyMetricsSetting(true, false);
616 // Next set the roaming setting as needed.
617 ApplyRoamingSetting(pol.has_data_roaming_enabled() ?
618 pol.data_roaming_enabled().data_roaming_enabled() : false);
619 }
620
621 bool DeviceSettingsProvider::MitigateMissingPolicy() {
622 // First check if the device has been owned already and if not exit
623 // immediately.
624 if (g_browser_process->browser_policy_connector()->GetDeviceMode() !=
625 policy::DEVICE_MODE_CONSUMER) {
626 return false;
627 }
628
629 // If we are here the policy file were corrupted or missing. This can happen
630 // because we are migrating Pre R11 device to the new secure policies or there
631 // was an attempt to circumvent policy system. In this case we should populate
632 // the policy cache with "safe-mode" defaults which should allow the owner to
633 // log in but lock the device for anyone else until the policy blob has been
634 // recreated by the session manager.
635 LOG(ERROR) << "Corruption of the policy data has been detected."
636 << "Switching to \"safe-mode\" policies until the owner logs in "
637 << "to regenerate the policy data.";
638 values_cache_.SetBoolean(kAccountsPrefAllowNewUser, true);
639 values_cache_.SetBoolean(kAccountsPrefAllowGuest, true);
640 values_cache_.SetBoolean(kPolicyMissingMitigationMode, true);
641 trusted_status_ = TRUSTED;
642 // Make sure we will recreate the policy once the owner logs in.
643 // Any value not in this list will be left to the default which is fine as
644 // we repopulate the whitelist with the owner and all other existing users
645 // every time the owner enables whitelist filtering on the UI.
646 migration_helper_->AddMigrationValue(
647 kAccountsPrefAllowNewUser, base::Value::CreateBooleanValue(true));
648 migration_helper_->MigrateValues();
649 return true;
650 }
651
652 const base::Value* DeviceSettingsProvider::Get(const std::string& path) const {
653 if (IsControlledSetting(path)) {
654 const base::Value* value;
655 if (values_cache_.GetValue(path, &value))
656 return value;
657 } else {
658 NOTREACHED() << "Trying to get non cros setting.";
659 }
660
661 return NULL;
662 }
663
664 DeviceSettingsProvider::TrustedStatus
665 DeviceSettingsProvider::PrepareTrustedValues(const base::Closure& cb) {
666 TrustedStatus status = RequestTrustedEntity();
667 if (status == TEMPORARILY_UNTRUSTED && !cb.is_null())
668 callbacks_.push_back(cb);
669 return status;
670 }
671
672 bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const {
673 return IsControlledSetting(path);
674 }
675
676 DeviceSettingsProvider::TrustedStatus
677 DeviceSettingsProvider::RequestTrustedEntity() {
678 if (ownership_status_ == OwnershipService::OWNERSHIP_NONE)
679 return TRUSTED;
680 return trusted_status_;
681 }
682
683 void DeviceSettingsProvider::OnStorePolicyCompleted(
684 SignedSettings::ReturnCode code) {
685 // In any case reload the policy cache to now.
686 if (code != SignedSettings::SUCCESS)
687 Reload();
688 else
689 trusted_status_ = TRUSTED;
690
691 // Clear the finished task and proceed with any other stores that could be
692 // pending by now.
693 delete pending_changes_[0].second;
694 pending_changes_.erase(pending_changes_.begin());
695 if (!pending_changes_.empty())
696 SetInPolicy();
697 }
698
699 void DeviceSettingsProvider::OnRetrievePolicyCompleted(
700 SignedSettings::ReturnCode code,
701 const em::PolicyFetchResponse& policy_data) {
702 VLOG(1) << "OnRetrievePolicyCompleted. Error code: " << code
703 << ", trusted status : " << trusted_status_
704 << ", ownership status : " << ownership_status_;
705 switch (code) {
706 case SignedSettings::SUCCESS: {
707 DCHECK(policy_data.has_policy_data());
708 policy_.ParseFromString(policy_data.policy_data());
709 signed_settings_cache::Store(policy(),
710 g_browser_process->local_state());
711 UpdateValuesCache();
712 trusted_status_ = TRUSTED;
713 // TODO(pastarmovj): Make those side effects responsibility of the
714 // respective subsystems.
715 ApplySideEffects();
716 break;
717 }
718 case SignedSettings::NOT_FOUND:
719 if (MitigateMissingPolicy())
720 break;
721 case SignedSettings::KEY_UNAVAILABLE: {
722 if (ownership_status_ != OwnershipService::OWNERSHIP_TAKEN)
723 NOTREACHED() << "No policies present yet, will use the temp storage.";
724 trusted_status_ = PERMANENTLY_UNTRUSTED;
725 break;
726 }
727 case SignedSettings::BAD_SIGNATURE:
728 case SignedSettings::OPERATION_FAILED: {
729 LOG(ERROR) << "Failed to retrieve cros policies. Reason:" << code;
730 if (retries_left_ > 0) {
731 trusted_status_ = TEMPORARILY_UNTRUSTED;
732 retries_left_ -= 1;
733 Reload();
734 return;
735 }
736 LOG(ERROR) << "No retries left";
737 trusted_status_ = PERMANENTLY_UNTRUSTED;
738 break;
739 }
740 }
741 // Notify the observers we are done.
742 std::vector<base::Closure> callbacks;
743 callbacks.swap(callbacks_);
744 for (size_t i = 0; i < callbacks.size(); ++i)
745 callbacks[i].Run();
746 }
747
748 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/device_settings_provider.h ('k') | chrome/browser/chromeos/device_settings_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698