blob: 28bcaa6e322dc88542459e24313c587fcf8e7c9d [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"
6#include "base/stl_util-inl.h"
7#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
14// Install predicate used by AddFromDefaultAppList().
15bool IsApp(const Extension& extension) {
16 return extension.is_app();
17}
18
19// Install predicate used by AddFromExternalUpdateUrl().
20bool AlwaysInstall(const Extension& extension) {
21 return true;
22}
23
24} // namespace
25
26PendingExtensionManager::PendingExtensionManager(
[email protected]2859946f2011-04-04 18:18:0627 const ExtensionServiceInterface& service)
[email protected]b2907fd2011-03-25 16:43:3728 : service_(service) {
29}
30
31PendingExtensionManager::~PendingExtensionManager() {}
32
33bool PendingExtensionManager::GetById(
34 const std::string& id,
35 PendingExtensionInfo* out_pending_extension_info) const {
36
37 PendingExtensionMap::const_iterator it = pending_extension_map_.find(id);
38 if (it != pending_extension_map_.end()) {
39 *out_pending_extension_info = it->second;
40 return true;
41 }
42
43 return false;
44}
45
46void PendingExtensionManager::Remove(const std::string& id) {
47 pending_extension_map_.erase(id);
48}
49
50bool PendingExtensionManager::IsIdPending(const std::string& id) const {
51 return ContainsKey(pending_extension_map_, id);
52}
53
[email protected]145a317b2011-04-12 16:03:4654bool PendingExtensionManager::AddFromSync(
[email protected]b2907fd2011-03-25 16:43:3755 const std::string& id,
56 const GURL& update_url,
57 PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
58 bool install_silently,
59 bool enable_on_install,
60 bool enable_incognito_on_install) {
61 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
62
63 if (service_.GetExtensionById(id, true)) {
[email protected]145a317b2011-04-12 16:03:4664 LOG(ERROR) << "Trying to add pending extension " << id
65 << " which already exists";
66 return false;
[email protected]b2907fd2011-03-25 16:43:3767 }
68
[email protected]145a317b2011-04-12 16:03:4669 const bool kIsFromSync = true;
70 const Extension::Location kSyncLocation = Extension::INTERNAL;
71
72 return AddExtensionImpl(id, update_url, should_allow_install,
73 kIsFromSync, install_silently,
74 enable_on_install,
75 enable_incognito_on_install,
76 kSyncLocation);
[email protected]b2907fd2011-03-25 16:43:3777}
78
79void PendingExtensionManager::AddFromExternalUpdateUrl(
80 const std::string& id, const GURL& update_url,
81 Extension::Location location) {
82 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
83
84 const bool kIsFromSync = false;
85 const bool kInstallSilently = true;
86 const bool kEnableOnInstall = true;
87 const bool kEnableIncognitoOnInstall = false;
88
[email protected]c3cfb012011-04-06 22:07:3589 if (service_.IsExternalExtensionUninstalled(id))
[email protected]b2907fd2011-03-25 16:43:3790 return;
91
92 if (service_.GetExtensionById(id, true)) {
93 LOG(DFATAL) << "Trying to add extension " << id
94 << " by external update, but it is already installed.";
95 return;
96 }
97
98 AddExtensionImpl(id, update_url, &AlwaysInstall,
99 kIsFromSync, kInstallSilently,
100 kEnableOnInstall, kEnableIncognitoOnInstall,
101 location);
102}
103
104
105// TODO(akalin): Change DefaultAppList to DefaultExtensionList and
106// remove the IsApp() check.
107void PendingExtensionManager::AddFromDefaultAppList(
108 const std::string& id) {
109 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
110
111 const bool kIsFromSync = false;
112 const bool kInstallSilently = true;
113 const bool kEnableOnInstall = true;
114 const bool kEnableIncognitoOnInstall = true;
115
116 // This can legitimately happen if the user manually installed one of the
117 // default apps before this code ran.
118 if (service_.GetExtensionById(id, true))
119 return;
120
121 AddExtensionImpl(id, GURL(), &IsApp,
122 kIsFromSync, kInstallSilently,
123 kEnableOnInstall, kEnableIncognitoOnInstall,
124 Extension::INTERNAL);
125}
126
127void PendingExtensionManager::AddFromExternalFile(
128 const std::string& id,
129 Extension::Location location) {
130
131 GURL kUpdateUrl = GURL();
132 bool kIsFromSync = false;
133 bool kInstallSilently = true;
134 bool kEnableOnInstall = true;
135 bool kEnableIncognitoOnInstall = false;
136
137 pending_extension_map_[id] =
138 PendingExtensionInfo(kUpdateUrl,
139 &AlwaysInstall,
140 kIsFromSync,
141 kInstallSilently,
142 kEnableOnInstall,
143 kEnableIncognitoOnInstall,
144 location);
145}
146
[email protected]145a317b2011-04-12 16:03:46147bool PendingExtensionManager::AddExtensionImpl(
[email protected]b2907fd2011-03-25 16:43:37148 const std::string& id, const GURL& update_url,
149 PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
150 bool is_from_sync, bool install_silently,
151 bool enable_on_install, bool enable_incognito_on_install,
152 Extension::Location install_source) {
153 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
154
[email protected]145a317b2011-04-12 16:03:46155 // Will add a pending extension record unless this variable is set to false.
156 bool should_add_pending_record = true;
[email protected]b2907fd2011-03-25 16:43:37157
[email protected]145a317b2011-04-12 16:03:46158 if (ContainsKey(pending_extension_map_, id)) {
159 // Bugs in this code will manifest as sporadic incorrect extension
160 // locations in situations where multiple install sources run at the
161 // same time. For example, on first login to a chrome os machine, an
162 // extension may be requested by sync sync and the default extension set.
163 // The following logging will help diagnose such issues.
[email protected]b2907fd2011-03-25 16:43:37164 VLOG(1) << "Extension id " << id
165 << " was entered for update more than once."
[email protected]145a317b2011-04-12 16:03:46166 << " old location: " << pending_extension_map_[id].install_source()
167 << " new location: " << install_source;
168
169 Extension::Location higher_priority_location =
170 Extension::GetHigherPriorityLocation(
171 install_source, pending_extension_map_[id].install_source());
172
173 if (higher_priority_location == install_source) {
174 VLOG(1) << "Overwrite existing record.";
175
176 } else {
177 VLOG(1) << "Keep existing record.";
178 should_add_pending_record = false;
179 }
[email protected]b2907fd2011-03-25 16:43:37180 }
181
[email protected]145a317b2011-04-12 16:03:46182 if (should_add_pending_record) {
183 pending_extension_map_[id] = PendingExtensionInfo(
184 update_url,
185 should_allow_install,
186 is_from_sync,
187 install_silently,
188 enable_on_install,
189 enable_incognito_on_install,
190 install_source);
191 return true;
192 }
193 return false;
[email protected]b2907fd2011-03-25 16:43:37194}
195
196void PendingExtensionManager::AddForTesting(
197 const std::string& id,
198 const PendingExtensionInfo& pending_extension_info) {
199 pending_extension_map_[id] = pending_extension_info;
200}