cros_settings.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/device_settings_provider.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/device_settings_service.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/system_settings_provider.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_notification_types.h"
18b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chromeos/chromeos_switches.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_util.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static CrosSettings*  g_cros_settings = NULL;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CrosSettings::Initialize() {
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK(!g_cros_settings);
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  g_cros_settings = new CrosSettings();
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool CrosSettings::IsInitialized() {
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return g_cros_settings;
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CrosSettings::Shutdown() {
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(g_cros_settings);
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delete g_cros_settings;
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  g_cros_settings = NULL;
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrosSettings* CrosSettings::Get() {
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK(g_cros_settings);
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return g_cros_settings;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CrosSettings::IsCrosSettings(const std::string& path) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return StartsWithASCII(path, kCrosSettingsPrefix, true);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrosSettings::Set(const std::string& path, const base::Value& in_value) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CrosSettingsProvider* provider;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  provider = GetProvider(path);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (provider)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    provider->Set(path, in_value);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const base::Value* CrosSettings::GetPref(const std::string& path) const {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CrosSettingsProvider* provider = GetProvider(path);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (provider)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return provider->Get(path);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED() << path << " preference was not found in the signed settings.";
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrosSettingsProvider::TrustedStatus CrosSettings::PrepareTrustedValues(
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Closure& callback) const {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < providers_.size(); ++i) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CrosSettingsProvider::TrustedStatus status =
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        providers_[i]->PrepareTrustedValues(callback);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status != CrosSettingsProvider::TRUSTED)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return status;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CrosSettingsProvider::TRUSTED;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrosSettings::SetBoolean(const std::string& path, bool in_value) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::FundamentalValue value(in_value);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Set(path, value);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrosSettings::SetInteger(const std::string& path, int in_value) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::FundamentalValue value(in_value);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Set(path, value);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrosSettings::SetDouble(const std::string& path, double in_value) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::FundamentalValue value(in_value);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Set(path, value);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrosSettings::SetString(const std::string& path,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const std::string& in_value) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::StringValue value(in_value);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Set(path, value);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrosSettings::AppendToList(const std::string& path,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const base::Value* value) {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::Value* old_value = GetPref(path);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> new_value(
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      old_value ? old_value->DeepCopy() : new base::ListValue());
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static_cast<base::ListValue*>(new_value.get())->Append(value->DeepCopy());
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Set(path, *new_value);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrosSettings::RemoveFromList(const std::string& path,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const base::Value* value) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::Value* old_value = GetPref(path);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> new_value(
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      old_value ? old_value->DeepCopy() : new base::ListValue());
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static_cast<base::ListValue*>(new_value.get())->Remove(*value, NULL);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Set(path, *new_value);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CrosSettings::GetBoolean(const std::string& path,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              bool* bool_value) const {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::Value* value = GetPref(path);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value->GetAsBoolean(bool_value);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CrosSettings::GetInteger(const std::string& path,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              int* out_value) const {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::Value* value = GetPref(path);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value->GetAsInteger(out_value);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CrosSettings::GetDouble(const std::string& path,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             double* out_value) const {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::Value* value = GetPref(path);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value->GetAsDouble(out_value);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CrosSettings::GetString(const std::string& path,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             std::string* out_value) const {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::Value* value = GetPref(path);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value->GetAsString(out_value);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CrosSettings::GetList(const std::string& path,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const base::ListValue** out_value) const {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::Value* value = GetPref(path);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value->GetAsList(out_value);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool CrosSettings::GetDictionary(
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& path,
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::DictionaryValue** out_value) const {
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(CalledOnValidThread());
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const base::Value* value = GetPref(path);
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (value)
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return value->GetAsDictionary(out_value);
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CrosSettings::FindEmailInList(const std::string& path,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const std::string& email) const {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string canonicalized_email(
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gaia::CanonicalizeEmail(gaia::SanitizeEmail(email)));
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string wildcard_email;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string::size_type at_pos = canonicalized_email.find('@');
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (at_pos != std::string::npos) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wildcard_email =
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string("*").append(canonicalized_email.substr(at_pos));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::ListValue* list;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetList(path, &list))
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (base::ListValue::const_iterator entry(list->begin());
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       entry != list->end();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++entry) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string entry_string;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(*entry)->GetAsString(&entry_string)) {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string canonicalized_entry(
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gaia::CanonicalizeEmail(gaia::SanitizeEmail(entry_string)));
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (canonicalized_entry == canonicalized_email ||
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        canonicalized_entry == wildcard_email) {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CrosSettings::AddSettingsProvider(CrosSettingsProvider* provider) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  providers_.push_back(provider);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allow the provider to notify this object when settings have changed.
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Providers instantiated inside this class will have the same callback
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // passed to their constructor, but doing it here allows for providers
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to be instantiated outside this class.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CrosSettingsProvider::NotifyObserversCallback notify_cb(
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&CrosSettings::FireObservers, base::Unretained(this)));
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  provider->SetNotifyObserversCallback(notify_cb);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CrosSettings::RemoveSettingsProvider(CrosSettingsProvider* provider) {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<CrosSettingsProvider*>::iterator it =
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::find(providers_.begin(), providers_.end(), provider);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it != providers_.end()) {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    providers_.erase(it);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrosSettings::AddSettingsObserver(const char* path,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       content::NotificationObserver* obs) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(path);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(obs);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetProvider(std::string(path))) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Trying to add an observer for an unregistered setting: "
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << path;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the settings observer list associated with the path.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationObserverList* observer_list = NULL;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SettingsObserverMap::iterator observer_iterator =
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      settings_observers_.find(path);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (observer_iterator == settings_observers_.end()) {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer_list = new NotificationObserverList;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    settings_observers_[path] = observer_list;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer_list = observer_iterator->second;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that this observer doesn't already exist.
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationObserverList::Iterator it(*observer_list);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationObserver* existing_obs;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while ((existing_obs = it.GetNext()) != NULL) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (existing_obs == obs)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ok, safe to add the pref observer.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_list->AddObserver(obs);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrosSettings::RemoveSettingsObserver(const char* path,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          content::NotificationObserver* obs) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SettingsObserverMap::iterator observer_iterator =
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      settings_observers_.find(path);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (observer_iterator == settings_observers_.end())
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationObserverList* observer_list = observer_iterator->second;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_list->RemoveObserver(obs);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrosSettingsProvider* CrosSettings::GetProvider(
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& path) const {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < providers_.size(); ++i) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (providers_[i]->HandlesSetting(path))
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return providers_[i];
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrosSettings::CrosSettings() {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CrosSettingsProvider::NotifyObserversCallback notify_cb(
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&CrosSettings::FireObservers,
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 // This is safe since |this| is never deleted.
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          switches::kStubCrosSettings)) {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddSettingsProvider(new StubCrosSettingsProvider(notify_cb));
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddSettingsProvider(
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new DeviceSettingsProvider(notify_cb, DeviceSettingsService::Get()));
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // System settings are not mocked currently.
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSettingsProvider(new SystemSettingsProvider(notify_cb));
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrosSettings::~CrosSettings() {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteElements(&providers_);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteValues(&settings_observers_);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrosSettings::FireObservers(const std::string& path) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SettingsObserverMap::iterator observer_iterator =
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      settings_observers_.find(path);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (observer_iterator == settings_observers_.end())
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationObserverList::Iterator it(*(observer_iterator->second));
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationObserver* observer;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while ((observer = it.GetNext()) != NULL) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer->Observe(chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED,
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      content::Source<CrosSettings>(this),
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      content::Details<const std::string>(&path));
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ScopedTestCrosSettings::ScopedTestCrosSettings() {
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CrosSettings::Initialize();
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ScopedTestCrosSettings::~ScopedTestCrosSettings() {
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CrosSettings::Shutdown();
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
347