extension_pref_value_map.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. // Copyright 2014 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 "extensions/browser/extension_pref_value_map.h"
  5. #include <utility>
  6. #include "base/memory/ptr_util.h"
  7. #include "base/observer_list.h"
  8. #include "base/time/time.h"
  9. #include "base/values.h"
  10. #include "components/prefs/pref_value_map.h"
  11. using extensions::ExtensionPrefsScope;
  12. struct ExtensionPrefValueMap::ExtensionEntry {
  13. // Installation time of the extension.
  14. base::Time install_time;
  15. // Whether extension is enabled in the profile.
  16. bool enabled;
  17. // Whether the extension has access to the incognito profile.
  18. bool incognito_enabled;
  19. // Extension controlled preferences for the regular profile.
  20. PrefValueMap regular_profile_preferences;
  21. // Extension controlled preferences that should *only* apply to the regular
  22. // profile.
  23. PrefValueMap regular_only_profile_preferences;
  24. // Persistent extension controlled preferences for the incognito profile,
  25. // empty for regular profile ExtensionPrefStore.
  26. PrefValueMap incognito_profile_preferences_persistent;
  27. // Session only extension controlled preferences for the incognito profile.
  28. // These preferences are deleted when the incognito profile is destroyed.
  29. PrefValueMap incognito_profile_preferences_session_only;
  30. };
  31. ExtensionPrefValueMap::ExtensionPrefValueMap() : destroyed_(false) {
  32. }
  33. ExtensionPrefValueMap::~ExtensionPrefValueMap() {
  34. if (!destroyed_) {
  35. NotifyOfDestruction();
  36. destroyed_ = true;
  37. }
  38. }
  39. void ExtensionPrefValueMap::Shutdown() {
  40. NotifyOfDestruction();
  41. destroyed_ = true;
  42. }
  43. void ExtensionPrefValueMap::SetExtensionPref(const std::string& ext_id,
  44. const std::string& key,
  45. ExtensionPrefsScope scope,
  46. base::Value value) {
  47. PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope);
  48. if (prefs->SetValue(key, std::move(value)))
  49. NotifyPrefValueChanged(key);
  50. }
  51. void ExtensionPrefValueMap::RemoveExtensionPref(
  52. const std::string& ext_id,
  53. const std::string& key,
  54. ExtensionPrefsScope scope) {
  55. PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope);
  56. if (prefs->RemoveValue(key))
  57. NotifyPrefValueChanged(key);
  58. }
  59. bool ExtensionPrefValueMap::CanExtensionControlPref(
  60. const std::string& extension_id,
  61. const std::string& pref_key,
  62. bool incognito) const {
  63. auto ext = entries_.find(extension_id);
  64. if (ext == entries_.end()) {
  65. NOTREACHED() << "Extension " << extension_id
  66. << " is not registered but accesses pref " << pref_key
  67. << " (incognito: " << incognito << ")."
  68. << " http://crbug.com/454513";
  69. return false;
  70. }
  71. if (incognito && !ext->second->incognito_enabled)
  72. return false;
  73. auto winner = GetEffectivePrefValueController(pref_key, incognito, NULL);
  74. if (winner == entries_.end())
  75. return true;
  76. return winner->second->install_time <= ext->second->install_time;
  77. }
  78. void ExtensionPrefValueMap::ClearAllIncognitoSessionOnlyPreferences() {
  79. typedef std::set<std::string> KeySet;
  80. KeySet deleted_keys;
  81. for (const auto& entry : entries_) {
  82. PrefValueMap& inc_prefs =
  83. entry.second->incognito_profile_preferences_session_only;
  84. for (const auto& pref : inc_prefs)
  85. deleted_keys.insert(pref.first);
  86. inc_prefs.Clear();
  87. }
  88. for (const auto& key : deleted_keys)
  89. NotifyPrefValueChanged(key);
  90. }
  91. bool ExtensionPrefValueMap::DoesExtensionControlPref(
  92. const std::string& extension_id,
  93. const std::string& pref_key,
  94. bool* from_incognito) const {
  95. bool incognito = (from_incognito != NULL);
  96. auto winner =
  97. GetEffectivePrefValueController(pref_key, incognito, from_incognito);
  98. if (winner == entries_.end())
  99. return false;
  100. return winner->first == extension_id;
  101. }
  102. void ExtensionPrefValueMap::RegisterExtension(const std::string& ext_id,
  103. const base::Time& install_time,
  104. bool is_enabled,
  105. bool is_incognito_enabled) {
  106. if (entries_.find(ext_id) == entries_.end()) {
  107. entries_[ext_id] = base::WrapUnique(new ExtensionEntry);
  108. // Only update the install time if the extension is newly installed.
  109. entries_[ext_id]->install_time = install_time;
  110. }
  111. entries_[ext_id]->enabled = is_enabled;
  112. entries_[ext_id]->incognito_enabled = is_incognito_enabled;
  113. }
  114. void ExtensionPrefValueMap::UnregisterExtension(const std::string& ext_id) {
  115. auto i = entries_.find(ext_id);
  116. if (i == entries_.end())
  117. return;
  118. std::set<std::string> keys; // keys set by this extension
  119. GetExtensionControlledKeys(*(i->second.get()), &keys);
  120. entries_.erase(i);
  121. NotifyPrefValueChanged(keys);
  122. }
  123. void ExtensionPrefValueMap::SetExtensionState(const std::string& ext_id,
  124. bool is_enabled) {
  125. ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
  126. // This may happen when sync sets the extension state for an
  127. // extension that is not installed.
  128. if (i == entries_.end())
  129. return;
  130. if (i->second->enabled == is_enabled)
  131. return;
  132. std::set<std::string> keys; // keys set by this extension
  133. GetExtensionControlledKeys(*(i->second), &keys);
  134. i->second->enabled = is_enabled;
  135. NotifyPrefValueChanged(keys);
  136. }
  137. void ExtensionPrefValueMap::SetExtensionIncognitoState(
  138. const std::string& ext_id,
  139. bool is_incognito_enabled) {
  140. ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
  141. // This may happen when sync sets the extension state for an
  142. // extension that is not installed.
  143. if (i == entries_.end())
  144. return;
  145. if (i->second->incognito_enabled == is_incognito_enabled)
  146. return;
  147. std::set<std::string> keys; // keys set by this extension
  148. GetExtensionControlledKeys(*(i->second), &keys);
  149. i->second->incognito_enabled = is_incognito_enabled;
  150. NotifyPrefValueChanged(keys);
  151. }
  152. PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
  153. const std::string& ext_id,
  154. ExtensionPrefsScope scope) {
  155. ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
  156. CHECK(i != entries_.end());
  157. switch (scope) {
  158. case extensions::kExtensionPrefsScopeRegular:
  159. return &(i->second->regular_profile_preferences);
  160. case extensions::kExtensionPrefsScopeRegularOnly:
  161. return &(i->second->regular_only_profile_preferences);
  162. case extensions::kExtensionPrefsScopeIncognitoPersistent:
  163. return &(i->second->incognito_profile_preferences_persistent);
  164. case extensions::kExtensionPrefsScopeIncognitoSessionOnly:
  165. return &(i->second->incognito_profile_preferences_session_only);
  166. }
  167. NOTREACHED();
  168. return NULL;
  169. }
  170. const PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
  171. const std::string& ext_id,
  172. ExtensionPrefsScope scope) const {
  173. auto i = entries_.find(ext_id);
  174. CHECK(i != entries_.end());
  175. switch (scope) {
  176. case extensions::kExtensionPrefsScopeRegular:
  177. return &(i->second->regular_profile_preferences);
  178. case extensions::kExtensionPrefsScopeRegularOnly:
  179. return &(i->second->regular_only_profile_preferences);
  180. case extensions::kExtensionPrefsScopeIncognitoPersistent:
  181. return &(i->second->incognito_profile_preferences_persistent);
  182. case extensions::kExtensionPrefsScopeIncognitoSessionOnly:
  183. return &(i->second->incognito_profile_preferences_session_only);
  184. }
  185. NOTREACHED();
  186. return NULL;
  187. }
  188. void ExtensionPrefValueMap::GetExtensionControlledKeys(
  189. const ExtensionEntry& entry,
  190. std::set<std::string>* out) const {
  191. PrefValueMap::const_iterator i;
  192. const PrefValueMap& regular_prefs = entry.regular_profile_preferences;
  193. for (i = regular_prefs.begin(); i != regular_prefs.end(); ++i)
  194. out->insert(i->first);
  195. const PrefValueMap& regular_only_prefs =
  196. entry.regular_only_profile_preferences;
  197. for (i = regular_only_prefs.begin(); i != regular_only_prefs.end(); ++i)
  198. out->insert(i->first);
  199. const PrefValueMap& inc_prefs_pers =
  200. entry.incognito_profile_preferences_persistent;
  201. for (i = inc_prefs_pers.begin(); i != inc_prefs_pers.end(); ++i)
  202. out->insert(i->first);
  203. const PrefValueMap& inc_prefs_session =
  204. entry.incognito_profile_preferences_session_only;
  205. for (i = inc_prefs_session.begin(); i != inc_prefs_session.end(); ++i)
  206. out->insert(i->first);
  207. }
  208. const base::Value* ExtensionPrefValueMap::GetEffectivePrefValue(
  209. const std::string& key,
  210. bool incognito,
  211. bool* from_incognito) const {
  212. auto winner = GetEffectivePrefValueController(key, incognito, from_incognito);
  213. if (winner == entries_.end())
  214. return NULL;
  215. const base::Value* value = NULL;
  216. const std::string& ext_id = winner->first;
  217. // First search for incognito session only preferences.
  218. if (incognito) {
  219. DCHECK(winner->second->incognito_enabled);
  220. const PrefValueMap* prefs = GetExtensionPrefValueMap(
  221. ext_id, extensions::kExtensionPrefsScopeIncognitoSessionOnly);
  222. prefs->GetValue(key, &value);
  223. if (value)
  224. return value;
  225. // If no incognito session only preference exists, fall back to persistent
  226. // incognito preference.
  227. prefs = GetExtensionPrefValueMap(
  228. ext_id,
  229. extensions::kExtensionPrefsScopeIncognitoPersistent);
  230. prefs->GetValue(key, &value);
  231. if (value)
  232. return value;
  233. } else {
  234. // Regular-only preference.
  235. const PrefValueMap* prefs = GetExtensionPrefValueMap(
  236. ext_id, extensions::kExtensionPrefsScopeRegularOnly);
  237. prefs->GetValue(key, &value);
  238. if (value)
  239. return value;
  240. }
  241. // Regular preference.
  242. const PrefValueMap* prefs = GetExtensionPrefValueMap(
  243. ext_id, extensions::kExtensionPrefsScopeRegular);
  244. prefs->GetValue(key, &value);
  245. return value;
  246. }
  247. ExtensionPrefValueMap::ExtensionEntryMap::const_iterator
  248. ExtensionPrefValueMap::GetEffectivePrefValueController(
  249. const std::string& key,
  250. bool incognito,
  251. bool* from_incognito) const {
  252. auto winner = entries_.cend();
  253. base::Time winners_install_time;
  254. for (auto i = entries_.cbegin(); i != entries_.cend(); ++i) {
  255. const std::string& ext_id = i->first;
  256. const base::Time& install_time = i->second->install_time;
  257. const bool enabled = i->second->enabled;
  258. const bool incognito_enabled = i->second->incognito_enabled;
  259. if (!enabled)
  260. continue;
  261. if (install_time < winners_install_time)
  262. continue;
  263. if (incognito && !incognito_enabled)
  264. continue;
  265. const base::Value* value = NULL;
  266. const PrefValueMap* prefs = GetExtensionPrefValueMap(
  267. ext_id, extensions::kExtensionPrefsScopeRegular);
  268. if (prefs->GetValue(key, &value)) {
  269. winner = i;
  270. winners_install_time = install_time;
  271. if (from_incognito)
  272. *from_incognito = false;
  273. }
  274. if (!incognito) {
  275. prefs = GetExtensionPrefValueMap(
  276. ext_id, extensions::kExtensionPrefsScopeRegularOnly);
  277. if (prefs->GetValue(key, &value)) {
  278. winner = i;
  279. winners_install_time = install_time;
  280. if (from_incognito)
  281. *from_incognito = false;
  282. }
  283. // Ignore the following prefs, because they're incognito-only.
  284. continue;
  285. }
  286. prefs = GetExtensionPrefValueMap(
  287. ext_id, extensions::kExtensionPrefsScopeIncognitoPersistent);
  288. if (prefs->GetValue(key, &value)) {
  289. winner = i;
  290. winners_install_time = install_time;
  291. if (from_incognito)
  292. *from_incognito = true;
  293. }
  294. prefs = GetExtensionPrefValueMap(
  295. ext_id, extensions::kExtensionPrefsScopeIncognitoSessionOnly);
  296. if (prefs->GetValue(key, &value)) {
  297. winner = i;
  298. winners_install_time = install_time;
  299. if (from_incognito)
  300. *from_incognito = true;
  301. }
  302. }
  303. return winner;
  304. }
  305. void ExtensionPrefValueMap::AddObserver(
  306. ExtensionPrefValueMap::Observer* observer) {
  307. observers_.AddObserver(observer);
  308. // Collect all currently used keys and notify the new observer.
  309. std::set<std::string> keys;
  310. ExtensionEntryMap::const_iterator i;
  311. for (i = entries_.begin(); i != entries_.end(); ++i)
  312. GetExtensionControlledKeys(*(i->second), &keys);
  313. std::set<std::string>::const_iterator j;
  314. for (j = keys.begin(); j != keys.end(); ++j)
  315. observer->OnPrefValueChanged(*j);
  316. }
  317. void ExtensionPrefValueMap::RemoveObserver(
  318. ExtensionPrefValueMap::Observer* observer) {
  319. observers_.RemoveObserver(observer);
  320. }
  321. std::string ExtensionPrefValueMap::GetExtensionControllingPref(
  322. const std::string& pref_key) const {
  323. auto winner = GetEffectivePrefValueController(pref_key, false, NULL);
  324. if (winner == entries_.end())
  325. return std::string();
  326. return winner->first;
  327. }
  328. void ExtensionPrefValueMap::NotifyInitializationCompleted() {
  329. for (auto& observer : observers_)
  330. observer.OnInitializationCompleted();
  331. }
  332. void ExtensionPrefValueMap::NotifyPrefValueChanged(
  333. const std::set<std::string>& keys) {
  334. for (const auto& key : keys)
  335. NotifyPrefValueChanged(key);
  336. }
  337. void ExtensionPrefValueMap::NotifyPrefValueChanged(const std::string& key) {
  338. for (auto& observer : observers_)
  339. observer.OnPrefValueChanged(key);
  340. }
  341. void ExtensionPrefValueMap::NotifyOfDestruction() {
  342. for (auto& observer : observers_)
  343. observer.OnExtensionPrefValueMapDestruction();
  344. }