Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / extensions / pending_extension_manager.cc
blob1a4ed427781fbd75a4290f4bc326b505346666e6
1 // Copyright 2014 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 "chrome/browser/extensions/pending_extension_manager.h"
7 #include <algorithm>
9 #include "base/logging.h"
10 #include "base/version.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "extensions/browser/extension_prefs.h"
14 #include "extensions/common/extension.h"
15 #include "url/gurl.h"
17 using content::BrowserThread;
19 namespace {
21 // Install predicate used by AddFromExternalUpdateUrl().
22 bool AlwaysInstall(const extensions::Extension* extension) {
23 return true;
26 std::string GetVersionString(const Version& version) {
27 return version.IsValid() ? version.GetString() : "invalid";
30 } // namespace
32 namespace extensions {
34 PendingExtensionManager::PendingExtensionManager(
35 const ExtensionServiceInterface& service,
36 content::BrowserContext* context)
37 : service_(service), context_(context) {}
39 PendingExtensionManager::~PendingExtensionManager() {}
41 const PendingExtensionInfo* PendingExtensionManager::GetById(
42 const std::string& id) const {
43 PendingExtensionList::const_iterator iter;
44 for (iter = pending_extension_list_.begin();
45 iter != pending_extension_list_.end();
46 ++iter) {
47 if (id == iter->id())
48 return &(*iter);
51 return NULL;
54 bool PendingExtensionManager::Remove(const std::string& id) {
55 PendingExtensionList::iterator iter;
56 for (iter = pending_extension_list_.begin();
57 iter != pending_extension_list_.end();
58 ++iter) {
59 if (id == iter->id()) {
60 pending_extension_list_.erase(iter);
61 return true;
65 return false;
68 bool PendingExtensionManager::IsIdPending(const std::string& id) const {
69 return GetById(id) != NULL;
72 bool PendingExtensionManager::HasPendingExtensions() const {
73 return !pending_extension_list_.empty();
76 bool PendingExtensionManager::HasPendingExtensionFromSync() const {
77 PendingExtensionList::const_iterator iter;
78 for (iter = pending_extension_list_.begin();
79 iter != pending_extension_list_.end();
80 ++iter) {
81 if (iter->is_from_sync())
82 return true;
85 return false;
88 bool PendingExtensionManager::AddFromSync(
89 const std::string& id,
90 const GURL& update_url,
91 PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
92 bool install_silently) {
93 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
95 if (service_.GetInstalledExtension(id)) {
96 LOG(ERROR) << "Trying to add pending extension " << id
97 << " which already exists";
98 return false;
101 // Make sure we don't ever try to install the CWS app, because even though
102 // it is listed as a syncable app (because its values need to be synced) it
103 // should already be installed on every instance.
104 if (id == extension_misc::kWebStoreAppId) {
105 NOTREACHED();
106 return false;
109 const bool kIsFromSync = true;
110 const Manifest::Location kSyncLocation = Manifest::INTERNAL;
111 const bool kMarkAcknowledged = false;
113 return AddExtensionImpl(id,
114 std::string(),
115 update_url,
116 Version(),
117 should_allow_install,
118 kIsFromSync,
119 install_silently,
120 kSyncLocation,
121 Extension::NO_FLAGS,
122 kMarkAcknowledged);
125 bool PendingExtensionManager::AddFromExtensionImport(
126 const std::string& id,
127 const GURL& update_url,
128 PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install) {
129 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
131 if (service_.GetInstalledExtension(id)) {
132 LOG(ERROR) << "Trying to add pending extension " << id
133 << " which already exists";
134 return false;
137 const bool kIsFromSync = false;
138 const bool kInstallSilently = true;
139 const Manifest::Location kManifestLocation = Manifest::INTERNAL;
140 const bool kMarkAcknowledged = false;
142 return AddExtensionImpl(id,
143 std::string(),
144 update_url,
145 Version(),
146 should_allow_install,
147 kIsFromSync,
148 kInstallSilently,
149 kManifestLocation,
150 Extension::NO_FLAGS,
151 kMarkAcknowledged);
154 bool PendingExtensionManager::AddFromExternalUpdateUrl(
155 const std::string& id,
156 const std::string& install_parameter,
157 const GURL& update_url,
158 Manifest::Location location,
159 int creation_flags,
160 bool mark_acknowledged) {
161 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
163 const bool kIsFromSync = false;
164 const bool kInstallSilently = true;
166 const Extension* extension = service_.GetInstalledExtension(id);
167 if (extension && location == Manifest::GetHigherPriorityLocation(
168 location, extension->location())) {
169 // If the new location has higher priority than the location of an existing
170 // extension, let the update process overwrite the existing extension.
171 } else {
172 if (ExtensionPrefs::Get(context_)->IsExternalExtensionUninstalled(id))
173 return false;
175 if (extension) {
176 LOG(DFATAL) << "Trying to add extension " << id
177 << " by external update, but it is already installed.";
178 return false;
182 return AddExtensionImpl(id,
183 install_parameter,
184 update_url,
185 Version(),
186 &AlwaysInstall,
187 kIsFromSync,
188 kInstallSilently,
189 location,
190 creation_flags,
191 mark_acknowledged);
195 bool PendingExtensionManager::AddFromExternalFile(
196 const std::string& id,
197 Manifest::Location install_source,
198 const Version& version,
199 int creation_flags,
200 bool mark_acknowledged) {
201 // TODO(skerner): AddFromSync() checks to see if the extension is
202 // installed, but this method assumes that the caller already
203 // made sure it is not installed. Make all AddFrom*() methods
204 // consistent.
205 GURL kUpdateUrl = GURL();
206 bool kIsFromSync = false;
207 bool kInstallSilently = true;
209 return AddExtensionImpl(id,
210 std::string(),
211 kUpdateUrl,
212 version,
213 &AlwaysInstall,
214 kIsFromSync,
215 kInstallSilently,
216 install_source,
217 creation_flags,
218 mark_acknowledged);
221 void PendingExtensionManager::GetPendingIdsForUpdateCheck(
222 std::list<std::string>* out_ids_for_update_check) const {
223 PendingExtensionList::const_iterator iter;
224 for (iter = pending_extension_list_.begin();
225 iter != pending_extension_list_.end();
226 ++iter) {
227 Manifest::Location install_source = iter->install_source();
229 // Some install sources read a CRX from the filesystem. They can
230 // not be fetched from an update URL, so don't include them in the
231 // set of ids.
232 if (install_source == Manifest::EXTERNAL_PREF ||
233 install_source == Manifest::EXTERNAL_REGISTRY)
234 continue;
236 out_ids_for_update_check->push_back(iter->id());
240 bool PendingExtensionManager::AddExtensionImpl(
241 const std::string& id,
242 const std::string& install_parameter,
243 const GURL& update_url,
244 const Version& version,
245 PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
246 bool is_from_sync,
247 bool install_silently,
248 Manifest::Location install_source,
249 int creation_flags,
250 bool mark_acknowledged) {
251 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
253 PendingExtensionInfo info(id,
254 install_parameter,
255 update_url,
256 version,
257 should_allow_install,
258 is_from_sync,
259 install_silently,
260 install_source,
261 creation_flags,
262 mark_acknowledged);
264 if (const PendingExtensionInfo* pending = GetById(id)) {
265 // Bugs in this code will manifest as sporadic incorrect extension
266 // locations in situations where multiple install sources run at the
267 // same time. For example, on first login to a chrome os machine, an
268 // extension may be requested by sync and the default extension set.
269 // The following logging will help diagnose such issues.
270 VLOG(1) << "Extension id " << id
271 << " was entered for update more than once."
272 << " old location: " << pending->install_source()
273 << " new location: " << install_source
274 << " old version: " << GetVersionString(pending->version())
275 << " new version: " << GetVersionString(version);
277 // Never override an existing extension with an older version. Only
278 // extensions from local CRX files have a known version; extensions from an
279 // update URL will get the latest version.
281 // If |pending| has the same or higher precedence than |info| then don't
282 // install |info| over |pending|.
283 if (pending->CompareTo(info) >= 0)
284 return false;
286 VLOG(1) << "Overwrite existing record.";
288 std::replace(pending_extension_list_.begin(),
289 pending_extension_list_.end(),
290 *pending,
291 info);
292 } else {
293 pending_extension_list_.push_back(info);
296 return true;
299 void PendingExtensionManager::AddForTesting(
300 const PendingExtensionInfo& pending_extension_info) {
301 pending_extension_list_.push_back(pending_extension_info);
304 } // namespace extensions