blob: 677f44719c6c6db71aa17d040fd36b29fecdfe6d [file] [log] [blame]
[email protected]a12ce8b22012-01-17 18:40:531// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]8e4560b62011-01-14 10:09:142// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]5df038b2012-07-16 19:03:275#include "chrome/browser/extensions/external_provider_impl.h"
[email protected]8e4560b62011-01-14 10:09:146
[email protected]8a839a02013-03-07 05:23:337#include <set>
8#include <vector>
9
[email protected]83b59325a2011-10-14 15:58:0710#include "base/command_line.h"
[email protected]57999812013-02-24 05:40:5211#include "base/files/file_path.h"
[email protected]8e4560b62011-01-14 10:09:1412#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1513#include "base/memory/linked_ptr.h"
[email protected]51a7a9d2011-09-27 17:21:4114#include "base/metrics/field_trial.h"
[email protected]8e4560b62011-01-14 10:09:1415#include "base/path_service.h"
[email protected]46acbf12013-06-10 18:43:4216#include "base/strings/string_util.h"
[email protected]8e4560b62011-01-14 10:09:1417#include "base/values.h"
18#include "base/version.h"
[email protected]8a839a02013-03-07 05:23:3319#include "chrome/browser/app_mode/app_mode_utils.h"
[email protected]e601e822011-10-05 19:25:3720#include "chrome/browser/browser_process.h"
[email protected]51a7a9d2011-09-27 17:21:4121#include "chrome/browser/extensions/extension_service.h"
[email protected]19eac6d2013-05-30 06:51:0322#include "chrome/browser/extensions/extension_system.h"
[email protected]8aa50c7752013-05-23 12:57:5023#include "chrome/browser/extensions/external_component_loader.h"
[email protected]5df038b2012-07-16 19:03:2724#include "chrome/browser/extensions/external_policy_loader.h"
25#include "chrome/browser/extensions/external_pref_loader.h"
26#include "chrome/browser/extensions/external_provider_interface.h"
[email protected]8e4560b62011-01-14 10:09:1427#include "chrome/browser/profiles/profile.h"
[email protected]f0841cd2011-01-19 15:07:2428#include "chrome/common/chrome_paths.h"
[email protected]83b59325a2011-10-14 15:58:0729#include "chrome/common/chrome_switches.h"
[email protected]1d5e58b2013-01-31 08:41:4030#include "chrome/common/extensions/extension.h"
31#include "chrome/common/extensions/manifest.h"
[email protected]83b59325a2011-10-14 15:58:0732#include "chrome/common/pref_names.h"
[email protected]c38831a12011-10-28 12:44:4933#include "content/public/browser/browser_thread.h"
[email protected]9d32ded072011-10-11 16:31:0534#include "ui/base/l10n/l10n_util.h"
[email protected]8e4560b62011-01-14 10:09:1435
[email protected]7da12212013-02-14 10:53:4936#if defined(ENABLE_MANAGED_USERS)
37#include "chrome/browser/managed_mode/managed_user_service.h"
38#include "chrome/browser/managed_mode/managed_user_service_factory.h"
39#endif
40
[email protected]944dfa82012-03-20 02:07:5141#if defined(OS_CHROMEOS)
[email protected]a4567732013-07-25 21:01:2042#include "chrome/browser/chromeos/extensions/external_pref_cache_loader.h"
[email protected]944dfa82012-03-20 02:07:5143#include "chrome/browser/chromeos/login/user_manager.h"
[email protected]b39d25712013-03-14 09:53:4044#include "chrome/browser/chromeos/policy/app_pack_updater.h"
[email protected]944dfa82012-03-20 02:07:5145#include "chrome/browser/policy/browser_policy_connector.h"
[email protected]b39d25712013-03-14 09:53:4046#else
[email protected]86c6b9e32011-10-25 17:09:1047#include "chrome/browser/extensions/default_apps.h"
48#endif
49
[email protected]8e4560b62011-01-14 10:09:1450#if defined(OS_WIN)
[email protected]5df038b2012-07-16 19:03:2751#include "chrome/browser/extensions/external_registry_loader_win.h"
[email protected]8e4560b62011-01-14 10:09:1452#endif
53
[email protected]631bb742011-11-02 11:29:3954using content::BrowserThread;
[email protected]5df038b2012-07-16 19:03:2755
56namespace extensions {
[email protected]631bb742011-11-02 11:29:3957
[email protected]8e4560b62011-01-14 10:09:1458// Constants for keeping track of extension preferences in a dictionary.
[email protected]5df038b2012-07-16 19:03:2759const char ExternalProviderImpl::kExternalCrx[] = "external_crx";
[email protected]7425d7df2012-11-28 14:35:4260const char ExternalProviderImpl::kExternalVersion[] = "external_version";
61const char ExternalProviderImpl::kExternalUpdateUrl[] = "external_update_url";
62const char ExternalProviderImpl::kSupportedLocales[] = "supported_locales";
63const char ExternalProviderImpl::kIsBookmarkApp[] = "is_bookmark_app";
64const char ExternalProviderImpl::kIsFromWebstore[] = "is_from_webstore";
[email protected]19eac6d2013-05-30 06:51:0365const char ExternalProviderImpl::kKeepIfPresent[] = "keep_if_present";
[email protected]8e4560b62011-01-14 10:09:1466
[email protected]4b4c0132013-06-12 17:58:5567ExternalProviderImpl::ExternalProviderImpl(VisitorInterface* service,
68 ExternalLoader* loader,
69 Profile* profile,
70 Manifest::Location crx_location,
71 Manifest::Location download_location,
72 int creation_flags)
73 : crx_location_(crx_location),
74 download_location_(download_location),
75 service_(service),
76 ready_(false),
77 loader_(loader),
78 profile_(profile),
79 creation_flags_(creation_flags),
80 auto_acknowledge_(false) {
[email protected]8e4560b62011-01-14 10:09:1481 loader_->Init(this);
82}
83
[email protected]5df038b2012-07-16 19:03:2784ExternalProviderImpl::~ExternalProviderImpl() {
[email protected]8e4560b62011-01-14 10:09:1485 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
86 loader_->OwnerShutdown();
87}
88
[email protected]5df038b2012-07-16 19:03:2789void ExternalProviderImpl::VisitRegisteredExtension() {
[email protected]8e4560b62011-01-14 10:09:1490 // The loader will call back to SetPrefs.
91 loader_->StartLoading();
92}
93
[email protected]aeca23f2013-06-21 22:34:4194void ExternalProviderImpl::SetPrefs(base::DictionaryValue* prefs) {
[email protected]8e4560b62011-01-14 10:09:1495 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
96
[email protected]47fc70c2011-12-06 07:29:5197 // Check if the service is still alive. It is possible that it went
[email protected]8e4560b62011-01-14 10:09:1498 // away while |loader_| was working on the FILE thread.
99 if (!service_) return;
100
101 prefs_.reset(prefs);
[email protected]8a839a02013-03-07 05:23:33102 ready_ = true; // Queries for extensions are allowed from this point.
[email protected]8e4560b62011-01-14 10:09:14103
[email protected]9d32ded072011-10-11 16:31:05104 // Set of unsupported extensions that need to be deleted from prefs_.
105 std::set<std::string> unsupported_extensions;
106
[email protected]8e4560b62011-01-14 10:09:14107 // Notify ExtensionService about all the extensions this provider has.
[email protected]aeca23f2013-06-21 22:34:41108 for (base::DictionaryValue::Iterator i(*prefs_); !i.IsAtEnd(); i.Advance()) {
[email protected]02d9b272013-03-06 12:54:56109 const std::string& extension_id = i.key();
[email protected]aeca23f2013-06-21 22:34:41110 const base::DictionaryValue* extension = NULL;
[email protected]ab22ba42011-01-14 16:36:38111
112 if (!Extension::IdIsValid(extension_id)) {
113 LOG(WARNING) << "Malformed extension dictionary: key "
114 << extension_id.c_str() << " is not a valid id.";
[email protected]8e4560b62011-01-14 10:09:14115 continue;
[email protected]ab22ba42011-01-14 16:36:38116 }
117
[email protected]02d9b272013-03-06 12:54:56118 if (!i.value().GetAsDictionary(&extension)) {
[email protected]ab22ba42011-01-14 16:36:38119 LOG(WARNING) << "Malformed extension dictionary: key "
120 << extension_id.c_str()
121 << " has a value that is not a dictionary.";
122 continue;
123 }
[email protected]8e4560b62011-01-14 10:09:14124
[email protected]650b2d52013-02-10 03:41:45125 base::FilePath::StringType external_crx;
[email protected]02d9b272013-03-06 12:54:56126 const Value* external_version_value = NULL;
[email protected]8e4560b62011-01-14 10:09:14127 std::string external_version;
128 std::string external_update_url;
129
130 bool has_external_crx = extension->GetString(kExternalCrx, &external_crx);
[email protected]0d461c52012-07-03 19:29:41131
132 bool has_external_version = false;
133 if (extension->Get(kExternalVersion, &external_version_value)) {
134 if (external_version_value->IsType(Value::TYPE_STRING)) {
135 external_version_value->GetAsString(&external_version);
136 has_external_version = true;
137 } else {
138 LOG(WARNING) << "Malformed extension dictionary for extension: "
139 << extension_id.c_str() << ". " << kExternalVersion
140 << " value must be a string.";
141 continue;
142 }
143 }
144
[email protected]8e4560b62011-01-14 10:09:14145 bool has_external_update_url = extension->GetString(kExternalUpdateUrl,
146 &external_update_url);
147 if (has_external_crx != has_external_version) {
148 LOG(WARNING) << "Malformed extension dictionary for extension: "
149 << extension_id.c_str() << ". " << kExternalCrx
150 << " and " << kExternalVersion << " must be used together.";
151 continue;
152 }
153
154 if (has_external_crx == has_external_update_url) {
155 LOG(WARNING) << "Malformed extension dictionary for extension: "
156 << extension_id.c_str() << ". Exactly one of the "
157 << "followng keys should be used: " << kExternalCrx
158 << ", " << kExternalUpdateUrl << ".";
159 continue;
160 }
161
[email protected]9d32ded072011-10-11 16:31:05162 // Check that extension supports current browser locale.
[email protected]aeca23f2013-06-21 22:34:41163 const base::ListValue* supported_locales = NULL;
[email protected]9d32ded072011-10-11 16:31:05164 if (extension->GetList(kSupportedLocales, &supported_locales)) {
165 std::vector<std::string> browser_locales;
166 l10n_util::GetParentLocales(g_browser_process->GetApplicationLocale(),
167 &browser_locales);
168
169 size_t num_locales = supported_locales->GetSize();
170 bool locale_supported = false;
171 for (size_t j = 0; j < num_locales; j++) {
172 std::string current_locale;
173 if (supported_locales->GetString(j, &current_locale) &&
174 l10n_util::IsValidLocaleSyntax(current_locale)) {
175 current_locale = l10n_util::NormalizeLocale(current_locale);
176 if (std::find(browser_locales.begin(), browser_locales.end(),
177 current_locale) != browser_locales.end()) {
178 locale_supported = true;
179 break;
180 }
181 } else {
182 LOG(WARNING) << "Unrecognized locale '" << current_locale
183 << "' found as supported locale for extension: "
184 << extension_id;
185 }
186 }
187
188 if (!locale_supported) {
189 unsupported_extensions.insert(extension_id);
[email protected]19eac6d2013-05-30 06:51:03190 VLOG(1) << "Skip installing (or uninstall) external extension: "
191 << extension_id << " because the extension doesn't support "
192 << "the browser locale.";
[email protected]9d32ded072011-10-11 16:31:05193 continue;
194 }
195 }
196
[email protected]f121003b2012-05-04 21:57:47197 int creation_flags = creation_flags_;
198 bool is_bookmark_app;
199 if (extension->GetBoolean(kIsBookmarkApp, &is_bookmark_app) &&
200 is_bookmark_app) {
201 creation_flags |= Extension::FROM_BOOKMARK;
202 }
[email protected]7425d7df2012-11-28 14:35:42203 bool is_from_webstore;
204 if (extension->GetBoolean(kIsFromWebstore, &is_from_webstore) &&
205 is_from_webstore) {
206 creation_flags |= Extension::FROM_WEBSTORE;
207 }
[email protected]19eac6d2013-05-30 06:51:03208 bool keep_if_present;
209 if (extension->GetBoolean(kKeepIfPresent, &keep_if_present) &&
210 keep_if_present && profile_) {
211 ExtensionServiceInterface* extension_service =
212 ExtensionSystem::Get(profile_)->extension_service();
213 const Extension* extension = extension_service ?
214 extension_service->GetExtensionById(extension_id, true) : NULL;
215 if (!extension) {
216 VLOG(1) << "Skip installing (or uninstall) external extension: "
217 << extension_id << " because the extension should be kept "
218 << "only if it is already installed.";
219 continue;
220 }
221 }
[email protected]f121003b2012-05-04 21:57:47222
[email protected]8e4560b62011-01-14 10:09:14223 if (has_external_crx) {
[email protected]1d5e58b2013-01-31 08:41:40224 if (crx_location_ == Manifest::INVALID_LOCATION) {
[email protected]8e4560b62011-01-14 10:09:14225 LOG(WARNING) << "This provider does not support installing external "
226 << "extensions from crx files.";
227 continue;
228 }
[email protected]650b2d52013-02-10 03:41:45229 if (external_crx.find(base::FilePath::kParentDirectory) !=
[email protected]8e4560b62011-01-14 10:09:14230 base::StringPiece::npos) {
231 LOG(WARNING) << "Path traversal not allowed in path: "
232 << external_crx.c_str();
233 continue;
234 }
235
[email protected]f0841cd2011-01-19 15:07:24236 // If the path is relative, and the provider has a base path,
237 // build the absolute path to the crx file.
[email protected]650b2d52013-02-10 03:41:45238 base::FilePath path(external_crx);
[email protected]8e4560b62011-01-14 10:09:14239 if (!path.IsAbsolute()) {
[email protected]650b2d52013-02-10 03:41:45240 base::FilePath base_path = loader_->GetBaseCrxFilePath();
[email protected]f0841cd2011-01-19 15:07:24241 if (base_path.empty()) {
242 LOG(WARNING) << "File path " << external_crx.c_str()
243 << " is relative. An absolute path is required.";
244 continue;
245 }
[email protected]8e4560b62011-01-14 10:09:14246 path = base_path.Append(external_crx);
247 }
248
[email protected]12126d372012-07-11 18:40:53249 Version version(external_version);
250 if (!version.IsValid()) {
[email protected]8e4560b62011-01-14 10:09:14251 LOG(WARNING) << "Malformed extension dictionary for extension: "
252 << extension_id.c_str() << ". Invalid version string \""
253 << external_version << "\".";
254 continue;
255 }
[email protected]12126d372012-07-11 18:40:53256 service_->OnExternalExtensionFileFound(extension_id, &version, path,
[email protected]f121003b2012-05-04 21:57:47257 crx_location_, creation_flags,
[email protected]47fc70c2011-12-06 07:29:51258 auto_acknowledge_);
[email protected]8a839a02013-03-07 05:23:33259 } else { // if (has_external_update_url)
[email protected]8e4560b62011-01-14 10:09:14260 CHECK(has_external_update_url); // Checking of keys above ensures this.
[email protected]1d5e58b2013-01-31 08:41:40261 if (download_location_ == Manifest::INVALID_LOCATION) {
[email protected]8e4560b62011-01-14 10:09:14262 LOG(WARNING) << "This provider does not support installing external "
263 << "extensions from update URLs.";
264 continue;
265 }
266 GURL update_url(external_update_url);
267 if (!update_url.is_valid()) {
268 LOG(WARNING) << "Malformed extension dictionary for extension: "
[email protected]ab22ba42011-01-14 16:36:38269 << extension_id.c_str() << ". Key " << kExternalUpdateUrl
270 << " has value \"" << external_update_url
271 << "\", which is not a valid URL.";
[email protected]8e4560b62011-01-14 10:09:14272 continue;
273 }
274 service_->OnExternalExtensionUpdateUrlFound(
275 extension_id, update_url, download_location_);
276 }
277 }
278
[email protected]9d32ded072011-10-11 16:31:05279 for (std::set<std::string>::iterator it = unsupported_extensions.begin();
280 it != unsupported_extensions.end(); ++it) {
281 // Remove extension for the list of know external extensions. The extension
282 // will be uninstalled later because provider doesn't provide it anymore.
283 prefs_->Remove(*it, NULL);
284 }
285
[email protected]50067e52011-10-20 23:17:07286 service_->OnExternalProviderReady(this);
[email protected]8e4560b62011-01-14 10:09:14287}
288
[email protected]5df038b2012-07-16 19:03:27289void ExternalProviderImpl::ServiceShutdown() {
[email protected]8e4560b62011-01-14 10:09:14290 service_ = NULL;
291}
292
[email protected]5df038b2012-07-16 19:03:27293bool ExternalProviderImpl::IsReady() const {
[email protected]8e4560b62011-01-14 10:09:14294 return ready_;
295}
296
[email protected]5df038b2012-07-16 19:03:27297bool ExternalProviderImpl::HasExtension(
[email protected]8e4560b62011-01-14 10:09:14298 const std::string& id) const {
299 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
300 CHECK(prefs_.get());
301 CHECK(ready_);
302 return prefs_->HasKey(id);
303}
304
[email protected]5df038b2012-07-16 19:03:27305bool ExternalProviderImpl::GetExtensionDetails(
[email protected]1d5e58b2013-01-31 08:41:40306 const std::string& id, Manifest::Location* location,
[email protected]8e4560b62011-01-14 10:09:14307 scoped_ptr<Version>* version) const {
308 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
309 CHECK(prefs_.get());
310 CHECK(ready_);
[email protected]aeca23f2013-06-21 22:34:41311 base::DictionaryValue* extension = NULL;
[email protected]8e4560b62011-01-14 10:09:14312 if (!prefs_->GetDictionary(id, &extension))
313 return false;
314
[email protected]1d5e58b2013-01-31 08:41:40315 Manifest::Location loc = Manifest::INVALID_LOCATION;
[email protected]8e4560b62011-01-14 10:09:14316 if (extension->HasKey(kExternalUpdateUrl)) {
317 loc = download_location_;
318
319 } else if (extension->HasKey(kExternalCrx)) {
320 loc = crx_location_;
321
322 std::string external_version;
323 if (!extension->GetString(kExternalVersion, &external_version))
324 return false;
325
326 if (version)
[email protected]12126d372012-07-11 18:40:53327 version->reset(new Version(external_version));
[email protected]8e4560b62011-01-14 10:09:14328
329 } else {
330 NOTREACHED(); // Chrome should not allow prefs to get into this state.
331 return false;
332 }
333
334 if (location)
335 *location = loc;
336
337 return true;
338}
339
340// static
[email protected]5df038b2012-07-16 19:03:27341void ExternalProviderImpl::CreateExternalProviders(
[email protected]8e4560b62011-01-14 10:09:14342 VisitorInterface* service,
343 Profile* profile,
344 ProviderCollection* provider_list) {
[email protected]b9f4fe52012-11-09 21:40:59345 // Policies are mandatory so they can't be skipped with command line flag.
346 provider_list->push_back(
347 linked_ptr<ExternalProviderInterface>(
348 new ExternalProviderImpl(
349 service,
350 new ExternalPolicyLoader(profile),
[email protected]19eac6d2013-05-30 06:51:03351 profile,
[email protected]1d5e58b2013-01-31 08:41:40352 Manifest::INVALID_LOCATION,
353 Manifest::EXTERNAL_POLICY_DOWNLOAD,
[email protected]b9f4fe52012-11-09 21:40:59354 Extension::NO_FLAGS)));
355
356 // In tests don't install extensions from default external sources.
357 // It would only slowdown tests and make them flaky.
358 if (CommandLine::ForCurrentProcess()->HasSwitch(
359 switches::kDisableDefaultApps))
360 return;
[email protected]73e4c362011-09-22 14:47:18361
[email protected]8a839a02013-03-07 05:23:33362 // No external app install in app mode.
363 if (chrome::IsRunningInForcedAppMode())
364 return;
365
[email protected]73e4c362011-09-22 14:47:18366 // On Mac OS, items in /Library/... should be written by the superuser.
367 // Check that all components of the path are writable by root only.
[email protected]5df038b2012-07-16 19:03:27368 ExternalPrefLoader::Options check_admin_permissions_on_mac;
[email protected]73e4c362011-09-22 14:47:18369#if defined(OS_MACOSX)
[email protected]0edc55412011-11-07 16:47:33370 check_admin_permissions_on_mac =
[email protected]5df038b2012-07-16 19:03:27371 ExternalPrefLoader::ENSURE_PATH_CONTROLLED_BY_ADMIN;
[email protected]73e4c362011-09-22 14:47:18372#else
[email protected]5df038b2012-07-16 19:03:27373 check_admin_permissions_on_mac = ExternalPrefLoader::NONE;
[email protected]73e4c362011-09-22 14:47:18374#endif
375
[email protected]d6f7b102012-05-04 13:59:05376 bool is_chromeos_demo_session = false;
377 int bundled_extension_creation_flags = Extension::NO_FLAGS;
[email protected]03d3ba012012-04-02 22:36:13378#if defined(OS_CHROMEOS)
[email protected]d6f7b102012-05-04 13:59:05379 chromeos::UserManager* user_manager = chromeos::UserManager::Get();
380 is_chromeos_demo_session =
381 user_manager && user_manager->IsLoggedInAsDemoUser() &&
382 g_browser_process->browser_policy_connector()->GetDeviceMode() ==
[email protected]cf7a8702013-06-14 22:32:16383 policy::DEVICE_MODE_RETAIL_KIOSK;
[email protected]5861bcd2012-10-16 21:40:19384 bundled_extension_creation_flags = Extension::FROM_WEBSTORE |
385 Extension::WAS_INSTALLED_BY_DEFAULT;
[email protected]03d3ba012012-04-02 22:36:13386#endif
[email protected]bbe95652012-05-01 20:29:58387
[email protected]7da12212013-02-14 10:53:49388 bool is_managed_profile = false;
389 int external_apps_path_id = chrome::DIR_EXTERNAL_EXTENSIONS;
390#if defined(ENABLE_MANAGED_USERS)
391 ManagedUserService* managed_user_service =
392 ManagedUserServiceFactory::GetForProfile(profile);
393 is_managed_profile = managed_user_service->ProfileIsManaged();
394 if (is_managed_profile)
395 external_apps_path_id = chrome::DIR_MANAGED_USERS_DEFAULT_APPS;
396#endif
397
[email protected]a4567732013-07-25 21:01:20398#if defined(OS_CHROMEOS)
399 typedef chromeos::ExternalPrefCacheLoader PrefLoader;
400#else
401 typedef ExternalPrefLoader PrefLoader;
402#endif
403
[email protected]d6f7b102012-05-04 13:59:05404 if (!is_chromeos_demo_session) {
405 provider_list->push_back(
[email protected]5df038b2012-07-16 19:03:27406 linked_ptr<ExternalProviderInterface>(
407 new ExternalProviderImpl(
[email protected]d6f7b102012-05-04 13:59:05408 service,
[email protected]a4567732013-07-25 21:01:20409 new PrefLoader(external_apps_path_id,
410 check_admin_permissions_on_mac),
[email protected]19eac6d2013-05-30 06:51:03411 profile,
[email protected]1d5e58b2013-01-31 08:41:40412 Manifest::EXTERNAL_PREF,
413 Manifest::EXTERNAL_PREF_DOWNLOAD,
[email protected]d6f7b102012-05-04 13:59:05414 bundled_extension_creation_flags)));
415 }
416
[email protected]7da12212013-02-14 10:53:49417 if (!is_managed_profile) {
[email protected]bbe95652012-05-01 20:29:58418#if defined(OS_CHROMEOS) || defined (OS_MACOSX)
[email protected]7da12212013-02-14 10:53:49419 // Define a per-user source of external extensions.
420 // On Chrome OS, this serves as a source for OEM customization.
421 provider_list->push_back(
422 linked_ptr<ExternalProviderInterface>(
423 new ExternalProviderImpl(
424 service,
425 new ExternalPrefLoader(chrome::DIR_USER_EXTERNAL_EXTENSIONS,
426 ExternalPrefLoader::NONE),
[email protected]19eac6d2013-05-30 06:51:03427 profile,
[email protected]7da12212013-02-14 10:53:49428 Manifest::EXTERNAL_PREF,
429 Manifest::EXTERNAL_PREF_DOWNLOAD,
430 Extension::NO_FLAGS)));
[email protected]a29a517a2011-01-21 21:11:12431#endif
[email protected]7da12212013-02-14 10:53:49432
[email protected]8e4560b62011-01-14 10:09:14433#if defined(OS_WIN)
[email protected]7da12212013-02-14 10:53:49434 provider_list->push_back(
435 linked_ptr<ExternalProviderInterface>(
436 new ExternalProviderImpl(
437 service,
438 new ExternalRegistryLoader,
[email protected]19eac6d2013-05-30 06:51:03439 profile,
[email protected]7da12212013-02-14 10:53:49440 Manifest::EXTERNAL_REGISTRY,
441 Manifest::INVALID_LOCATION,
442 Extension::NO_FLAGS)));
[email protected]8e4560b62011-01-14 10:09:14443#endif
[email protected]ed7bbb52012-05-02 11:07:29444
[email protected]91dbd8802012-09-14 16:11:01445#if defined(OS_LINUX)
[email protected]7da12212013-02-14 10:53:49446 provider_list->push_back(
447 linked_ptr<ExternalProviderInterface>(
448 new ExternalProviderImpl(
449 service,
450 new ExternalPrefLoader(
451 chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS,
452 ExternalPrefLoader::NONE),
[email protected]19eac6d2013-05-30 06:51:03453 profile,
[email protected]7da12212013-02-14 10:53:49454 Manifest::EXTERNAL_PREF,
455 Manifest::EXTERNAL_PREF_DOWNLOAD,
456 bundled_extension_creation_flags)));
[email protected]ed7bbb52012-05-02 11:07:29457#endif
458
[email protected]98b4aca62011-09-28 01:27:23459#if !defined(OS_CHROMEOS)
[email protected]7da12212013-02-14 10:53:49460 // The default apps are installed as INTERNAL but use the external
461 // extension installer codeflow.
462 provider_list->push_back(
463 linked_ptr<ExternalProviderInterface>(
464 new default_apps::Provider(
465 profile,
466 service,
467 new ExternalPrefLoader(chrome::DIR_DEFAULT_APPS,
468 ExternalPrefLoader::NONE),
469 Manifest::INTERNAL,
470 Manifest::INVALID_LOCATION,
471 Extension::FROM_WEBSTORE |
472 Extension::WAS_INSTALLED_BY_DEFAULT)));
[email protected]98b4aca62011-09-28 01:27:23473#endif
[email protected]944dfa82012-03-20 02:07:51474
475#if defined(OS_CHROMEOS)
[email protected]0b0927d2013-05-21 22:39:42476 policy::AppPackUpdater* app_pack_updater =
477 g_browser_process->browser_policy_connector()->GetAppPackUpdater();
478 if (is_chromeos_demo_session && app_pack_updater &&
479 !app_pack_updater->created_external_loader()) {
[email protected]7da12212013-02-14 10:53:49480 provider_list->push_back(
481 linked_ptr<ExternalProviderInterface>(
482 new ExternalProviderImpl(
483 service,
[email protected]0b0927d2013-05-21 22:39:42484 app_pack_updater->CreateExternalLoader(),
[email protected]19eac6d2013-05-30 06:51:03485 profile,
[email protected]7da12212013-02-14 10:53:49486 Manifest::EXTERNAL_PREF,
487 Manifest::INVALID_LOCATION,
488 Extension::NO_FLAGS)));
489 }
[email protected]944dfa82012-03-20 02:07:51490#endif
[email protected]7da12212013-02-14 10:53:49491 }
[email protected]8aa50c7752013-05-23 12:57:50492
493 provider_list->push_back(
494 linked_ptr<ExternalProviderInterface>(
495 new ExternalProviderImpl(
496 service,
497 new ExternalComponentLoader(),
[email protected]19eac6d2013-05-30 06:51:03498 profile,
[email protected]8aa50c7752013-05-23 12:57:50499 Manifest::INVALID_LOCATION,
500 Manifest::EXTERNAL_POLICY_DOWNLOAD,
501 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT)));
[email protected]8e4560b62011-01-14 10:09:14502}
[email protected]5df038b2012-07-16 19:03:27503
504} // namespace extensions