blob: e3c70a3840a8739814e8f0a5ecc0d9b6875cecd4 [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"
Matthew Dentonef83a622019-08-30 02:07:0017#include "base/memory/scoped_refptr.h"
[email protected]51a7a9d2011-09-27 17:21:4118#include "base/metrics/field_trial.h"
chakshu.ac20f38782016-04-06 09:58:0819#include "base/stl_util.h"
[email protected]46acbf12013-06-10 18:43:4220#include "base/strings/string_util.h"
rkaplowdd66a1342015-03-05 00:31:4921#include "base/trace_event/trace_event.h"
[email protected]8e4560b62011-01-14 10:09:1422#include "base/values.h"
23#include "base/version.h"
Nico Weber897593f2019-07-25 23:17:5524#include "build/branding_buildflags.h"
avia2f4804a2015-12-24 23:11:1325#include "build/build_config.h"
[email protected]8a839a02013-03-07 05:23:3326#include "chrome/browser/app_mode/app_mode_utils.h"
[email protected]e601e822011-10-05 19:25:3727#include "chrome/browser/browser_process.h"
pbond43ddd4f2015-09-08 16:39:1928#include "chrome/browser/browser_process_platform_part.h"
binjin30301062014-09-08 20:27:3429#include "chrome/browser/extensions/extension_management.h"
xiyuan65b68ab12015-06-26 19:00:1830#include "chrome/browser/extensions/extension_migrator.h"
[email protected]8aa50c7752013-05-23 12:57:5031#include "chrome/browser/extensions/external_component_loader.h"
[email protected]5df038b2012-07-16 19:03:2732#include "chrome/browser/extensions/external_policy_loader.h"
33#include "chrome/browser/extensions/external_pref_loader.h"
Oleg Davydovc00866812019-04-04 10:47:2734#include "chrome/browser/extensions/forced_extensions/installation_reporter.h"
dpolukhin1687ef32015-06-22 11:12:3735#include "chrome/browser/policy/profile_policy_connector.h"
[email protected]8e4560b62011-01-14 10:09:1436#include "chrome/browser/profiles/profile.h"
[email protected]f0841cd2011-01-19 15:07:2437#include "chrome/common/chrome_paths.h"
[email protected]83b59325a2011-10-14 15:58:0738#include "chrome/common/chrome_switches.h"
xiyuan65b68ab12015-06-26 19:00:1839#include "chrome/common/extensions/extension_constants.h"
dpolukhin2c6ef2932015-05-12 16:06:1340#include "chrome/common/pref_names.h"
[email protected]fdd28372014-08-21 02:27:2641#include "components/crx_file/id_util.h"
brettwb1fc1b82016-02-02 00:19:0842#include "components/prefs/pref_service.h"
[email protected]c38831a12011-10-28 12:44:4943#include "content/public/browser/browser_thread.h"
David Bertoni58c113a2019-08-02 19:53:2644#include "extensions/browser/extension_registry.h"
lazyboye8634172016-01-28 00:10:4845#include "extensions/browser/external_install_info.h"
[email protected]301116c62013-11-26 10:37:4546#include "extensions/browser/external_provider_interface.h"
[email protected]e4452d32013-11-15 23:07:4147#include "extensions/common/extension.h"
[email protected]d42c11152013-08-22 19:36:3248#include "extensions/common/manifest.h"
[email protected]9d32ded072011-10-11 16:31:0549#include "ui/base/l10n/l10n_util.h"
[email protected]8e4560b62011-01-14 10:09:1450
[email protected]944dfa82012-03-20 02:07:5151#if defined(OS_CHROMEOS)
Wenzhao Zang463f1142018-09-05 22:50:5052#include "base/path_service.h"
Toni Barzic87026682018-01-08 23:21:0453#include "chrome/browser/chromeos/app_mode/kiosk_app_external_loader.h"
Satoru Takabayashi876d4e62014-12-03 04:52:2454#include "chrome/browser/chromeos/customization/customization_document.h"
[email protected]af984882013-10-21 21:08:5155#include "chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.h"
Toni Barzicdff51562018-07-24 19:55:4656#include "chrome/browser/chromeos/login/demo_mode/demo_extensions_external_loader.h"
Wenzhao Zang463f1142018-09-05 22:50:5057#include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
[email protected]97275822014-01-21 19:30:3658#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
[email protected]af984882013-10-21 21:08:5159#include "chrome/browser/chromeos/policy/device_local_account.h"
60#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
[email protected]052e3ac2014-06-30 14:22:4761#include "chrome/browser/chromeos/profiles/profile_helper.h"
Steven Bennetts38e9bde22019-01-03 17:31:1062#include "chromeos/constants/chromeos_paths.h"
Ahmed Fakhry9ef29e042017-09-01 16:32:0063#include "components/arc/arc_util.h"
[email protected]b39d25712013-03-14 09:53:4064#else
[email protected]86c6b9e32011-10-25 17:09:1065#include "chrome/browser/extensions/default_apps.h"
66#endif
67
[email protected]8e4560b62011-01-14 10:09:1468#if defined(OS_WIN)
[email protected]5df038b2012-07-16 19:03:2769#include "chrome/browser/extensions/external_registry_loader_win.h"
[email protected]8e4560b62011-01-14 10:09:1470#endif
71
[email protected]631bb742011-11-02 11:29:3972using content::BrowserThread;
[email protected]5df038b2012-07-16 19:03:2773
74namespace extensions {
[email protected]631bb742011-11-02 11:29:3975
Ahmed Fakhry9ef29e042017-09-01 16:32:0076namespace {
77
78#if defined(OS_CHROMEOS)
79
80// Certain default extensions are no longer needed on ARC devices as they were
81// replaced by their ARC counterparts.
82bool ShouldUninstallExtensionReplacedByArcApp(const std::string& extension_id) {
Alex Newcomerf8c542f2018-08-13 23:48:5083 if (!arc::IsArcAvailable())
Ahmed Fakhry9ef29e042017-09-01 16:32:0084 return false;
85
86 if (extension_id == extension_misc::kGooglePlayBooksAppId ||
87 extension_id == extension_misc::kGooglePlayMoviesAppId ||
88 extension_id == extension_misc::kGooglePlayMusicAppId) {
89 return true;
90 }
91
92 return false;
93}
94
95#endif // defined(OS_CHROMEOS)
96
97} // namespace
98
[email protected]8e4560b62011-01-14 10:09:1499// Constants for keeping track of extension preferences in a dictionary.
[email protected]d8fd0fd2014-03-24 13:16:06100const char ExternalProviderImpl::kInstallParam[] = "install_parameter";
[email protected]5df038b2012-07-16 19:03:27101const char ExternalProviderImpl::kExternalCrx[] = "external_crx";
[email protected]7425d7df2012-11-28 14:35:42102const char ExternalProviderImpl::kExternalVersion[] = "external_version";
103const char ExternalProviderImpl::kExternalUpdateUrl[] = "external_update_url";
[email protected]7425d7df2012-11-28 14:35:42104const char ExternalProviderImpl::kIsBookmarkApp[] = "is_bookmark_app";
105const char ExternalProviderImpl::kIsFromWebstore[] = "is_from_webstore";
[email protected]19eac6d2013-05-30 06:51:03106const char ExternalProviderImpl::kKeepIfPresent[] = "keep_if_present";
[email protected]bf9fd5ae2014-04-09 22:50:06107const char ExternalProviderImpl::kWasInstalledByOem[] = "was_installed_by_oem";
108const char ExternalProviderImpl::kSupportedLocales[] = "supported_locales";
[email protected]2b6a5802014-08-16 07:58:08109const char ExternalProviderImpl::kMayBeUntrusted[] = "may_be_untrusted";
dpolukhin2c6ef2932015-05-12 16:06:13110const char ExternalProviderImpl::kMinProfileCreatedByVersion[] =
111 "min_profile_created_by_version";
dpolukhin1687ef32015-06-22 11:12:37112const char ExternalProviderImpl::kDoNotInstallForEnterprise[] =
113 "do_not_install_for_enterprise";
[email protected]8e4560b62011-01-14 10:09:14114
[email protected]af984882013-10-21 21:08:51115ExternalProviderImpl::ExternalProviderImpl(
116 VisitorInterface* service,
117 const scoped_refptr<ExternalLoader>& loader,
118 Profile* profile,
119 Manifest::Location crx_location,
120 Manifest::Location download_location,
121 int creation_flags)
[email protected]4b4c0132013-06-12 17:58:55122 : crx_location_(crx_location),
123 download_location_(download_location),
124 service_(service),
[email protected]4b4c0132013-06-12 17:58:55125 loader_(loader),
126 profile_(profile),
Toni Barzic87026682018-01-08 23:21:04127 creation_flags_(creation_flags) {
[email protected]8e4560b62011-01-14 10:09:14128 loader_->Init(this);
129}
130
[email protected]5df038b2012-07-16 19:03:27131ExternalProviderImpl::~ExternalProviderImpl() {
Istiaque Ahmedf6e72622017-09-08 23:14:17132 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14133 loader_->OwnerShutdown();
134}
135
[email protected]5df038b2012-07-16 19:03:27136void ExternalProviderImpl::VisitRegisteredExtension() {
[email protected]8e4560b62011-01-14 10:09:14137 // The loader will call back to SetPrefs.
138 loader_->StartLoading();
139}
140
Istiaque Ahmeda7431b32017-08-20 18:33:37141void ExternalProviderImpl::SetPrefs(
142 std::unique_ptr<base::DictionaryValue> prefs) {
Istiaque Ahmedf6e72622017-09-08 23:14:17143 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14144
[email protected]47fc70c2011-12-06 07:29:51145 // Check if the service is still alive. It is possible that it went
[email protected]8e4560b62011-01-14 10:09:14146 // away while |loader_| was working on the FILE thread.
147 if (!service_) return;
148
Oleg Davydov52db8742019-08-20 09:14:40149 for (const auto& it : prefs->DictItems()) {
150 InstallationReporter::ReportInstallationStage(
151 profile_, it.first,
152 InstallationReporter::Stage::SEEN_BY_EXTERNAL_PROVIDER);
153 }
154
Istiaque Ahmeda7431b32017-08-20 18:33:37155 prefs_ = std::move(prefs);
[email protected]8a839a02013-03-07 05:23:33156 ready_ = true; // Queries for extensions are allowed from this point.
[email protected]8e4560b62011-01-14 10:09:14157
Devlin Cronin19f70b6a2017-10-01 04:14:05158 std::vector<ExternalInstallInfoUpdateUrl> external_update_url_extensions;
159 std::vector<ExternalInstallInfoFile> external_file_extensions;
lazyboye8634172016-01-28 00:10:48160
161 RetrieveExtensionsFromPrefs(&external_update_url_extensions,
162 &external_file_extensions);
lazyboy4aeef202016-09-07 21:28:59163 for (const auto& extension : external_update_url_extensions)
Devlin Cronin19f70b6a2017-10-01 04:14:05164 service_->OnExternalExtensionUpdateUrlFound(extension, true);
lazyboye8634172016-01-28 00:10:48165
lazyboy4aeef202016-09-07 21:28:59166 for (const auto& extension : external_file_extensions)
Devlin Cronin19f70b6a2017-10-01 04:14:05167 service_->OnExternalExtensionFileFound(extension);
lazyboye8634172016-01-28 00:10:48168
169 service_->OnExternalProviderReady(this);
170}
171
Istiaque Ahmeda7431b32017-08-20 18:33:37172void ExternalProviderImpl::UpdatePrefs(
173 std::unique_ptr<base::DictionaryValue> prefs) {
Istiaque Ahmedf6e72622017-09-08 23:14:17174 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Toni Barzic87026682018-01-08 23:21:04175 CHECK(allow_updates_);
lazyboye8634172016-01-28 00:10:48176
177 // Check if the service is still alive. It is possible that it went
178 // away while |loader_| was working on the FILE thread.
179 if (!service_)
180 return;
181
182 std::set<std::string> removed_extensions;
183 // Find extensions that were removed by this ExternalProvider.
184 for (base::DictionaryValue::Iterator i(*prefs_); !i.IsAtEnd(); i.Advance()) {
185 const std::string& extension_id = i.key();
186 // Don't bother about invalid ids.
187 if (!crx_file::id_util::IdIsValid(extension_id))
188 continue;
189 if (!prefs->HasKey(extension_id))
190 removed_extensions.insert(extension_id);
191 }
192
Istiaque Ahmeda7431b32017-08-20 18:33:37193 prefs_ = std::move(prefs);
lazyboye8634172016-01-28 00:10:48194
Devlin Cronin19f70b6a2017-10-01 04:14:05195 std::vector<ExternalInstallInfoUpdateUrl> external_update_url_extensions;
196 std::vector<ExternalInstallInfoFile> external_file_extensions;
lazyboye8634172016-01-28 00:10:48197 RetrieveExtensionsFromPrefs(&external_update_url_extensions,
198 &external_file_extensions);
199
200 // Notify ExtensionService about completion of finding incremental updates
201 // from this provider.
202 // Provide the list of added and removed extensions.
203 service_->OnExternalProviderUpdateComplete(
204 this, external_update_url_extensions, external_file_extensions,
205 removed_extensions);
206}
207
208void ExternalProviderImpl::RetrieveExtensionsFromPrefs(
Devlin Cronin19f70b6a2017-10-01 04:14:05209 std::vector<ExternalInstallInfoUpdateUrl>* external_update_url_extensions,
210 std::vector<ExternalInstallInfoFile>* external_file_extensions) {
[email protected]9d32ded072011-10-11 16:31:05211 // Set of unsupported extensions that need to be deleted from prefs_.
212 std::set<std::string> unsupported_extensions;
213
lazyboye8634172016-01-28 00:10:48214 // Discover all the extensions this provider has.
[email protected]aeca23f2013-06-21 22:34:41215 for (base::DictionaryValue::Iterator i(*prefs_); !i.IsAtEnd(); i.Advance()) {
[email protected]02d9b272013-03-06 12:54:56216 const std::string& extension_id = i.key();
[email protected]aeca23f2013-06-21 22:34:41217 const base::DictionaryValue* extension = NULL;
[email protected]ab22ba42011-01-14 16:36:38218
Ahmed Fakhry9ef29e042017-09-01 16:32:00219#if defined(OS_CHROMEOS)
220 if (ShouldUninstallExtensionReplacedByArcApp(extension_id)) {
221 VLOG(1) << "Extension with key: " << extension_id << " was replaced "
222 << "by a default ARC app, and will be uninstalled.";
223 unsupported_extensions.emplace(extension_id);
Oleg Davydovc00866812019-04-04 10:47:27224 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08225 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27226 InstallationReporter::FailureReason::REPLACED_BY_ARC_APP);
Ahmed Fakhry9ef29e042017-09-01 16:32:00227 continue;
228 }
229#endif // defined(OS_CHROMEOS)
230
[email protected]fdd28372014-08-21 02:27:26231 if (!crx_file::id_util::IdIsValid(extension_id)) {
[email protected]ab22ba42011-01-14 16:36:38232 LOG(WARNING) << "Malformed extension dictionary: key "
233 << extension_id.c_str() << " is not a valid id.";
Oleg Davydovc00866812019-04-04 10:47:27234 InstallationReporter::ReportFailure(
235 profile_, extension_id,
236 InstallationReporter::FailureReason::INVALID_ID);
[email protected]8e4560b62011-01-14 10:09:14237 continue;
[email protected]ab22ba42011-01-14 16:36:38238 }
239
[email protected]02d9b272013-03-06 12:54:56240 if (!i.value().GetAsDictionary(&extension)) {
[email protected]ab22ba42011-01-14 16:36:38241 LOG(WARNING) << "Malformed extension dictionary: key "
242 << extension_id.c_str()
243 << " has a value that is not a dictionary.";
Oleg Davydovc00866812019-04-04 10:47:27244 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08245 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27246 InstallationReporter::FailureReason::MALFORMED_EXTENSION_DICT);
[email protected]ab22ba42011-01-14 16:36:38247 continue;
248 }
[email protected]8e4560b62011-01-14 10:09:14249
[email protected]650b2d52013-02-10 03:41:45250 base::FilePath::StringType external_crx;
[email protected]cb1078de2013-12-23 20:04:22251 const base::Value* external_version_value = NULL;
[email protected]8e4560b62011-01-14 10:09:14252 std::string external_version;
253 std::string external_update_url;
254
255 bool has_external_crx = extension->GetString(kExternalCrx, &external_crx);
[email protected]0d461c52012-07-03 19:29:41256
257 bool has_external_version = false;
258 if (extension->Get(kExternalVersion, &external_version_value)) {
jdoerrie1f536b22017-10-23 17:15:11259 if (external_version_value->is_string()) {
[email protected]0d461c52012-07-03 19:29:41260 external_version_value->GetAsString(&external_version);
261 has_external_version = true;
262 } else {
Oleg Davydovc00866812019-04-04 10:47:27263 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08264 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27265 InstallationReporter::FailureReason::
266 MALFORMED_EXTENSION_DICT_VERSION);
[email protected]0d461c52012-07-03 19:29:41267 LOG(WARNING) << "Malformed extension dictionary for extension: "
268 << extension_id.c_str() << ". " << kExternalVersion
269 << " value must be a string.";
270 continue;
271 }
272 }
273
[email protected]8e4560b62011-01-14 10:09:14274 bool has_external_update_url = extension->GetString(kExternalUpdateUrl,
275 &external_update_url);
276 if (has_external_crx != has_external_version) {
Oleg Davydovc00866812019-04-04 10:47:27277 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08278 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27279 InstallationReporter::FailureReason::MALFORMED_EXTENSION_DICT);
[email protected]8e4560b62011-01-14 10:09:14280 LOG(WARNING) << "Malformed extension dictionary for extension: "
281 << extension_id.c_str() << ". " << kExternalCrx
282 << " and " << kExternalVersion << " must be used together.";
283 continue;
284 }
285
286 if (has_external_crx == has_external_update_url) {
Oleg Davydovc00866812019-04-04 10:47:27287 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08288 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27289 InstallationReporter::FailureReason::MALFORMED_EXTENSION_DICT);
[email protected]8e4560b62011-01-14 10:09:14290 LOG(WARNING) << "Malformed extension dictionary for extension: "
291 << extension_id.c_str() << ". Exactly one of the "
292 << "followng keys should be used: " << kExternalCrx
293 << ", " << kExternalUpdateUrl << ".";
294 continue;
295 }
296
[email protected]9d32ded072011-10-11 16:31:05297 // Check that extension supports current browser locale.
[email protected]aeca23f2013-06-21 22:34:41298 const base::ListValue* supported_locales = NULL;
[email protected]9d32ded072011-10-11 16:31:05299 if (extension->GetList(kSupportedLocales, &supported_locales)) {
300 std::vector<std::string> browser_locales;
301 l10n_util::GetParentLocales(g_browser_process->GetApplicationLocale(),
302 &browser_locales);
303
304 size_t num_locales = supported_locales->GetSize();
305 bool locale_supported = false;
306 for (size_t j = 0; j < num_locales; j++) {
307 std::string current_locale;
308 if (supported_locales->GetString(j, &current_locale) &&
309 l10n_util::IsValidLocaleSyntax(current_locale)) {
310 current_locale = l10n_util::NormalizeLocale(current_locale);
Jan Wilken Dörrieade79222019-06-06 19:01:12311 if (base::Contains(browser_locales, current_locale)) {
[email protected]9d32ded072011-10-11 16:31:05312 locale_supported = true;
313 break;
314 }
315 } else {
316 LOG(WARNING) << "Unrecognized locale '" << current_locale
317 << "' found as supported locale for extension: "
318 << extension_id;
319 }
320 }
321
322 if (!locale_supported) {
323 unsupported_extensions.insert(extension_id);
Oleg Davydovc00866812019-04-04 10:47:27324 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08325 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27326 InstallationReporter::FailureReason::LOCALE_NOT_SUPPORTED);
[email protected]19eac6d2013-05-30 06:51:03327 VLOG(1) << "Skip installing (or uninstall) external extension: "
328 << extension_id << " because the extension doesn't support "
329 << "the browser locale.";
[email protected]9d32ded072011-10-11 16:31:05330 continue;
331 }
332 }
333
[email protected]f121003b2012-05-04 21:57:47334 int creation_flags = creation_flags_;
335 bool is_bookmark_app;
336 if (extension->GetBoolean(kIsBookmarkApp, &is_bookmark_app) &&
337 is_bookmark_app) {
338 creation_flags |= Extension::FROM_BOOKMARK;
339 }
[email protected]2b6a5802014-08-16 07:58:08340 bool is_from_webstore = false;
[email protected]7425d7df2012-11-28 14:35:42341 if (extension->GetBoolean(kIsFromWebstore, &is_from_webstore) &&
342 is_from_webstore) {
343 creation_flags |= Extension::FROM_WEBSTORE;
344 }
[email protected]2b6a5802014-08-16 07:58:08345 bool keep_if_present = false;
[email protected]19eac6d2013-05-30 06:51:03346 if (extension->GetBoolean(kKeepIfPresent, &keep_if_present) &&
347 keep_if_present && profile_) {
David Bertoni58c113a2019-08-02 19:53:26348 ExtensionRegistry* extension_registry = ExtensionRegistry::Get(profile_);
349 const Extension* extension =
350 extension_registry
351 ? extension_registry->GetExtensionById(
352 extension_id, ExtensionRegistry::COMPATIBILITY)
353 : nullptr;
[email protected]19eac6d2013-05-30 06:51:03354 if (!extension) {
dpolukhin2c6ef2932015-05-12 16:06:13355 unsupported_extensions.insert(extension_id);
Oleg Davydovc00866812019-04-04 10:47:27356 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08357 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27358 InstallationReporter::FailureReason::NOT_PERFORMING_NEW_INSTALL);
[email protected]19eac6d2013-05-30 06:51:03359 VLOG(1) << "Skip installing (or uninstall) external extension: "
360 << extension_id << " because the extension should be kept "
361 << "only if it is already installed.";
362 continue;
363 }
364 }
dpolukhind0be494a2015-05-28 09:43:17365 bool was_installed_by_oem = false;
366 if (extension->GetBoolean(kWasInstalledByOem, &was_installed_by_oem) &&
367 was_installed_by_oem) {
368 creation_flags |= Extension::WAS_INSTALLED_BY_OEM;
369 }
[email protected]2b6a5802014-08-16 07:58:08370 bool may_be_untrusted = false;
371 if (extension->GetBoolean(kMayBeUntrusted, &may_be_untrusted) &&
372 may_be_untrusted) {
373 creation_flags |= Extension::MAY_BE_UNTRUSTED;
374 }
[email protected]f121003b2012-05-04 21:57:47375
dpolukhin1687ef32015-06-22 11:12:37376 if (!HandleMinProfileVersion(extension, extension_id,
377 &unsupported_extensions)) {
dpolukhin2c6ef2932015-05-12 16:06:13378 continue;
dpolukhin1687ef32015-06-22 11:12:37379 }
380
381 if (!HandleDoNotInstallForEnterprise(extension, extension_id,
382 &unsupported_extensions)) {
383 continue;
384 }
dpolukhin2c6ef2932015-05-12 16:06:13385
[email protected]d8fd0fd2014-03-24 13:16:06386 std::string install_parameter;
387 extension->GetString(kInstallParam, &install_parameter);
388
[email protected]8e4560b62011-01-14 10:09:14389 if (has_external_crx) {
[email protected]1d5e58b2013-01-31 08:41:40390 if (crx_location_ == Manifest::INVALID_LOCATION) {
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::NOT_SUPPORTED_EXTENSION_DICT);
[email protected]8e4560b62011-01-14 10:09:14394 LOG(WARNING) << "This provider does not support installing external "
395 << "extensions from crx files.";
396 continue;
397 }
[email protected]650b2d52013-02-10 03:41:45398 if (external_crx.find(base::FilePath::kParentDirectory) !=
[email protected]8e4560b62011-01-14 10:09:14399 base::StringPiece::npos) {
Oleg Davydovc00866812019-04-04 10:47:27400 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08401 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27402 InstallationReporter::FailureReason::
403 MALFORMED_EXTENSION_DICT_FILE_PATH);
[email protected]8e4560b62011-01-14 10:09:14404 LOG(WARNING) << "Path traversal not allowed in path: "
405 << external_crx.c_str();
406 continue;
407 }
408
[email protected]f0841cd2011-01-19 15:07:24409 // If the path is relative, and the provider has a base path,
410 // build the absolute path to the crx file.
[email protected]650b2d52013-02-10 03:41:45411 base::FilePath path(external_crx);
[email protected]8e4560b62011-01-14 10:09:14412 if (!path.IsAbsolute()) {
[email protected]650b2d52013-02-10 03:41:45413 base::FilePath base_path = loader_->GetBaseCrxFilePath();
[email protected]f0841cd2011-01-19 15:07:24414 if (base_path.empty()) {
Oleg Davydovc00866812019-04-04 10:47:27415 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08416 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27417 InstallationReporter::FailureReason::
418 MALFORMED_EXTENSION_DICT_FILE_PATH);
[email protected]f0841cd2011-01-19 15:07:24419 LOG(WARNING) << "File path " << external_crx.c_str()
420 << " is relative. An absolute path is required.";
421 continue;
422 }
[email protected]8e4560b62011-01-14 10:09:14423 path = base_path.Append(external_crx);
424 }
425
Devlin Cronind4c2a8f32017-09-29 17:08:30426 base::Version version(external_version);
427 if (!version.IsValid()) {
Oleg Davydovc00866812019-04-04 10:47:27428 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08429 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27430 InstallationReporter::FailureReason::
431 MALFORMED_EXTENSION_DICT_VERSION);
[email protected]8e4560b62011-01-14 10:09:14432 LOG(WARNING) << "Malformed extension dictionary for extension: "
433 << extension_id.c_str() << ". Invalid version string \""
434 << external_version << "\".";
435 continue;
436 }
Devlin Cronin19f70b6a2017-10-01 04:14:05437 external_file_extensions->emplace_back(
438 extension_id, version, path, crx_location_, creation_flags,
439 auto_acknowledge_, install_immediately_);
[email protected]8a839a02013-03-07 05:23:33440 } else { // if (has_external_update_url)
[email protected]8e4560b62011-01-14 10:09:14441 CHECK(has_external_update_url); // Checking of keys above ensures this.
[email protected]1d5e58b2013-01-31 08:41:40442 if (download_location_ == Manifest::INVALID_LOCATION) {
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::NOT_SUPPORTED_EXTENSION_DICT);
[email protected]8e4560b62011-01-14 10:09:14446 LOG(WARNING) << "This provider does not support installing external "
447 << "extensions from update URLs.";
448 continue;
449 }
Devlin Cronind4c2a8f32017-09-29 17:08:30450 GURL update_url(external_update_url);
451 if (!update_url.is_valid()) {
Oleg Davydovc00866812019-04-04 10:47:27452 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08453 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27454 InstallationReporter::FailureReason::
455 MALFORMED_EXTENSION_DICT_UPDATE_URL);
[email protected]8e4560b62011-01-14 10:09:14456 LOG(WARNING) << "Malformed extension dictionary for extension: "
[email protected]ab22ba42011-01-14 16:36:38457 << extension_id.c_str() << ". Key " << kExternalUpdateUrl
458 << " has value \"" << external_update_url
459 << "\", which is not a valid URL.";
[email protected]8e4560b62011-01-14 10:09:14460 continue;
461 }
Devlin Cronin19f70b6a2017-10-01 04:14:05462 external_update_url_extensions->emplace_back(
463 extension_id, install_parameter, std::move(update_url),
464 download_location_, creation_flags, auto_acknowledge_);
[email protected]8e4560b62011-01-14 10:09:14465 }
466 }
467
jdoerrie13cd648c82018-10-02 21:21:02468 for (auto it = unsupported_extensions.begin();
[email protected]9d32ded072011-10-11 16:31:05469 it != unsupported_extensions.end(); ++it) {
470 // Remove extension for the list of know external extensions. The extension
471 // will be uninstalled later because provider doesn't provide it anymore.
472 prefs_->Remove(*it, NULL);
473 }
[email protected]8e4560b62011-01-14 10:09:14474}
475
[email protected]5df038b2012-07-16 19:03:27476void ExternalProviderImpl::ServiceShutdown() {
[email protected]8e4560b62011-01-14 10:09:14477 service_ = NULL;
478}
479
[email protected]5df038b2012-07-16 19:03:27480bool ExternalProviderImpl::IsReady() const {
[email protected]8e4560b62011-01-14 10:09:14481 return ready_;
482}
483
[email protected]5df038b2012-07-16 19:03:27484bool ExternalProviderImpl::HasExtension(
[email protected]8e4560b62011-01-14 10:09:14485 const std::string& id) const {
Istiaque Ahmedf6e72622017-09-08 23:14:17486 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14487 CHECK(prefs_.get());
488 CHECK(ready_);
489 return prefs_->HasKey(id);
490}
491
[email protected]5df038b2012-07-16 19:03:27492bool ExternalProviderImpl::GetExtensionDetails(
dchengc963c7142016-04-08 03:55:22493 const std::string& id,
494 Manifest::Location* location,
pwnallcbd73192016-08-22 18:59:17495 std::unique_ptr<base::Version>* version) const {
Istiaque Ahmedf6e72622017-09-08 23:14:17496 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14497 CHECK(prefs_.get());
498 CHECK(ready_);
[email protected]aeca23f2013-06-21 22:34:41499 base::DictionaryValue* extension = NULL;
[email protected]8e4560b62011-01-14 10:09:14500 if (!prefs_->GetDictionary(id, &extension))
501 return false;
502
[email protected]1d5e58b2013-01-31 08:41:40503 Manifest::Location loc = Manifest::INVALID_LOCATION;
[email protected]8e4560b62011-01-14 10:09:14504 if (extension->HasKey(kExternalUpdateUrl)) {
505 loc = download_location_;
506
507 } else if (extension->HasKey(kExternalCrx)) {
508 loc = crx_location_;
509
510 std::string external_version;
511 if (!extension->GetString(kExternalVersion, &external_version))
512 return false;
513
514 if (version)
pwnallcbd73192016-08-22 18:59:17515 version->reset(new base::Version(external_version));
[email protected]8e4560b62011-01-14 10:09:14516
517 } else {
518 NOTREACHED(); // Chrome should not allow prefs to get into this state.
519 return false;
520 }
521
522 if (location)
523 *location = loc;
524
525 return true;
526}
527
dpolukhin2c6ef2932015-05-12 16:06:13528bool ExternalProviderImpl::HandleMinProfileVersion(
529 const base::DictionaryValue* extension,
530 const std::string& extension_id,
531 std::set<std::string>* unsupported_extensions) {
532 std::string min_profile_created_by_version;
533 if (profile_ &&
534 extension->GetString(kMinProfileCreatedByVersion,
535 &min_profile_created_by_version)) {
pwnallcbd73192016-08-22 18:59:17536 base::Version profile_version(
dpolukhin2c6ef2932015-05-12 16:06:13537 profile_->GetPrefs()->GetString(prefs::kProfileCreatedByVersion));
pwnallcbd73192016-08-22 18:59:17538 base::Version min_version(min_profile_created_by_version);
dpolukhin2c6ef2932015-05-12 16:06:13539 if (min_version.IsValid() && profile_version.CompareTo(min_version) < 0) {
540 unsupported_extensions->insert(extension_id);
Oleg Davydovc00866812019-04-04 10:47:27541 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08542 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27543 InstallationReporter::FailureReason::TOO_OLD_PROFILE);
dpolukhin2c6ef2932015-05-12 16:06:13544 VLOG(1) << "Skip installing (or uninstall) external extension: "
545 << extension_id
546 << " profile.created_by_version: " << profile_version.GetString()
547 << " min_profile_created_by_version: "
548 << min_profile_created_by_version;
549 return false;
550 }
551 }
552 return true;
553}
554
dpolukhin1687ef32015-06-22 11:12:37555bool ExternalProviderImpl::HandleDoNotInstallForEnterprise(
556 const base::DictionaryValue* extension,
557 const std::string& extension_id,
558 std::set<std::string>* unsupported_extensions) {
559 bool do_not_install_for_enterprise = false;
560 if (extension->GetBoolean(kDoNotInstallForEnterprise,
561 &do_not_install_for_enterprise) &&
562 do_not_install_for_enterprise) {
563 const policy::ProfilePolicyConnector* const connector =
Xi Hanfe39afc62019-04-29 14:50:14564 profile_->GetProfilePolicyConnector();
dpolukhin1687ef32015-06-22 11:12:37565 if (connector->IsManaged()) {
566 unsupported_extensions->insert(extension_id);
Oleg Davydovc00866812019-04-04 10:47:27567 InstallationReporter::ReportFailure(
Sergey Poromov296de0a2018-10-11 21:44:08568 profile_, extension_id,
Oleg Davydovc00866812019-04-04 10:47:27569 InstallationReporter::FailureReason::DO_NOT_INSTALL_FOR_ENTERPRISE);
dpolukhin1687ef32015-06-22 11:12:37570 VLOG(1) << "Skip installing (or uninstall) external extension "
571 << extension_id << " restricted for managed user";
572 return false;
573 }
574 }
575 return true;
576}
577
[email protected]8e4560b62011-01-14 10:09:14578// static
[email protected]5df038b2012-07-16 19:03:27579void ExternalProviderImpl::CreateExternalProviders(
[email protected]8e4560b62011-01-14 10:09:14580 VisitorInterface* service,
581 Profile* profile,
582 ProviderCollection* provider_list) {
rkaplowdd66a1342015-03-05 00:31:49583 TRACE_EVENT0("browser,startup",
584 "ExternalProviderImpl::CreateExternalProviders");
[email protected]af984882013-10-21 21:08:51585 scoped_refptr<ExternalLoader> external_loader;
binjincccacef2014-10-13 19:00:20586 scoped_refptr<ExternalLoader> external_recommended_loader;
[email protected]af984882013-10-21 21:08:51587 extensions::Manifest::Location crx_location = Manifest::INVALID_LOCATION;
achuithd3da4f02017-03-23 20:05:29588
[email protected]af984882013-10-21 21:08:51589#if defined(OS_CHROMEOS)
achuithd3da4f02017-03-23 20:05:29590 if (chromeos::ProfileHelper::IsSigninProfile(profile)) {
Alexander Hendrich33ec65ee2019-05-21 09:29:13591 // Download extensions/apps installed by policy in the login profile. Flags
592 // FROM_WEBSTORE/WAS_INSTALLED_BY_DEFAULT are applied because these
593 // extension/apps are downloaded from the webstore, and we want to treat
594 // them as built-in extensions. Extensions (not apps) installed through this
595 // path will have type |TYPE_LOGIN_SCREE_EXTENSION| with limited API
596 // capabilities.
Matthew Dentonef83a622019-08-30 02:07:00597 external_loader = base::MakeRefCounted<ExternalPolicyLoader>(
Oleg Davydov52db8742019-08-20 09:14:40598 profile, ExtensionManagementFactory::GetForBrowserContext(profile),
achuithd3da4f02017-03-23 20:05:29599 ExternalPolicyLoader::FORCED);
Jinho Bangb5216cec2018-01-17 19:43:11600 auto signin_profile_provider = std::make_unique<ExternalProviderImpl>(
achuithd3da4f02017-03-23 20:05:29601 service, external_loader, profile, crx_location,
602 Manifest::EXTERNAL_POLICY_DOWNLOAD,
Alexander Hendrich33ec65ee2019-05-21 09:29:13603 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT |
604 Extension::FOR_LOGIN_SCREEN);
Toni Barzic87026682018-01-08 23:21:04605 signin_profile_provider->set_allow_updates(true);
606 provider_list->push_back(std::move(signin_profile_provider));
achuithd3da4f02017-03-23 20:05:29607 return;
608 }
609
[email protected]97275822014-01-21 19:30:36610 policy::BrowserPolicyConnectorChromeOS* connector =
611 g_browser_process->platform_part()->browser_policy_connector_chromeos();
[email protected]2d4cfed2014-01-14 13:59:57612 bool is_chrome_os_public_session = false;
[email protected]2fda9972014-07-23 14:51:59613 const user_manager::User* user =
[email protected]052e3ac2014-06-30 14:22:47614 chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
[email protected]2d4cfed2014-01-14 13:59:57615 policy::DeviceLocalAccount::Type account_type;
alemate909aa58a2016-11-03 22:49:07616 if (user && connector->IsEnterpriseManaged() &&
617 policy::IsDeviceLocalAccountUser(user->GetAccountId().GetUserEmail(),
618 &account_type)) {
[email protected]2d4cfed2014-01-14 13:59:57619 if (account_type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
620 is_chrome_os_public_session = true;
[email protected]af984882013-10-21 21:08:51621 policy::DeviceLocalAccountPolicyBroker* broker =
[email protected]97275822014-01-21 19:30:36622 connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser(
alemate909aa58a2016-11-03 22:49:07623 user->GetAccountId().GetUserEmail());
[email protected]af984882013-10-21 21:08:51624 if (broker) {
625 external_loader = broker->extension_loader();
626 crx_location = Manifest::EXTERNAL_POLICY;
627 } else {
628 NOTREACHED();
629 }
630 } else {
Matthew Dentonef83a622019-08-30 02:07:00631 external_loader = base::MakeRefCounted<ExternalPolicyLoader>(
Oleg Davydov52db8742019-08-20 09:14:40632 profile, ExtensionManagementFactory::GetForBrowserContext(profile),
binjincccacef2014-10-13 19:00:20633 ExternalPolicyLoader::FORCED);
Matthew Dentonef83a622019-08-30 02:07:00634 external_recommended_loader = base::MakeRefCounted<ExternalPolicyLoader>(
Oleg Davydov52db8742019-08-20 09:14:40635 profile, ExtensionManagementFactory::GetForBrowserContext(profile),
binjincccacef2014-10-13 19:00:20636 ExternalPolicyLoader::RECOMMENDED);
[email protected]af984882013-10-21 21:08:51637 }
638#else
Matthew Dentonef83a622019-08-30 02:07:00639 external_loader = base::MakeRefCounted<ExternalPolicyLoader>(
Oleg Davydov52db8742019-08-20 09:14:40640 profile, ExtensionManagementFactory::GetForBrowserContext(profile),
binjincccacef2014-10-13 19:00:20641 ExternalPolicyLoader::FORCED);
Matthew Dentonef83a622019-08-30 02:07:00642 external_recommended_loader = base::MakeRefCounted<ExternalPolicyLoader>(
Oleg Davydov52db8742019-08-20 09:14:40643 profile, ExtensionManagementFactory::GetForBrowserContext(profile),
binjincccacef2014-10-13 19:00:20644 ExternalPolicyLoader::RECOMMENDED);
[email protected]af984882013-10-21 21:08:51645#endif
646
[email protected]b9f4fe52012-11-09 21:40:59647 // Policies are mandatory so they can't be skipped with command line flag.
dchengc7047942014-08-26 05:05:31648 if (external_loader.get()) {
Jinho Bangb5216cec2018-01-17 19:43:11649 auto policy_provider = std::make_unique<ExternalProviderImpl>(
lazyboyf33109d2016-08-31 00:37:08650 service, external_loader, profile, crx_location,
Toni Barzic87026682018-01-08 23:21:04651 Manifest::EXTERNAL_POLICY_DOWNLOAD, Extension::NO_FLAGS);
652 policy_provider->set_allow_updates(true);
653 provider_list->push_back(std::move(policy_provider));
[email protected]af984882013-10-21 21:08:51654 }
[email protected]b9f4fe52012-11-09 21:40:59655
[email protected]ee3da0552014-07-16 05:27:31656 // Load the KioskAppExternalProvider when running in kiosk mode.
657 if (chrome::IsRunningInForcedAppMode()) {
658#if defined(OS_CHROMEOS)
jennyz26b7f432015-09-03 20:59:27659 // Kiosk primary app external provider.
Toni Barzic87026682018-01-08 23:21:04660 // For enterprise managed kiosk apps, change the location to
661 // "force-installed by policy".
662 policy::BrowserPolicyConnectorChromeOS* const connector =
663 g_browser_process->platform_part()->browser_policy_connector_chromeos();
664 Manifest::Location location = Manifest::EXTERNAL_PREF;
665 if (connector && connector->IsEnterpriseManaged())
666 location = Manifest::EXTERNAL_POLICY;
pbond43ddd4f2015-09-08 16:39:19667
Toni Barzic87026682018-01-08 23:21:04668 std::unique_ptr<ExternalProviderImpl> kiosk_app_provider(
669 new ExternalProviderImpl(
670 service,
671 base::MakeRefCounted<chromeos::KioskAppExternalLoader>(
672 chromeos::KioskAppExternalLoader::AppClass::kPrimary),
673 profile, location, Manifest::INVALID_LOCATION,
674 Extension::NO_FLAGS));
675 kiosk_app_provider->set_auto_acknowledge(true);
676 kiosk_app_provider->set_install_immediately(true);
677 kiosk_app_provider->set_allow_updates(true);
678 provider_list->push_back(std::move(kiosk_app_provider));
jennyz26b7f432015-09-03 20:59:27679
680 // Kiosk secondary app external provider.
Toni Barzic87026682018-01-08 23:21:04681 std::unique_ptr<ExternalProviderImpl> secondary_kiosk_app_provider(
682 new ExternalProviderImpl(
683 service,
684 base::MakeRefCounted<chromeos::KioskAppExternalLoader>(
685 chromeos::KioskAppExternalLoader::AppClass::kSecondary),
686 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
687 Extension::NO_FLAGS));
688 secondary_kiosk_app_provider->set_auto_acknowledge(true);
689 secondary_kiosk_app_provider->set_install_immediately(true);
690 secondary_kiosk_app_provider->set_allow_updates(true);
691 provider_list->push_back(std::move(secondary_kiosk_app_provider));
[email protected]ee3da0552014-07-16 05:27:31692#endif
693 return;
694 }
695
binjincccacef2014-10-13 19:00:20696 // Extensions provided by recommended policies.
697 if (external_recommended_loader.get()) {
Jinho Bangb5216cec2018-01-17 19:43:11698 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
lazyboyf33109d2016-08-31 00:37:08699 service, external_recommended_loader, profile, crx_location,
700 Manifest::EXTERNAL_PREF_DOWNLOAD, Extension::NO_FLAGS));
binjincccacef2014-10-13 19:00:20701 }
702
[email protected]b9f4fe52012-11-09 21:40:59703 // In tests don't install extensions from default external sources.
704 // It would only slowdown tests and make them flaky.
avi3ef9ec9e2014-12-22 22:50:17705 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]98820ac72019-01-24 19:47:16706 ::switches::kDisableDefaultApps)) {
[email protected]b9f4fe52012-11-09 21:40:59707 return;
[email protected]98820ac72019-01-24 19:47:16708 }
[email protected]73e4c362011-09-22 14:47:18709
710 // On Mac OS, items in /Library/... should be written by the superuser.
711 // Check that all components of the path are writable by root only.
[email protected]5df038b2012-07-16 19:03:27712 ExternalPrefLoader::Options check_admin_permissions_on_mac;
[email protected]73e4c362011-09-22 14:47:18713#if defined(OS_MACOSX)
[email protected]0edc55412011-11-07 16:47:33714 check_admin_permissions_on_mac =
[email protected]5df038b2012-07-16 19:03:27715 ExternalPrefLoader::ENSURE_PATH_CONTROLLED_BY_ADMIN;
[email protected]73e4c362011-09-22 14:47:18716#else
[email protected]5df038b2012-07-16 19:03:27717 check_admin_permissions_on_mac = ExternalPrefLoader::NONE;
[email protected]73e4c362011-09-22 14:47:18718#endif
719
Peter Kastingbe940e92014-11-20 23:14:08720#if !defined(OS_WIN)
[email protected]d6f7b102012-05-04 13:59:05721 int bundled_extension_creation_flags = Extension::NO_FLAGS;
Peter Kastingbe940e92014-11-20 23:14:08722#endif
[email protected]03d3ba012012-04-02 22:36:13723#if defined(OS_CHROMEOS)
[email protected]5861bcd2012-10-16 21:40:19724 bundled_extension_creation_flags = Extension::FROM_WEBSTORE |
725 Extension::WAS_INSTALLED_BY_DEFAULT;
[email protected]a4567732013-07-25 21:01:20726
rkcb526cd6b2014-12-18 16:54:37727 if (!is_chrome_os_public_session) {
[email protected]98820ac72019-01-24 19:47:16728 int pref_load_flags =
ginkagef66fae522015-03-03 16:38:16729 profile->IsNewProfile()
730 ? ExternalPrefLoader::DELAY_LOAD_UNTIL_PRIORITY_SYNC
731 : ExternalPrefLoader::NONE;
[email protected]98820ac72019-01-24 19:47:16732 pref_load_flags |= ExternalPrefLoader::USE_USER_TYPE_PROFILE_FILTER;
733 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
734 service,
Matthew Dentonef83a622019-08-30 02:07:00735 base::MakeRefCounted<ExternalPrefLoader>(
736 chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS, pref_load_flags,
737 profile),
[email protected]98820ac72019-01-24 19:47:16738 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
739 bundled_extension_creation_flags));
[email protected]d0b28892014-03-05 18:56:31740
741 // OEM default apps.
[email protected]acc3c7c22014-03-19 06:23:39742 int oem_extension_creation_flags =
743 bundled_extension_creation_flags | Extension::WAS_INSTALLED_BY_OEM;
[email protected]d0b28892014-03-05 18:56:31744 chromeos::ServicesCustomizationDocument* customization =
745 chromeos::ServicesCustomizationDocument::GetInstance();
Jinho Bangb5216cec2018-01-17 19:43:11746 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
lazyboyf33109d2016-08-31 00:37:08747 service, customization->CreateExternalLoader(profile), profile,
748 Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
749 oem_extension_creation_flags));
[email protected]ebb489f2013-09-19 22:08:52750 }
Toni Barzicdff51562018-07-24 19:55:46751
752 // For Chrome OS demo sessions, add pre-installed demo extensions and apps.
753 if (chromeos::DemoExtensionsExternalLoader::SupportedForProfile(profile)) {
Wenzhao Zang463f1142018-09-05 22:50:50754 base::FilePath cache_dir;
755 CHECK(base::PathService::Get(chromeos::DIR_DEVICE_EXTENSION_LOCAL_CACHE,
756 &cache_dir));
757 scoped_refptr<chromeos::DemoExtensionsExternalLoader> loader =
758 base::MakeRefCounted<chromeos::DemoExtensionsExternalLoader>(cache_dir);
Toni Barzicdff51562018-07-24 19:55:46759 std::unique_ptr<ExternalProviderImpl> demo_apps_provider =
760 std::make_unique<ExternalProviderImpl>(
Michael Giuffrida00afa042019-01-29 08:41:09761 service, loader, profile, Manifest::EXTERNAL_POLICY,
762 Manifest::EXTERNAL_POLICY_DOWNLOAD, Extension::NO_FLAGS);
Toni Barzicdff51562018-07-24 19:55:46763 demo_apps_provider->set_auto_acknowledge(true);
764 demo_apps_provider->set_install_immediately(true);
Wenzhao Zanga90de072018-09-19 02:39:26765 chromeos::DemoSession::Get()->SetExtensionsExternalLoader(loader);
Toni Barzicdff51562018-07-24 19:55:46766 provider_list->push_back(std::move(demo_apps_provider));
767 }
Peter Kastingbe940e92014-11-20 23:14:08768#elif defined(OS_LINUX)
[email protected]98820ac72019-01-24 19:47:16769 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
770 service,
Matthew Dentonef83a622019-08-30 02:07:00771 base::MakeRefCounted<ExternalPrefLoader>(
772 chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS,
773 ExternalPrefLoader::USE_USER_TYPE_PROFILE_FILTER, profile),
[email protected]98820ac72019-01-24 19:47:16774 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
775 bundled_extension_creation_flags));
[email protected]5bed2ec32013-08-29 22:55:46776#endif
777
Taiju Tsuikib1879b72018-09-21 06:22:47778 if (!profile->IsLegacySupervised()) {
Peter Kastingbe940e92014-11-20 23:14:08779#if defined(OS_WIN)
Taiju Tsuikib1879b72018-09-21 06:22:47780 auto registry_provider = std::make_unique<ExternalProviderImpl>(
781 service, new ExternalRegistryLoader, profile,
782 Manifest::EXTERNAL_REGISTRY, Manifest::EXTERNAL_PREF_DOWNLOAD,
783 Extension::NO_FLAGS);
784 registry_provider->set_allow_updates(true);
785 provider_list->push_back(std::move(registry_provider));
Peter Kastingbe940e92014-11-20 23:14:08786#else
Taiju Tsuikib1879b72018-09-21 06:22:47787 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
788 service,
Matthew Dentonef83a622019-08-30 02:07:00789 base::MakeRefCounted<ExternalPrefLoader>(
790 chrome::DIR_EXTERNAL_EXTENSIONS, check_admin_permissions_on_mac,
791 nullptr),
Taiju Tsuikib1879b72018-09-21 06:22:47792 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
793 bundled_extension_creation_flags));
[email protected]5bed2ec32013-08-29 22:55:46794
Taiju Tsuikib1879b72018-09-21 06:22:47795 // Define a per-user source of external extensions.
Nico Weber897593f2019-07-25 23:17:55796#if defined(OS_MACOSX) || (defined(OS_LINUX) && BUILDFLAG(CHROMIUM_BRANDING))
Taiju Tsuikib1879b72018-09-21 06:22:47797 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
798 service,
Matthew Dentonef83a622019-08-30 02:07:00799 base::MakeRefCounted<ExternalPrefLoader>(
800 chrome::DIR_USER_EXTERNAL_EXTENSIONS, ExternalPrefLoader::NONE,
801 nullptr),
Taiju Tsuikib1879b72018-09-21 06:22:47802 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
803 Extension::NO_FLAGS));
[email protected]a29a517a2011-01-21 21:11:12804#endif
[email protected]8e4560b62011-01-14 10:09:14805#endif
[email protected]ed7bbb52012-05-02 11:07:29806
[email protected]98b4aca62011-09-28 01:27:23807#if !defined(OS_CHROMEOS)
[email protected]7da12212013-02-14 10:53:49808 // The default apps are installed as INTERNAL but use the external
809 // extension installer codeflow.
Taiju Tsuikib1879b72018-09-21 06:22:47810 provider_list->push_back(std::make_unique<default_apps::Provider>(
811 profile, service,
Matthew Dentonef83a622019-08-30 02:07:00812 base::MakeRefCounted<ExternalPrefLoader>(
813 chrome::DIR_DEFAULT_APPS, ExternalPrefLoader::NONE, nullptr),
Taiju Tsuikib1879b72018-09-21 06:22:47814 Manifest::INTERNAL, Manifest::INTERNAL,
815 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT));
[email protected]98b4aca62011-09-28 01:27:23816#endif
xiyuan65b68ab12015-06-26 19:00:18817
Taiju Tsuikib1879b72018-09-21 06:22:47818 std::unique_ptr<ExternalProviderImpl> drive_migration_provider(
819 new ExternalProviderImpl(
820 service,
Matthew Dentonef83a622019-08-30 02:07:00821 base::MakeRefCounted<ExtensionMigrator>(
822 profile, extension_misc::kDriveHostedAppId,
823 extension_misc::kDocsOfflineExtensionId),
Taiju Tsuikib1879b72018-09-21 06:22:47824 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
825 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT));
826 drive_migration_provider->set_auto_acknowledge(true);
827 provider_list->push_back(std::move(drive_migration_provider));
828 }
treibcc82ab82015-03-02 09:41:49829
Jinho Bangb5216cec2018-01-17 19:43:11830 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
Matthew Dentonef83a622019-08-30 02:07:00831 service, base::MakeRefCounted<ExternalComponentLoader>(profile), profile,
lazyboyf33109d2016-08-31 00:37:08832 Manifest::INVALID_LOCATION, Manifest::EXTERNAL_COMPONENT,
833 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT));
[email protected]8e4560b62011-01-14 10:09:14834}
[email protected]5df038b2012-07-16 19:03:27835
836} // namespace extensions