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
{
20 void CheckOnValidThread() { DCHECK_CURRENTLY_ON(BrowserThread::IO
); }
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
;
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
) {
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
) {
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
);
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
);
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
;
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
;
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
,
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
,
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
,
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(
146 APIPermission::ID permission
,
147 ExtensionSet
* extensions
) const {
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
);
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
,
172 APIPermission::ID permission
)
174 ExtensionSet extensions
;
175 GetExtensionsWithAPIPermissionForSecurityOrigin(
176 origin
, process_id
, permission
, &extensions
);
177 return !extensions
.is_empty();
180 QuotaService
* InfoMap::GetQuotaService() {
181 CheckOnValidThread();
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
;
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