pref_value_store.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/prefs/pref_value_store.h"
  5. #include <stddef.h>
  6. #include "base/logging.h"
  7. #include "components/prefs/pref_notifier.h"
  8. #include "components/prefs/pref_observer.h"
  9. PrefValueStore::PrefStoreKeeper::PrefStoreKeeper()
  10. : pref_value_store_(nullptr), type_(PrefValueStore::INVALID_STORE) {}
  11. PrefValueStore::PrefStoreKeeper::~PrefStoreKeeper() {
  12. if (pref_store_) {
  13. pref_store_->RemoveObserver(this);
  14. pref_store_ = nullptr;
  15. }
  16. pref_value_store_ = nullptr;
  17. }
  18. void PrefValueStore::PrefStoreKeeper::Initialize(
  19. PrefValueStore* store,
  20. PrefStore* pref_store,
  21. PrefValueStore::PrefStoreType type) {
  22. if (pref_store_) {
  23. pref_store_->RemoveObserver(this);
  24. DCHECK(!pref_store_->HasObservers());
  25. }
  26. type_ = type;
  27. pref_value_store_ = store;
  28. pref_store_ = pref_store;
  29. if (pref_store_)
  30. pref_store_->AddObserver(this);
  31. }
  32. void PrefValueStore::PrefStoreKeeper::OnPrefValueChanged(
  33. const std::string& key) {
  34. pref_value_store_->OnPrefValueChanged(type_, key);
  35. }
  36. void PrefValueStore::PrefStoreKeeper::OnInitializationCompleted(
  37. bool succeeded) {
  38. pref_value_store_->OnInitializationCompleted(type_, succeeded);
  39. }
  40. PrefValueStore::PrefValueStore(PrefStore* managed_prefs,
  41. PrefStore* supervised_user_prefs,
  42. PrefStore* extension_prefs,
  43. PrefStore* standalone_browser_prefs,
  44. PrefStore* command_line_prefs,
  45. PrefStore* user_prefs,
  46. PrefStore* recommended_prefs,
  47. PrefStore* default_prefs,
  48. PrefNotifier* pref_notifier,
  49. std::unique_ptr<Delegate> delegate)
  50. : pref_notifier_(pref_notifier),
  51. initialization_failed_(false),
  52. delegate_(std::move(delegate)) {
  53. InitPrefStore(MANAGED_STORE, managed_prefs);
  54. InitPrefStore(SUPERVISED_USER_STORE, supervised_user_prefs);
  55. InitPrefStore(EXTENSION_STORE, extension_prefs);
  56. InitPrefStore(STANDALONE_BROWSER_STORE, standalone_browser_prefs);
  57. InitPrefStore(COMMAND_LINE_STORE, command_line_prefs);
  58. InitPrefStore(USER_STORE, user_prefs);
  59. InitPrefStore(RECOMMENDED_STORE, recommended_prefs);
  60. InitPrefStore(DEFAULT_STORE, default_prefs);
  61. CheckInitializationCompleted();
  62. if (delegate_) {
  63. delegate_->Init(managed_prefs, supervised_user_prefs, extension_prefs,
  64. standalone_browser_prefs, command_line_prefs, user_prefs,
  65. recommended_prefs, default_prefs, pref_notifier);
  66. }
  67. }
  68. PrefValueStore::~PrefValueStore() {}
  69. std::unique_ptr<PrefValueStore> PrefValueStore::CloneAndSpecialize(
  70. PrefStore* managed_prefs,
  71. PrefStore* supervised_user_prefs,
  72. PrefStore* extension_prefs,
  73. PrefStore* standalone_browser_prefs,
  74. PrefStore* command_line_prefs,
  75. PrefStore* user_prefs,
  76. PrefStore* recommended_prefs,
  77. PrefStore* default_prefs,
  78. PrefNotifier* pref_notifier,
  79. std::unique_ptr<Delegate> delegate) {
  80. DCHECK(pref_notifier);
  81. if (!managed_prefs)
  82. managed_prefs = GetPrefStore(MANAGED_STORE);
  83. if (!supervised_user_prefs)
  84. supervised_user_prefs = GetPrefStore(SUPERVISED_USER_STORE);
  85. if (!extension_prefs)
  86. extension_prefs = GetPrefStore(EXTENSION_STORE);
  87. if (!standalone_browser_prefs)
  88. standalone_browser_prefs = GetPrefStore(STANDALONE_BROWSER_STORE);
  89. if (!command_line_prefs)
  90. command_line_prefs = GetPrefStore(COMMAND_LINE_STORE);
  91. if (!user_prefs)
  92. user_prefs = GetPrefStore(USER_STORE);
  93. if (!recommended_prefs)
  94. recommended_prefs = GetPrefStore(RECOMMENDED_STORE);
  95. if (!default_prefs)
  96. default_prefs = GetPrefStore(DEFAULT_STORE);
  97. return std::make_unique<PrefValueStore>(
  98. managed_prefs, supervised_user_prefs, extension_prefs,
  99. standalone_browser_prefs, command_line_prefs, user_prefs,
  100. recommended_prefs, default_prefs, pref_notifier, std::move(delegate));
  101. }
  102. bool PrefValueStore::GetValue(const std::string& name,
  103. base::Value::Type type,
  104. const base::Value** out_value) const {
  105. // Check the |PrefStore|s in order of their priority from highest to lowest,
  106. // looking for the first preference value with the given |name| and |type|.
  107. for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
  108. if (GetValueFromStoreWithType(name, type, static_cast<PrefStoreType>(i),
  109. out_value))
  110. return true;
  111. }
  112. return false;
  113. }
  114. bool PrefValueStore::GetRecommendedValue(const std::string& name,
  115. base::Value::Type type,
  116. const base::Value** out_value) const {
  117. return GetValueFromStoreWithType(name, type, RECOMMENDED_STORE, out_value);
  118. }
  119. void PrefValueStore::NotifyPrefChanged(
  120. const std::string& path,
  121. PrefValueStore::PrefStoreType new_store) {
  122. DCHECK(new_store != INVALID_STORE);
  123. // A notification is sent when the pref value in any store changes. If this
  124. // store is currently being overridden by a higher-priority store, the
  125. // effective value of the pref will not have changed.
  126. pref_notifier_->OnPreferenceChanged(path);
  127. if (!pref_changed_callback_.is_null())
  128. pref_changed_callback_.Run(path);
  129. }
  130. bool PrefValueStore::PrefValueInManagedStore(const std::string& name) const {
  131. return PrefValueInStore(name, MANAGED_STORE);
  132. }
  133. bool PrefValueStore::PrefValueInSupervisedStore(const std::string& name) const {
  134. return PrefValueInStore(name, SUPERVISED_USER_STORE);
  135. }
  136. bool PrefValueStore::PrefValueInExtensionStore(const std::string& name) const {
  137. return PrefValueInStore(name, EXTENSION_STORE);
  138. }
  139. bool PrefValueStore::PrefValueInUserStore(const std::string& name) const {
  140. return PrefValueInStore(name, USER_STORE);
  141. }
  142. bool PrefValueStore::PrefValueFromExtensionStore(
  143. const std::string& name) const {
  144. return ControllingPrefStoreForPref(name) == EXTENSION_STORE;
  145. }
  146. bool PrefValueStore::PrefValueFromUserStore(const std::string& name) const {
  147. return ControllingPrefStoreForPref(name) == USER_STORE;
  148. }
  149. bool PrefValueStore::PrefValueFromRecommendedStore(
  150. const std::string& name) const {
  151. return ControllingPrefStoreForPref(name) == RECOMMENDED_STORE;
  152. }
  153. bool PrefValueStore::PrefValueFromStandaloneBrowserStore(
  154. const std::string& name) const {
  155. return ControllingPrefStoreForPref(name) == STANDALONE_BROWSER_STORE;
  156. }
  157. bool PrefValueStore::PrefValueFromDefaultStore(const std::string& name) const {
  158. return ControllingPrefStoreForPref(name) == DEFAULT_STORE;
  159. }
  160. bool PrefValueStore::PrefValueUserModifiable(const std::string& name) const {
  161. PrefStoreType effective_store = ControllingPrefStoreForPref(name);
  162. return effective_store >= USER_STORE ||
  163. effective_store == INVALID_STORE;
  164. }
  165. bool PrefValueStore::PrefValueExtensionModifiable(
  166. const std::string& name) const {
  167. PrefStoreType effective_store = ControllingPrefStoreForPref(name);
  168. return effective_store >= EXTENSION_STORE ||
  169. effective_store == INVALID_STORE;
  170. }
  171. bool PrefValueStore::PrefValueStandaloneBrowserModifiable(
  172. const std::string& name) const {
  173. PrefStoreType effective_store = ControllingPrefStoreForPref(name);
  174. return effective_store >= STANDALONE_BROWSER_STORE ||
  175. effective_store == INVALID_STORE;
  176. }
  177. void PrefValueStore::UpdateCommandLinePrefStore(PrefStore* command_line_prefs) {
  178. InitPrefStore(COMMAND_LINE_STORE, command_line_prefs);
  179. if (delegate_)
  180. delegate_->UpdateCommandLinePrefStore(command_line_prefs);
  181. }
  182. bool PrefValueStore::IsInitializationComplete() const {
  183. for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
  184. const PrefStore* pref_store = GetPrefStore(static_cast<PrefStoreType>(i));
  185. if (pref_store && !pref_store->IsInitializationComplete())
  186. return false;
  187. }
  188. return true;
  189. }
  190. bool PrefValueStore::HasPrefStore(PrefStoreType type) const {
  191. return GetPrefStore(type);
  192. }
  193. bool PrefValueStore::PrefValueInStore(
  194. const std::string& name,
  195. PrefValueStore::PrefStoreType store) const {
  196. // Declare a temp Value* and call GetValueFromStore,
  197. // ignoring the output value.
  198. const base::Value* tmp_value = nullptr;
  199. return GetValueFromStore(name, store, &tmp_value);
  200. }
  201. bool PrefValueStore::PrefValueInStoreRange(
  202. const std::string& name,
  203. PrefValueStore::PrefStoreType first_checked_store,
  204. PrefValueStore::PrefStoreType last_checked_store) const {
  205. if (first_checked_store > last_checked_store) {
  206. NOTREACHED();
  207. return false;
  208. }
  209. for (size_t i = first_checked_store;
  210. i <= static_cast<size_t>(last_checked_store); ++i) {
  211. if (PrefValueInStore(name, static_cast<PrefStoreType>(i)))
  212. return true;
  213. }
  214. return false;
  215. }
  216. PrefValueStore::PrefStoreType PrefValueStore::ControllingPrefStoreForPref(
  217. const std::string& name) const {
  218. for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
  219. if (PrefValueInStore(name, static_cast<PrefStoreType>(i)))
  220. return static_cast<PrefStoreType>(i);
  221. }
  222. return INVALID_STORE;
  223. }
  224. bool PrefValueStore::GetValueFromStore(const std::string& name,
  225. PrefValueStore::PrefStoreType store_type,
  226. const base::Value** out_value) const {
  227. // Only return true if we find a value and it is the correct type, so stale
  228. // values with the incorrect type will be ignored.
  229. const PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(store_type));
  230. if (store && store->GetValue(name, out_value))
  231. return true;
  232. // No valid value found for the given preference name: set the return value
  233. // to false.
  234. *out_value = nullptr;
  235. return false;
  236. }
  237. bool PrefValueStore::GetValueFromStoreWithType(
  238. const std::string& name,
  239. base::Value::Type type,
  240. PrefStoreType store,
  241. const base::Value** out_value) const {
  242. if (GetValueFromStore(name, store, out_value)) {
  243. if ((*out_value)->type() == type)
  244. return true;
  245. LOG(WARNING) << "Expected type for " << name << " is " << type
  246. << " but got " << (*out_value)->type() << " in store "
  247. << store;
  248. }
  249. *out_value = nullptr;
  250. return false;
  251. }
  252. void PrefValueStore::OnPrefValueChanged(PrefValueStore::PrefStoreType type,
  253. const std::string& key) {
  254. NotifyPrefChanged(key, type);
  255. }
  256. void PrefValueStore::OnInitializationCompleted(
  257. PrefValueStore::PrefStoreType type, bool succeeded) {
  258. if (initialization_failed_)
  259. return;
  260. if (!succeeded) {
  261. initialization_failed_ = true;
  262. pref_notifier_->OnInitializationCompleted(false);
  263. return;
  264. }
  265. CheckInitializationCompleted();
  266. }
  267. void PrefValueStore::InitPrefStore(PrefValueStore::PrefStoreType type,
  268. PrefStore* pref_store) {
  269. pref_stores_[type].Initialize(this, pref_store, type);
  270. }
  271. void PrefValueStore::CheckInitializationCompleted() {
  272. if (initialization_failed_)
  273. return;
  274. for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
  275. scoped_refptr<PrefStore> store =
  276. GetPrefStore(static_cast<PrefStoreType>(i));
  277. if (store.get() && !store->IsInitializationComplete())
  278. return;
  279. }
  280. pref_notifier_->OnInitializationCompleted(true);
  281. }