blob: c89153226fb52cd0b7f9da8410c47c2942d2a902 [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
avia2f4804a2015-12-24 23:11:137#include <stddef.h>
8
Toni Barzic87026682018-01-08 23:21:049#include <memory>
[email protected]8a839a02013-03-07 05:23:3310#include <set>
Toni Barzic87026682018-01-08 23:21:0411#include <utility>
[email protected]8a839a02013-03-07 05:23:3312#include <vector>
13
[email protected]83b59325a2011-10-14 15:58:0714#include "base/command_line.h"
[email protected]57999812013-02-24 05:40:5215#include "base/files/file_path.h"
[email protected]8e4560b62011-01-14 10:09:1416#include "base/logging.h"
[email protected]51a7a9d2011-09-27 17:21:4117#include "base/metrics/field_trial.h"
chakshu.ac20f38782016-04-06 09:58:0818#include "base/stl_util.h"
[email protected]46acbf12013-06-10 18:43:4219#include "base/strings/string_util.h"
rkaplowdd66a1342015-03-05 00:31:4920#include "base/trace_event/trace_event.h"
[email protected]8e4560b62011-01-14 10:09:1421#include "base/values.h"
22#include "base/version.h"
avia2f4804a2015-12-24 23:11:1323#include "build/build_config.h"
[email protected]8a839a02013-03-07 05:23:3324#include "chrome/browser/app_mode/app_mode_utils.h"
[email protected]e601e822011-10-05 19:25:3725#include "chrome/browser/browser_process.h"
pbond43ddd4f2015-09-08 16:39:1926#include "chrome/browser/browser_process_platform_part.h"
binjin30301062014-09-08 20:27:3427#include "chrome/browser/extensions/extension_management.h"
xiyuan65b68ab12015-06-26 19:00:1828#include "chrome/browser/extensions/extension_migrator.h"
[email protected]51a7a9d2011-09-27 17:21:4129#include "chrome/browser/extensions/extension_service.h"
[email protected]8aa50c7752013-05-23 12:57:5030#include "chrome/browser/extensions/external_component_loader.h"
[email protected]5df038b2012-07-16 19:03:2731#include "chrome/browser/extensions/external_policy_loader.h"
32#include "chrome/browser/extensions/external_pref_loader.h"
Oleg Davydovc00866812019-04-04 10:47:2733#include "chrome/browser/extensions/forced_extensions/installation_reporter.h"
dpolukhin1687ef32015-06-22 11:12:3734#include "chrome/browser/policy/profile_policy_connector.h"
[email protected]8e4560b62011-01-14 10:09:1435#include "chrome/browser/profiles/profile.h"
[email protected]f0841cd2011-01-19 15:07:2436#include "chrome/common/chrome_paths.h"
[email protected]83b59325a2011-10-14 15:58:0737#include "chrome/common/chrome_switches.h"
xiyuan65b68ab12015-06-26 19:00:1838#include "chrome/common/extensions/extension_constants.h"
dpolukhin2c6ef2932015-05-12 16:06:1339#include "chrome/common/pref_names.h"
[email protected]fdd28372014-08-21 02:27:2640#include "components/crx_file/id_util.h"
brettwb1fc1b82016-02-02 00:19:0841#include "components/prefs/pref_service.h"
[email protected]c38831a12011-10-28 12:44:4942#include "content/public/browser/browser_thread.h"
[email protected]59b0e602014-01-30 00:41:2443#include "extensions/browser/extension_system.h"
lazyboye8634172016-01-28 00:10:4844#include "extensions/browser/external_install_info.h"
[email protected]301116c62013-11-26 10:37:4545#include "extensions/browser/external_provider_interface.h"
[email protected]e4452d32013-11-15 23:07:4146#include "extensions/common/extension.h"
[email protected]d42c11152013-08-22 19:36:3247#include "extensions/common/manifest.h"
[email protected]9d32ded072011-10-11 16:31:0548#include "ui/base/l10n/l10n_util.h"
[email protected]8e4560b62011-01-14 10:09:1449
[email protected]944dfa82012-03-20 02:07:5150#if defined(OS_CHROMEOS)
Wenzhao Zang463f1142018-09-05 22:50:5051#include "base/path_service.h"
Toni Barzic87026682018-01-08 23:21:0452#include "chrome/browser/chromeos/app_mode/kiosk_app_external_loader.h"
Satoru Takabayashi876d4e62014-12-03 04:52:2453#include "chrome/browser/chromeos/customization/customization_document.h"
[email protected]af984882013-10-21 21:08:5154#include "chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.h"
Toni Barzicdff51562018-07-24 19:55:4655#include "chrome/browser/chromeos/login/demo_mode/demo_extensions_external_loader.h"
Wenzhao Zang463f1142018-09-05 22:50:5056#include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
[email protected]97275822014-01-21 19:30:3657#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
[email protected]af984882013-10-21 21:08:5158#include "chrome/browser/chromeos/policy/device_local_account.h"
59#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
[email protected]052e3ac2014-06-30 14:22:4760#include "chrome/browser/chromeos/profiles/profile_helper.h"
Steven Bennetts38e9bde22019-01-03 17:31:1061#include "chromeos/constants/chromeos_paths.h"
Ahmed Fakhry9ef29e042017-09-01 16:32:0062#include "components/arc/arc_util.h"
[email protected]b39d25712013-03-14 09:53:4063#else
[email protected]86c6b9e32011-10-25 17:09:1064#include "chrome/browser/extensions/default_apps.h"
65#endif
66
[email protected]8e4560b62011-01-14 10:09:1467#if defined(OS_WIN)
[email protected]5df038b2012-07-16 19:03:2768#include "chrome/browser/extensions/external_registry_loader_win.h"
[email protected]8e4560b62011-01-14 10:09:1469#endif
70
[email protected]631bb742011-11-02 11:29:3971using content::BrowserThread;
[email protected]5df038b2012-07-16 19:03:2772
73namespace extensions {
[email protected]631bb742011-11-02 11:29:3974
Ahmed Fakhry9ef29e042017-09-01 16:32:0075namespace {
76
77#if defined(OS_CHROMEOS)
78
79// Certain default extensions are no longer needed on ARC devices as they were
80// replaced by their ARC counterparts.
81bool ShouldUninstallExtensionReplacedByArcApp(const std::string& extension_id) {
Alex Newcomerf8c542f2018-08-13 23:48:5082 if (!arc::IsArcAvailable())
Ahmed Fakhry9ef29e042017-09-01 16:32:0083 return false;
84
85 if (extension_id == extension_misc::kGooglePlayBooksAppId ||
86 extension_id == extension_misc::kGooglePlayMoviesAppId ||
87 extension_id == extension_misc::kGooglePlayMusicAppId) {
88 return true;
89 }
90
91 return false;
92}
93
94#endif // defined(OS_CHROMEOS)
95
96} // namespace
97
[email protected]8e4560b62011-01-14 10:09:1498// Constants for keeping track of extension preferences in a dictionary.
[email protected]d8fd0fd2014-03-24 13:16:0699const char ExternalProviderImpl::kInstallParam[] = "install_parameter";
[email protected]5df038b2012-07-16 19:03:27100const char ExternalProviderImpl::kExternalCrx[] = "external_crx";
[email protected]7425d7df2012-11-28 14:35:42101const char ExternalProviderImpl::kExternalVersion[] = "external_version";
102const char ExternalProviderImpl::kExternalUpdateUrl[] = "external_update_url";
[email protected]7425d7df2012-11-28 14:35:42103const char ExternalProviderImpl::kIsBookmarkApp[] = "is_bookmark_app";
104const char ExternalProviderImpl::kIsFromWebstore[] = "is_from_webstore";
[email protected]19eac6d2013-05-30 06:51:03105const char ExternalProviderImpl::kKeepIfPresent[] = "keep_if_present";
[email protected]bf9fd5ae2014-04-09 22:50:06106const char ExternalProviderImpl::kWasInstalledByOem[] = "was_installed_by_oem";
107const char ExternalProviderImpl::kSupportedLocales[] = "supported_locales";
[email protected]2b6a5802014-08-16 07:58:08108const char ExternalProviderImpl::kMayBeUntrusted[] = "may_be_untrusted";
dpolukhin2c6ef2932015-05-12 16:06:13109const char ExternalProviderImpl::kMinProfileCreatedByVersion[] =
110 "min_profile_created_by_version";
dpolukhin1687ef32015-06-22 11:12:37111const char ExternalProviderImpl::kDoNotInstallForEnterprise[] =
112 "do_not_install_for_enterprise";
[email protected]8e4560b62011-01-14 10:09:14113
[email protected]af984882013-10-21 21:08:51114ExternalProviderImpl::ExternalProviderImpl(
115 VisitorInterface* service,
116 const scoped_refptr<ExternalLoader>& loader,
117 Profile* profile,
118 Manifest::Location crx_location,
119 Manifest::Location download_location,
120 int creation_flags)
[email protected]4b4c0132013-06-12 17:58:55121 : crx_location_(crx_location),
122 download_location_(download_location),
123 service_(service),
[email protected]4b4c0132013-06-12 17:58:55124 loader_(loader),
125 profile_(profile),
Toni Barzic87026682018-01-08 23:21:04126 creation_flags_(creation_flags) {
[email protected]8e4560b62011-01-14 10:09:14127 loader_->Init(this);
128}
129
[email protected]5df038b2012-07-16 19:03:27130ExternalProviderImpl::~ExternalProviderImpl() {
Istiaque Ahmedf6e72622017-09-08 23:14:17131 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14132 loader_->OwnerShutdown();
133}
134
[email protected]5df038b2012-07-16 19:03:27135void ExternalProviderImpl::VisitRegisteredExtension() {
[email protected]8e4560b62011-01-14 10:09:14136 // The loader will call back to SetPrefs.
137 loader_->StartLoading();
138}
139
Istiaque Ahmeda7431b32017-08-20 18:33:37140void ExternalProviderImpl::SetPrefs(
141 std::unique_ptr<base::DictionaryValue> prefs) {
Istiaque Ahmedf6e72622017-09-08 23:14:17142 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14143
[email protected]47fc70c2011-12-06 07:29:51144 // Check if the service is still alive. It is possible that it went
[email protected]8e4560b62011-01-14 10:09:14145 // away while |loader_| was working on the FILE thread.
146 if (!service_) return;
147
Istiaque Ahmeda7431b32017-08-20 18:33:37148 prefs_ = std::move(prefs);
[email protected]8a839a02013-03-07 05:23:33149 ready_ = true; // Queries for extensions are allowed from this point.
[email protected]8e4560b62011-01-14 10:09:14150
Devlin Cronin19f70b6a2017-10-01 04:14:05151 std::vector<ExternalInstallInfoUpdateUrl> external_update_url_extensions;
152 std::vector<ExternalInstallInfoFile> external_file_extensions;
lazyboye8634172016-01-28 00:10:48153
154 RetrieveExtensionsFromPrefs(&external_update_url_extensions,
155 &external_file_extensions);
lazyboy4aeef202016-09-07 21:28:59156 for (const auto& extension : external_update_url_extensions)
Devlin Cronin19f70b6a2017-10-01 04:14:05157 service_->OnExternalExtensionUpdateUrlFound(extension, true);
lazyboye8634172016-01-28 00:10:48158
lazyboy4aeef202016-09-07 21:28:59159 for (const auto& extension : external_file_extensions)
Devlin Cronin19f70b6a2017-10-01 04:14:05160 service_->OnExternalExtensionFileFound(extension);
lazyboye8634172016-01-28 00:10:48161
162 service_->OnExternalProviderReady(this);
163}
164
Istiaque Ahmeda7431b32017-08-20 18:33:37165void ExternalProviderImpl::UpdatePrefs(
166 std::unique_ptr<base::DictionaryValue> prefs) {
Istiaque Ahmedf6e72622017-09-08 23:14:17167 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Toni Barzic87026682018-01-08 23:21:04168 CHECK(allow_updates_);
lazyboye8634172016-01-28 00:10:48169
170 // Check if the service is still alive. It is possible that it went
171 // away while |loader_| was working on the FILE thread.
172 if (!service_)
173 return;
174
175 std::set<std::string> removed_extensions;
176 // Find extensions that were removed by this ExternalProvider.
177 for (base::DictionaryValue::Iterator i(*prefs_); !i.IsAtEnd(); i.Advance()) {
178 const std::string& extension_id = i.key();
179 // Don't bother about invalid ids.
180 if (!crx_file::id_util::IdIsValid(extension_id))
181 continue;
182 if (!prefs->HasKey(extension_id))
183 removed_extensions.insert(extension_id);
184 }
185
Istiaque Ahmeda7431b32017-08-20 18:33:37186 prefs_ = std::move(prefs);
lazyboye8634172016-01-28 00:10:48187
Devlin Cronin19f70b6a2017-10-01 04:14:05188 std::vector<ExternalInstallInfoUpdateUrl> external_update_url_extensions;
189 std::vector<ExternalInstallInfoFile> external_file_extensions;
lazyboye8634172016-01-28 00:10:48190 RetrieveExtensionsFromPrefs(&external_update_url_extensions,
191 &external_file_extensions);
192
193 // Notify ExtensionService about completion of finding incremental updates
194 // from this provider.
195 // Provide the list of added and removed extensions.
196 service_->OnExternalProviderUpdateComplete(
197 this, external_update_url_extensions, external_file_extensions,
198 removed_extensions);
199}
200
201void ExternalProviderImpl::RetrieveExtensionsFromPrefs(
Devlin Cronin19f70b6a2017-10-01 04:14:05202 std::vector<ExternalInstallInfoUpdateUrl>* external_update_url_extensions,
203 std::vector<ExternalInstallInfoFile>* external_file_extensions) {
[email protected]9d32ded072011-10-11 16:31:05204 // Set of unsupported extensions that need to be deleted from prefs_.
205 std::set<std::string> unsupported_extensions;
206
lazyboye8634172016-01-28 00:10:48207 // Discover all the extensions this provider has.
[email protected]aeca23f2013-06-21 22:34:41208 for (base::DictionaryValue::Iterator i(*prefs_); !i.IsAtEnd(); i.Advance()) {
[email protected]02d9b272013-03-06 12:54:56209 const std::string& extension_id = i.key();
[email protected]aeca23f2013-06-21 22:34:41210 const base::DictionaryValue* extension = NULL;
[email protected]ab22ba42011-01-14 16:36:38211
Ahmed Fakhry9ef29e042017-09-01 16:32:00212#if defined(OS_CHROMEOS)
213 if (ShouldUninstallExtensionReplacedByArcApp(extension_id)) {
214 VLOG(1) << "Extension with key: " << extension_id << " was replaced "
215 << "by a default ARC app, and will be uninstalled.";
216 unsupported_extensions.emplace(extension_id);
Oleg Davydovc00866812019-04-04 10:47:27217 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08218 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27219 InstallationReporter::FailureReason::REPLACED_BY_ARC_APP);
Ahmed Fakhry9ef29e042017-09-01 16:32:00220 continue;
221 }
222#endif // defined(OS_CHROMEOS)
223
[email protected]fdd28372014-08-21 02:27:26224 if (!crx_file::id_util::IdIsValid(extension_id)) {
[email protected]ab22ba42011-01-14 16:36:38225 LOG(WARNING) << "Malformed extension dictionary: key "
226 << extension_id.c_str() << " is not a valid id.";
Oleg Davydovc00866812019-04-04 10:47:27227 InstallationReporter::ReportFailure(
228 profile_, extension_id,
229 InstallationReporter::FailureReason::INVALID_ID);
[email protected]8e4560b62011-01-14 10:09:14230 continue;
[email protected]ab22ba42011-01-14 16:36:38231 }
232
[email protected]02d9b272013-03-06 12:54:56233 if (!i.value().GetAsDictionary(&extension)) {
[email protected]ab22ba42011-01-14 16:36:38234 LOG(WARNING) << "Malformed extension dictionary: key "
235 << extension_id.c_str()
236 << " has a value that is not a dictionary.";
Oleg Davydovc00866812019-04-04 10:47:27237 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08238 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27239 InstallationReporter::FailureReason::MALFORMED_EXTENSION_DICT);
[email protected]ab22ba42011-01-14 16:36:38240 continue;
241 }
[email protected]8e4560b62011-01-14 10:09:14242
[email protected]650b2d52013-02-10 03:41:45243 base::FilePath::StringType external_crx;
[email protected]cb1078de2013-12-23 20:04:22244 const base::Value* external_version_value = NULL;
[email protected]8e4560b62011-01-14 10:09:14245 std::string external_version;
246 std::string external_update_url;
247
248 bool has_external_crx = extension->GetString(kExternalCrx, &external_crx);
[email protected]0d461c52012-07-03 19:29:41249
250 bool has_external_version = false;
251 if (extension->Get(kExternalVersion, &external_version_value)) {
jdoerrie1f536b22017-10-23 17:15:11252 if (external_version_value->is_string()) {
[email protected]0d461c52012-07-03 19:29:41253 external_version_value->GetAsString(&external_version);
254 has_external_version = true;
255 } else {
Oleg Davydovc00866812019-04-04 10:47:27256 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08257 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27258 InstallationReporter::FailureReason::
259 MALFORMED_EXTENSION_DICT_VERSION);
[email protected]0d461c52012-07-03 19:29:41260 LOG(WARNING) << "Malformed extension dictionary for extension: "
261 << extension_id.c_str() << ". " << kExternalVersion
262 << " value must be a string.";
263 continue;
264 }
265 }
266
[email protected]8e4560b62011-01-14 10:09:14267 bool has_external_update_url = extension->GetString(kExternalUpdateUrl,
268 &external_update_url);
269 if (has_external_crx != has_external_version) {
Oleg Davydovc00866812019-04-04 10:47:27270 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08271 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27272 InstallationReporter::FailureReason::MALFORMED_EXTENSION_DICT);
[email protected]8e4560b62011-01-14 10:09:14273 LOG(WARNING) << "Malformed extension dictionary for extension: "
274 << extension_id.c_str() << ". " << kExternalCrx
275 << " and " << kExternalVersion << " must be used together.";
276 continue;
277 }
278
279 if (has_external_crx == has_external_update_url) {
Oleg Davydovc00866812019-04-04 10:47:27280 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08281 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27282 InstallationReporter::FailureReason::MALFORMED_EXTENSION_DICT);
[email protected]8e4560b62011-01-14 10:09:14283 LOG(WARNING) << "Malformed extension dictionary for extension: "
284 << extension_id.c_str() << ". Exactly one of the "
285 << "followng keys should be used: " << kExternalCrx
286 << ", " << kExternalUpdateUrl << ".";
287 continue;
288 }
289
[email protected]9d32ded072011-10-11 16:31:05290 // Check that extension supports current browser locale.
[email protected]aeca23f2013-06-21 22:34:41291 const base::ListValue* supported_locales = NULL;
[email protected]9d32ded072011-10-11 16:31:05292 if (extension->GetList(kSupportedLocales, &supported_locales)) {
293 std::vector<std::string> browser_locales;
294 l10n_util::GetParentLocales(g_browser_process->GetApplicationLocale(),
295 &browser_locales);
296
297 size_t num_locales = supported_locales->GetSize();
298 bool locale_supported = false;
299 for (size_t j = 0; j < num_locales; j++) {
300 std::string current_locale;
301 if (supported_locales->GetString(j, &current_locale) &&
302 l10n_util::IsValidLocaleSyntax(current_locale)) {
303 current_locale = l10n_util::NormalizeLocale(current_locale);
skyostil32fa6b3f92016-08-12 13:15:43304 if (base::ContainsValue(browser_locales, current_locale)) {
[email protected]9d32ded072011-10-11 16:31:05305 locale_supported = true;
306 break;
307 }
308 } else {
309 LOG(WARNING) << "Unrecognized locale '" << current_locale
310 << "' found as supported locale for extension: "
311 << extension_id;
312 }
313 }
314
315 if (!locale_supported) {
316 unsupported_extensions.insert(extension_id);
Oleg Davydovc00866812019-04-04 10:47:27317 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08318 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27319 InstallationReporter::FailureReason::LOCALE_NOT_SUPPORTED);
[email protected]19eac6d2013-05-30 06:51:03320 VLOG(1) << "Skip installing (or uninstall) external extension: "
321 << extension_id << " because the extension doesn't support "
322 << "the browser locale.";
[email protected]9d32ded072011-10-11 16:31:05323 continue;
324 }
325 }
326
[email protected]f121003b2012-05-04 21:57:47327 int creation_flags = creation_flags_;
328 bool is_bookmark_app;
329 if (extension->GetBoolean(kIsBookmarkApp, &is_bookmark_app) &&
330 is_bookmark_app) {
331 creation_flags |= Extension::FROM_BOOKMARK;
332 }
[email protected]2b6a5802014-08-16 07:58:08333 bool is_from_webstore = false;
[email protected]7425d7df2012-11-28 14:35:42334 if (extension->GetBoolean(kIsFromWebstore, &is_from_webstore) &&
335 is_from_webstore) {
336 creation_flags |= Extension::FROM_WEBSTORE;
337 }
[email protected]2b6a5802014-08-16 07:58:08338 bool keep_if_present = false;
[email protected]19eac6d2013-05-30 06:51:03339 if (extension->GetBoolean(kKeepIfPresent, &keep_if_present) &&
340 keep_if_present && profile_) {
341 ExtensionServiceInterface* extension_service =
342 ExtensionSystem::Get(profile_)->extension_service();
343 const Extension* extension = extension_service ?
344 extension_service->GetExtensionById(extension_id, true) : NULL;
345 if (!extension) {
dpolukhin2c6ef2932015-05-12 16:06:13346 unsupported_extensions.insert(extension_id);
Oleg Davydovc00866812019-04-04 10:47:27347 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08348 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27349 InstallationReporter::FailureReason::NOT_PERFORMING_NEW_INSTALL);
[email protected]19eac6d2013-05-30 06:51:03350 VLOG(1) << "Skip installing (or uninstall) external extension: "
351 << extension_id << " because the extension should be kept "
352 << "only if it is already installed.";
353 continue;
354 }
355 }
dpolukhind0be494a2015-05-28 09:43:17356 bool was_installed_by_oem = false;
357 if (extension->GetBoolean(kWasInstalledByOem, &was_installed_by_oem) &&
358 was_installed_by_oem) {
359 creation_flags |= Extension::WAS_INSTALLED_BY_OEM;
360 }
[email protected]2b6a5802014-08-16 07:58:08361 bool may_be_untrusted = false;
362 if (extension->GetBoolean(kMayBeUntrusted, &may_be_untrusted) &&
363 may_be_untrusted) {
364 creation_flags |= Extension::MAY_BE_UNTRUSTED;
365 }
[email protected]f121003b2012-05-04 21:57:47366
dpolukhin1687ef32015-06-22 11:12:37367 if (!HandleMinProfileVersion(extension, extension_id,
368 &unsupported_extensions)) {
dpolukhin2c6ef2932015-05-12 16:06:13369 continue;
dpolukhin1687ef32015-06-22 11:12:37370 }
371
372 if (!HandleDoNotInstallForEnterprise(extension, extension_id,
373 &unsupported_extensions)) {
374 continue;
375 }
dpolukhin2c6ef2932015-05-12 16:06:13376
[email protected]d8fd0fd2014-03-24 13:16:06377 std::string install_parameter;
378 extension->GetString(kInstallParam, &install_parameter);
379
[email protected]8e4560b62011-01-14 10:09:14380 if (has_external_crx) {
[email protected]1d5e58b2013-01-31 08:41:40381 if (crx_location_ == Manifest::INVALID_LOCATION) {
Oleg Davydovc00866812019-04-04 10:47:27382 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08383 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27384 InstallationReporter::FailureReason::NOT_SUPPORTED_EXTENSION_DICT);
[email protected]8e4560b62011-01-14 10:09:14385 LOG(WARNING) << "This provider does not support installing external "
386 << "extensions from crx files.";
387 continue;
388 }
[email protected]650b2d52013-02-10 03:41:45389 if (external_crx.find(base::FilePath::kParentDirectory) !=
[email protected]8e4560b62011-01-14 10:09:14390 base::StringPiece::npos) {
Oleg Davydovc00866812019-04-04 10:47:27391 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08392 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27393 InstallationReporter::FailureReason::
394 MALFORMED_EXTENSION_DICT_FILE_PATH);
[email protected]8e4560b62011-01-14 10:09:14395 LOG(WARNING) << "Path traversal not allowed in path: "
396 << external_crx.c_str();
397 continue;
398 }
399
[email protected]f0841cd2011-01-19 15:07:24400 // If the path is relative, and the provider has a base path,
401 // build the absolute path to the crx file.
[email protected]650b2d52013-02-10 03:41:45402 base::FilePath path(external_crx);
[email protected]8e4560b62011-01-14 10:09:14403 if (!path.IsAbsolute()) {
[email protected]650b2d52013-02-10 03:41:45404 base::FilePath base_path = loader_->GetBaseCrxFilePath();
[email protected]f0841cd2011-01-19 15:07:24405 if (base_path.empty()) {
Oleg Davydovc00866812019-04-04 10:47:27406 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08407 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27408 InstallationReporter::FailureReason::
409 MALFORMED_EXTENSION_DICT_FILE_PATH);
[email protected]f0841cd2011-01-19 15:07:24410 LOG(WARNING) << "File path " << external_crx.c_str()
411 << " is relative. An absolute path is required.";
412 continue;
413 }
[email protected]8e4560b62011-01-14 10:09:14414 path = base_path.Append(external_crx);
415 }
416
Devlin Cronind4c2a8f32017-09-29 17:08:30417 base::Version version(external_version);
418 if (!version.IsValid()) {
Oleg Davydovc00866812019-04-04 10:47:27419 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08420 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27421 InstallationReporter::FailureReason::
422 MALFORMED_EXTENSION_DICT_VERSION);
[email protected]8e4560b62011-01-14 10:09:14423 LOG(WARNING) << "Malformed extension dictionary for extension: "
424 << extension_id.c_str() << ". Invalid version string \""
425 << external_version << "\".";
426 continue;
427 }
Devlin Cronin19f70b6a2017-10-01 04:14:05428 external_file_extensions->emplace_back(
429 extension_id, version, path, crx_location_, creation_flags,
430 auto_acknowledge_, install_immediately_);
[email protected]8a839a02013-03-07 05:23:33431 } else { // if (has_external_update_url)
[email protected]8e4560b62011-01-14 10:09:14432 CHECK(has_external_update_url); // Checking of keys above ensures this.
[email protected]1d5e58b2013-01-31 08:41:40433 if (download_location_ == Manifest::INVALID_LOCATION) {
Oleg Davydovc00866812019-04-04 10:47:27434 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08435 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27436 InstallationReporter::FailureReason::NOT_SUPPORTED_EXTENSION_DICT);
[email protected]8e4560b62011-01-14 10:09:14437 LOG(WARNING) << "This provider does not support installing external "
438 << "extensions from update URLs.";
439 continue;
440 }
Devlin Cronind4c2a8f32017-09-29 17:08:30441 GURL update_url(external_update_url);
442 if (!update_url.is_valid()) {
Oleg Davydovc00866812019-04-04 10:47:27443 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08444 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27445 InstallationReporter::FailureReason::
446 MALFORMED_EXTENSION_DICT_UPDATE_URL);
[email protected]8e4560b62011-01-14 10:09:14447 LOG(WARNING) << "Malformed extension dictionary for extension: "
[email protected]ab22ba42011-01-14 16:36:38448 << extension_id.c_str() << ". Key " << kExternalUpdateUrl
449 << " has value \"" << external_update_url
450 << "\", which is not a valid URL.";
[email protected]8e4560b62011-01-14 10:09:14451 continue;
452 }
Devlin Cronin19f70b6a2017-10-01 04:14:05453 external_update_url_extensions->emplace_back(
454 extension_id, install_parameter, std::move(update_url),
455 download_location_, creation_flags, auto_acknowledge_);
[email protected]8e4560b62011-01-14 10:09:14456 }
457 }
458
jdoerrie13cd648c82018-10-02 21:21:02459 for (auto it = unsupported_extensions.begin();
[email protected]9d32ded072011-10-11 16:31:05460 it != unsupported_extensions.end(); ++it) {
461 // Remove extension for the list of know external extensions. The extension
462 // will be uninstalled later because provider doesn't provide it anymore.
463 prefs_->Remove(*it, NULL);
464 }
[email protected]8e4560b62011-01-14 10:09:14465}
466
[email protected]5df038b2012-07-16 19:03:27467void ExternalProviderImpl::ServiceShutdown() {
[email protected]8e4560b62011-01-14 10:09:14468 service_ = NULL;
469}
470
[email protected]5df038b2012-07-16 19:03:27471bool ExternalProviderImpl::IsReady() const {
[email protected]8e4560b62011-01-14 10:09:14472 return ready_;
473}
474
[email protected]5df038b2012-07-16 19:03:27475bool ExternalProviderImpl::HasExtension(
[email protected]8e4560b62011-01-14 10:09:14476 const std::string& id) const {
Istiaque Ahmedf6e72622017-09-08 23:14:17477 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14478 CHECK(prefs_.get());
479 CHECK(ready_);
480 return prefs_->HasKey(id);
481}
482
[email protected]5df038b2012-07-16 19:03:27483bool ExternalProviderImpl::GetExtensionDetails(
dchengc963c7142016-04-08 03:55:22484 const std::string& id,
485 Manifest::Location* location,
pwnallcbd73192016-08-22 18:59:17486 std::unique_ptr<base::Version>* version) const {
Istiaque Ahmedf6e72622017-09-08 23:14:17487 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14488 CHECK(prefs_.get());
489 CHECK(ready_);
[email protected]aeca23f2013-06-21 22:34:41490 base::DictionaryValue* extension = NULL;
[email protected]8e4560b62011-01-14 10:09:14491 if (!prefs_->GetDictionary(id, &extension))
492 return false;
493
[email protected]1d5e58b2013-01-31 08:41:40494 Manifest::Location loc = Manifest::INVALID_LOCATION;
[email protected]8e4560b62011-01-14 10:09:14495 if (extension->HasKey(kExternalUpdateUrl)) {
496 loc = download_location_;
497
498 } else if (extension->HasKey(kExternalCrx)) {
499 loc = crx_location_;
500
501 std::string external_version;
502 if (!extension->GetString(kExternalVersion, &external_version))
503 return false;
504
505 if (version)
pwnallcbd73192016-08-22 18:59:17506 version->reset(new base::Version(external_version));
[email protected]8e4560b62011-01-14 10:09:14507
508 } else {
509 NOTREACHED(); // Chrome should not allow prefs to get into this state.
510 return false;
511 }
512
513 if (location)
514 *location = loc;
515
516 return true;
517}
518
dpolukhin2c6ef2932015-05-12 16:06:13519bool ExternalProviderImpl::HandleMinProfileVersion(
520 const base::DictionaryValue* extension,
521 const std::string& extension_id,
522 std::set<std::string>* unsupported_extensions) {
523 std::string min_profile_created_by_version;
524 if (profile_ &&
525 extension->GetString(kMinProfileCreatedByVersion,
526 &min_profile_created_by_version)) {
pwnallcbd73192016-08-22 18:59:17527 base::Version profile_version(
dpolukhin2c6ef2932015-05-12 16:06:13528 profile_->GetPrefs()->GetString(prefs::kProfileCreatedByVersion));
pwnallcbd73192016-08-22 18:59:17529 base::Version min_version(min_profile_created_by_version);
dpolukhin2c6ef2932015-05-12 16:06:13530 if (min_version.IsValid() && profile_version.CompareTo(min_version) < 0) {
531 unsupported_extensions->insert(extension_id);
Oleg Davydovc00866812019-04-04 10:47:27532 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08533 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27534 InstallationReporter::FailureReason::TOO_OLD_PROFILE);
dpolukhin2c6ef2932015-05-12 16:06:13535 VLOG(1) << "Skip installing (or uninstall) external extension: "
536 << extension_id
537 << " profile.created_by_version: " << profile_version.GetString()
538 << " min_profile_created_by_version: "
539 << min_profile_created_by_version;
540 return false;
541 }
542 }
543 return true;
544}
545
dpolukhin1687ef32015-06-22 11:12:37546bool ExternalProviderImpl::HandleDoNotInstallForEnterprise(
547 const base::DictionaryValue* extension,
548 const std::string& extension_id,
549 std::set<std::string>* unsupported_extensions) {
550 bool do_not_install_for_enterprise = false;
551 if (extension->GetBoolean(kDoNotInstallForEnterprise,
552 &do_not_install_for_enterprise) &&
553 do_not_install_for_enterprise) {
554 const policy::ProfilePolicyConnector* const connector =
Xi Hanfe39afc62019-04-29 14:50:14555 profile_->GetProfilePolicyConnector();
dpolukhin1687ef32015-06-22 11:12:37556 if (connector->IsManaged()) {
557 unsupported_extensions->insert(extension_id);
Oleg Davydovc00866812019-04-04 10:47:27558 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08559 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27560 InstallationReporter::FailureReason::DO_NOT_INSTALL_FOR_ENTERPRISE);
dpolukhin1687ef32015-06-22 11:12:37561 VLOG(1) << "Skip installing (or uninstall) external extension "
562 << extension_id << " restricted for managed user";
563 return false;
564 }
565 }
566 return true;
567}
568
[email protected]8e4560b62011-01-14 10:09:14569// static
[email protected]5df038b2012-07-16 19:03:27570void ExternalProviderImpl::CreateExternalProviders(
[email protected]8e4560b62011-01-14 10:09:14571 VisitorInterface* service,
572 Profile* profile,
573 ProviderCollection* provider_list) {
rkaplowdd66a1342015-03-05 00:31:49574 TRACE_EVENT0("browser,startup",
575 "ExternalProviderImpl::CreateExternalProviders");
[email protected]af984882013-10-21 21:08:51576 scoped_refptr<ExternalLoader> external_loader;
binjincccacef2014-10-13 19:00:20577 scoped_refptr<ExternalLoader> external_recommended_loader;
[email protected]af984882013-10-21 21:08:51578 extensions::Manifest::Location crx_location = Manifest::INVALID_LOCATION;
achuithd3da4f02017-03-23 20:05:29579
[email protected]af984882013-10-21 21:08:51580#if defined(OS_CHROMEOS)
achuithd3da4f02017-03-23 20:05:29581 if (chromeos::ProfileHelper::IsSigninProfile(profile)) {
582 // Download apps installed by policy in the login profile. Flags
583 // FROM_WEBSTORE/WAS_INSTALLED_BY_DEFAULT are applied because these apps are
584 // downloaded from the webstore, and we want to treat them as built-in
585 // extensions.
586 external_loader = new ExternalPolicyLoader(
587 ExtensionManagementFactory::GetForBrowserContext(profile),
588 ExternalPolicyLoader::FORCED);
Jinho Bangb5216cec2018-01-17 19:43:11589 auto signin_profile_provider = std::make_unique<ExternalProviderImpl>(
achuithd3da4f02017-03-23 20:05:29590 service, external_loader, profile, crx_location,
591 Manifest::EXTERNAL_POLICY_DOWNLOAD,
Toni Barzic87026682018-01-08 23:21:04592 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
593 signin_profile_provider->set_allow_updates(true);
594 provider_list->push_back(std::move(signin_profile_provider));
achuithd3da4f02017-03-23 20:05:29595 return;
596 }
597
[email protected]97275822014-01-21 19:30:36598 policy::BrowserPolicyConnectorChromeOS* connector =
599 g_browser_process->platform_part()->browser_policy_connector_chromeos();
[email protected]2d4cfed2014-01-14 13:59:57600 bool is_chrome_os_public_session = false;
[email protected]2fda9972014-07-23 14:51:59601 const user_manager::User* user =
[email protected]052e3ac2014-06-30 14:22:47602 chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
[email protected]2d4cfed2014-01-14 13:59:57603 policy::DeviceLocalAccount::Type account_type;
alemate909aa58a2016-11-03 22:49:07604 if (user && connector->IsEnterpriseManaged() &&
605 policy::IsDeviceLocalAccountUser(user->GetAccountId().GetUserEmail(),
606 &account_type)) {
[email protected]2d4cfed2014-01-14 13:59:57607 if (account_type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
608 is_chrome_os_public_session = true;
[email protected]af984882013-10-21 21:08:51609 policy::DeviceLocalAccountPolicyBroker* broker =
[email protected]97275822014-01-21 19:30:36610 connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser(
alemate909aa58a2016-11-03 22:49:07611 user->GetAccountId().GetUserEmail());
[email protected]af984882013-10-21 21:08:51612 if (broker) {
613 external_loader = broker->extension_loader();
614 crx_location = Manifest::EXTERNAL_POLICY;
615 } else {
616 NOTREACHED();
617 }
618 } else {
binjin30301062014-09-08 20:27:34619 external_loader = new ExternalPolicyLoader(
binjincccacef2014-10-13 19:00:20620 ExtensionManagementFactory::GetForBrowserContext(profile),
621 ExternalPolicyLoader::FORCED);
622 external_recommended_loader = new ExternalPolicyLoader(
623 ExtensionManagementFactory::GetForBrowserContext(profile),
624 ExternalPolicyLoader::RECOMMENDED);
[email protected]af984882013-10-21 21:08:51625 }
626#else
binjin30301062014-09-08 20:27:34627 external_loader = new ExternalPolicyLoader(
binjincccacef2014-10-13 19:00:20628 ExtensionManagementFactory::GetForBrowserContext(profile),
629 ExternalPolicyLoader::FORCED);
630 external_recommended_loader = new ExternalPolicyLoader(
631 ExtensionManagementFactory::GetForBrowserContext(profile),
632 ExternalPolicyLoader::RECOMMENDED);
[email protected]af984882013-10-21 21:08:51633#endif
634
[email protected]b9f4fe52012-11-09 21:40:59635 // Policies are mandatory so they can't be skipped with command line flag.
dchengc7047942014-08-26 05:05:31636 if (external_loader.get()) {
Jinho Bangb5216cec2018-01-17 19:43:11637 auto policy_provider = std::make_unique<ExternalProviderImpl>(
lazyboyf33109d2016-08-31 00:37:08638 service, external_loader, profile, crx_location,
Toni Barzic87026682018-01-08 23:21:04639 Manifest::EXTERNAL_POLICY_DOWNLOAD, Extension::NO_FLAGS);
640 policy_provider->set_allow_updates(true);
641 provider_list->push_back(std::move(policy_provider));
[email protected]af984882013-10-21 21:08:51642 }
[email protected]b9f4fe52012-11-09 21:40:59643
[email protected]ee3da0552014-07-16 05:27:31644 // Load the KioskAppExternalProvider when running in kiosk mode.
645 if (chrome::IsRunningInForcedAppMode()) {
646#if defined(OS_CHROMEOS)
jennyz26b7f432015-09-03 20:59:27647 // Kiosk primary app external provider.
Toni Barzic87026682018-01-08 23:21:04648 // For enterprise managed kiosk apps, change the location to
649 // "force-installed by policy".
650 policy::BrowserPolicyConnectorChromeOS* const connector =
651 g_browser_process->platform_part()->browser_policy_connector_chromeos();
652 Manifest::Location location = Manifest::EXTERNAL_PREF;
653 if (connector && connector->IsEnterpriseManaged())
654 location = Manifest::EXTERNAL_POLICY;
pbond43ddd4f2015-09-08 16:39:19655
Toni Barzic87026682018-01-08 23:21:04656 std::unique_ptr<ExternalProviderImpl> kiosk_app_provider(
657 new ExternalProviderImpl(
658 service,
659 base::MakeRefCounted<chromeos::KioskAppExternalLoader>(
660 chromeos::KioskAppExternalLoader::AppClass::kPrimary),
661 profile, location, Manifest::INVALID_LOCATION,
662 Extension::NO_FLAGS));
663 kiosk_app_provider->set_auto_acknowledge(true);
664 kiosk_app_provider->set_install_immediately(true);
665 kiosk_app_provider->set_allow_updates(true);
666 provider_list->push_back(std::move(kiosk_app_provider));
jennyz26b7f432015-09-03 20:59:27667
668 // Kiosk secondary app external provider.
Toni Barzic87026682018-01-08 23:21:04669 std::unique_ptr<ExternalProviderImpl> secondary_kiosk_app_provider(
670 new ExternalProviderImpl(
671 service,
672 base::MakeRefCounted<chromeos::KioskAppExternalLoader>(
673 chromeos::KioskAppExternalLoader::AppClass::kSecondary),
674 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
675 Extension::NO_FLAGS));
676 secondary_kiosk_app_provider->set_auto_acknowledge(true);
677 secondary_kiosk_app_provider->set_install_immediately(true);
678 secondary_kiosk_app_provider->set_allow_updates(true);
679 provider_list->push_back(std::move(secondary_kiosk_app_provider));
[email protected]ee3da0552014-07-16 05:27:31680#endif
681 return;
682 }
683
binjincccacef2014-10-13 19:00:20684 // Extensions provided by recommended policies.
685 if (external_recommended_loader.get()) {
Jinho Bangb5216cec2018-01-17 19:43:11686 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
lazyboyf33109d2016-08-31 00:37:08687 service, external_recommended_loader, profile, crx_location,
688 Manifest::EXTERNAL_PREF_DOWNLOAD, Extension::NO_FLAGS));
binjincccacef2014-10-13 19:00:20689 }
690
[email protected]b9f4fe52012-11-09 21:40:59691 // In tests don't install extensions from default external sources.
692 // It would only slowdown tests and make them flaky.
avi3ef9ec9e2014-12-22 22:50:17693 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]98820ac72019-01-24 19:47:16694 ::switches::kDisableDefaultApps)) {
[email protected]b9f4fe52012-11-09 21:40:59695 return;
[email protected]98820ac72019-01-24 19:47:16696 }
[email protected]73e4c362011-09-22 14:47:18697
698 // On Mac OS, items in /Library/... should be written by the superuser.
699 // Check that all components of the path are writable by root only.
[email protected]5df038b2012-07-16 19:03:27700 ExternalPrefLoader::Options check_admin_permissions_on_mac;
[email protected]73e4c362011-09-22 14:47:18701#if defined(OS_MACOSX)
[email protected]0edc55412011-11-07 16:47:33702 check_admin_permissions_on_mac =
[email protected]5df038b2012-07-16 19:03:27703 ExternalPrefLoader::ENSURE_PATH_CONTROLLED_BY_ADMIN;
[email protected]73e4c362011-09-22 14:47:18704#else
[email protected]5df038b2012-07-16 19:03:27705 check_admin_permissions_on_mac = ExternalPrefLoader::NONE;
[email protected]73e4c362011-09-22 14:47:18706#endif
707
Peter Kastingbe940e92014-11-20 23:14:08708#if !defined(OS_WIN)
[email protected]d6f7b102012-05-04 13:59:05709 int bundled_extension_creation_flags = Extension::NO_FLAGS;
Peter Kastingbe940e92014-11-20 23:14:08710#endif
[email protected]03d3ba012012-04-02 22:36:13711#if defined(OS_CHROMEOS)
[email protected]5861bcd2012-10-16 21:40:19712 bundled_extension_creation_flags = Extension::FROM_WEBSTORE |
713 Extension::WAS_INSTALLED_BY_DEFAULT;
[email protected]a4567732013-07-25 21:01:20714
rkcb526cd6b2014-12-18 16:54:37715 if (!is_chrome_os_public_session) {
[email protected]98820ac72019-01-24 19:47:16716 int pref_load_flags =
ginkagef66fae522015-03-03 16:38:16717 profile->IsNewProfile()
718 ? ExternalPrefLoader::DELAY_LOAD_UNTIL_PRIORITY_SYNC
719 : ExternalPrefLoader::NONE;
[email protected]98820ac72019-01-24 19:47:16720 pref_load_flags |= ExternalPrefLoader::USE_USER_TYPE_PROFILE_FILTER;
721 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
722 service,
723 new ExternalPrefLoader(chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS,
724 pref_load_flags, profile),
725 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
726 bundled_extension_creation_flags));
[email protected]d0b28892014-03-05 18:56:31727
728 // OEM default apps.
[email protected]acc3c7c22014-03-19 06:23:39729 int oem_extension_creation_flags =
730 bundled_extension_creation_flags | Extension::WAS_INSTALLED_BY_OEM;
[email protected]d0b28892014-03-05 18:56:31731 chromeos::ServicesCustomizationDocument* customization =
732 chromeos::ServicesCustomizationDocument::GetInstance();
Jinho Bangb5216cec2018-01-17 19:43:11733 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
lazyboyf33109d2016-08-31 00:37:08734 service, customization->CreateExternalLoader(profile), profile,
735 Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
736 oem_extension_creation_flags));
[email protected]ebb489f2013-09-19 22:08:52737 }
Toni Barzicdff51562018-07-24 19:55:46738
739 // For Chrome OS demo sessions, add pre-installed demo extensions and apps.
740 if (chromeos::DemoExtensionsExternalLoader::SupportedForProfile(profile)) {
Wenzhao Zang463f1142018-09-05 22:50:50741 base::FilePath cache_dir;
742 CHECK(base::PathService::Get(chromeos::DIR_DEVICE_EXTENSION_LOCAL_CACHE,
743 &cache_dir));
744 scoped_refptr<chromeos::DemoExtensionsExternalLoader> loader =
745 base::MakeRefCounted<chromeos::DemoExtensionsExternalLoader>(cache_dir);
Toni Barzicdff51562018-07-24 19:55:46746 std::unique_ptr<ExternalProviderImpl> demo_apps_provider =
747 std::make_unique<ExternalProviderImpl>(
Michael Giuffrida00afa042019-01-29 08:41:09748 service, loader, profile, Manifest::EXTERNAL_POLICY,
749 Manifest::EXTERNAL_POLICY_DOWNLOAD, Extension::NO_FLAGS);
Toni Barzicdff51562018-07-24 19:55:46750 demo_apps_provider->set_auto_acknowledge(true);
751 demo_apps_provider->set_install_immediately(true);
Wenzhao Zanga90de072018-09-19 02:39:26752 chromeos::DemoSession::Get()->SetExtensionsExternalLoader(loader);
Toni Barzicdff51562018-07-24 19:55:46753 provider_list->push_back(std::move(demo_apps_provider));
754 }
Peter Kastingbe940e92014-11-20 23:14:08755#elif defined(OS_LINUX)
[email protected]98820ac72019-01-24 19:47:16756 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
757 service,
758 new ExternalPrefLoader(chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS,
759 ExternalPrefLoader::USE_USER_TYPE_PROFILE_FILTER,
760 profile),
761 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
762 bundled_extension_creation_flags));
[email protected]5bed2ec32013-08-29 22:55:46763#endif
764
Taiju Tsuikib1879b72018-09-21 06:22:47765 if (!profile->IsLegacySupervised()) {
Peter Kastingbe940e92014-11-20 23:14:08766#if defined(OS_WIN)
Taiju Tsuikib1879b72018-09-21 06:22:47767 auto registry_provider = std::make_unique<ExternalProviderImpl>(
768 service, new ExternalRegistryLoader, profile,
769 Manifest::EXTERNAL_REGISTRY, Manifest::EXTERNAL_PREF_DOWNLOAD,
770 Extension::NO_FLAGS);
771 registry_provider->set_allow_updates(true);
772 provider_list->push_back(std::move(registry_provider));
Peter Kastingbe940e92014-11-20 23:14:08773#else
Taiju Tsuikib1879b72018-09-21 06:22:47774 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
775 service,
776 new ExternalPrefLoader(chrome::DIR_EXTERNAL_EXTENSIONS,
777 check_admin_permissions_on_mac, nullptr),
778 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
779 bundled_extension_creation_flags));
[email protected]5bed2ec32013-08-29 22:55:46780
Taiju Tsuikib1879b72018-09-21 06:22:47781 // Define a per-user source of external extensions.
sydlie21e153d2015-07-30 19:57:56782#if defined(OS_MACOSX) || (defined(OS_LINUX) && defined(CHROMIUM_BUILD))
Taiju Tsuikib1879b72018-09-21 06:22:47783 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
784 service,
785 new ExternalPrefLoader(chrome::DIR_USER_EXTERNAL_EXTENSIONS,
786 ExternalPrefLoader::NONE, nullptr),
787 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
788 Extension::NO_FLAGS));
[email protected]a29a517a2011-01-21 21:11:12789#endif
[email protected]8e4560b62011-01-14 10:09:14790#endif
[email protected]ed7bbb52012-05-02 11:07:29791
[email protected]98b4aca62011-09-28 01:27:23792#if !defined(OS_CHROMEOS)
[email protected]7da12212013-02-14 10:53:49793 // The default apps are installed as INTERNAL but use the external
794 // extension installer codeflow.
Taiju Tsuikib1879b72018-09-21 06:22:47795 provider_list->push_back(std::make_unique<default_apps::Provider>(
796 profile, service,
797 new ExternalPrefLoader(chrome::DIR_DEFAULT_APPS,
798 ExternalPrefLoader::NONE, nullptr),
799 Manifest::INTERNAL, Manifest::INTERNAL,
800 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT));
[email protected]98b4aca62011-09-28 01:27:23801#endif
xiyuan65b68ab12015-06-26 19:00:18802
Taiju Tsuikib1879b72018-09-21 06:22:47803 std::unique_ptr<ExternalProviderImpl> drive_migration_provider(
804 new ExternalProviderImpl(
805 service,
806 new ExtensionMigrator(profile, extension_misc::kDriveHostedAppId,
Devlin Cronin06194e32018-12-05 19:33:49807 extension_misc::kDocsOfflineExtensionId),
Taiju Tsuikib1879b72018-09-21 06:22:47808 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
809 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT));
810 drive_migration_provider->set_auto_acknowledge(true);
811 provider_list->push_back(std::move(drive_migration_provider));
812 }
treibcc82ab82015-03-02 09:41:49813
Jinho Bangb5216cec2018-01-17 19:43:11814 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
lazyboyf33109d2016-08-31 00:37:08815 service, new ExternalComponentLoader(profile), profile,
816 Manifest::INVALID_LOCATION, Manifest::EXTERNAL_COMPONENT,
817 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT));
[email protected]8e4560b62011-01-14 10:09:14818}
[email protected]5df038b2012-07-16 19:03:27819
820} // namespace extensions