blob: 10fa8c394b295ee3de2fd88fef1632cc24ff2c79 [file] [log] [blame]
[email protected]36296912012-03-20 11:08:491// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]4361c7c2010-09-30 21:57:532// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/extensions/extension_info_map.h"
6
[email protected]6f229e82010-11-02 17:47:267#include "chrome/common/extensions/extension.h"
[email protected]34eec7ffe32011-11-02 23:49:028#include "chrome/common/extensions/extension_set.h"
[email protected]06492ed2013-03-24 22:13:149#include "chrome/common/extensions/incognito_handler.h"
[email protected]34eec7ffe32011-11-02 23:49:0210#include "chrome/common/url_constants.h"
[email protected]c38831a12011-10-28 12:44:4911#include "content/public/browser/browser_thread.h"
[email protected]885c0e92012-11-13 20:27:4212#include "extensions/common/constants.h"
[email protected]4361c7c2010-09-30 21:57:5313
[email protected]631bb742011-11-02 11:29:3914using content::BrowserThread;
[email protected]1c321ee2012-05-21 03:02:3415using extensions::Extension;
[email protected]b0af4792013-10-23 09:12:1316using extensions::UnloadedExtensionInfo;
[email protected]631bb742011-11-02 11:29:3917
[email protected]4361c7c2010-09-30 21:57:5318namespace {
19
[email protected]2cce7ae2011-10-23 15:54:3620void CheckOnValidThread() {
[email protected]ca4b5fa32010-10-09 12:42:1821 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]4361c7c2010-09-30 21:57:5322}
23
24} // namespace
25
[email protected]c357acb42011-06-09 20:52:4226struct ExtensionInfoMap::ExtraData {
27 // When the extension was installed.
28 base::Time install_time;
29
30 // True if the user has allowed this extension to run in incognito mode.
31 bool incognito_enabled;
32
33 ExtraData();
34 ~ExtraData();
35};
36
[email protected]5f2a4752012-04-27 22:18:5837ExtensionInfoMap::ExtraData::ExtraData() : incognito_enabled(false) {}
[email protected]c357acb42011-06-09 20:52:4238
[email protected]5f2a4752012-04-27 22:18:5839ExtensionInfoMap::ExtraData::~ExtraData() {}
[email protected]c357acb42011-06-09 20:52:4240
[email protected]1deace22013-05-22 06:14:4641ExtensionInfoMap::ExtensionInfoMap() : signin_process_id_(-1) {}
[email protected]4361c7c2010-09-30 21:57:5342
[email protected]6f371442011-11-09 06:45:4643const extensions::ProcessMap& ExtensionInfoMap::process_map() const {
44 return process_map_;
45}
46
[email protected]c357acb42011-06-09 20:52:4247void ExtensionInfoMap::AddExtension(const Extension* extension,
48 base::Time install_time,
49 bool incognito_enabled) {
[email protected]4361c7c2010-09-30 21:57:5350 CheckOnValidThread();
[email protected]be0a2cfd2011-06-02 21:36:4251 extensions_.Insert(extension);
52 disabled_extensions_.Remove(extension->id());
[email protected]c357acb42011-06-09 20:52:4253
54 extra_data_[extension->id()].install_time = install_time;
55 extra_data_[extension->id()].incognito_enabled = incognito_enabled;
[email protected]4361c7c2010-09-30 21:57:5356}
57
[email protected]b0af4792013-10-23 09:12:1358void ExtensionInfoMap::RemoveExtension(
59 const std::string& extension_id,
60 const UnloadedExtensionInfo::Reason reason) {
[email protected]4361c7c2010-09-30 21:57:5361 CheckOnValidThread();
[email protected]c357acb42011-06-09 20:52:4262 const Extension* extension = extensions_.GetByID(extension_id);
63 extra_data_.erase(extension_id); // we don't care about disabled extra data
[email protected]b0af4792013-10-23 09:12:1364 bool was_uninstalled = (reason != UnloadedExtensionInfo::REASON_DISABLE &&
65 reason != UnloadedExtensionInfo::REASON_TERMINATE);
[email protected]be0a2cfd2011-06-02 21:36:4266 if (extension) {
[email protected]b3f7fe22011-11-11 19:27:5667 if (!was_uninstalled)
[email protected]be0a2cfd2011-06-02 21:36:4268 disabled_extensions_.Insert(extension);
[email protected]c357acb42011-06-09 20:52:4269 extensions_.Remove(extension_id);
[email protected]b3f7fe22011-11-11 19:27:5670 } else if (was_uninstalled) {
[email protected]dd163fb02011-05-04 22:22:1771 // If the extension was uninstalled, make sure it's removed from the map of
72 // disabled extensions.
[email protected]c357acb42011-06-09 20:52:4273 disabled_extensions_.Remove(extension_id);
[email protected]4361c7c2010-09-30 21:57:5374 } else {
75 // NOTE: This can currently happen if we receive multiple unload
76 // notifications, e.g. setting incognito-enabled state for a
77 // disabled extension (e.g., via sync). See
78 // http://code.google.com/p/chromium/issues/detail?id=50582 .
[email protected]c357acb42011-06-09 20:52:4279 NOTREACHED() << extension_id;
[email protected]4361c7c2010-09-30 21:57:5380 }
81}
[email protected]c357acb42011-06-09 20:52:4282
83base::Time ExtensionInfoMap::GetInstallTime(
84 const std::string& extension_id) const {
85 ExtraDataMap::const_iterator iter = extra_data_.find(extension_id);
86 if (iter != extra_data_.end())
87 return iter->second.install_time;
88 return base::Time();
89}
90
91bool ExtensionInfoMap::IsIncognitoEnabled(
92 const std::string& extension_id) const {
[email protected]8d3132f62011-10-12 07:13:4293 // Keep in sync with duplicate in extension_process_manager.cc.
[email protected]c357acb42011-06-09 20:52:4294 ExtraDataMap::const_iterator iter = extra_data_.find(extension_id);
95 if (iter != extra_data_.end())
96 return iter->second.incognito_enabled;
97 return false;
98}
99
[email protected]3dfa4c02012-07-30 17:21:41100bool ExtensionInfoMap::CanCrossIncognito(const Extension* extension) const {
[email protected]c357acb42011-06-09 20:52:42101 // This is duplicated from ExtensionService :(.
102 return IsIncognitoEnabled(extension->id()) &&
[email protected]06492ed2013-03-24 22:13:14103 !extensions::IncognitoInfo::IsSplitMode(extension);
[email protected]c357acb42011-06-09 20:52:42104}
[email protected]8add5412011-10-01 21:02:14105
[email protected]2cce7ae2011-10-23 15:54:36106void ExtensionInfoMap::RegisterExtensionProcess(const std::string& extension_id,
[email protected]6bc04fd82011-12-04 02:29:35107 int process_id,
108 int site_instance_id) {
109 if (!process_map_.Insert(extension_id, process_id, site_instance_id)) {
[email protected]6f371442011-11-09 06:45:46110 NOTREACHED() << "Duplicate extension process registration for: "
111 << extension_id << "," << process_id << ".";
112 }
[email protected]8add5412011-10-01 21:02:14113}
114
[email protected]2cce7ae2011-10-23 15:54:36115void ExtensionInfoMap::UnregisterExtensionProcess(
116 const std::string& extension_id,
[email protected]6bc04fd82011-12-04 02:29:35117 int process_id,
118 int site_instance_id) {
119 if (!process_map_.Remove(extension_id, process_id, site_instance_id)) {
[email protected]6f371442011-11-09 06:45:46120 NOTREACHED() << "Unknown extension process registration for: "
121 << extension_id << "," << process_id << ".";
122 }
[email protected]8add5412011-10-01 21:02:14123}
124
[email protected]6f371442011-11-09 06:45:46125void ExtensionInfoMap::UnregisterAllExtensionsInProcess(int process_id) {
[email protected]6bc04fd82011-12-04 02:29:35126 process_map_.RemoveAllFromProcess(process_id);
[email protected]8add5412011-10-01 21:02:14127}
[email protected]34eec7ffe32011-11-02 23:49:02128
[email protected]c7cd5942013-04-30 03:31:01129void ExtensionInfoMap::GetExtensionsWithAPIPermissionForSecurityOrigin(
130 const GURL& origin,
131 int process_id,
132 extensions::APIPermission::ID permission,
133 ExtensionSet* extensions) const {
134 DCHECK(extensions);
135
[email protected]885c0e92012-11-13 20:27:42136 if (origin.SchemeIs(extensions::kExtensionScheme)) {
[email protected]34eec7ffe32011-11-02 23:49:02137 const std::string& id = origin.host();
[email protected]af73c252012-07-27 00:16:39138 const Extension* extension = extensions_.GetByID(id);
[email protected]c7cd5942013-04-30 03:31:01139 if (extension && extension->HasAPIPermission(permission) &&
140 process_map_.Contains(id, process_id)) {
141 extensions->Insert(extension);
142 }
143 return;
[email protected]34eec7ffe32011-11-02 23:49:02144 }
145
[email protected]84df8332011-12-06 18:22:46146 ExtensionSet::const_iterator i = extensions_.begin();
[email protected]34eec7ffe32011-11-02 23:49:02147 for (; i != extensions_.end(); ++i) {
[email protected]84df8332011-12-06 18:22:46148 if ((*i)->web_extent().MatchesSecurityOrigin(origin) &&
149 process_map_.Contains((*i)->id(), process_id) &&
150 (*i)->HasAPIPermission(permission)) {
[email protected]c7cd5942013-04-30 03:31:01151 extensions->Insert(*i);
[email protected]34eec7ffe32011-11-02 23:49:02152 }
153 }
[email protected]c7cd5942013-04-30 03:31:01154}
155
156bool ExtensionInfoMap::SecurityOriginHasAPIPermission(
157 const GURL& origin, int process_id,
158 extensions::APIPermission::ID permission) const {
159 ExtensionSet extensions;
160 GetExtensionsWithAPIPermissionForSecurityOrigin(
161 origin, process_id, permission, &extensions);
162 return !extensions.is_empty();
[email protected]34eec7ffe32011-11-02 23:49:02163}
[email protected]36296912012-03-20 11:08:49164
165ExtensionsQuotaService* ExtensionInfoMap::GetQuotaService() {
166 CheckOnValidThread();
[email protected]3eeddd892013-04-17 17:00:11167 if (!quota_service_)
[email protected]36296912012-03-20 11:08:49168 quota_service_.reset(new ExtensionsQuotaService());
169 return quota_service_.get();
170}
[email protected]5f2a4752012-04-27 22:18:58171
[email protected]1deace22013-05-22 06:14:46172void ExtensionInfoMap::SetSigninProcess(int process_id) {
173 signin_process_id_ = process_id;
174}
175
176bool ExtensionInfoMap::IsSigninProcess(int process_id) const {
177 return process_id == signin_process_id_;
178}
179
[email protected]5f2a4752012-04-27 22:18:58180ExtensionInfoMap::~ExtensionInfoMap() {
[email protected]3eeddd892013-04-17 17:00:11181 if (quota_service_) {
[email protected]5f2a4752012-04-27 22:18:58182 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE,
183 quota_service_.release());
184 }
185}