blob: 7816dc7d6a36dc56ef6d8924e7c7498ea44103eb [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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/settings/device_settings_provider.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/callback.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000010#include "base/command_line.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000011#include "base/logging.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000012#include "base/metrics/histogram.h"
13#include "base/prefs/pref_service.h"
Torne (Richard Coles)5e3f23d2013-06-11 16:24:11 +010014#include "base/strings/string_util.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000015#include "base/threading/thread_restrictions.h"
16#include "base/values.h"
17#include "chrome/browser/browser_process.h"
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010018#include "chrome/browser/chromeos/policy/device_local_account.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000019#include "chrome/browser/chromeos/settings/cros_settings.h"
20#include "chrome/browser/chromeos/settings/cros_settings_names.h"
21#include "chrome/browser/chromeos/settings/device_settings_cache.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000022#include "chrome/browser/policy/browser_policy_connector.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000023#include "chrome/browser/policy/cloud/cloud_policy_constants.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010024#include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000025#include "chrome/browser/ui/options/options_util.h"
26#include "chrome/installer/util/google_update_settings.h"
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +010027#include "chromeos/chromeos_switches.h"
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010028#include "chromeos/network/device_state.h"
29#include "chromeos/network/network_device_handler.h"
30#include "chromeos/network/network_event_log.h"
31#include "chromeos/network/network_handler.h"
32#include "chromeos/network/network_state_handler.h"
33#include "third_party/cros_system_api/dbus/service_constants.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000034
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010035using google::protobuf::RepeatedField;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000036using google::protobuf::RepeatedPtrField;
37
38namespace em = enterprise_management;
39
40namespace chromeos {
41
42namespace {
43
44// List of settings handled by the DeviceSettingsProvider.
45const char* kKnownSettings[] = {
46 kAccountsPrefAllowGuest,
47 kAccountsPrefAllowNewUser,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000048 kAccountsPrefDeviceLocalAccounts,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010049 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000050 kAccountsPrefDeviceLocalAccountAutoLoginDelay,
51 kAccountsPrefDeviceLocalAccountAutoLoginId,
Torne (Richard Coles)58218062012-11-14 11:43:16 +000052 kAccountsPrefEphemeralUsersEnabled,
53 kAccountsPrefShowUserNamesOnSignIn,
Ben Murdocheb525c52013-07-10 11:40:50 +010054 kAccountsPrefSupervisedUsersEnabled,
Torne (Richard Coles)58218062012-11-14 11:43:16 +000055 kAccountsPrefUsers,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000056 kAllowRedeemChromeOsRegistrationOffers,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010057 kAllowedConnectionTypesForUpdate,
Torne (Richard Coles)58218062012-11-14 11:43:16 +000058 kAppPack,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010059 kDeviceAttestationEnabled,
Torne (Richard Coles)58218062012-11-14 11:43:16 +000060 kDeviceOwner,
61 kIdleLogoutTimeout,
62 kIdleLogoutWarningDuration,
63 kPolicyMissingMitigationMode,
64 kReleaseChannel,
65 kReleaseChannelDelegated,
66 kReportDeviceActivityTimes,
67 kReportDeviceBootMode,
68 kReportDeviceLocation,
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010069 kReportDeviceNetworkInterfaces,
Torne (Richard Coles)58218062012-11-14 11:43:16 +000070 kReportDeviceVersionInfo,
71 kScreenSaverExtensionId,
72 kScreenSaverTimeout,
Torne (Richard Coles)58218062012-11-14 11:43:16 +000073 kSignedDataRoamingEnabled,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010074 kStartUpFlags,
Torne (Richard Coles)58218062012-11-14 11:43:16 +000075 kStartUpUrls,
76 kStatsReportingPref,
77 kSystemTimezonePolicy,
Ben Murdochbb1529c2013-08-08 10:24:53 +010078 kSystemUse24HourClock,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010079 kUpdateDisabled,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010080 kVariationsRestrictParameter,
Torne (Richard Coles)58218062012-11-14 11:43:16 +000081};
82
83// Legacy policy file location. Used to detect migration from pre v12 ChromeOS.
84const char kLegacyPolicyFile[] = "/var/lib/whitelist/preferences";
85
Torne (Richard Coles)58218062012-11-14 11:43:16 +000086bool 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();
93}
94
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010095void LogShillError(
96 const std::string& name,
97 scoped_ptr<base::DictionaryValue> error_data) {
98 NET_LOG_ERROR("Shill error: " + name, "Network operation failed.");
99}
100
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000101} // namespace
102
103DeviceSettingsProvider::DeviceSettingsProvider(
104 const NotifyObserversCallback& notify_cb,
105 DeviceSettingsService* device_settings_service)
106 : CrosSettingsProvider(notify_cb),
107 device_settings_service_(device_settings_service),
108 trusted_status_(TEMPORARILY_UNTRUSTED),
109 ownership_status_(device_settings_service_->GetOwnershipStatus()),
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100110 store_callback_factory_(this) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000111 device_settings_service_->AddObserver(this);
112
113 if (!UpdateFromService()) {
114 // Make sure we have at least the cache data immediately.
115 RetrieveCachedData();
116 }
117}
118
119DeviceSettingsProvider::~DeviceSettingsProvider() {
120 device_settings_service_->RemoveObserver(this);
121}
122
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000123// static
124bool DeviceSettingsProvider::IsDeviceSetting(const std::string& name) {
125 const char** end = kKnownSettings + arraysize(kKnownSettings);
126 return std::find(kKnownSettings, end, name) != end;
127}
128
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000129void DeviceSettingsProvider::DoSet(const std::string& path,
130 const base::Value& in_value) {
131 // Make sure that either the current user is the device owner or the
132 // device doesn't have an owner yet.
133 if (!(device_settings_service_->HasPrivateOwnerKey() ||
134 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)) {
135 LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
136
137 // Revert UI change.
138 NotifyObservers(path);
139 return;
140 }
141
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000142 if (IsDeviceSetting(path)) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000143 pending_changes_.push_back(PendingQueueElement(path, in_value.DeepCopy()));
144 if (!store_callback_factory_.HasWeakPtrs())
145 SetInPolicy();
146 } else {
147 NOTREACHED() << "Try to set unhandled cros setting " << path;
148 }
149}
150
151void DeviceSettingsProvider::OwnershipStatusChanged() {
152 DeviceSettingsService::OwnershipStatus new_ownership_status =
153 device_settings_service_->GetOwnershipStatus();
154
155 // If the device just became owned, write the settings accumulated in the
156 // cache to device settings proper. It is important that writing only happens
157 // in this case, as during normal operation, the contents of the cache should
158 // never overwrite actual device settings.
159 if (new_ownership_status == DeviceSettingsService::OWNERSHIP_TAKEN &&
160 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE &&
161 device_settings_service_->HasPrivateOwnerKey()) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000162 // There shouldn't be any pending writes, since the cache writes are all
163 // immediate.
164 DCHECK(!store_callback_factory_.HasWeakPtrs());
165
166 // Apply the locally-accumulated device settings on top of the initial
167 // settings from the service and write back the result.
168 if (device_settings_service_->device_settings()) {
169 em::ChromeDeviceSettingsProto new_settings(
170 *device_settings_service_->device_settings());
171 new_settings.MergeFrom(device_settings_);
172 device_settings_.Swap(&new_settings);
173 }
174 StoreDeviceSettings();
175 }
176
177 // The owner key might have become available, allowing migration to happen.
178 AttemptMigration();
179
180 ownership_status_ = new_ownership_status;
181}
182
183void DeviceSettingsProvider::DeviceSettingsUpdated() {
184 if (!store_callback_factory_.HasWeakPtrs())
185 UpdateAndProceedStoring();
186}
187
188void DeviceSettingsProvider::RetrieveCachedData() {
189 em::PolicyData policy_data;
190 if (!device_settings_cache::Retrieve(&policy_data,
191 g_browser_process->local_state()) ||
192 !device_settings_.ParseFromString(policy_data.policy_value())) {
193 VLOG(1) << "Can't retrieve temp store, possibly not created yet.";
194 }
195
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000196 UpdateValuesCache(policy_data, device_settings_, trusted_status_);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000197}
198
199void DeviceSettingsProvider::SetInPolicy() {
200 if (pending_changes_.empty()) {
201 NOTREACHED();
202 return;
203 }
204
205 if (RequestTrustedEntity() != TRUSTED) {
206 // Re-sync device settings before proceeding.
207 device_settings_service_->Load();
208 return;
209 }
210
211 std::string prop(pending_changes_.front().first);
212 scoped_ptr<base::Value> value(pending_changes_.front().second);
213 pending_changes_.pop_front();
214
215 trusted_status_ = TEMPORARILY_UNTRUSTED;
216 if (prop == kAccountsPrefAllowNewUser) {
217 em::AllowNewUsersProto* allow =
218 device_settings_.mutable_allow_new_users();
219 bool allow_value;
220 if (value->GetAsBoolean(&allow_value))
221 allow->set_allow_new_users(allow_value);
222 else
223 NOTREACHED();
224 } else if (prop == kAccountsPrefAllowGuest) {
225 em::GuestModeEnabledProto* guest =
226 device_settings_.mutable_guest_mode_enabled();
227 bool guest_value;
228 if (value->GetAsBoolean(&guest_value))
229 guest->set_guest_mode_enabled(guest_value);
230 else
231 NOTREACHED();
232 } else if (prop == kAccountsPrefShowUserNamesOnSignIn) {
233 em::ShowUserNamesOnSigninProto* show =
234 device_settings_.mutable_show_user_names();
235 bool show_value;
236 if (value->GetAsBoolean(&show_value))
237 show->set_show_user_names(show_value);
238 else
239 NOTREACHED();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000240 } else if (prop == kAccountsPrefDeviceLocalAccounts) {
241 em::DeviceLocalAccountsProto* device_local_accounts =
242 device_settings_.mutable_device_local_accounts();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100243 device_local_accounts->clear_account();
244 const base::ListValue* accounts_list = NULL;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000245 if (value->GetAsList(&accounts_list)) {
246 for (base::ListValue::const_iterator entry(accounts_list->begin());
247 entry != accounts_list->end(); ++entry) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100248 const base::DictionaryValue* entry_dict = NULL;
249 if ((*entry)->GetAsDictionary(&entry_dict)) {
250 em::DeviceLocalAccountInfoProto* account =
251 device_local_accounts->add_account();
252 std::string account_id;
253 if (entry_dict->GetStringWithoutPathExpansion(
254 kAccountsPrefDeviceLocalAccountsKeyId, &account_id)) {
255 account->set_account_id(account_id);
256 }
257 int type;
258 if (entry_dict->GetIntegerWithoutPathExpansion(
259 kAccountsPrefDeviceLocalAccountsKeyType, &type)) {
260 account->set_type(
261 static_cast<em::DeviceLocalAccountInfoProto::AccountType>(
262 type));
263 }
264 std::string kiosk_app_id;
265 if (entry_dict->GetStringWithoutPathExpansion(
266 kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
267 &kiosk_app_id)) {
268 account->mutable_kiosk_app()->set_app_id(kiosk_app_id);
269 }
270 std::string kiosk_app_update_url;
271 if (entry_dict->GetStringWithoutPathExpansion(
272 kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL,
273 &kiosk_app_update_url)) {
274 account->mutable_kiosk_app()->set_update_url(kiosk_app_update_url);
275 }
276 } else {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000277 NOTREACHED();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100278 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000279 }
280 } else {
281 NOTREACHED();
282 }
283 } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginId) {
284 em::DeviceLocalAccountsProto* device_local_accounts =
285 device_settings_.mutable_device_local_accounts();
286 std::string id;
287 if (value->GetAsString(&id))
288 device_local_accounts->set_auto_login_id(id);
289 else
290 NOTREACHED();
291 } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginDelay) {
292 em::DeviceLocalAccountsProto* device_local_accounts =
293 device_settings_.mutable_device_local_accounts();
294 int delay;
295 if (value->GetAsInteger(&delay))
296 device_local_accounts->set_auto_login_delay(delay);
297 else
298 NOTREACHED();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100299 } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled) {
300 em::DeviceLocalAccountsProto* device_local_accounts =
301 device_settings_.mutable_device_local_accounts();
302 bool enabled;
303 if (value->GetAsBoolean(&enabled))
304 device_local_accounts->set_enable_auto_login_bailout(enabled);
305 else
306 NOTREACHED();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000307 } else if (prop == kSignedDataRoamingEnabled) {
308 em::DataRoamingEnabledProto* roam =
309 device_settings_.mutable_data_roaming_enabled();
310 bool roaming_value = false;
311 if (value->GetAsBoolean(&roaming_value))
312 roam->set_data_roaming_enabled(roaming_value);
313 else
314 NOTREACHED();
315 ApplyRoamingSetting(roaming_value);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000316 } else if (prop == kReleaseChannel) {
317 em::ReleaseChannelProto* release_channel =
318 device_settings_.mutable_release_channel();
319 std::string channel_value;
320 if (value->GetAsString(&channel_value))
321 release_channel->set_release_channel(channel_value);
322 else
323 NOTREACHED();
324 } else if (prop == kStatsReportingPref) {
325 em::MetricsEnabledProto* metrics =
326 device_settings_.mutable_metrics_enabled();
327 bool metrics_value = false;
328 if (value->GetAsBoolean(&metrics_value))
329 metrics->set_metrics_enabled(metrics_value);
330 else
331 NOTREACHED();
332 ApplyMetricsSetting(false, metrics_value);
333 } else if (prop == kAccountsPrefUsers) {
334 em::UserWhitelistProto* whitelist_proto =
335 device_settings_.mutable_user_whitelist();
336 whitelist_proto->clear_user_whitelist();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000337 const base::ListValue* users;
338 if (value->GetAsList(&users)) {
339 for (base::ListValue::const_iterator i = users->begin();
340 i != users->end(); ++i) {
341 std::string email;
342 if ((*i)->GetAsString(&email))
343 whitelist_proto->add_user_whitelist(email);
344 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000345 }
346 } else if (prop == kAccountsPrefEphemeralUsersEnabled) {
347 em::EphemeralUsersEnabledProto* ephemeral_users_enabled =
348 device_settings_.mutable_ephemeral_users_enabled();
349 bool ephemeral_users_enabled_value = false;
350 if (value->GetAsBoolean(&ephemeral_users_enabled_value)) {
351 ephemeral_users_enabled->set_ephemeral_users_enabled(
352 ephemeral_users_enabled_value);
353 } else {
354 NOTREACHED();
355 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000356 } else if (prop == kAllowRedeemChromeOsRegistrationOffers) {
357 em::AllowRedeemChromeOsRegistrationOffersProto* allow_redeem_offers =
358 device_settings_.mutable_allow_redeem_offers();
359 bool allow_redeem_offers_value;
360 if (value->GetAsBoolean(&allow_redeem_offers_value)) {
361 allow_redeem_offers->set_allow_redeem_offers(
362 allow_redeem_offers_value);
363 } else {
364 NOTREACHED();
365 }
366 } else if (prop == kStartUpFlags) {
367 em::StartUpFlagsProto* flags_proto =
368 device_settings_.mutable_start_up_flags();
369 flags_proto->Clear();
370 const base::ListValue* flags;
371 if (value->GetAsList(&flags)) {
372 for (base::ListValue::const_iterator i = flags->begin();
373 i != flags->end(); ++i) {
374 std::string flag;
375 if ((*i)->GetAsString(&flag))
376 flags_proto->add_flags(flag);
377 }
378 }
Ben Murdochbb1529c2013-08-08 10:24:53 +0100379 } else if (prop == kSystemUse24HourClock) {
380 em::SystemUse24HourClockProto* use_24hour_clock_proto =
381 device_settings_.mutable_use_24hour_clock();
382 use_24hour_clock_proto->Clear();
383 bool use_24hour_clock_value;
384 if (value->GetAsBoolean(&use_24hour_clock_value)) {
385 use_24hour_clock_proto->set_use_24hour_clock(use_24hour_clock_value);
386 } else {
387 NOTREACHED();
388 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000389 } else {
390 // The remaining settings don't support Set(), since they are not
391 // intended to be customizable by the user:
Ben Murdocheb525c52013-07-10 11:40:50 +0100392 // kAccountsPrefSupervisedUsersEnabled
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000393 // kAppPack
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100394 // kDeviceAttestationEnabled
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000395 // kDeviceOwner
396 // kIdleLogoutTimeout
397 // kIdleLogoutWarningDuration
398 // kReleaseChannelDelegated
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000399 // kReportDeviceActivityTimes
400 // kReportDeviceBootMode
401 // kReportDeviceLocation
Ben Murdocheb525c52013-07-10 11:40:50 +0100402 // kReportDeviceVersionInfo
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100403 // kReportDeviceNetworkInterfaces
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000404 // kScreenSaverExtensionId
405 // kScreenSaverTimeout
406 // kStartUpUrls
407 // kSystemTimezonePolicy
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100408 // kVariationsRestrictParameter
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000409
410 LOG(FATAL) << "Device setting " << prop << " is read-only.";
411 }
412
413 em::PolicyData data;
414 data.set_username(device_settings_service_->GetUsername());
415 CHECK(device_settings_.SerializeToString(data.mutable_policy_value()));
416
417 // Set the cache to the updated value.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000418 UpdateValuesCache(data, device_settings_, trusted_status_);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000419
420 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_TAKEN) {
421 StoreDeviceSettings();
422 } else {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000423 if (!device_settings_cache::Store(data, g_browser_process->local_state()))
424 LOG(ERROR) << "Couldn't store to the temp storage.";
425
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000426 // OnStorePolicyCompleted won't get called in this case so proceed with any
427 // pending operations immediately.
428 if (!pending_changes_.empty())
429 SetInPolicy();
430 }
431}
432
433void DeviceSettingsProvider::DecodeLoginPolicies(
434 const em::ChromeDeviceSettingsProto& policy,
435 PrefValueMap* new_values_cache) const {
436 // For all our boolean settings the following is applicable:
437 // true is default permissive value and false is safe prohibitive value.
438 // Exceptions:
439 // kSignedDataRoamingEnabled has a default value of false.
440 // kAccountsPrefEphemeralUsersEnabled has a default value of false.
441 if (policy.has_allow_new_users() &&
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100442 policy.allow_new_users().has_allow_new_users()) {
443 if (policy.allow_new_users().allow_new_users()) {
444 // New users allowed, user whitelist ignored.
445 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true);
446 } else {
447 // New users not allowed, enforce user whitelist if present.
448 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser,
449 !policy.has_user_whitelist());
450 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000451 } else {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100452 // No configured allow-new-users value, enforce whitelist if non-empty.
453 new_values_cache->SetBoolean(
454 kAccountsPrefAllowNewUser,
455 policy.user_whitelist().user_whitelist_size() == 0);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000456 }
457
458 new_values_cache->SetBoolean(
459 kAccountsPrefAllowGuest,
460 !policy.has_guest_mode_enabled() ||
461 !policy.guest_mode_enabled().has_guest_mode_enabled() ||
462 policy.guest_mode_enabled().guest_mode_enabled());
463
464 new_values_cache->SetBoolean(
465 kAccountsPrefShowUserNamesOnSignIn,
466 !policy.has_show_user_names() ||
467 !policy.show_user_names().has_show_user_names() ||
468 policy.show_user_names().show_user_names());
469
470 new_values_cache->SetBoolean(
471 kAccountsPrefEphemeralUsersEnabled,
472 policy.has_ephemeral_users_enabled() &&
473 policy.ephemeral_users_enabled().has_ephemeral_users_enabled() &&
474 policy.ephemeral_users_enabled().ephemeral_users_enabled());
475
Ben Murdocheb525c52013-07-10 11:40:50 +0100476 new_values_cache->SetBoolean(
477 kAccountsPrefSupervisedUsersEnabled,
478 policy.has_supervised_users_settings() &&
479 policy.supervised_users_settings().supervised_users_enabled());
480
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000481 base::ListValue* list = new base::ListValue();
482 const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist();
483 const RepeatedPtrField<std::string>& whitelist =
484 whitelist_proto.user_whitelist();
485 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin();
486 it != whitelist.end(); ++it) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000487 list->Append(new base::StringValue(*it));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000488 }
489 new_values_cache->SetValue(kAccountsPrefUsers, list);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000490
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100491 scoped_ptr<base::ListValue> account_list(new base::ListValue());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000492 CommandLine* command_line = CommandLine::ForCurrentProcess();
493 if (!command_line->HasSwitch(switches::kDisableLocalAccounts)) {
494 const em::DeviceLocalAccountsProto device_local_accounts_proto =
495 policy.device_local_accounts();
496 const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts =
497 device_local_accounts_proto.account();
498 RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry;
499 for (entry = accounts.begin(); entry != accounts.end(); ++entry) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100500 scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue());
501 if (entry->has_type()) {
502 if (entry->has_account_id()) {
503 entry_dict->SetStringWithoutPathExpansion(
504 kAccountsPrefDeviceLocalAccountsKeyId, entry->account_id());
505 }
506 entry_dict->SetIntegerWithoutPathExpansion(
507 kAccountsPrefDeviceLocalAccountsKeyType, entry->type());
508 if (entry->kiosk_app().has_app_id()) {
509 entry_dict->SetStringWithoutPathExpansion(
510 kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
511 entry->kiosk_app().app_id());
512 }
513 if (entry->kiosk_app().has_update_url()) {
514 entry_dict->SetStringWithoutPathExpansion(
515 kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL,
516 entry->kiosk_app().update_url());
517 }
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100518 } else if (entry->has_deprecated_public_session_id()) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100519 // Deprecated public session specification.
520 entry_dict->SetStringWithoutPathExpansion(
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100521 kAccountsPrefDeviceLocalAccountsKeyId,
522 entry->deprecated_public_session_id());
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100523 entry_dict->SetIntegerWithoutPathExpansion(
524 kAccountsPrefDeviceLocalAccountsKeyType,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100525 policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100526 }
527 account_list->Append(entry_dict.release());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000528 }
529 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100530 new_values_cache->SetValue(kAccountsPrefDeviceLocalAccounts,
531 account_list.release());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000532
533 if (policy.has_device_local_accounts()) {
534 if (policy.device_local_accounts().has_auto_login_id()) {
535 new_values_cache->SetString(
536 kAccountsPrefDeviceLocalAccountAutoLoginId,
537 policy.device_local_accounts().auto_login_id());
538 }
539 if (policy.device_local_accounts().has_auto_login_delay()) {
540 new_values_cache->SetInteger(
541 kAccountsPrefDeviceLocalAccountAutoLoginDelay,
542 policy.device_local_accounts().auto_login_delay());
543 }
544 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100545
546 new_values_cache->SetBoolean(
547 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
548 policy.device_local_accounts().enable_auto_login_bailout());
549
550 if (policy.has_start_up_flags()) {
551 base::ListValue* list = new base::ListValue();
552 const em::StartUpFlagsProto& flags_proto = policy.start_up_flags();
553 const RepeatedPtrField<std::string>& flags = flags_proto.flags();
554 for (RepeatedPtrField<std::string>::const_iterator it = flags.begin();
555 it != flags.end(); ++it) {
556 list->Append(new base::StringValue(*it));
557 }
558 new_values_cache->SetValue(kStartUpFlags, list);
559 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000560}
561
562void DeviceSettingsProvider::DecodeKioskPolicies(
563 const em::ChromeDeviceSettingsProto& policy,
564 PrefValueMap* new_values_cache) const {
565 if (policy.has_forced_logout_timeouts()) {
566 if (policy.forced_logout_timeouts().has_idle_logout_timeout()) {
567 new_values_cache->SetInteger(
568 kIdleLogoutTimeout,
569 policy.forced_logout_timeouts().idle_logout_timeout());
570 }
571
572 if (policy.forced_logout_timeouts().has_idle_logout_warning_duration()) {
573 new_values_cache->SetInteger(
574 kIdleLogoutWarningDuration,
575 policy.forced_logout_timeouts().idle_logout_warning_duration());
576 }
577 }
578
579 if (policy.has_login_screen_saver()) {
580 if (policy.login_screen_saver().has_screen_saver_timeout()) {
581 new_values_cache->SetInteger(
582 kScreenSaverTimeout,
583 policy.login_screen_saver().screen_saver_timeout());
584 }
585
586 if (policy.login_screen_saver().has_screen_saver_extension_id()) {
587 new_values_cache->SetString(
588 kScreenSaverExtensionId,
589 policy.login_screen_saver().screen_saver_extension_id());
590 }
591 }
592
593 if (policy.has_app_pack()) {
594 typedef RepeatedPtrField<em::AppPackEntryProto> proto_type;
595 base::ListValue* list = new base::ListValue;
596 const proto_type& app_pack = policy.app_pack().app_pack();
597 for (proto_type::const_iterator it = app_pack.begin();
598 it != app_pack.end(); ++it) {
599 base::DictionaryValue* entry = new base::DictionaryValue;
600 if (it->has_extension_id()) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100601 entry->SetStringWithoutPathExpansion(kAppPackKeyExtensionId,
602 it->extension_id());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000603 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100604 if (it->has_update_url()) {
605 entry->SetStringWithoutPathExpansion(kAppPackKeyUpdateUrl,
606 it->update_url());
607 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000608 list->Append(entry);
609 }
610 new_values_cache->SetValue(kAppPack, list);
611 }
612
613 if (policy.has_start_up_urls()) {
614 base::ListValue* list = new base::ListValue();
615 const em::StartUpUrlsProto& urls_proto = policy.start_up_urls();
616 const RepeatedPtrField<std::string>& urls = urls_proto.start_up_urls();
617 for (RepeatedPtrField<std::string>::const_iterator it = urls.begin();
618 it != urls.end(); ++it) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000619 list->Append(new base::StringValue(*it));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000620 }
621 new_values_cache->SetValue(kStartUpUrls, list);
622 }
623}
624
625void DeviceSettingsProvider::DecodeNetworkPolicies(
626 const em::ChromeDeviceSettingsProto& policy,
627 PrefValueMap* new_values_cache) const {
628 new_values_cache->SetBoolean(
629 kSignedDataRoamingEnabled,
630 policy.has_data_roaming_enabled() &&
631 policy.data_roaming_enabled().has_data_roaming_enabled() &&
632 policy.data_roaming_enabled().data_roaming_enabled());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000633}
634
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100635void DeviceSettingsProvider::DecodeAutoUpdatePolicies(
636 const em::ChromeDeviceSettingsProto& policy,
637 PrefValueMap* new_values_cache) const {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100638 if (policy.has_auto_update_settings()) {
639 const em::AutoUpdateSettingsProto& au_settings_proto =
640 policy.auto_update_settings();
641 if (au_settings_proto.has_update_disabled()) {
642 new_values_cache->SetBoolean(kUpdateDisabled,
643 au_settings_proto.update_disabled());
644 }
645 const RepeatedField<int>& allowed_connection_types =
646 au_settings_proto.allowed_connection_types();
647 base::ListValue* list = new base::ListValue();
648 for (RepeatedField<int>::const_iterator i(allowed_connection_types.begin());
649 i != allowed_connection_types.end(); ++i) {
650 list->Append(new base::FundamentalValue(*i));
651 }
652 new_values_cache->SetValue(kAllowedConnectionTypesForUpdate, list);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100653 }
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100654}
655
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000656void DeviceSettingsProvider::DecodeReportingPolicies(
657 const em::ChromeDeviceSettingsProto& policy,
658 PrefValueMap* new_values_cache) const {
659 if (policy.has_device_reporting()) {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100660 const em::DeviceReportingProto& reporting_policy =
661 policy.device_reporting();
662 if (reporting_policy.has_report_version_info()) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000663 new_values_cache->SetBoolean(
664 kReportDeviceVersionInfo,
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100665 reporting_policy.report_version_info());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000666 }
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100667 if (reporting_policy.has_report_activity_times()) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000668 new_values_cache->SetBoolean(
669 kReportDeviceActivityTimes,
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100670 reporting_policy.report_activity_times());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000671 }
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100672 if (reporting_policy.has_report_boot_mode()) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000673 new_values_cache->SetBoolean(
674 kReportDeviceBootMode,
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100675 reporting_policy.report_boot_mode());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000676 }
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100677 if (reporting_policy.has_report_network_interfaces()) {
678 new_values_cache->SetBoolean(
679 kReportDeviceNetworkInterfaces,
680 reporting_policy.report_network_interfaces());
681 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000682 }
683}
684
685void DeviceSettingsProvider::DecodeGenericPolicies(
686 const em::ChromeDeviceSettingsProto& policy,
687 PrefValueMap* new_values_cache) const {
688 if (policy.has_metrics_enabled()) {
689 new_values_cache->SetBoolean(kStatsReportingPref,
690 policy.metrics_enabled().metrics_enabled());
691 } else {
692 new_values_cache->SetBoolean(kStatsReportingPref, HasOldMetricsFile());
693 }
694
695 if (!policy.has_release_channel() ||
696 !policy.release_channel().has_release_channel()) {
697 // Default to an invalid channel (will be ignored).
698 new_values_cache->SetString(kReleaseChannel, "");
699 } else {
700 new_values_cache->SetString(kReleaseChannel,
701 policy.release_channel().release_channel());
702 }
703
704 new_values_cache->SetBoolean(
705 kReleaseChannelDelegated,
706 policy.has_release_channel() &&
707 policy.release_channel().has_release_channel_delegated() &&
708 policy.release_channel().release_channel_delegated());
709
710 if (policy.has_system_timezone()) {
711 if (policy.system_timezone().has_timezone()) {
712 new_values_cache->SetString(
713 kSystemTimezonePolicy,
714 policy.system_timezone().timezone());
715 }
716 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000717
Ben Murdochbb1529c2013-08-08 10:24:53 +0100718 if (policy.has_use_24hour_clock()) {
719 if (policy.use_24hour_clock().has_use_24hour_clock()) {
720 new_values_cache->SetBoolean(
721 kSystemUse24HourClock, policy.use_24hour_clock().use_24hour_clock());
722 }
723 }
724
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000725 if (policy.has_allow_redeem_offers()) {
726 new_values_cache->SetBoolean(
727 kAllowRedeemChromeOsRegistrationOffers,
728 policy.allow_redeem_offers().allow_redeem_offers());
729 } else {
730 new_values_cache->SetBoolean(
731 kAllowRedeemChromeOsRegistrationOffers,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100732 true);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000733 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100734
735 if (policy.has_variations_parameter()) {
736 new_values_cache->SetString(
737 kVariationsRestrictParameter,
738 policy.variations_parameter().parameter());
739 }
740
741 new_values_cache->SetBoolean(
742 kDeviceAttestationEnabled,
743 policy.attestation_settings().attestation_enabled());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000744}
745
746void DeviceSettingsProvider::UpdateValuesCache(
747 const em::PolicyData& policy_data,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000748 const em::ChromeDeviceSettingsProto& settings,
749 TrustedStatus trusted_status) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000750 PrefValueMap new_values_cache;
751
752 if (policy_data.has_username() && !policy_data.has_request_token())
753 new_values_cache.SetString(kDeviceOwner, policy_data.username());
754
755 DecodeLoginPolicies(settings, &new_values_cache);
756 DecodeKioskPolicies(settings, &new_values_cache);
757 DecodeNetworkPolicies(settings, &new_values_cache);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100758 DecodeAutoUpdatePolicies(settings, &new_values_cache);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000759 DecodeReportingPolicies(settings, &new_values_cache);
760 DecodeGenericPolicies(settings, &new_values_cache);
761
762 // Collect all notifications but send them only after we have swapped the
763 // cache so that if somebody actually reads the cache will be already valid.
764 std::vector<std::string> notifications;
765 // Go through the new values and verify in the old ones.
766 PrefValueMap::iterator iter = new_values_cache.begin();
767 for (; iter != new_values_cache.end(); ++iter) {
768 const base::Value* old_value;
769 if (!values_cache_.GetValue(iter->first, &old_value) ||
770 !old_value->Equals(iter->second)) {
771 notifications.push_back(iter->first);
772 }
773 }
774 // Now check for values that have been removed from the policy blob.
775 for (iter = values_cache_.begin(); iter != values_cache_.end(); ++iter) {
776 const base::Value* value;
777 if (!new_values_cache.GetValue(iter->first, &value))
778 notifications.push_back(iter->first);
779 }
780 // Swap and notify.
781 values_cache_.Swap(&new_values_cache);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000782 trusted_status_ = trusted_status;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000783 for (size_t i = 0; i < notifications.size(); ++i)
784 NotifyObservers(notifications[i]);
785}
786
787void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file,
788 bool new_value) {
789 // TODO(pastarmovj): Remove this once migration is not needed anymore.
790 // If the value is not set we should try to migrate legacy consent file.
791 if (use_file) {
792 new_value = HasOldMetricsFile();
793 // Make sure the values will get eventually written to the policy file.
794 migration_values_.SetValue(kStatsReportingPref,
795 base::Value::CreateBooleanValue(new_value));
796 AttemptMigration();
797 LOG(INFO) << "No metrics policy set will revert to checking "
798 << "consent file which is "
799 << (new_value ? "on." : "off.");
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000800 UMA_HISTOGRAM_COUNTS("DeviceSettings.MetricsMigrated", 1);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000801 }
802 VLOG(1) << "Metrics policy is being set to : " << new_value
803 << "(use file : " << use_file << ")";
804 // TODO(pastarmovj): Remove this once we don't need to regenerate the
805 // consent file for the GUID anymore.
806 OptionsUtil::ResolveMetricsReportingEnabled(new_value);
807}
808
809void DeviceSettingsProvider::ApplyRoamingSetting(bool new_value) {
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100810 // TODO(armansito): Look up the device by explicitly using the device path.
811 const DeviceState* cellular =
812 NetworkHandler::Get()->network_state_handler()->
813 GetDeviceStateByType(flimflam::kTypeCellular);
814 if (!cellular) {
815 NET_LOG_DEBUG("No cellular device is available",
816 "Roaming is only supported by cellular devices.");
817 return;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000818 }
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100819 bool current_value;
820 if (!cellular->properties().GetBooleanWithoutPathExpansion(
821 flimflam::kCellularAllowRoamingProperty, &current_value)) {
822 NET_LOG_ERROR("Could not get \"allow roaming\" property from cellular "
823 "device.", cellular->path());
824 return;
825 }
826
827 // Only set the value if the current value is different from |new_value|.
828 // If roaming is required by the provider, always try to set to true.
829 new_value = (cellular->provider_requires_roaming() ? true : new_value);
830 if (new_value == current_value)
831 return;
832
833 NetworkHandler::Get()->network_device_handler()->SetDeviceProperty(
834 cellular->path(),
835 flimflam::kCellularAllowRoamingProperty,
836 base::FundamentalValue(new_value),
837 base::Bind(&base::DoNothing),
838 base::Bind(&LogShillError));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000839}
840
841void DeviceSettingsProvider::ApplySideEffects(
842 const em::ChromeDeviceSettingsProto& settings) {
843 // First migrate metrics settings as needed.
844 if (settings.has_metrics_enabled())
845 ApplyMetricsSetting(false, settings.metrics_enabled().metrics_enabled());
846 else
847 ApplyMetricsSetting(true, false);
848
849 // Next set the roaming setting as needed.
850 ApplyRoamingSetting(
851 settings.has_data_roaming_enabled() ?
852 settings.data_roaming_enabled().data_roaming_enabled() :
853 false);
854}
855
856bool DeviceSettingsProvider::MitigateMissingPolicy() {
857 // First check if the device has been owned already and if not exit
858 // immediately.
859 if (g_browser_process->browser_policy_connector()->GetDeviceMode() !=
860 policy::DEVICE_MODE_CONSUMER) {
861 return false;
862 }
863
864 // If we are here the policy file were corrupted or missing. This can happen
865 // because we are migrating Pre R11 device to the new secure policies or there
866 // was an attempt to circumvent policy system. In this case we should populate
867 // the policy cache with "safe-mode" defaults which should allow the owner to
868 // log in but lock the device for anyone else until the policy blob has been
869 // recreated by the session manager.
870 LOG(ERROR) << "Corruption of the policy data has been detected."
871 << "Switching to \"safe-mode\" policies until the owner logs in "
872 << "to regenerate the policy data.";
873
874 device_settings_.Clear();
875 device_settings_.mutable_allow_new_users()->set_allow_new_users(true);
876 device_settings_.mutable_guest_mode_enabled()->set_guest_mode_enabled(true);
877 em::PolicyData empty_policy_data;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000878 UpdateValuesCache(empty_policy_data, device_settings_, TRUSTED);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000879 values_cache_.SetBoolean(kPolicyMissingMitigationMode, true);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000880
881 return true;
882}
883
884const base::Value* DeviceSettingsProvider::Get(const std::string& path) const {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000885 if (IsDeviceSetting(path)) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000886 const base::Value* value;
887 if (values_cache_.GetValue(path, &value))
888 return value;
889 } else {
890 NOTREACHED() << "Trying to get non cros setting.";
891 }
892
893 return NULL;
894}
895
896DeviceSettingsProvider::TrustedStatus
897 DeviceSettingsProvider::PrepareTrustedValues(const base::Closure& cb) {
898 TrustedStatus status = RequestTrustedEntity();
899 if (status == TEMPORARILY_UNTRUSTED && !cb.is_null())
900 callbacks_.push_back(cb);
901 return status;
902}
903
904bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000905 return IsDeviceSetting(path);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000906}
907
908DeviceSettingsProvider::TrustedStatus
909 DeviceSettingsProvider::RequestTrustedEntity() {
910 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)
911 return TRUSTED;
912 return trusted_status_;
913}
914
915void DeviceSettingsProvider::UpdateAndProceedStoring() {
916 // Re-sync the cache from the service.
917 UpdateFromService();
918
919 // Trigger the next change if necessary.
920 if (trusted_status_ == TRUSTED && !pending_changes_.empty())
921 SetInPolicy();
922}
923
924bool DeviceSettingsProvider::UpdateFromService() {
925 bool settings_loaded = false;
926 switch (device_settings_service_->status()) {
927 case DeviceSettingsService::STORE_SUCCESS: {
928 const em::PolicyData* policy_data =
929 device_settings_service_->policy_data();
930 const em::ChromeDeviceSettingsProto* device_settings =
931 device_settings_service_->device_settings();
932 if (policy_data && device_settings) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000933 if (!device_settings_cache::Store(*policy_data,
934 g_browser_process->local_state())) {
935 LOG(ERROR) << "Couldn't update the local state cache.";
936 }
937 UpdateValuesCache(*policy_data, *device_settings, TRUSTED);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000938 device_settings_ = *device_settings;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000939
940 // TODO(pastarmovj): Make those side effects responsibility of the
941 // respective subsystems.
942 ApplySideEffects(*device_settings);
943
944 settings_loaded = true;
945 } else {
946 // Initial policy load is still pending.
947 trusted_status_ = TEMPORARILY_UNTRUSTED;
948 }
949 break;
950 }
951 case DeviceSettingsService::STORE_NO_POLICY:
952 if (MitigateMissingPolicy())
953 break;
954 // fall through.
955 case DeviceSettingsService::STORE_KEY_UNAVAILABLE:
956 VLOG(1) << "No policies present yet, will use the temp storage.";
957 trusted_status_ = PERMANENTLY_UNTRUSTED;
958 break;
959 case DeviceSettingsService::STORE_POLICY_ERROR:
960 case DeviceSettingsService::STORE_VALIDATION_ERROR:
961 case DeviceSettingsService::STORE_INVALID_POLICY:
962 case DeviceSettingsService::STORE_OPERATION_FAILED:
963 LOG(ERROR) << "Failed to retrieve cros policies. Reason: "
964 << device_settings_service_->status();
965 trusted_status_ = PERMANENTLY_UNTRUSTED;
966 break;
967 case DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR:
968 // The policy has failed to validate due to temporary error but it might
969 // take a long time until we recover so behave as it is a permanent error.
970 LOG(ERROR) << "Failed to retrieve cros policies because a temporary "
971 << "validation error has occurred. Retrying might succeed.";
972 trusted_status_ = PERMANENTLY_UNTRUSTED;
973 break;
974 }
975
976 // Notify the observers we are done.
977 std::vector<base::Closure> callbacks;
978 callbacks.swap(callbacks_);
979 for (size_t i = 0; i < callbacks.size(); ++i)
980 callbacks[i].Run();
981
982 return settings_loaded;
983}
984
985void DeviceSettingsProvider::StoreDeviceSettings() {
986 // Mute all previous callbacks to guarantee the |pending_changes_| queue is
987 // processed serially.
988 store_callback_factory_.InvalidateWeakPtrs();
989
990 device_settings_service_->SignAndStore(
991 scoped_ptr<em::ChromeDeviceSettingsProto>(
992 new em::ChromeDeviceSettingsProto(device_settings_)),
993 base::Bind(&DeviceSettingsProvider::UpdateAndProceedStoring,
994 store_callback_factory_.GetWeakPtr()));
995}
996
997void DeviceSettingsProvider::AttemptMigration() {
998 if (device_settings_service_->HasPrivateOwnerKey()) {
999 PrefValueMap::const_iterator i;
1000 for (i = migration_values_.begin(); i != migration_values_.end(); ++i)
1001 DoSet(i->first, *i->second);
1002 migration_values_.Clear();
1003 }
1004}
1005
1006} // namespace chromeos