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/common/constants.h"
9 #include "extensions/common/extension.h"
10 #include "extensions/common/extension_set.h"
11 #include "extensions/common/manifest_handlers/incognito_info.h"
13 using content::BrowserThread
;
15 namespace extensions
{
19 void CheckOnValidThread() { DCHECK_CURRENTLY_ON(BrowserThread::IO
); }
23 struct InfoMap::ExtraData
{
24 // When the extension was installed.
25 base::Time install_time
;
27 // True if the user has allowed this extension to run in incognito mode.
28 bool incognito_enabled
;
30 // True if the user has disabled notifications for this extension manually.
31 bool notifications_disabled
;
37 InfoMap::ExtraData::ExtraData() : incognito_enabled(false) {}
39 InfoMap::ExtraData::~ExtraData() {}
41 InfoMap::InfoMap() : signin_process_id_(-1) {}
43 const ProcessMap
& InfoMap::process_map() const { return process_map_
; }
45 const ProcessMap
& InfoMap::worker_process_map() const {
46 return worker_process_map_
;
49 void InfoMap::AddExtension(const Extension
* extension
,
50 base::Time install_time
,
51 bool incognito_enabled
,
52 bool notifications_disabled
) {
54 extensions_
.Insert(extension
);
55 disabled_extensions_
.Remove(extension
->id());
57 extra_data_
[extension
->id()].install_time
= install_time
;
58 extra_data_
[extension
->id()].incognito_enabled
= incognito_enabled
;
59 extra_data_
[extension
->id()].notifications_disabled
= notifications_disabled
;
62 void InfoMap::RemoveExtension(const std::string
& extension_id
,
63 const UnloadedExtensionInfo::Reason reason
) {
65 const Extension
* extension
= extensions_
.GetByID(extension_id
);
66 extra_data_
.erase(extension_id
); // we don't care about disabled extra data
67 bool was_uninstalled
= (reason
!= UnloadedExtensionInfo::REASON_DISABLE
&&
68 reason
!= UnloadedExtensionInfo::REASON_TERMINATE
);
71 disabled_extensions_
.Insert(extension
);
72 extensions_
.Remove(extension_id
);
73 } else if (was_uninstalled
) {
74 // If the extension was uninstalled, make sure it's removed from the map of
75 // disabled extensions.
76 disabled_extensions_
.Remove(extension_id
);
78 // NOTE: This can currently happen if we receive multiple unload
79 // notifications, e.g. setting incognito-enabled state for a
80 // disabled extension (e.g., via sync). See
81 // http://code.google.com/p/chromium/issues/detail?id=50582 .
82 NOTREACHED() << extension_id
;
86 base::Time
InfoMap::GetInstallTime(const std::string
& extension_id
) const {
87 ExtraDataMap::const_iterator iter
= extra_data_
.find(extension_id
);
88 if (iter
!= extra_data_
.end())
89 return iter
->second
.install_time
;
93 bool InfoMap::IsIncognitoEnabled(const std::string
& extension_id
) const {
94 // Keep in sync with duplicate in extensions/browser/process_manager.cc.
95 ExtraDataMap::const_iterator iter
= extra_data_
.find(extension_id
);
96 if (iter
!= extra_data_
.end())
97 return iter
->second
.incognito_enabled
;
101 bool InfoMap::CanCrossIncognito(const Extension
* extension
) const {
102 // This is duplicated from ExtensionService :(.
103 return IsIncognitoEnabled(extension
->id()) &&
104 !IncognitoInfo::IsSplitMode(extension
);
107 void InfoMap::RegisterExtensionProcess(const std::string
& extension_id
,
109 int site_instance_id
) {
110 if (!process_map_
.Insert(extension_id
, process_id
, site_instance_id
)) {
111 NOTREACHED() << "Duplicate extension process registration for: "
112 << extension_id
<< "," << process_id
<< ".";
116 void InfoMap::UnregisterExtensionProcess(const std::string
& extension_id
,
118 int site_instance_id
) {
119 if (!process_map_
.Remove(extension_id
, process_id
, site_instance_id
)) {
120 NOTREACHED() << "Unknown extension process registration for: "
121 << extension_id
<< "," << process_id
<< ".";
125 void InfoMap::UnregisterAllExtensionsInProcess(int process_id
) {
126 process_map_
.RemoveAllFromProcess(process_id
);
129 void InfoMap::RegisterExtensionWorkerProcess(const std::string
& extension_id
,
131 int site_instance_id
) {
132 if (!worker_process_map_
.Insert(extension_id
, process_id
, site_instance_id
)) {
133 NOTREACHED() << "Duplicate extension worker process registration for: "
134 << extension_id
<< "," << process_id
<< ".";
138 void InfoMap::UnregisterExtensionWorkerProcess(int process_id
) {
139 worker_process_map_
.RemoveAllFromProcess(process_id
);
142 void InfoMap::GetExtensionsWithAPIPermissionForSecurityOrigin(
145 APIPermission::ID permission
,
146 ExtensionSet
* extensions
) const {
149 if (origin
.SchemeIs(kExtensionScheme
)) {
150 const std::string
& id
= origin
.host();
151 const Extension
* extension
= extensions_
.GetByID(id
);
152 if (extension
&& extension
->HasAPIPermission(permission
) &&
153 process_map_
.Contains(id
, process_id
)) {
154 extensions
->Insert(extension
);
159 ExtensionSet::const_iterator i
= extensions_
.begin();
160 for (; i
!= extensions_
.end(); ++i
) {
161 if ((*i
)->web_extent().MatchesSecurityOrigin(origin
) &&
162 process_map_
.Contains((*i
)->id(), process_id
) &&
163 (*i
)->HasAPIPermission(permission
)) {
164 extensions
->Insert(*i
);
169 bool InfoMap::SecurityOriginHasAPIPermission(const GURL
& origin
,
171 APIPermission::ID permission
)
173 ExtensionSet extensions
;
174 GetExtensionsWithAPIPermissionForSecurityOrigin(
175 origin
, process_id
, permission
, &extensions
);
176 return !extensions
.is_empty();
179 QuotaService
* InfoMap::GetQuotaService() {
180 CheckOnValidThread();
182 quota_service_
.reset(new QuotaService());
183 return quota_service_
.get();
186 void InfoMap::SetSigninProcess(int process_id
) {
187 signin_process_id_
= process_id
;
190 bool InfoMap::IsSigninProcess(int process_id
) const {
191 return process_id
== signin_process_id_
;
194 void InfoMap::SetNotificationsDisabled(
195 const std::string
& extension_id
,
196 bool notifications_disabled
) {
197 ExtraDataMap::iterator iter
= extra_data_
.find(extension_id
);
198 if (iter
!= extra_data_
.end())
199 iter
->second
.notifications_disabled
= notifications_disabled
;
202 bool InfoMap::AreNotificationsDisabled(
203 const std::string
& extension_id
) const {
204 ExtraDataMap::const_iterator iter
= extra_data_
.find(extension_id
);
205 if (iter
!= extra_data_
.end())
206 return iter
->second
.notifications_disabled
;
210 InfoMap::~InfoMap() {
211 if (quota_service_
) {
212 BrowserThread::DeleteSoon(
213 BrowserThread::IO
, FROM_HERE
, quota_service_
.release());
217 } // namespace extensions