Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / info_map.cc
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.
4
5 #include "extensions/browser/info_map.h"
6
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"
13
14 using content::BrowserThread;
15
16 namespace extensions {
17
18 namespace {
19
20 void CheckOnValidThread() { DCHECK_CURRENTLY_ON(BrowserThread::IO); }
21
22 }  // namespace
23
24 struct InfoMap::ExtraData {
25   // When the extension was installed.
26   base::Time install_time;
27
28   // True if the user has allowed this extension to run in incognito mode.
29   bool incognito_enabled;
30
31   // True if the user has disabled notifications for this extension manually.
32   bool notifications_disabled;
33
34   ExtraData();
35   ~ExtraData();
36 };
37
38 InfoMap::ExtraData::ExtraData() : incognito_enabled(false) {}
39
40 InfoMap::ExtraData::~ExtraData() {}
41
42 InfoMap::InfoMap() : signin_process_id_(-1) {}
43
44 const ProcessMap& InfoMap::process_map() const { return process_map_; }
45
46 const ProcessMap& InfoMap::worker_process_map() const {
47   return worker_process_map_;
48 }
49
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());
57
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;
61 }
62
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;
84   }
85 }
86
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();
92 }
93
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;
100 }
101
102 bool InfoMap::CanCrossIncognito(const Extension* extension) const {
103   // This is duplicated from ExtensionService :(.
104   return IsIncognitoEnabled(extension->id()) &&
105          !IncognitoInfo::IsSplitMode(extension);
106 }
107
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 << ".";
114   }
115 }
116
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 << ".";
123   }
124 }
125
126 void InfoMap::UnregisterAllExtensionsInProcess(int process_id) {
127   process_map_.RemoveAllFromProcess(process_id);
128 }
129
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 << ".";
136   }
137 }
138
139 void InfoMap::UnregisterExtensionWorkerProcess(int process_id) {
140   worker_process_map_.RemoveAllFromProcess(process_id);
141 }
142
143 void InfoMap::GetExtensionsWithAPIPermissionForSecurityOrigin(
144     const GURL& origin,
145     int process_id,
146     APIPermission::ID permission,
147     ExtensionSet* extensions) const {
148   DCHECK(extensions);
149
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);
156     }
157     return;
158   }
159
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);
166     }
167   }
168 }
169
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();
178 }
179
180 QuotaService* InfoMap::GetQuotaService() {
181   CheckOnValidThread();
182   if (!quota_service_)
183     quota_service_.reset(new QuotaService());
184   return quota_service_.get();
185 }
186
187 void InfoMap::SetSigninProcess(int process_id) {
188   signin_process_id_ = process_id;
189 }
190
191 bool InfoMap::IsSigninProcess(int process_id) const {
192   return process_id == signin_process_id_;
193 }
194
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;
201 }
202
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;
209 }
210
211 void InfoMap::SetContentVerifier(ContentVerifier* verifier) {
212   content_verifier_ = verifier;
213 }
214
215 InfoMap::~InfoMap() {
216   if (quota_service_) {
217     BrowserThread::DeleteSoon(
218         BrowserThread::IO, FROM_HERE, quota_service_.release());
219   }
220 }
221
222 }  // namespace extensions