user_cros_settings_provider.cc revision 21d179b334e59e9a3bfcaed4c4430bef1bc5759d
1bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file.
4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
54a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/chromeos/user_cros_settings_provider.h"
6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <map>
821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <set>
921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/hash_tables.h"
11bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/logging.h"
1221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/singleton.h"
13bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/string_util.h"
1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/task.h"
15bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/values.h"
16bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/browser_process.h"
1721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/browser_thread.h"
18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/chromeos/cros/cros_library.h"
19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/chromeos/cros/login_library.h"
20bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/chromeos/cros_settings.h"
21bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/chromeos/cros_settings_names.h"
2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/chromeos/login/ownership_service.h"
23bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/chromeos/login/user_manager.h"
24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/prefs/pref_service.h"
2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/common/notification_observer.h"
2621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/common/notification_registrar.h"
2721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/common/notification_service.h"
2821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/common/notification_type.h"
29bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
30731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace chromeos {
31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace {
33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
3421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst char kTrueIncantation[] = "true";
3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst char kFalseIncantation[] = "false";
3621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst char kTrustedSuffix[] = "/trusted";
3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// For all our boolean settings following is applicable:
3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// true is default permissive value and false is safe prohibitic value.
4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst char* kBooleanSettings[] = {
4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  kAccountsPrefAllowNewUser,
4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  kAccountsPrefAllowGuest,
4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  kAccountsPrefShowUserNamesOnSignIn
4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen};
4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
4621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst char* kStringSettings[] = {
4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  kDeviceOwner
4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen};
4921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst char* kListSettings[] = {
5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  kAccountsPrefUsers
5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen};
5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool IsControlledBooleanSetting(const std::string& pref_path) {
5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return std::find(kBooleanSettings,
5621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                   kBooleanSettings + arraysize(kBooleanSettings),
5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                   pref_path) !=
5821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      kBooleanSettings + arraysize(kBooleanSettings);
5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
6021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool IsControlledStringSetting(const std::string& pref_path) {
6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return std::find(kStringSettings,
6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                   kStringSettings + arraysize(kStringSettings),
6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                   pref_path) !=
6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      kStringSettings + arraysize(kStringSettings);
6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool IsControlledListSetting(const std::string& pref_path) {
6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return std::find(kListSettings,
7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                   kListSettings + arraysize(kListSettings),
7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                   pref_path) !=
7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      kListSettings + arraysize(kListSettings);
7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid RegisterSetting(PrefService* local_state, const std::string& pref_path) {
7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  local_state->RegisterBooleanPref((pref_path + kTrustedSuffix).c_str(),
7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                   false);
7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (IsControlledBooleanSetting(pref_path)) {
7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    local_state->RegisterBooleanPref(pref_path.c_str(), true);
8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else if (IsControlledStringSetting(pref_path)) {
8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    local_state->RegisterStringPref(pref_path.c_str(), "");
8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DCHECK(IsControlledListSetting(pref_path));
8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    local_state->RegisterListPref(pref_path.c_str());
8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
88bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenValue* CreateSettingsBooleanValue(bool value, bool managed) {
89bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DictionaryValue* dict = new DictionaryValue;
90bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  dict->Set("value", Value::CreateBooleanValue(value));
91bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  dict->Set("managed", Value::CreateBooleanValue(managed));
92bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return dict;
93bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
94bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenenum UseValue {
9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  USE_VALUE_SUPPLIED,
9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  USE_VALUE_DEFAULT
9821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen};
9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid UpdateCacheBool(const std::string& name,
10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                     bool value,
10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                     UseValue use_value) {
103bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  PrefService* prefs = g_browser_process->local_state();
10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (use_value == USE_VALUE_DEFAULT)
10521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    prefs->ClearPref(name.c_str());
10621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  else
10721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    prefs->SetBoolean(name.c_str(), value);
108bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  prefs->ScheduleSavePersistentPrefs();
109bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
110bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
11121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid UpdateCacheString(const std::string& name,
11221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                       const std::string& value,
11321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                       UseValue use_value) {
114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  PrefService* prefs = g_browser_process->local_state();
11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (use_value == USE_VALUE_DEFAULT)
11621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    prefs->ClearPref(name.c_str());
11721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  else
11821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    prefs->SetString(name.c_str(), value);
119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  prefs->ScheduleSavePersistentPrefs();
120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool GetUserWhitelist(ListValue* user_list) {
123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::vector<std::string> whitelist;
124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!CrosLibrary::Get()->EnsureLoaded() ||
125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      !CrosLibrary::Get()->GetLoginLibrary()->EnumerateWhitelisted(
126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          &whitelist)) {
127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    LOG(WARNING) << "Failed to retrieve user whitelist.";
128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return false;
129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
130bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
131731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  PrefService* prefs = g_browser_process->local_state();
132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ListValue* cached_whitelist = prefs->GetMutableList(kAccountsPrefUsers);
133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  cached_whitelist->Clear();
134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const UserManager::User& self = UserManager::Get()->logged_in_user();
136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  bool is_owner = UserManager::Get()->current_user_is_owner();
137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  for (size_t i = 0; i < whitelist.size(); ++i) {
139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const std::string& email = whitelist[i];
140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (user_list) {
142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      DictionaryValue* user = new DictionaryValue;
143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      user->SetString("email", email);
144731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      user->SetString("name", "");
145731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      user->SetBoolean("owner", is_owner && email == self.email());
146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      user_list->Append(user);
147731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
148bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    cached_whitelist->Append(Value::CreateStringValue(email));
150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  prefs->ScheduleSavePersistentPrefs();
153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return true;
155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
15721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenclass UserCrosSettingsTrust : public SignedSettingsHelper::Callback,
15821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                              public NotificationObserver {
15921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen public:
16021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  static UserCrosSettingsTrust* GetInstance() {
16121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return Singleton<UserCrosSettingsTrust>::get();
16221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
16321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
16421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Working horse for UserCrosSettingsProvider::RequestTrusted* family.
16521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  bool RequestTrustedEntity(const std::string& name, Task* callback) {
16621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (GetOwnershipStatus() == OWNERSHIP_NONE)
16721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return true;
16821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (GetOwnershipStatus() == OWNERSHIP_TAKEN) {
16921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      DCHECK(g_browser_process);
17021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      PrefService* prefs = g_browser_process->local_state();
17121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      DCHECK(prefs);
17221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      if (prefs->GetBoolean((name + kTrustedSuffix).c_str()))
17321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        return true;
17421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
17521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (callback)
17621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      callbacks_[name].push_back(callback);
17721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return false;
17821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
17921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
18021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void Set(const std::string& path, Value* in_value) {
18121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (!UserManager::Get()->current_user_is_owner()) {
18221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
18321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
18421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Revert UI change.
18521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      CrosSettings::Get()->FireObservers(path.c_str());
18621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
18721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
18821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (IsControlledBooleanSetting(path)) {
19021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      bool bool_value = false;
19121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      if (in_value->GetAsBoolean(&bool_value)) {
19221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        std::string value = bool_value ? kTrueIncantation : kFalseIncantation;
19321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        SignedSettingsHelper::Get()->StartStorePropertyOp(path, value, this);
19421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        UpdateCacheBool(path, bool_value, USE_VALUE_SUPPLIED);
19521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
19621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        VLOG(1) << "Set cros setting " << path << "=" << value;
19721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      }
19821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    } else if (path == kDeviceOwner) {
19921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      VLOG(1) << "Setting owner is not supported. Please use "
20021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                 "'UpdateCachedOwner' instead.";
20121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    } else if (path == kAccountsPrefUsers) {
20221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      VLOG(1) << "Setting user whitelist is not implemented.  Please use "
20321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                 "whitelist/unwhitelist instead.";
20421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    } else {
20521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      LOG(WARNING) << "Try to set unhandled cros setting " << path;
20621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
20721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
20821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
20921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen private:
21021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Listed in upgrade order.
21121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  enum OwnershipStatus {
21221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    OWNERSHIP_UNKNOWN = 0,
21321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    OWNERSHIP_NONE,
21421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    OWNERSHIP_TAKEN
21521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  };
21621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
21721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Used to discriminate different sources of ownership status info.
21821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  enum OwnershipSource {
21921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    SOURCE_FETCH,  // Info comes from FetchOwnershipStatus method.
22021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    SOURCE_OBSERVE // Info comes from Observe method.
22121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  };
22221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
22321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // upper bound for number of retries to fetch a signed setting.
22421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  static const int kNumRetriesLimit = 9;
22521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
22621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UserCrosSettingsTrust() : ownership_status_(OWNERSHIP_UNKNOWN),
22721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                            retries_left_(kNumRetriesLimit) {
22821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    notification_registrar_.Add(this,
22921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                NotificationType::OWNERSHIP_TAKEN,
23021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                NotificationService::AllSources());
23121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Start getting ownership status.
23221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    BrowserThread::PostTask(
23321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        BrowserThread::FILE,
23421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        FROM_HERE,
23521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NewRunnableMethod(this, &UserCrosSettingsTrust::FetchOwnershipStatus));
23621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
23721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
23821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ~UserCrosSettingsTrust() {
23921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (BrowserThread::CurrentlyOn(BrowserThread::UI) &&
24021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        CrosLibrary::Get()->EnsureLoaded()) {
24121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Cancels all pending callbacks from us.
24221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      SignedSettingsHelper::Get()->CancelCallback(this);
24321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
24421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
24521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
24621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void FetchOwnershipStatus() {
24721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
24821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    OwnershipStatus status =
24921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        OwnershipService::GetSharedInstance()->IsAlreadyOwned() ?
25021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        OWNERSHIP_TAKEN : OWNERSHIP_NONE;
25121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
25221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NewRunnableMethod(this, &UserCrosSettingsTrust::SetOwnershipStatus,
25321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen            status, SOURCE_FETCH));
25421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
25521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
25621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void SetOwnershipStatus(OwnershipStatus new_status,
25721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          OwnershipSource source) {
25821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
25921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DCHECK(new_status == OWNERSHIP_TAKEN || new_status == OWNERSHIP_NONE);
26021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (source == SOURCE_FETCH) {
26121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      DCHECK(ownership_status_ != OWNERSHIP_NONE);
26221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      if (ownership_status_ == OWNERSHIP_TAKEN) {
26321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        // OWNERSHIP_TAKEN notification was observed earlier.
26421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        return;
26521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      }
26621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
26721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ownership_status_ = new_status;
26821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (source == SOURCE_FETCH) {
26921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Start prefetching Boolean and String preferences.
27021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      for (size_t i = 0; i < arraysize(kBooleanSettings); ++i)
27121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        StartFetchingSetting(kBooleanSettings[i]);
27221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      for (size_t i = 0; i < arraysize(kStringSettings); ++i)
27321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        StartFetchingSetting(kStringSettings[i]);
27421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
27521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
27621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
27721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Returns ownership status.
27821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Called on UI thread unlike OwnershipService::IsAlreadyOwned.
27921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  OwnershipStatus GetOwnershipStatus() {
28021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return ownership_status_;
28121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
28221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
28321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void StartFetchingSetting(const std::string& name) {
28421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DCHECK(g_browser_process);
28521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    PrefService* prefs = g_browser_process->local_state();
28621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (!prefs)
28721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
28821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Do not trust before fetching complete.
28921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    prefs->ClearPref((name + kTrustedSuffix).c_str());
29021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    prefs->ScheduleSavePersistentPrefs();
29121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (CrosLibrary::Get()->EnsureLoaded()) {
29221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
29321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
29421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
29521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
29621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Implementation of SignedSettingsHelper::Callback.
29721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual void OnRetrievePropertyCompleted(SignedSettings::ReturnCode code,
29821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                           const std::string& name,
29921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                           const std::string& value) {
30021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (!IsControlledBooleanSetting(name) && !IsControlledStringSetting(name)) {
30121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      NOTREACHED();
30221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
30321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
30421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DCHECK(GetOwnershipStatus() != OWNERSHIP_UNKNOWN);
30521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
30621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    PrefService* prefs = g_browser_process->local_state();
30721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    switch (code) {
30821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      case SignedSettings::SUCCESS:
30921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      case SignedSettings::NOT_FOUND:
31021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      case SignedSettings::KEY_UNAVAILABLE: {
31121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        bool fallback_to_default = (code == SignedSettings::NOT_FOUND) ||
31221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen            (GetOwnershipStatus() == OWNERSHIP_NONE);
31321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        DCHECK(fallback_to_default || code == SignedSettings::SUCCESS);
31421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        if (fallback_to_default)
31521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          VLOG(1) << "Going default for cros setting " << name;
31621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        else
31721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          VLOG(1) << "Retrieved cros setting " << name << "=" << value;
31821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        if (IsControlledBooleanSetting(name)) {
31921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          // We assume our boolean settings are true before explicitly set.
32021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          UpdateCacheBool(name, (value == kTrueIncantation),
32121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen              fallback_to_default ? USE_VALUE_DEFAULT : USE_VALUE_SUPPLIED);
32221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        } else if (IsControlledStringSetting(name)) {
32321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          UpdateCacheString(name, value,
32421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen              fallback_to_default ? USE_VALUE_DEFAULT : USE_VALUE_SUPPLIED);
32521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        }
32621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        break;
32721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      }
32821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      case SignedSettings::OPERATION_FAILED:
32921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      default: {
33021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        DCHECK(code == SignedSettings::OPERATION_FAILED);
33121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        DCHECK(GetOwnershipStatus() == OWNERSHIP_TAKEN);
33221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        LOG(ERROR) << "On owned device: failed to retrieve cros "
33321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                      "setting, name=" << name;
33421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        if (retries_left_ > 0) {
33521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          retries_left_ -= 1;
33621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          StartFetchingSetting(name);
33721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          return;
33821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        }
33921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        LOG(ERROR) << "No retries left";
34021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        if (IsControlledBooleanSetting(name)) {
34121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          // For boolean settings we can just set safe (false) values
34221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          // and continue as trusted.
34321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          UpdateCacheBool(name, false, USE_VALUE_SUPPLIED);
34421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        } else {
34521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          prefs->ClearPref((name + kTrustedSuffix).c_str());
34621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          return;
34721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        }
34821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        break;
34921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      }
35021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
35121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    prefs->SetBoolean((name + kTrustedSuffix).c_str(), true);
35221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    {
35321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      DCHECK(GetOwnershipStatus() != OWNERSHIP_UNKNOWN);
35421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      std::vector<Task*>& callbacks_vector = callbacks_[name];
35521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      for (size_t i = 0; i < callbacks_vector.size(); ++i)
35621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        MessageLoop::current()->PostTask(FROM_HERE, callbacks_vector[i]);
35721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      callbacks_vector.clear();
35821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
35921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (code == SignedSettings::SUCCESS)
36021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      CrosSettings::Get()->FireObservers(name.c_str());
36121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
36221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
36321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Implementation of SignedSettingsHelper::Callback.
36421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual void OnStorePropertyCompleted(SignedSettings::ReturnCode code,
36521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                        const std::string& name,
36621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                        const std::string& value) {
36721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    VLOG(1) << "Store cros setting " << name << "=" << value << ", code="
36821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen            << code;
36921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
37021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Reload the setting if store op fails.
37121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (code != SignedSettings::SUCCESS)
37221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
37321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
37421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
37521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Implementation of SignedSettingsHelper::Callback.
37621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual void OnWhitelistCompleted(SignedSettings::ReturnCode code,
37721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                    const std::string& email) {
37821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    VLOG(1) << "Add " << email << " to whitelist, code=" << code;
37921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
38021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Reload the whitelist on settings op failure.
38121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (code != SignedSettings::SUCCESS)
38221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
38321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
38421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
38521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Implementation of SignedSettingsHelper::Callback.
38621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual void OnUnwhitelistCompleted(SignedSettings::ReturnCode code,
38721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                      const std::string& email) {
38821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    VLOG(1) << "Remove " << email << " from whitelist, code=" << code;
38921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
39021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Reload the whitelist on settings op failure.
39121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (code != SignedSettings::SUCCESS)
39221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
39321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
39421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
39521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // NotificationObserver implementation.
39621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual void Observe(NotificationType type,
39721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                       const NotificationSource& source,
39821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                       const NotificationDetails& details) {
39921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (type.value == NotificationType::OWNERSHIP_TAKEN) {
40021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      SetOwnershipStatus(OWNERSHIP_TAKEN, SOURCE_OBSERVE);
40121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      notification_registrar_.RemoveAll();
40221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    } else {
40321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      NOTREACHED();
40421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
40521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
40621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
40721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Pending callbacks that need to be invoked after settings verification.
40821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  base::hash_map< std::string, std::vector< Task* > > callbacks_;
40921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
41021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  NotificationRegistrar notification_registrar_;
41121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  OwnershipStatus ownership_status_;
41221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
41321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // In order to guard against occasional failure to fetch a property
41421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // we allow for some number of retries.
41521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  int retries_left_;
41621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
41721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  friend class SignedSettingsHelper;
41821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  friend struct DefaultSingletonTraits<UserCrosSettingsTrust>;
41921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
42021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DISALLOW_COPY_AND_ASSIGN(UserCrosSettingsTrust);
42121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen};
42221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
423731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}  // namespace
424731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
42521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}  // namespace chromeos
426bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
42721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// We want to use NewRunnableMethod with this class but need to disable
42821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// reference counting since it is singleton.
42921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenDISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::UserCrosSettingsTrust);
43021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
43121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennamespace chromeos {
43221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
43321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenUserCrosSettingsProvider::UserCrosSettingsProvider() {
43421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Trigger prefetching of settings.
43521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UserCrosSettingsTrust::GetInstance();
436bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
437bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
438513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static
439bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid UserCrosSettingsProvider::RegisterPrefs(PrefService* local_state) {
44021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  for (size_t i = 0; i < arraysize(kBooleanSettings); ++i)
44121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    RegisterSetting(local_state, kBooleanSettings[i]);
44221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  for (size_t i = 0; i < arraysize(kStringSettings); ++i)
44321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    RegisterSetting(local_state, kStringSettings[i]);
44421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  for (size_t i = 0; i < arraysize(kListSettings); ++i)
44521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    RegisterSetting(local_state, kListSettings[i]);
44621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
44721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
44821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool UserCrosSettingsProvider::RequestTrustedAllowGuest(Task* callback) {
44921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return UserCrosSettingsTrust::GetInstance()->RequestTrustedEntity(
45021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      kAccountsPrefAllowGuest, callback);
45121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
45221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
45321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool UserCrosSettingsProvider::RequestTrustedAllowNewUser(Task* callback) {
45421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return UserCrosSettingsTrust::GetInstance()->RequestTrustedEntity(
45521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      kAccountsPrefAllowNewUser, callback);
45621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
45721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
45821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool UserCrosSettingsProvider::RequestTrustedShowUsersOnSignin(Task* callback) {
45921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return UserCrosSettingsTrust::GetInstance()->RequestTrustedEntity(
46021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      kAccountsPrefShowUserNamesOnSignIn, callback);
46121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
46221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
46321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool UserCrosSettingsProvider::RequestTrustedOwner(Task* callback) {
46421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return UserCrosSettingsTrust::GetInstance()->RequestTrustedEntity(
46521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      kDeviceOwner, callback);
466bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
467bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
468513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static
469bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool UserCrosSettingsProvider::cached_allow_guest() {
47021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Trigger prefetching if singleton object still does not exist.
47121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UserCrosSettingsTrust::GetInstance();
472bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return g_browser_process->local_state()->GetBoolean(kAccountsPrefAllowGuest);
473bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
474bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
475513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static
476731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool UserCrosSettingsProvider::cached_allow_new_user() {
47721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Trigger prefetching if singleton object still does not exist.
47821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UserCrosSettingsTrust::GetInstance();
479731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return g_browser_process->local_state()->GetBoolean(
480731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    kAccountsPrefAllowNewUser);
481731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
482731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
483513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static
484bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool UserCrosSettingsProvider::cached_show_users_on_signin() {
48521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Trigger prefetching if singleton object still does not exist.
48621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UserCrosSettingsTrust::GetInstance();
487bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return g_browser_process->local_state()->GetBoolean(
488bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      kAccountsPrefShowUserNamesOnSignIn);
489bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
490bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
491513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static
492bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst ListValue* UserCrosSettingsProvider::cached_whitelist() {
493731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  PrefService* prefs = g_browser_process->local_state();
494731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const ListValue* cached_users = prefs->GetList(kAccountsPrefUsers);
495731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
496731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!cached_users) {
497731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // Update whitelist cache.
498731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    GetUserWhitelist(NULL);
499731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
500731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    cached_users = prefs->GetList(kAccountsPrefUsers);
501731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
502731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
503731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return cached_users;
504731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
505731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
506513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static
507731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstd::string UserCrosSettingsProvider::cached_owner() {
50821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Trigger prefetching if singleton object still does not exist.
50921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UserCrosSettingsTrust::GetInstance();
5104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (!g_browser_process || !g_browser_process->local_state())
5114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return std::string();
512731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return g_browser_process->local_state()->GetString(kDeviceOwner);
513bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
514bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
515513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static
516513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool UserCrosSettingsProvider::IsEmailInCachedWhitelist(
517513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const std::string& email) {
518513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const ListValue* whitelist = cached_whitelist();
519513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (whitelist) {
520513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    StringValue email_value(email);
521513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    for (ListValue::const_iterator i(whitelist->begin());
522513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        i != whitelist->end(); ++i) {
523513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      if ((*i)->Equals(&email_value))
524513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        return true;
525513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    }
526513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
527513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return false;
528513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
529513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
530513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid UserCrosSettingsProvider::DoSet(const std::string& path,
531513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                     Value* in_value) {
53221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UserCrosSettingsTrust::GetInstance()->Set(path, in_value);
533bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
534bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
535bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool UserCrosSettingsProvider::Get(const std::string& path,
536bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                   Value** out_value) const {
53721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (IsControlledBooleanSetting(path)) {
538bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    *out_value = CreateSettingsBooleanValue(
539bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        g_browser_process->local_state()->GetBoolean(path.c_str()),
540731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        !UserManager::Get()->current_user_is_owner());
541bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return true;
542bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  } else if (path == kAccountsPrefUsers) {
543731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    ListValue* user_list = new ListValue;
544731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    GetUserWhitelist(user_list);
545731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    *out_value = user_list;
546bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return true;
547bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
548bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
549bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return false;
550bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
551bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
552bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool UserCrosSettingsProvider::HandlesSetting(const std::string& path) {
553bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return ::StartsWithASCII(path, "cros.accounts.", true);
554bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
555bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
556bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid UserCrosSettingsProvider::WhitelistUser(const std::string& email) {
55721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  SignedSettingsHelper::Get()->StartWhitelistOp(
55821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      email, true, UserCrosSettingsTrust::GetInstance());
559bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  PrefService* prefs = g_browser_process->local_state();
560bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  ListValue* cached_whitelist = prefs->GetMutableList(kAccountsPrefUsers);
561bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  cached_whitelist->Append(Value::CreateStringValue(email));
562bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  prefs->ScheduleSavePersistentPrefs();
563bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
564bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
565bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid UserCrosSettingsProvider::UnwhitelistUser(const std::string& email) {
56621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  SignedSettingsHelper::Get()->StartWhitelistOp(
56721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      email, false, UserCrosSettingsTrust::GetInstance());
568bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
569bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  PrefService* prefs = g_browser_process->local_state();
570bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  ListValue* cached_whitelist = prefs->GetMutableList(kAccountsPrefUsers);
571bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  StringValue email_value(email);
572bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (cached_whitelist->Remove(email_value) != -1)
573bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    prefs->ScheduleSavePersistentPrefs();
574bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
575bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
576731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// static
577731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid UserCrosSettingsProvider::UpdateCachedOwner(const std::string& email) {
57821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UpdateCacheString(kDeviceOwner, email, USE_VALUE_SUPPLIED);
579bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
580bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
581bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}  // namespace chromeos
582