blob: 82492d9920d5bc0e02cee5699d61397ebc7256eb [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"
9#include "chrome/common/url_constants.h"
[email protected]c38831a12011-10-28 12:44:4910#include "content/public/browser/browser_thread.h"
[email protected]4361c7c2010-09-30 21:57:5311
[email protected]631bb742011-11-02 11:29:3912using content::BrowserThread;
13
[email protected]4361c7c2010-09-30 21:57:5314namespace {
15
[email protected]2cce7ae2011-10-23 15:54:3616void CheckOnValidThread() {
[email protected]ca4b5fa32010-10-09 12:42:1817 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]4361c7c2010-09-30 21:57:5318}
19
20} // namespace
21
[email protected]c357acb42011-06-09 20:52:4222
23struct ExtensionInfoMap::ExtraData {
24 // When the extension was installed.
25 base::Time install_time;
26
27 // True if the user has allowed this extension to run in incognito mode.
28 bool incognito_enabled;
29
30 ExtraData();
31 ~ExtraData();
32};
33
34ExtensionInfoMap::ExtraData::ExtraData() : incognito_enabled(false) {
35}
36
37ExtensionInfoMap::ExtraData::~ExtraData() {
38}
39
40
[email protected]4361c7c2010-09-30 21:57:5341ExtensionInfoMap::ExtensionInfoMap() {
42}
43
44ExtensionInfoMap::~ExtensionInfoMap() {
[email protected]36296912012-03-20 11:08:4945 if (quota_service_.get()) {
46 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE,
47 quota_service_.release());
48 }
[email protected]4361c7c2010-09-30 21:57:5349}
50
[email protected]6f371442011-11-09 06:45:4651const extensions::ProcessMap& ExtensionInfoMap::process_map() const {
52 return process_map_;
53}
54
[email protected]c357acb42011-06-09 20:52:4255void ExtensionInfoMap::AddExtension(const Extension* extension,
56 base::Time install_time,
57 bool incognito_enabled) {
[email protected]4361c7c2010-09-30 21:57:5358 CheckOnValidThread();
[email protected]be0a2cfd2011-06-02 21:36:4259 extensions_.Insert(extension);
60 disabled_extensions_.Remove(extension->id());
[email protected]c357acb42011-06-09 20:52:4261
62 extra_data_[extension->id()].install_time = install_time;
63 extra_data_[extension->id()].incognito_enabled = incognito_enabled;
[email protected]4361c7c2010-09-30 21:57:5364}
65
[email protected]c357acb42011-06-09 20:52:4266void ExtensionInfoMap::RemoveExtension(const std::string& extension_id,
[email protected]814a7bf0f2011-08-13 05:30:5967 const extension_misc::UnloadedExtensionReason reason) {
[email protected]4361c7c2010-09-30 21:57:5368 CheckOnValidThread();
[email protected]c357acb42011-06-09 20:52:4269 const Extension* extension = extensions_.GetByID(extension_id);
70 extra_data_.erase(extension_id); // we don't care about disabled extra data
[email protected]b3f7fe22011-11-11 19:27:5671 bool was_uninstalled = (reason != extension_misc::UNLOAD_REASON_DISABLE &&
72 reason != extension_misc::UNLOAD_REASON_TERMINATE);
[email protected]be0a2cfd2011-06-02 21:36:4273 if (extension) {
[email protected]b3f7fe22011-11-11 19:27:5674 if (!was_uninstalled)
[email protected]be0a2cfd2011-06-02 21:36:4275 disabled_extensions_.Insert(extension);
[email protected]c357acb42011-06-09 20:52:4276 extensions_.Remove(extension_id);
[email protected]b3f7fe22011-11-11 19:27:5677 } else if (was_uninstalled) {
[email protected]dd163fb02011-05-04 22:22:1778 // If the extension was uninstalled, make sure it's removed from the map of
79 // disabled extensions.
[email protected]c357acb42011-06-09 20:52:4280 disabled_extensions_.Remove(extension_id);
[email protected]4361c7c2010-09-30 21:57:5381 } else {
82 // NOTE: This can currently happen if we receive multiple unload
83 // notifications, e.g. setting incognito-enabled state for a
84 // disabled extension (e.g., via sync). See
85 // http://code.google.com/p/chromium/issues/detail?id=50582 .
[email protected]c357acb42011-06-09 20:52:4286 NOTREACHED() << extension_id;
[email protected]4361c7c2010-09-30 21:57:5387 }
88}
[email protected]c357acb42011-06-09 20:52:4289
90base::Time ExtensionInfoMap::GetInstallTime(
91 const std::string& extension_id) const {
92 ExtraDataMap::const_iterator iter = extra_data_.find(extension_id);
93 if (iter != extra_data_.end())
94 return iter->second.install_time;
95 return base::Time();
96}
97
98bool ExtensionInfoMap::IsIncognitoEnabled(
99 const std::string& extension_id) const {
[email protected]8d3132f62011-10-12 07:13:42100 // Keep in sync with duplicate in extension_process_manager.cc.
[email protected]c357acb42011-06-09 20:52:42101 ExtraDataMap::const_iterator iter = extra_data_.find(extension_id);
102 if (iter != extra_data_.end())
103 return iter->second.incognito_enabled;
104 return false;
105}
106
107bool ExtensionInfoMap::CanCrossIncognito(const Extension* extension) {
108 // This is duplicated from ExtensionService :(.
109 return IsIncognitoEnabled(extension->id()) &&
110 !extension->incognito_split_mode();
111}
[email protected]8add5412011-10-01 21:02:14112
[email protected]2cce7ae2011-10-23 15:54:36113void ExtensionInfoMap::RegisterExtensionProcess(const std::string& extension_id,
[email protected]6bc04fd82011-12-04 02:29:35114 int process_id,
115 int site_instance_id) {
116 if (!process_map_.Insert(extension_id, process_id, site_instance_id)) {
[email protected]6f371442011-11-09 06:45:46117 NOTREACHED() << "Duplicate extension process registration for: "
118 << extension_id << "," << process_id << ".";
119 }
[email protected]8add5412011-10-01 21:02:14120}
121
[email protected]2cce7ae2011-10-23 15:54:36122void ExtensionInfoMap::UnregisterExtensionProcess(
123 const std::string& extension_id,
[email protected]6bc04fd82011-12-04 02:29:35124 int process_id,
125 int site_instance_id) {
126 if (!process_map_.Remove(extension_id, process_id, site_instance_id)) {
[email protected]6f371442011-11-09 06:45:46127 NOTREACHED() << "Unknown extension process registration for: "
128 << extension_id << "," << process_id << ".";
129 }
[email protected]8add5412011-10-01 21:02:14130}
131
[email protected]6f371442011-11-09 06:45:46132void ExtensionInfoMap::UnregisterAllExtensionsInProcess(int process_id) {
[email protected]6bc04fd82011-12-04 02:29:35133 process_map_.RemoveAllFromProcess(process_id);
[email protected]8add5412011-10-01 21:02:14134}
[email protected]34eec7ffe32011-11-02 23:49:02135
136bool ExtensionInfoMap::SecurityOriginHasAPIPermission(
137 const GURL& origin, int process_id,
138 ExtensionAPIPermission::ID permission) const {
139 if (origin.SchemeIs(chrome::kExtensionScheme)) {
140 const std::string& id = origin.host();
141 return extensions_.GetByID(id)->HasAPIPermission(permission) &&
[email protected]6f371442011-11-09 06:45:46142 process_map_.Contains(id, process_id);
[email protected]34eec7ffe32011-11-02 23:49:02143 }
144
[email protected]84df8332011-12-06 18:22:46145 ExtensionSet::const_iterator i = extensions_.begin();
[email protected]34eec7ffe32011-11-02 23:49:02146 for (; i != extensions_.end(); ++i) {
[email protected]84df8332011-12-06 18:22:46147 if ((*i)->web_extent().MatchesSecurityOrigin(origin) &&
148 process_map_.Contains((*i)->id(), process_id) &&
149 (*i)->HasAPIPermission(permission)) {
[email protected]34eec7ffe32011-11-02 23:49:02150 return true;
151 }
152 }
153 return false;
154}
[email protected]36296912012-03-20 11:08:49155
156ExtensionsQuotaService* ExtensionInfoMap::GetQuotaService() {
157 CheckOnValidThread();
158 if (!quota_service_.get())
159 quota_service_.reset(new ExtensionsQuotaService());
160 return quota_service_.get();
161}