blob: 0a0b51973151afb1990511640ddf515df1522a66 [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]e601e822011-10-05 19:25:3716#include "base/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]8aa50c7752013-05-23 12:57:5022#include "chrome/browser/extensions/external_component_loader.h"
[email protected]5df038b2012-07-16 19:03:2723#include "chrome/browser/extensions/external_policy_loader.h"
24#include "chrome/browser/extensions/external_pref_loader.h"
25#include "chrome/browser/extensions/external_provider_interface.h"
[email protected]8e4560b62011-01-14 10:09:1426#include "chrome/browser/profiles/profile.h"
[email protected]f0841cd2011-01-19 15:07:2427#include "chrome/common/chrome_paths.h"
[email protected]83b59325a2011-10-14 15:58:0728#include "chrome/common/chrome_switches.h"
[email protected]1d5e58b2013-01-31 08:41:4029#include "chrome/common/extensions/extension.h"
30#include "chrome/common/extensions/manifest.h"
[email protected]83b59325a2011-10-14 15:58:0731#include "chrome/common/pref_names.h"
[email protected]c38831a12011-10-28 12:44:4932#include "content/public/browser/browser_thread.h"
[email protected]9d32ded072011-10-11 16:31:0533#include "ui/base/l10n/l10n_util.h"
[email protected]8e4560b62011-01-14 10:09:1434
[email protected]7da12212013-02-14 10:53:4935#if defined(ENABLE_MANAGED_USERS)
36#include "chrome/browser/managed_mode/managed_user_service.h"
37#include "chrome/browser/managed_mode/managed_user_service_factory.h"
38#endif
39
[email protected]944dfa82012-03-20 02:07:5140#if defined(OS_CHROMEOS)
41#include "chrome/browser/chromeos/login/user_manager.h"
[email protected]b39d25712013-03-14 09:53:4042#include "chrome/browser/chromeos/policy/app_pack_updater.h"
[email protected]944dfa82012-03-20 02:07:5143#include "chrome/browser/policy/browser_policy_connector.h"
[email protected]b39d25712013-03-14 09:53:4044#else
[email protected]86c6b9e32011-10-25 17:09:1045#include "chrome/browser/extensions/default_apps.h"
46#endif
47
[email protected]8e4560b62011-01-14 10:09:1448#if defined(OS_WIN)
[email protected]5df038b2012-07-16 19:03:2749#include "chrome/browser/extensions/external_registry_loader_win.h"
[email protected]8e4560b62011-01-14 10:09:1450#endif
51
[email protected]631bb742011-11-02 11:29:3952using content::BrowserThread;
[email protected]5df038b2012-07-16 19:03:2753
54namespace extensions {
[email protected]631bb742011-11-02 11:29:3955
[email protected]8e4560b62011-01-14 10:09:1456// Constants for keeping track of extension preferences in a dictionary.
[email protected]5df038b2012-07-16 19:03:2757const char ExternalProviderImpl::kExternalCrx[] = "external_crx";
[email protected]7425d7df2012-11-28 14:35:4258const char ExternalProviderImpl::kExternalVersion[] = "external_version";
59const char ExternalProviderImpl::kExternalUpdateUrl[] = "external_update_url";
60const char ExternalProviderImpl::kSupportedLocales[] = "supported_locales";
61const char ExternalProviderImpl::kIsBookmarkApp[] = "is_bookmark_app";
62const char ExternalProviderImpl::kIsFromWebstore[] = "is_from_webstore";
[email protected]8e4560b62011-01-14 10:09:1463
[email protected]5df038b2012-07-16 19:03:2764ExternalProviderImpl::ExternalProviderImpl(
[email protected]8e4560b62011-01-14 10:09:1465 VisitorInterface* service,
[email protected]5df038b2012-07-16 19:03:2766 ExternalLoader* loader,
[email protected]1d5e58b2013-01-31 08:41:4067 Manifest::Location crx_location,
68 Manifest::Location download_location,
[email protected]1bf73cc2011-10-26 22:38:3169 int creation_flags)
[email protected]8e4560b62011-01-14 10:09:1470 : crx_location_(crx_location),
71 download_location_(download_location),
72 service_(service),
73 prefs_(NULL),
74 ready_(false),
[email protected]1bf73cc2011-10-26 22:38:3175 loader_(loader),
[email protected]47fc70c2011-12-06 07:29:5176 creation_flags_(creation_flags),
77 auto_acknowledge_(false) {
[email protected]8e4560b62011-01-14 10:09:1478 loader_->Init(this);
79}
80
[email protected]5df038b2012-07-16 19:03:2781ExternalProviderImpl::~ExternalProviderImpl() {
[email protected]8e4560b62011-01-14 10:09:1482 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
83 loader_->OwnerShutdown();
84}
85
[email protected]5df038b2012-07-16 19:03:2786void ExternalProviderImpl::VisitRegisteredExtension() {
[email protected]8e4560b62011-01-14 10:09:1487 // The loader will call back to SetPrefs.
88 loader_->StartLoading();
89}
90
[email protected]5df038b2012-07-16 19:03:2791void ExternalProviderImpl::SetPrefs(DictionaryValue* prefs) {
[email protected]8e4560b62011-01-14 10:09:1492 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
93
[email protected]47fc70c2011-12-06 07:29:5194 // Check if the service is still alive. It is possible that it went
[email protected]8e4560b62011-01-14 10:09:1495 // away while |loader_| was working on the FILE thread.
96 if (!service_) return;
97
98 prefs_.reset(prefs);
[email protected]8a839a02013-03-07 05:23:3399 ready_ = true; // Queries for extensions are allowed from this point.
[email protected]8e4560b62011-01-14 10:09:14100
[email protected]9d32ded072011-10-11 16:31:05101 // Set of unsupported extensions that need to be deleted from prefs_.
102 std::set<std::string> unsupported_extensions;
103
[email protected]8e4560b62011-01-14 10:09:14104 // Notify ExtensionService about all the extensions this provider has.
[email protected]02d9b272013-03-06 12:54:56105 for (DictionaryValue::Iterator i(*prefs_); !i.IsAtEnd(); i.Advance()) {
106 const std::string& extension_id = i.key();
107 const DictionaryValue* extension = NULL;
[email protected]ab22ba42011-01-14 16:36:38108
109 if (!Extension::IdIsValid(extension_id)) {
110 LOG(WARNING) << "Malformed extension dictionary: key "
111 << extension_id.c_str() << " is not a valid id.";
[email protected]8e4560b62011-01-14 10:09:14112 continue;
[email protected]ab22ba42011-01-14 16:36:38113 }
114
[email protected]02d9b272013-03-06 12:54:56115 if (!i.value().GetAsDictionary(&extension)) {
[email protected]ab22ba42011-01-14 16:36:38116 LOG(WARNING) << "Malformed extension dictionary: key "
117 << extension_id.c_str()
118 << " has a value that is not a dictionary.";
119 continue;
120 }
[email protected]8e4560b62011-01-14 10:09:14121
[email protected]650b2d52013-02-10 03:41:45122 base::FilePath::StringType external_crx;
[email protected]02d9b272013-03-06 12:54:56123 const Value* external_version_value = NULL;
[email protected]8e4560b62011-01-14 10:09:14124 std::string external_version;
125 std::string external_update_url;
126
127 bool has_external_crx = extension->GetString(kExternalCrx, &external_crx);
[email protected]0d461c52012-07-03 19:29:41128
129 bool has_external_version = false;
130 if (extension->Get(kExternalVersion, &external_version_value)) {
131 if (external_version_value->IsType(Value::TYPE_STRING)) {
132 external_version_value->GetAsString(&external_version);
133 has_external_version = true;
134 } else {
135 LOG(WARNING) << "Malformed extension dictionary for extension: "
136 << extension_id.c_str() << ". " << kExternalVersion
137 << " value must be a string.";
138 continue;
139 }
140 }
141
[email protected]8e4560b62011-01-14 10:09:14142 bool has_external_update_url = extension->GetString(kExternalUpdateUrl,
143 &external_update_url);
144 if (has_external_crx != has_external_version) {
145 LOG(WARNING) << "Malformed extension dictionary for extension: "
146 << extension_id.c_str() << ". " << kExternalCrx
147 << " and " << kExternalVersion << " must be used together.";
148 continue;
149 }
150
151 if (has_external_crx == has_external_update_url) {
152 LOG(WARNING) << "Malformed extension dictionary for extension: "
153 << extension_id.c_str() << ". Exactly one of the "
154 << "followng keys should be used: " << kExternalCrx
155 << ", " << kExternalUpdateUrl << ".";
156 continue;
157 }
158
[email protected]9d32ded072011-10-11 16:31:05159 // Check that extension supports current browser locale.
[email protected]02d9b272013-03-06 12:54:56160 const ListValue* supported_locales = NULL;
[email protected]9d32ded072011-10-11 16:31:05161 if (extension->GetList(kSupportedLocales, &supported_locales)) {
162 std::vector<std::string> browser_locales;
163 l10n_util::GetParentLocales(g_browser_process->GetApplicationLocale(),
164 &browser_locales);
165
166 size_t num_locales = supported_locales->GetSize();
167 bool locale_supported = false;
168 for (size_t j = 0; j < num_locales; j++) {
169 std::string current_locale;
170 if (supported_locales->GetString(j, &current_locale) &&
171 l10n_util::IsValidLocaleSyntax(current_locale)) {
172 current_locale = l10n_util::NormalizeLocale(current_locale);
173 if (std::find(browser_locales.begin(), browser_locales.end(),
174 current_locale) != browser_locales.end()) {
175 locale_supported = true;
176 break;
177 }
178 } else {
179 LOG(WARNING) << "Unrecognized locale '" << current_locale
180 << "' found as supported locale for extension: "
181 << extension_id;
182 }
183 }
184
185 if (!locale_supported) {
186 unsupported_extensions.insert(extension_id);
187 LOG(INFO) << "Skip installing (or uninstall) external extension: "
188 << extension_id << " because the extension doesn't support "
189 << "the browser locale.";
190 continue;
191 }
192 }
193
[email protected]f121003b2012-05-04 21:57:47194 int creation_flags = creation_flags_;
195 bool is_bookmark_app;
196 if (extension->GetBoolean(kIsBookmarkApp, &is_bookmark_app) &&
197 is_bookmark_app) {
198 creation_flags |= Extension::FROM_BOOKMARK;
199 }
[email protected]7425d7df2012-11-28 14:35:42200 bool is_from_webstore;
201 if (extension->GetBoolean(kIsFromWebstore, &is_from_webstore) &&
202 is_from_webstore) {
203 creation_flags |= Extension::FROM_WEBSTORE;
204 }
[email protected]f121003b2012-05-04 21:57:47205
[email protected]8e4560b62011-01-14 10:09:14206 if (has_external_crx) {
[email protected]1d5e58b2013-01-31 08:41:40207 if (crx_location_ == Manifest::INVALID_LOCATION) {
[email protected]8e4560b62011-01-14 10:09:14208 LOG(WARNING) << "This provider does not support installing external "
209 << "extensions from crx files.";
210 continue;
211 }
[email protected]650b2d52013-02-10 03:41:45212 if (external_crx.find(base::FilePath::kParentDirectory) !=
[email protected]8e4560b62011-01-14 10:09:14213 base::StringPiece::npos) {
214 LOG(WARNING) << "Path traversal not allowed in path: "
215 << external_crx.c_str();
216 continue;
217 }
218
[email protected]f0841cd2011-01-19 15:07:24219 // If the path is relative, and the provider has a base path,
220 // build the absolute path to the crx file.
[email protected]650b2d52013-02-10 03:41:45221 base::FilePath path(external_crx);
[email protected]8e4560b62011-01-14 10:09:14222 if (!path.IsAbsolute()) {
[email protected]650b2d52013-02-10 03:41:45223 base::FilePath base_path = loader_->GetBaseCrxFilePath();
[email protected]f0841cd2011-01-19 15:07:24224 if (base_path.empty()) {
225 LOG(WARNING) << "File path " << external_crx.c_str()
226 << " is relative. An absolute path is required.";
227 continue;
228 }
[email protected]8e4560b62011-01-14 10:09:14229 path = base_path.Append(external_crx);
230 }
231
[email protected]12126d372012-07-11 18:40:53232 Version version(external_version);
233 if (!version.IsValid()) {
[email protected]8e4560b62011-01-14 10:09:14234 LOG(WARNING) << "Malformed extension dictionary for extension: "
235 << extension_id.c_str() << ". Invalid version string \""
236 << external_version << "\".";
237 continue;
238 }
[email protected]12126d372012-07-11 18:40:53239 service_->OnExternalExtensionFileFound(extension_id, &version, path,
[email protected]f121003b2012-05-04 21:57:47240 crx_location_, creation_flags,
[email protected]47fc70c2011-12-06 07:29:51241 auto_acknowledge_);
[email protected]8a839a02013-03-07 05:23:33242 } else { // if (has_external_update_url)
[email protected]8e4560b62011-01-14 10:09:14243 CHECK(has_external_update_url); // Checking of keys above ensures this.
[email protected]1d5e58b2013-01-31 08:41:40244 if (download_location_ == Manifest::INVALID_LOCATION) {
[email protected]8e4560b62011-01-14 10:09:14245 LOG(WARNING) << "This provider does not support installing external "
246 << "extensions from update URLs.";
247 continue;
248 }
249 GURL update_url(external_update_url);
250 if (!update_url.is_valid()) {
251 LOG(WARNING) << "Malformed extension dictionary for extension: "
[email protected]ab22ba42011-01-14 16:36:38252 << extension_id.c_str() << ". Key " << kExternalUpdateUrl
253 << " has value \"" << external_update_url
254 << "\", which is not a valid URL.";
[email protected]8e4560b62011-01-14 10:09:14255 continue;
256 }
257 service_->OnExternalExtensionUpdateUrlFound(
258 extension_id, update_url, download_location_);
259 }
260 }
261
[email protected]9d32ded072011-10-11 16:31:05262 for (std::set<std::string>::iterator it = unsupported_extensions.begin();
263 it != unsupported_extensions.end(); ++it) {
264 // Remove extension for the list of know external extensions. The extension
265 // will be uninstalled later because provider doesn't provide it anymore.
266 prefs_->Remove(*it, NULL);
267 }
268
[email protected]50067e52011-10-20 23:17:07269 service_->OnExternalProviderReady(this);
[email protected]8e4560b62011-01-14 10:09:14270}
271
[email protected]5df038b2012-07-16 19:03:27272void ExternalProviderImpl::ServiceShutdown() {
[email protected]8e4560b62011-01-14 10:09:14273 service_ = NULL;
274}
275
[email protected]5df038b2012-07-16 19:03:27276bool ExternalProviderImpl::IsReady() const {
[email protected]8e4560b62011-01-14 10:09:14277 return ready_;
278}
279
[email protected]5df038b2012-07-16 19:03:27280bool ExternalProviderImpl::HasExtension(
[email protected]8e4560b62011-01-14 10:09:14281 const std::string& id) const {
282 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
283 CHECK(prefs_.get());
284 CHECK(ready_);
285 return prefs_->HasKey(id);
286}
287
[email protected]5df038b2012-07-16 19:03:27288bool ExternalProviderImpl::GetExtensionDetails(
[email protected]1d5e58b2013-01-31 08:41:40289 const std::string& id, Manifest::Location* location,
[email protected]8e4560b62011-01-14 10:09:14290 scoped_ptr<Version>* version) const {
291 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
292 CHECK(prefs_.get());
293 CHECK(ready_);
294 DictionaryValue* extension = NULL;
295 if (!prefs_->GetDictionary(id, &extension))
296 return false;
297
[email protected]1d5e58b2013-01-31 08:41:40298 Manifest::Location loc = Manifest::INVALID_LOCATION;
[email protected]8e4560b62011-01-14 10:09:14299 if (extension->HasKey(kExternalUpdateUrl)) {
300 loc = download_location_;
301
302 } else if (extension->HasKey(kExternalCrx)) {
303 loc = crx_location_;
304
305 std::string external_version;
306 if (!extension->GetString(kExternalVersion, &external_version))
307 return false;
308
309 if (version)
[email protected]12126d372012-07-11 18:40:53310 version->reset(new Version(external_version));
[email protected]8e4560b62011-01-14 10:09:14311
312 } else {
313 NOTREACHED(); // Chrome should not allow prefs to get into this state.
314 return false;
315 }
316
317 if (location)
318 *location = loc;
319
320 return true;
321}
322
323// static
[email protected]5df038b2012-07-16 19:03:27324void ExternalProviderImpl::CreateExternalProviders(
[email protected]8e4560b62011-01-14 10:09:14325 VisitorInterface* service,
326 Profile* profile,
327 ProviderCollection* provider_list) {
[email protected]b9f4fe52012-11-09 21:40:59328 // Policies are mandatory so they can't be skipped with command line flag.
329 provider_list->push_back(
330 linked_ptr<ExternalProviderInterface>(
331 new ExternalProviderImpl(
332 service,
333 new ExternalPolicyLoader(profile),
[email protected]1d5e58b2013-01-31 08:41:40334 Manifest::INVALID_LOCATION,
335 Manifest::EXTERNAL_POLICY_DOWNLOAD,
[email protected]b9f4fe52012-11-09 21:40:59336 Extension::NO_FLAGS)));
337
338 // In tests don't install extensions from default external sources.
339 // It would only slowdown tests and make them flaky.
340 if (CommandLine::ForCurrentProcess()->HasSwitch(
341 switches::kDisableDefaultApps))
342 return;
[email protected]73e4c362011-09-22 14:47:18343
[email protected]8a839a02013-03-07 05:23:33344 // No external app install in app mode.
345 if (chrome::IsRunningInForcedAppMode())
346 return;
347
[email protected]73e4c362011-09-22 14:47:18348 // On Mac OS, items in /Library/... should be written by the superuser.
349 // Check that all components of the path are writable by root only.
[email protected]5df038b2012-07-16 19:03:27350 ExternalPrefLoader::Options check_admin_permissions_on_mac;
[email protected]73e4c362011-09-22 14:47:18351#if defined(OS_MACOSX)
[email protected]0edc55412011-11-07 16:47:33352 check_admin_permissions_on_mac =
[email protected]5df038b2012-07-16 19:03:27353 ExternalPrefLoader::ENSURE_PATH_CONTROLLED_BY_ADMIN;
[email protected]73e4c362011-09-22 14:47:18354#else
[email protected]5df038b2012-07-16 19:03:27355 check_admin_permissions_on_mac = ExternalPrefLoader::NONE;
[email protected]73e4c362011-09-22 14:47:18356#endif
357
[email protected]d6f7b102012-05-04 13:59:05358 bool is_chromeos_demo_session = false;
359 int bundled_extension_creation_flags = Extension::NO_FLAGS;
[email protected]03d3ba012012-04-02 22:36:13360#if defined(OS_CHROMEOS)
[email protected]d6f7b102012-05-04 13:59:05361 chromeos::UserManager* user_manager = chromeos::UserManager::Get();
362 is_chromeos_demo_session =
363 user_manager && user_manager->IsLoggedInAsDemoUser() &&
364 g_browser_process->browser_policy_connector()->GetDeviceMode() ==
365 policy::DEVICE_MODE_KIOSK;
[email protected]5861bcd2012-10-16 21:40:19366 bundled_extension_creation_flags = Extension::FROM_WEBSTORE |
367 Extension::WAS_INSTALLED_BY_DEFAULT;
[email protected]03d3ba012012-04-02 22:36:13368#endif
[email protected]bbe95652012-05-01 20:29:58369
[email protected]7da12212013-02-14 10:53:49370 bool is_managed_profile = false;
371 int external_apps_path_id = chrome::DIR_EXTERNAL_EXTENSIONS;
372#if defined(ENABLE_MANAGED_USERS)
373 ManagedUserService* managed_user_service =
374 ManagedUserServiceFactory::GetForProfile(profile);
375 is_managed_profile = managed_user_service->ProfileIsManaged();
376 if (is_managed_profile)
377 external_apps_path_id = chrome::DIR_MANAGED_USERS_DEFAULT_APPS;
378#endif
379
[email protected]d6f7b102012-05-04 13:59:05380 if (!is_chromeos_demo_session) {
381 provider_list->push_back(
[email protected]5df038b2012-07-16 19:03:27382 linked_ptr<ExternalProviderInterface>(
383 new ExternalProviderImpl(
[email protected]d6f7b102012-05-04 13:59:05384 service,
[email protected]7da12212013-02-14 10:53:49385 new ExternalPrefLoader(external_apps_path_id,
[email protected]5df038b2012-07-16 19:03:27386 check_admin_permissions_on_mac),
[email protected]1d5e58b2013-01-31 08:41:40387 Manifest::EXTERNAL_PREF,
388 Manifest::EXTERNAL_PREF_DOWNLOAD,
[email protected]d6f7b102012-05-04 13:59:05389 bundled_extension_creation_flags)));
390 }
391
[email protected]7da12212013-02-14 10:53:49392 if (!is_managed_profile) {
[email protected]bbe95652012-05-01 20:29:58393#if defined(OS_CHROMEOS) || defined (OS_MACOSX)
[email protected]7da12212013-02-14 10:53:49394 // Define a per-user source of external extensions.
395 // On Chrome OS, this serves as a source for OEM customization.
396 provider_list->push_back(
397 linked_ptr<ExternalProviderInterface>(
398 new ExternalProviderImpl(
399 service,
400 new ExternalPrefLoader(chrome::DIR_USER_EXTERNAL_EXTENSIONS,
401 ExternalPrefLoader::NONE),
402 Manifest::EXTERNAL_PREF,
403 Manifest::EXTERNAL_PREF_DOWNLOAD,
404 Extension::NO_FLAGS)));
[email protected]a29a517a2011-01-21 21:11:12405#endif
[email protected]7da12212013-02-14 10:53:49406
[email protected]8e4560b62011-01-14 10:09:14407#if defined(OS_WIN)
[email protected]7da12212013-02-14 10:53:49408 provider_list->push_back(
409 linked_ptr<ExternalProviderInterface>(
410 new ExternalProviderImpl(
411 service,
412 new ExternalRegistryLoader,
413 Manifest::EXTERNAL_REGISTRY,
414 Manifest::INVALID_LOCATION,
415 Extension::NO_FLAGS)));
[email protected]8e4560b62011-01-14 10:09:14416#endif
[email protected]ed7bbb52012-05-02 11:07:29417
[email protected]91dbd8802012-09-14 16:11:01418#if defined(OS_LINUX)
[email protected]7da12212013-02-14 10:53:49419 provider_list->push_back(
420 linked_ptr<ExternalProviderInterface>(
421 new ExternalProviderImpl(
422 service,
423 new ExternalPrefLoader(
424 chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS,
425 ExternalPrefLoader::NONE),
426 Manifest::EXTERNAL_PREF,
427 Manifest::EXTERNAL_PREF_DOWNLOAD,
428 bundled_extension_creation_flags)));
[email protected]ed7bbb52012-05-02 11:07:29429#endif
430
[email protected]98b4aca62011-09-28 01:27:23431#if !defined(OS_CHROMEOS)
[email protected]7da12212013-02-14 10:53:49432 // The default apps are installed as INTERNAL but use the external
433 // extension installer codeflow.
434 provider_list->push_back(
435 linked_ptr<ExternalProviderInterface>(
436 new default_apps::Provider(
437 profile,
438 service,
439 new ExternalPrefLoader(chrome::DIR_DEFAULT_APPS,
440 ExternalPrefLoader::NONE),
441 Manifest::INTERNAL,
442 Manifest::INVALID_LOCATION,
443 Extension::FROM_WEBSTORE |
444 Extension::WAS_INSTALLED_BY_DEFAULT)));
[email protected]98b4aca62011-09-28 01:27:23445#endif
[email protected]944dfa82012-03-20 02:07:51446
447#if defined(OS_CHROMEOS)
[email protected]0b0927d2013-05-21 22:39:42448 policy::AppPackUpdater* app_pack_updater =
449 g_browser_process->browser_policy_connector()->GetAppPackUpdater();
450 if (is_chromeos_demo_session && app_pack_updater &&
451 !app_pack_updater->created_external_loader()) {
[email protected]7da12212013-02-14 10:53:49452 provider_list->push_back(
453 linked_ptr<ExternalProviderInterface>(
454 new ExternalProviderImpl(
455 service,
[email protected]0b0927d2013-05-21 22:39:42456 app_pack_updater->CreateExternalLoader(),
[email protected]7da12212013-02-14 10:53:49457 Manifest::EXTERNAL_PREF,
458 Manifest::INVALID_LOCATION,
459 Extension::NO_FLAGS)));
460 }
[email protected]944dfa82012-03-20 02:07:51461#endif
[email protected]7da12212013-02-14 10:53:49462 }
[email protected]8aa50c7752013-05-23 12:57:50463
464 provider_list->push_back(
465 linked_ptr<ExternalProviderInterface>(
466 new ExternalProviderImpl(
467 service,
468 new ExternalComponentLoader(),
469 Manifest::INVALID_LOCATION,
470 Manifest::EXTERNAL_POLICY_DOWNLOAD,
471 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT)));
[email protected]8e4560b62011-01-14 10:09:14472}
[email protected]5df038b2012-07-16 19:03:27473
474} // namespace extensions