Implementation of leveldb-backed PrefStore.
[chromium-blink-merge.git] / extensions / browser / info_map.cc
blob42b85c550341b9d60c0e9bcc7f8f9636f7131290
1 // Copyright 2013 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.
5 #include "extensions/browser/info_map.h"
7 #include "content/public/browser/browser_thread.h"
8 #include "extensions/browser/content_verifier.h"
9 #include "extensions/common/constants.h"
10 #include "extensions/common/extension.h"
11 #include "extensions/common/extension_set.h"
12 #include "extensions/common/manifest_handlers/incognito_info.h"
14 using content::BrowserThread;
16 namespace extensions {
18 namespace {
20 void CheckOnValidThread() { DCHECK_CURRENTLY_ON(BrowserThread::IO); }
22 } // namespace
24 struct InfoMap::ExtraData {
25 // When the extension was installed.
26 base::Time install_time;
28 // True if the user has allowed this extension to run in incognito mode.
29 bool incognito_enabled;
31 // True if the user has disabled notifications for this extension manually.
32 bool notifications_disabled;
34 ExtraData();
35 ~ExtraData();
38 InfoMap::ExtraData::ExtraData() : incognito_enabled(false) {}
40 InfoMap::ExtraData::~ExtraData() {}
42 InfoMap::InfoMap() : signin_process_id_(-1) {}
44 const ProcessMap& InfoMap::process_map() const { return process_map_; }
46 const ProcessMap& InfoMap::worker_process_map() const {
47 return worker_process_map_;
50 void InfoMap::AddExtension(const Extension* extension,
51 base::Time install_time,
52 bool incognito_enabled,
53 bool notifications_disabled) {
54 CheckOnValidThread();
55 extensions_.Insert(extension);
56 disabled_extensions_.Remove(extension->id());
58 extra_data_[extension->id()].install_time = install_time;
59 extra_data_[extension->id()].incognito_enabled = incognito_enabled;
60 extra_data_[extension->id()].notifications_disabled = notifications_disabled;
63 void InfoMap::RemoveExtension(const std::string& extension_id,
64 const UnloadedExtensionInfo::Reason reason) {
65 CheckOnValidThread();
66 const Extension* extension = extensions_.GetByID(extension_id);
67 extra_data_.erase(extension_id); // we don't care about disabled extra data
68 bool was_uninstalled = (reason != UnloadedExtensionInfo::REASON_DISABLE &&
69 reason != UnloadedExtensionInfo::REASON_TERMINATE);
70 if (extension) {
71 if (!was_uninstalled)
72 disabled_extensions_.Insert(extension);
73 extensions_.Remove(extension_id);
74 } else if (was_uninstalled) {
75 // If the extension was uninstalled, make sure it's removed from the map of
76 // disabled extensions.
77 disabled_extensions_.Remove(extension_id);
78 } else {
79 // NOTE: This can currently happen if we receive multiple unload
80 // notifications, e.g. setting incognito-enabled state for a
81 // disabled extension (e.g., via sync). See
82 // http://code.google.com/p/chromium/issues/detail?id=50582 .
83 NOTREACHED() << extension_id;
87 base::Time InfoMap::GetInstallTime(const std::string& extension_id) const {
88 ExtraDataMap::const_iterator iter = extra_data_.find(extension_id);
89 if (iter != extra_data_.end())
90 return iter->second.install_time;
91 return base::Time();
94 bool InfoMap::IsIncognitoEnabled(const std::string& extension_id) const {
95 // Keep in sync with duplicate in extensions/browser/process_manager.cc.
96 ExtraDataMap::const_iterator iter = extra_data_.find(extension_id);
97 if (iter != extra_data_.end())
98 return iter->second.incognito_enabled;
99 return false;
102 bool InfoMap::CanCrossIncognito(const Extension* extension) const {
103 // This is duplicated from ExtensionService :(.
104 return IsIncognitoEnabled(extension->id()) &&
105 !IncognitoInfo::IsSplitMode(extension);
108 void InfoMap::RegisterExtensionProcess(const std::string& extension_id,
109 int process_id,
110 int site_instance_id) {
111 if (!process_map_.Insert(extension_id, process_id, site_instance_id)) {
112 NOTREACHED() << "Duplicate extension process registration for: "
113 << extension_id << "," << process_id << ".";
117 void InfoMap::UnregisterExtensionProcess(const std::string& extension_id,
118 int process_id,
119 int site_instance_id) {
120 if (!process_map_.Remove(extension_id, process_id, site_instance_id)) {
121 NOTREACHED() << "Unknown extension process registration for: "
122 << extension_id << "," << process_id << ".";
126 void InfoMap::UnregisterAllExtensionsInProcess(int process_id) {
127 process_map_.RemoveAllFromProcess(process_id);
130 void InfoMap::RegisterExtensionWorkerProcess(const std::string& extension_id,
131 int process_id,
132 int site_instance_id) {
133 if (!worker_process_map_.Insert(extension_id, process_id, site_instance_id)) {
134 NOTREACHED() << "Duplicate extension worker process registration for: "
135 << extension_id << "," << process_id << ".";
139 void InfoMap::UnregisterExtensionWorkerProcess(int process_id) {
140 worker_process_map_.RemoveAllFromProcess(process_id);
143 void InfoMap::GetExtensionsWithAPIPermissionForSecurityOrigin(
144 const GURL& origin,
145 int process_id,
146 APIPermission::ID permission,
147 ExtensionSet* extensions) const {
148 DCHECK(extensions);
150 if (origin.SchemeIs(kExtensionScheme)) {
151 const std::string& id = origin.host();
152 const Extension* extension = extensions_.GetByID(id);
153 if (extension && extension->HasAPIPermission(permission) &&
154 process_map_.Contains(id, process_id)) {
155 extensions->Insert(extension);
157 return;
160 ExtensionSet::const_iterator i = extensions_.begin();
161 for (; i != extensions_.end(); ++i) {
162 if ((*i)->web_extent().MatchesSecurityOrigin(origin) &&
163 process_map_.Contains((*i)->id(), process_id) &&
164 (*i)->HasAPIPermission(permission)) {
165 extensions->Insert(*i);
170 bool InfoMap::SecurityOriginHasAPIPermission(const GURL& origin,
171 int process_id,
172 APIPermission::ID permission)
173 const {
174 ExtensionSet extensions;
175 GetExtensionsWithAPIPermissionForSecurityOrigin(
176 origin, process_id, permission, &extensions);
177 return !extensions.is_empty();
180 QuotaService* InfoMap::GetQuotaService() {
181 CheckOnValidThread();
182 if (!quota_service_)
183 quota_service_.reset(new QuotaService());
184 return quota_service_.get();
187 void InfoMap::SetSigninProcess(int process_id) {
188 signin_process_id_ = process_id;
191 bool InfoMap::IsSigninProcess(int process_id) const {
192 return process_id == signin_process_id_;
195 void InfoMap::SetNotificationsDisabled(
196 const std::string& extension_id,
197 bool notifications_disabled) {
198 ExtraDataMap::iterator iter = extra_data_.find(extension_id);
199 if (iter != extra_data_.end())
200 iter->second.notifications_disabled = notifications_disabled;
203 bool InfoMap::AreNotificationsDisabled(
204 const std::string& extension_id) const {
205 ExtraDataMap::const_iterator iter = extra_data_.find(extension_id);
206 if (iter != extra_data_.end())
207 return iter->second.notifications_disabled;
208 return false;
211 void InfoMap::SetContentVerifier(ContentVerifier* verifier) {
212 content_verifier_ = verifier;
215 InfoMap::~InfoMap() {
216 if (quota_service_) {
217 BrowserThread::DeleteSoon(
218 BrowserThread::IO, FROM_HERE, quota_service_.release());
222 } // namespace extensions