blob: c978415f5c2fe734b63bbc410285077ebdecbc0c [file] [log] [blame]
[email protected]b2907fd2011-03-25 16:43:371// Copyright (c) 2011 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 "base/logging.h"
[email protected]7286e3fc2011-07-19 22:13:246#include "base/stl_util.h"
[email protected]b2907fd2011-03-25 16:43:377#include "chrome/browser/extensions/extension_service.h"
8#include "chrome/browser/extensions/pending_extension_manager.h"
[email protected]145a317b2011-04-12 16:03:469#include "chrome/common/extensions/extension.h"
[email protected]b2907fd2011-03-25 16:43:3710#include "content/browser/browser_thread.h"
11
12namespace {
13
[email protected]b2907fd2011-03-25 16:43:3714// Install predicate used by AddFromExternalUpdateUrl().
15bool AlwaysInstall(const Extension& extension) {
16 return true;
17}
18
19} // namespace
20
21PendingExtensionManager::PendingExtensionManager(
[email protected]2859946f2011-04-04 18:18:0622 const ExtensionServiceInterface& service)
[email protected]b2907fd2011-03-25 16:43:3723 : service_(service) {
24}
25
26PendingExtensionManager::~PendingExtensionManager() {}
27
28bool PendingExtensionManager::GetById(
29 const std::string& id,
30 PendingExtensionInfo* out_pending_extension_info) const {
31
32 PendingExtensionMap::const_iterator it = pending_extension_map_.find(id);
33 if (it != pending_extension_map_.end()) {
34 *out_pending_extension_info = it->second;
35 return true;
36 }
37
38 return false;
39}
40
41void PendingExtensionManager::Remove(const std::string& id) {
42 pending_extension_map_.erase(id);
43}
44
45bool PendingExtensionManager::IsIdPending(const std::string& id) const {
46 return ContainsKey(pending_extension_map_, id);
47}
48
[email protected]145a317b2011-04-12 16:03:4649bool PendingExtensionManager::AddFromSync(
[email protected]b2907fd2011-03-25 16:43:3750 const std::string& id,
51 const GURL& update_url,
52 PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
[email protected]6cc7dbae2011-04-29 21:18:3353 bool install_silently) {
[email protected]b2907fd2011-03-25 16:43:3754 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
55
[email protected]8001df22011-04-28 19:59:4756 if (service_.GetInstalledExtension(id)) {
[email protected]145a317b2011-04-12 16:03:4657 LOG(ERROR) << "Trying to add pending extension " << id
58 << " which already exists";
59 return false;
[email protected]b2907fd2011-03-25 16:43:3760 }
61
[email protected]145a317b2011-04-12 16:03:4662 const bool kIsFromSync = true;
63 const Extension::Location kSyncLocation = Extension::INTERNAL;
64
65 return AddExtensionImpl(id, update_url, should_allow_install,
[email protected]6cc7dbae2011-04-29 21:18:3366 kIsFromSync, install_silently, kSyncLocation);
[email protected]b2907fd2011-03-25 16:43:3767}
68
69void PendingExtensionManager::AddFromExternalUpdateUrl(
70 const std::string& id, const GURL& update_url,
71 Extension::Location location) {
72 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
73
74 const bool kIsFromSync = false;
75 const bool kInstallSilently = true;
[email protected]b2907fd2011-03-25 16:43:3776
[email protected]8a87a5332011-08-11 17:54:5977 const Extension* extension = service_.GetInstalledExtension(id);
78 if (extension &&
79 location == Extension::GetHigherPriorityLocation(location,
80 extension->location())) {
81 // If the new location has higher priority than the location of an existing
82 // extension, let the update process overwrite the existing extension.
83 } else {
84 if (service_.IsExternalExtensionUninstalled(id)) {
85 return;
86 }
87 if (extension) {
88 LOG(DFATAL) << "Trying to add extension " << id
89 << " by external update, but it is already installed.";
90 return;
91 }
[email protected]b2907fd2011-03-25 16:43:3792 }
93
94 AddExtensionImpl(id, update_url, &AlwaysInstall,
95 kIsFromSync, kInstallSilently,
[email protected]6cc7dbae2011-04-29 21:18:3396 location);
[email protected]b2907fd2011-03-25 16:43:3797}
98
99
[email protected]b2907fd2011-03-25 16:43:37100void PendingExtensionManager::AddFromExternalFile(
101 const std::string& id,
102 Extension::Location location) {
103
104 GURL kUpdateUrl = GURL();
105 bool kIsFromSync = false;
106 bool kInstallSilently = true;
[email protected]b2907fd2011-03-25 16:43:37107
108 pending_extension_map_[id] =
109 PendingExtensionInfo(kUpdateUrl,
110 &AlwaysInstall,
111 kIsFromSync,
112 kInstallSilently,
[email protected]b2907fd2011-03-25 16:43:37113 location);
114}
115
[email protected]145a317b2011-04-12 16:03:46116bool PendingExtensionManager::AddExtensionImpl(
[email protected]b2907fd2011-03-25 16:43:37117 const std::string& id, const GURL& update_url,
118 PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
119 bool is_from_sync, bool install_silently,
[email protected]6cc7dbae2011-04-29 21:18:33120 Extension::Location install_source) {
[email protected]b2907fd2011-03-25 16:43:37121 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
122
[email protected]145a317b2011-04-12 16:03:46123 // Will add a pending extension record unless this variable is set to false.
124 bool should_add_pending_record = true;
[email protected]b2907fd2011-03-25 16:43:37125
[email protected]145a317b2011-04-12 16:03:46126 if (ContainsKey(pending_extension_map_, id)) {
127 // Bugs in this code will manifest as sporadic incorrect extension
128 // locations in situations where multiple install sources run at the
129 // same time. For example, on first login to a chrome os machine, an
130 // extension may be requested by sync sync and the default extension set.
131 // The following logging will help diagnose such issues.
[email protected]b2907fd2011-03-25 16:43:37132 VLOG(1) << "Extension id " << id
133 << " was entered for update more than once."
[email protected]145a317b2011-04-12 16:03:46134 << " old location: " << pending_extension_map_[id].install_source()
135 << " new location: " << install_source;
136
137 Extension::Location higher_priority_location =
138 Extension::GetHigherPriorityLocation(
139 install_source, pending_extension_map_[id].install_source());
140
141 if (higher_priority_location == install_source) {
142 VLOG(1) << "Overwrite existing record.";
143
144 } else {
145 VLOG(1) << "Keep existing record.";
146 should_add_pending_record = false;
147 }
[email protected]b2907fd2011-03-25 16:43:37148 }
149
[email protected]145a317b2011-04-12 16:03:46150 if (should_add_pending_record) {
151 pending_extension_map_[id] = PendingExtensionInfo(
152 update_url,
153 should_allow_install,
154 is_from_sync,
155 install_silently,
[email protected]145a317b2011-04-12 16:03:46156 install_source);
157 return true;
158 }
159 return false;
[email protected]b2907fd2011-03-25 16:43:37160}
161
162void PendingExtensionManager::AddForTesting(
163 const std::string& id,
164 const PendingExtensionInfo& pending_extension_info) {
165 pending_extension_map_[id] = pending_extension_info;
166}