• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/user_cros_settings_provider.h"
6 
7 #include <map>
8 #include <set>
9 
10 #include "base/hash_tables.h"
11 #include "base/logging.h"
12 #include "base/memory/singleton.h"
13 #include "base/string_util.h"
14 #include "base/task.h"
15 #include "base/values.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/chromeos/cros/cros_library.h"
18 #include "chrome/browser/chromeos/cros/login_library.h"
19 #include "chrome/browser/chromeos/cros/network_library.h"
20 #include "chrome/browser/chromeos/cros_settings.h"
21 #include "chrome/browser/chromeos/cros_settings_names.h"
22 #include "chrome/browser/chromeos/login/ownership_service.h"
23 #include "chrome/browser/chromeos/login/user_manager.h"
24 #include "chrome/browser/prefs/pref_service.h"
25 #include "chrome/browser/prefs/scoped_user_pref_update.h"
26 #include "content/browser/browser_thread.h"
27 
28 namespace chromeos {
29 
30 namespace {
31 
32 const char kTrueIncantation[] = "true";
33 const char kFalseIncantation[] = "false";
34 const char kTrustedSuffix[] = "/trusted";
35 
36 // For all our boolean settings following is applicable:
37 // true is default permissive value and false is safe prohibitic value.
38 // Exception: kSignedDataRoamingEnabled which has default value of false.
39 const char* kBooleanSettings[] = {
40   kAccountsPrefAllowNewUser,
41   kAccountsPrefAllowGuest,
42   kAccountsPrefShowUserNamesOnSignIn,
43   kSignedDataRoamingEnabled,
44 };
45 
46 const char* kStringSettings[] = {
47   kDeviceOwner
48 };
49 
50 const char* kListSettings[] = {
51   kAccountsPrefUsers
52 };
53 
IsControlledBooleanSetting(const std::string & pref_path)54 bool IsControlledBooleanSetting(const std::string& pref_path) {
55   // TODO(nkostylev): Using std::find for 4 value array generates this warning
56   // in chroot stl_algo.h:231: error: array subscript is above array bounds.
57   // GCC 4.4.3
58   return (pref_path == kAccountsPrefAllowNewUser) ||
59          (pref_path == kAccountsPrefAllowGuest) ||
60          (pref_path == kAccountsPrefShowUserNamesOnSignIn) ||
61          (pref_path == kSignedDataRoamingEnabled);
62 }
63 
IsControlledStringSetting(const std::string & pref_path)64 bool IsControlledStringSetting(const std::string& pref_path) {
65   return std::find(kStringSettings,
66                    kStringSettings + arraysize(kStringSettings),
67                    pref_path) !=
68       kStringSettings + arraysize(kStringSettings);
69 }
70 
IsControlledListSetting(const std::string & pref_path)71 bool IsControlledListSetting(const std::string& pref_path) {
72   return std::find(kListSettings,
73                    kListSettings + arraysize(kListSettings),
74                    pref_path) !=
75       kListSettings + arraysize(kListSettings);
76 }
77 
RegisterSetting(PrefService * local_state,const std::string & pref_path)78 void RegisterSetting(PrefService* local_state, const std::string& pref_path) {
79   local_state->RegisterBooleanPref((pref_path + kTrustedSuffix).c_str(),
80                                    false);
81   if (IsControlledBooleanSetting(pref_path)) {
82     if (pref_path == kSignedDataRoamingEnabled)
83       local_state->RegisterBooleanPref(pref_path.c_str(), false);
84     else
85       local_state->RegisterBooleanPref(pref_path.c_str(), true);
86   } else if (IsControlledStringSetting(pref_path)) {
87     local_state->RegisterStringPref(pref_path.c_str(), "");
88   } else {
89     DCHECK(IsControlledListSetting(pref_path));
90     local_state->RegisterListPref(pref_path.c_str());
91   }
92 }
93 
94 // Create a settings boolean value with "managed" and "disabled" property.
95 // "managed" property is true if the setting is managed by administrator.
96 // "disabled" property is true if the UI for the setting should be disabled.
CreateSettingsBooleanValue(bool value,bool managed,bool disabled)97 Value* CreateSettingsBooleanValue(bool value, bool managed, bool disabled) {
98   DictionaryValue* dict = new DictionaryValue;
99   dict->Set("value", Value::CreateBooleanValue(value));
100   dict->Set("managed", Value::CreateBooleanValue(managed));
101   dict->Set("disabled", Value::CreateBooleanValue(disabled));
102   return dict;
103 }
104 
105 enum UseValue {
106   USE_VALUE_SUPPLIED,
107   USE_VALUE_DEFAULT
108 };
109 
UpdateCacheBool(const std::string & name,bool value,UseValue use_value)110 void UpdateCacheBool(const std::string& name,
111                      bool value,
112                      UseValue use_value) {
113   PrefService* prefs = g_browser_process->local_state();
114   if (use_value == USE_VALUE_DEFAULT)
115     prefs->ClearPref(name.c_str());
116   else
117     prefs->SetBoolean(name.c_str(), value);
118   prefs->ScheduleSavePersistentPrefs();
119 }
120 
UpdateCacheString(const std::string & name,const std::string & value,UseValue use_value)121 void UpdateCacheString(const std::string& name,
122                        const std::string& value,
123                        UseValue use_value) {
124   PrefService* prefs = g_browser_process->local_state();
125   if (use_value == USE_VALUE_DEFAULT)
126     prefs->ClearPref(name.c_str());
127   else
128     prefs->SetString(name.c_str(), value);
129   prefs->ScheduleSavePersistentPrefs();
130 }
131 
GetUserWhitelist(ListValue * user_list)132 bool GetUserWhitelist(ListValue* user_list) {
133   PrefService* prefs = g_browser_process->local_state();
134   DCHECK(!prefs->IsManagedPreference(kAccountsPrefUsers));
135 
136   std::vector<std::string> whitelist;
137   if (!SignedSettings::EnumerateWhitelist(&whitelist)) {
138     LOG(WARNING) << "Failed to retrieve user whitelist.";
139     return false;
140   }
141 
142   ListPrefUpdate cached_whitelist_update(prefs, kAccountsPrefUsers);
143   cached_whitelist_update->Clear();
144 
145   const UserManager::User& self = UserManager::Get()->logged_in_user();
146   bool is_owner = UserManager::Get()->current_user_is_owner();
147 
148   for (size_t i = 0; i < whitelist.size(); ++i) {
149     const std::string& email = whitelist[i];
150 
151     if (user_list) {
152       DictionaryValue* user = new DictionaryValue;
153       user->SetString("email", email);
154       user->SetString("name", "");
155       user->SetBoolean("owner", is_owner && email == self.email());
156       user_list->Append(user);
157     }
158 
159     cached_whitelist_update->Append(Value::CreateStringValue(email));
160   }
161 
162   prefs->ScheduleSavePersistentPrefs();
163   return true;
164 }
165 
166 class UserCrosSettingsTrust : public SignedSettingsHelper::Callback {
167  public:
GetInstance()168   static UserCrosSettingsTrust* GetInstance() {
169     return Singleton<UserCrosSettingsTrust>::get();
170   }
171 
172   // Working horse for UserCrosSettingsProvider::RequestTrusted* family.
RequestTrustedEntity(const std::string & name)173   bool RequestTrustedEntity(const std::string& name) {
174     OwnershipService::Status ownership_status =
175         ownership_service_->GetStatus(false);
176     if (ownership_status == OwnershipService::OWNERSHIP_NONE)
177       return true;
178     PrefService* prefs = g_browser_process->local_state();
179     if (prefs->IsManagedPreference(name.c_str()))
180       return true;
181     if (ownership_status == OwnershipService::OWNERSHIP_TAKEN) {
182       DCHECK(g_browser_process);
183       PrefService* prefs = g_browser_process->local_state();
184       DCHECK(prefs);
185       if (prefs->GetBoolean((name + kTrustedSuffix).c_str()))
186         return true;
187     }
188     return false;
189   }
190 
RequestTrustedEntity(const std::string & name,Task * callback)191   bool RequestTrustedEntity(const std::string& name, Task* callback) {
192     if (RequestTrustedEntity(name)) {
193       delete callback;
194       return true;
195     } else {
196       if (callback)
197         callbacks_[name].push_back(callback);
198       return false;
199     }
200   }
201 
Reload()202   void Reload() {
203     for (size_t i = 0; i < arraysize(kBooleanSettings); ++i)
204       StartFetchingSetting(kBooleanSettings[i]);
205     for (size_t i = 0; i < arraysize(kStringSettings); ++i)
206       StartFetchingSetting(kStringSettings[i]);
207   }
208 
Set(const std::string & path,Value * in_value)209   void Set(const std::string& path, Value* in_value) {
210     PrefService* prefs = g_browser_process->local_state();
211     DCHECK(!prefs->IsManagedPreference(path.c_str()));
212 
213     if (!UserManager::Get()->current_user_is_owner()) {
214       LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
215 
216       // Revert UI change.
217       CrosSettings::Get()->FireObservers(path.c_str());
218       return;
219     }
220 
221     if (IsControlledBooleanSetting(path)) {
222       bool bool_value = false;
223       if (in_value->GetAsBoolean(&bool_value)) {
224         OnBooleanPropertyChange(path, bool_value);
225         std::string value = bool_value ? kTrueIncantation : kFalseIncantation;
226         SignedSettingsHelper::Get()->StartStorePropertyOp(path, value, this);
227         UpdateCacheBool(path, bool_value, USE_VALUE_SUPPLIED);
228 
229         VLOG(1) << "Set cros setting " << path << "=" << value;
230       }
231     } else if (path == kDeviceOwner) {
232       VLOG(1) << "Setting owner is not supported. Please use "
233                  "'UpdateCachedOwner' instead.";
234     } else if (path == kAccountsPrefUsers) {
235       VLOG(1) << "Setting user whitelist is not implemented.  Please use "
236                  "whitelist/unwhitelist instead.";
237     } else {
238       LOG(WARNING) << "Try to set unhandled cros setting " << path;
239     }
240   }
241 
242  private:
243   // upper bound for number of retries to fetch a signed setting.
244   static const int kNumRetriesLimit = 9;
245 
UserCrosSettingsTrust()246   UserCrosSettingsTrust()
247       : ownership_service_(OwnershipService::GetSharedInstance()),
248         retries_left_(kNumRetriesLimit) {
249     // Start prefetching Boolean and String preferences.
250     Reload();
251   }
252 
~UserCrosSettingsTrust()253   ~UserCrosSettingsTrust() {
254     if (BrowserThread::CurrentlyOn(BrowserThread::UI) &&
255         CrosLibrary::Get()->EnsureLoaded()) {
256       // Cancels all pending callbacks from us.
257       SignedSettingsHelper::Get()->CancelCallback(this);
258     }
259   }
260 
261   // Called right before boolean property is changed.
OnBooleanPropertyChange(const std::string & path,bool new_value)262   void OnBooleanPropertyChange(const std::string& path, bool new_value) {
263     if (path == kSignedDataRoamingEnabled) {
264       if (!CrosLibrary::Get()->EnsureLoaded())
265         return;
266 
267       NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
268       cros->SetCellularDataRoamingAllowed(new_value);
269     }
270   }
271 
272   // Called right after signed value was checked.
OnBooleanPropertyRetrieve(const std::string & path,bool value,UseValue use_value)273   void OnBooleanPropertyRetrieve(const std::string& path,
274                                  bool value,
275                                  UseValue use_value) {
276     if (path == kSignedDataRoamingEnabled) {
277       if (!CrosLibrary::Get()->EnsureLoaded())
278         return;
279 
280       NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
281       const NetworkDevice* cellular = cros->FindCellularDevice();
282       if (cellular) {
283         bool device_value = cellular->data_roaming_allowed();
284         bool new_value = (use_value == USE_VALUE_SUPPLIED) ? value : false;
285         if (device_value != new_value)
286           cros->SetCellularDataRoamingAllowed(new_value);
287       }
288     }
289   }
290 
StartFetchingSetting(const std::string & name)291   void StartFetchingSetting(const std::string& name) {
292     DCHECK(g_browser_process);
293     PrefService* prefs = g_browser_process->local_state();
294     if (!prefs)
295       return;
296     // Do not trust before fetching complete.
297     prefs->ClearPref((name + kTrustedSuffix).c_str());
298     prefs->ScheduleSavePersistentPrefs();
299     if (CrosLibrary::Get()->EnsureLoaded()) {
300       SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
301     }
302   }
303 
304   // Implementation of SignedSettingsHelper::Callback.
OnRetrievePropertyCompleted(SignedSettings::ReturnCode code,const std::string & name,const std::string & value)305   virtual void OnRetrievePropertyCompleted(SignedSettings::ReturnCode code,
306                                            const std::string& name,
307                                            const std::string& value) {
308     if (!IsControlledBooleanSetting(name) && !IsControlledStringSetting(name)) {
309       NOTREACHED();
310       return;
311     }
312 
313     bool is_owned = ownership_service_->GetStatus(true) ==
314         OwnershipService::OWNERSHIP_TAKEN;
315     PrefService* prefs = g_browser_process->local_state();
316     switch (code) {
317       case SignedSettings::SUCCESS:
318       case SignedSettings::NOT_FOUND:
319       case SignedSettings::KEY_UNAVAILABLE: {
320         bool fallback_to_default = !is_owned
321             || (code == SignedSettings::NOT_FOUND);
322         DCHECK(fallback_to_default || code == SignedSettings::SUCCESS);
323         if (fallback_to_default)
324           VLOG(1) << "Going default for cros setting " << name;
325         else
326           VLOG(1) << "Retrieved cros setting " << name << "=" << value;
327         if (IsControlledBooleanSetting(name)) {
328           OnBooleanPropertyRetrieve(name, (value == kTrueIncantation),
329               fallback_to_default ? USE_VALUE_DEFAULT : USE_VALUE_SUPPLIED);
330           UpdateCacheBool(name, (value == kTrueIncantation),
331               fallback_to_default ? USE_VALUE_DEFAULT : USE_VALUE_SUPPLIED);
332         } else if (IsControlledStringSetting(name)) {
333           UpdateCacheString(name, value,
334               fallback_to_default ? USE_VALUE_DEFAULT : USE_VALUE_SUPPLIED);
335         }
336         break;
337       }
338       case SignedSettings::OPERATION_FAILED:
339       default: {
340         DCHECK(code == SignedSettings::OPERATION_FAILED);
341         DCHECK(is_owned);
342         LOG(ERROR) << "On owned device: failed to retrieve cros "
343                       "setting, name=" << name;
344         if (retries_left_ > 0) {
345           retries_left_ -= 1;
346           StartFetchingSetting(name);
347           return;
348         }
349         LOG(ERROR) << "No retries left";
350         if (IsControlledBooleanSetting(name)) {
351           // For boolean settings we can just set safe (false) values
352           // and continue as trusted.
353           OnBooleanPropertyRetrieve(name, false, USE_VALUE_SUPPLIED);
354           UpdateCacheBool(name, false, USE_VALUE_SUPPLIED);
355         } else {
356           prefs->ClearPref((name + kTrustedSuffix).c_str());
357           return;
358         }
359         break;
360       }
361     }
362     prefs->SetBoolean((name + kTrustedSuffix).c_str(), true);
363     {
364       std::vector<Task*>& callbacks_vector = callbacks_[name];
365       for (size_t i = 0; i < callbacks_vector.size(); ++i)
366         MessageLoop::current()->PostTask(FROM_HERE, callbacks_vector[i]);
367       callbacks_vector.clear();
368     }
369     if (code == SignedSettings::SUCCESS)
370       CrosSettings::Get()->FireObservers(name.c_str());
371   }
372 
373   // Implementation of SignedSettingsHelper::Callback.
OnStorePropertyCompleted(SignedSettings::ReturnCode code,const std::string & name,const std::string & value)374   virtual void OnStorePropertyCompleted(SignedSettings::ReturnCode code,
375                                         const std::string& name,
376                                         const std::string& value) {
377     VLOG(1) << "Store cros setting " << name << "=" << value << ", code="
378             << code;
379 
380     // Reload the setting if store op fails.
381     if (code != SignedSettings::SUCCESS)
382       SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
383   }
384 
385   // Implementation of SignedSettingsHelper::Callback.
OnWhitelistCompleted(SignedSettings::ReturnCode code,const std::string & email)386   virtual void OnWhitelistCompleted(SignedSettings::ReturnCode code,
387                                     const std::string& email) {
388     VLOG(1) << "Add " << email << " to whitelist, code=" << code;
389 
390     // Reload the whitelist on settings op failure.
391     if (code != SignedSettings::SUCCESS)
392       CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
393   }
394 
395   // Implementation of SignedSettingsHelper::Callback.
OnUnwhitelistCompleted(SignedSettings::ReturnCode code,const std::string & email)396   virtual void OnUnwhitelistCompleted(SignedSettings::ReturnCode code,
397                                       const std::string& email) {
398     VLOG(1) << "Remove " << email << " from whitelist, code=" << code;
399 
400     // Reload the whitelist on settings op failure.
401     if (code != SignedSettings::SUCCESS)
402       CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
403   }
404 
405   // Pending callbacks that need to be invoked after settings verification.
406   base::hash_map< std::string, std::vector< Task* > > callbacks_;
407 
408   OwnershipService* ownership_service_;
409 
410   // In order to guard against occasional failure to fetch a property
411   // we allow for some number of retries.
412   int retries_left_;
413 
414   friend class SignedSettingsHelper;
415   friend struct DefaultSingletonTraits<UserCrosSettingsTrust>;
416 
417   DISALLOW_COPY_AND_ASSIGN(UserCrosSettingsTrust);
418 };
419 
420 }  // namespace
421 
422 }  // namespace chromeos
423 
424 // We want to use NewRunnableMethod with this class but need to disable
425 // reference counting since it is singleton.
426 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::UserCrosSettingsTrust);
427 
428 namespace chromeos {
429 
UserCrosSettingsProvider()430 UserCrosSettingsProvider::UserCrosSettingsProvider() {
431   // Trigger prefetching of settings.
432   UserCrosSettingsTrust::GetInstance();
433 }
434 
435 // static
RegisterPrefs(PrefService * local_state)436 void UserCrosSettingsProvider::RegisterPrefs(PrefService* local_state) {
437   for (size_t i = 0; i < arraysize(kBooleanSettings); ++i)
438     RegisterSetting(local_state, kBooleanSettings[i]);
439   for (size_t i = 0; i < arraysize(kStringSettings); ++i)
440     RegisterSetting(local_state, kStringSettings[i]);
441   for (size_t i = 0; i < arraysize(kListSettings); ++i)
442     RegisterSetting(local_state, kListSettings[i]);
443 }
444 
RequestTrustedAllowGuest(Task * callback)445 bool UserCrosSettingsProvider::RequestTrustedAllowGuest(Task* callback) {
446   return UserCrosSettingsTrust::GetInstance()->RequestTrustedEntity(
447       kAccountsPrefAllowGuest, callback);
448 }
449 
RequestTrustedAllowNewUser(Task * callback)450 bool UserCrosSettingsProvider::RequestTrustedAllowNewUser(Task* callback) {
451   return UserCrosSettingsTrust::GetInstance()->RequestTrustedEntity(
452       kAccountsPrefAllowNewUser, callback);
453 }
454 
RequestTrustedShowUsersOnSignin(Task * callback)455 bool UserCrosSettingsProvider::RequestTrustedShowUsersOnSignin(Task* callback) {
456   return UserCrosSettingsTrust::GetInstance()->RequestTrustedEntity(
457       kAccountsPrefShowUserNamesOnSignIn, callback);
458 }
459 
RequestTrustedDataRoamingEnabled(Task * callback)460 bool UserCrosSettingsProvider::RequestTrustedDataRoamingEnabled(
461     Task* callback) {
462   return UserCrosSettingsTrust::GetInstance()->RequestTrustedEntity(
463       kSignedDataRoamingEnabled, callback);
464 }
465 
RequestTrustedOwner(Task * callback)466 bool UserCrosSettingsProvider::RequestTrustedOwner(Task* callback) {
467   return UserCrosSettingsTrust::GetInstance()->RequestTrustedEntity(
468       kDeviceOwner, callback);
469 }
470 
Reload()471 void UserCrosSettingsProvider::Reload() {
472   UserCrosSettingsTrust::GetInstance()->Reload();
473 }
474 
475 // static
cached_allow_guest()476 bool UserCrosSettingsProvider::cached_allow_guest() {
477   // Trigger prefetching if singleton object still does not exist.
478   UserCrosSettingsTrust::GetInstance();
479   return g_browser_process->local_state()->GetBoolean(kAccountsPrefAllowGuest);
480 }
481 
482 // static
cached_allow_new_user()483 bool UserCrosSettingsProvider::cached_allow_new_user() {
484   // Trigger prefetching if singleton object still does not exist.
485   UserCrosSettingsTrust::GetInstance();
486   return g_browser_process->local_state()->GetBoolean(
487       kAccountsPrefAllowNewUser);
488 }
489 
490 // static
cached_data_roaming_enabled()491 bool UserCrosSettingsProvider::cached_data_roaming_enabled() {
492   // Trigger prefetching if singleton object still does not exist.
493   UserCrosSettingsTrust::GetInstance();
494   return g_browser_process->local_state()->GetBoolean(
495       kSignedDataRoamingEnabled);
496 }
497 
498 // static
cached_show_users_on_signin()499 bool UserCrosSettingsProvider::cached_show_users_on_signin() {
500   // Trigger prefetching if singleton object still does not exist.
501   UserCrosSettingsTrust::GetInstance();
502   return g_browser_process->local_state()->GetBoolean(
503       kAccountsPrefShowUserNamesOnSignIn);
504 }
505 
506 // static
cached_whitelist()507 const ListValue* UserCrosSettingsProvider::cached_whitelist() {
508   PrefService* prefs = g_browser_process->local_state();
509   const ListValue* cached_users = prefs->GetList(kAccountsPrefUsers);
510   if (!prefs->IsManagedPreference(kAccountsPrefUsers)) {
511     if (cached_users == NULL) {
512       // Update whitelist cache.
513       GetUserWhitelist(NULL);
514       cached_users = prefs->GetList(kAccountsPrefUsers);
515     }
516   }
517   if (cached_users == NULL) {
518     NOTREACHED();
519     cached_users = new ListValue;
520   }
521   return cached_users;
522 }
523 
524 // static
cached_owner()525 std::string UserCrosSettingsProvider::cached_owner() {
526   // Trigger prefetching if singleton object still does not exist.
527   UserCrosSettingsTrust::GetInstance();
528   if (!g_browser_process || !g_browser_process->local_state())
529     return std::string();
530   return g_browser_process->local_state()->GetString(kDeviceOwner);
531 }
532 
533 // static
IsEmailInCachedWhitelist(const std::string & email)534 bool UserCrosSettingsProvider::IsEmailInCachedWhitelist(
535     const std::string& email) {
536   const ListValue* whitelist = cached_whitelist();
537   if (whitelist) {
538     StringValue email_value(email);
539     for (ListValue::const_iterator i(whitelist->begin());
540         i != whitelist->end(); ++i) {
541       if ((*i)->Equals(&email_value))
542         return true;
543     }
544   }
545   return false;
546 }
547 
DoSet(const std::string & path,Value * in_value)548 void UserCrosSettingsProvider::DoSet(const std::string& path,
549                                      Value* in_value) {
550   UserCrosSettingsTrust::GetInstance()->Set(path, in_value);
551 }
552 
Get(const std::string & path,Value ** out_value) const553 bool UserCrosSettingsProvider::Get(const std::string& path,
554                                    Value** out_value) const {
555   if (IsControlledBooleanSetting(path)) {
556     PrefService* prefs = g_browser_process->local_state();
557     *out_value = CreateSettingsBooleanValue(
558         prefs->GetBoolean(path.c_str()),
559         prefs->IsManagedPreference(path.c_str()),
560         !UserManager::Get()->current_user_is_owner());
561     return true;
562   } else if (path == kAccountsPrefUsers) {
563     ListValue* user_list = new ListValue;
564     GetUserWhitelist(user_list);
565     *out_value = user_list;
566     return true;
567   }
568 
569   return false;
570 }
571 
HandlesSetting(const std::string & path)572 bool UserCrosSettingsProvider::HandlesSetting(const std::string& path) {
573   return ::StartsWithASCII(path, "cros.accounts.", true) ||
574       ::StartsWithASCII(path, "cros.signed.", true);
575 }
576 
WhitelistUser(const std::string & email)577 void UserCrosSettingsProvider::WhitelistUser(const std::string& email) {
578   SignedSettingsHelper::Get()->StartWhitelistOp(
579       email, true, UserCrosSettingsTrust::GetInstance());
580   PrefService* prefs = g_browser_process->local_state();
581   ListPrefUpdate cached_whitelist_update(prefs, kAccountsPrefUsers);
582   cached_whitelist_update->Append(Value::CreateStringValue(email));
583   prefs->ScheduleSavePersistentPrefs();
584 }
585 
UnwhitelistUser(const std::string & email)586 void UserCrosSettingsProvider::UnwhitelistUser(const std::string& email) {
587   SignedSettingsHelper::Get()->StartWhitelistOp(
588       email, false, UserCrosSettingsTrust::GetInstance());
589 
590   PrefService* prefs = g_browser_process->local_state();
591   ListPrefUpdate cached_whitelist_update(prefs, kAccountsPrefUsers);
592   StringValue email_value(email);
593   if (cached_whitelist_update->Remove(email_value) != -1)
594     prefs->ScheduleSavePersistentPrefs();
595 }
596 
597 // static
UpdateCachedOwner(const std::string & email)598 void UserCrosSettingsProvider::UpdateCachedOwner(const std::string& email) {
599   UpdateCacheString(kDeviceOwner, email, USE_VALUE_SUPPLIED);
600 }
601 
602 }  // namespace chromeos
603