blob: 14428733acd94f670b54afe3801e5d53b2fc9f11 [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"
Jan Wilken Dörrieb5a41c32020-12-09 18:55:4715#include "base/containers/contains.h"
[email protected]57999812013-02-24 05:40:5216#include "base/files/file_path.h"
[email protected]8e4560b62011-01-14 10:09:1417#include "base/logging.h"
Matthew Dentonef83a622019-08-30 02:07:0018#include "base/memory/scoped_refptr.h"
[email protected]51a7a9d2011-09-27 17:21:4119#include "base/metrics/field_trial.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"
Yuta Hijikata1290fee22020-11-25 09:46:2826#include "build/chromeos_buildflags.h"
[email protected]8a839a02013-03-07 05:23:3327#include "chrome/browser/app_mode/app_mode_utils.h"
[email protected]e601e822011-10-05 19:25:3728#include "chrome/browser/browser_process.h"
pbond43ddd4f2015-09-08 16:39:1929#include "chrome/browser/browser_process_platform_part.h"
binjin30301062014-09-08 20:27:3430#include "chrome/browser/extensions/extension_management.h"
xiyuan65b68ab12015-06-26 19:00:1831#include "chrome/browser/extensions/extension_migrator.h"
[email protected]8aa50c7752013-05-23 12:57:5032#include "chrome/browser/extensions/external_component_loader.h"
[email protected]5df038b2012-07-16 19:03:2733#include "chrome/browser/extensions/external_policy_loader.h"
34#include "chrome/browser/extensions/external_pref_loader.h"
Oleg Davydovdec175a2020-05-25 16:44:2935#include "chrome/browser/extensions/forced_extensions/install_stage_tracker.h"
dpolukhin1687ef32015-06-22 11:12:3736#include "chrome/browser/policy/profile_policy_connector.h"
[email protected]8e4560b62011-01-14 10:09:1437#include "chrome/browser/profiles/profile.h"
Daniel Murphy3657906d2021-04-13 20:33:1238#include "chrome/browser/web_applications/components/preinstalled_app_install_features.h"
[email protected]f0841cd2011-01-19 15:07:2439#include "chrome/common/chrome_paths.h"
[email protected]83b59325a2011-10-14 15:58:0740#include "chrome/common/chrome_switches.h"
xiyuan65b68ab12015-06-26 19:00:1841#include "chrome/common/extensions/extension_constants.h"
dpolukhin2c6ef2932015-05-12 16:06:1342#include "chrome/common/pref_names.h"
[email protected]fdd28372014-08-21 02:27:2643#include "components/crx_file/id_util.h"
brettwb1fc1b82016-02-02 00:19:0844#include "components/prefs/pref_service.h"
[email protected]c38831a12011-10-28 12:44:4945#include "content/public/browser/browser_thread.h"
David Bertoni58c113a2019-08-02 19:53:2646#include "extensions/browser/extension_registry.h"
lazyboye8634172016-01-28 00:10:4847#include "extensions/browser/external_install_info.h"
[email protected]301116c62013-11-26 10:37:4548#include "extensions/browser/external_provider_interface.h"
Dominique Fauteux-Chapleauff3bb352019-10-16 14:32:3449#include "extensions/browser/pref_names.h"
[email protected]e4452d32013-11-15 23:07:4150#include "extensions/common/extension.h"
[email protected]d42c11152013-08-22 19:36:3251#include "extensions/common/manifest.h"
[email protected]9d32ded072011-10-11 16:31:0552#include "ui/base/l10n/l10n_util.h"
[email protected]8e4560b62011-01-14 10:09:1453
Yuta Hijikata1290fee22020-11-25 09:46:2854#if BUILDFLAG(IS_CHROMEOS_ASH)
Henrique Ferreiro37770262021-02-06 01:20:5355#include "ash/constants/ash_paths.h"
Wenzhao Zang463f1142018-09-05 22:50:5056#include "base/path_service.h"
Henrique Ferreiro53d4dc42021-01-27 01:02:3857#include "chrome/browser/ash/app_mode/kiosk_app_external_loader.h"
Yeunjoo Choi91907642021-04-16 13:18:1958#include "chrome/browser/ash/customization/customization_document.h"
Henrique Ferreiro606669a2021-02-24 13:36:5559#include "chrome/browser/ash/login/demo_mode/demo_extensions_external_loader.h"
60#include "chrome/browser/ash/login/demo_mode/demo_session.h"
Yeunjoo Choi7227dba2021-08-04 06:35:4761#include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h"
Yeunjoo Choi8623e4a2021-07-02 01:57:0662#include "chrome/browser/ash/policy/core/device_local_account.h"
63#include "chrome/browser/ash/policy/core/device_local_account_policy_service.h"
Yeunjoo Choi15ab1ac2021-02-04 17:15:0764#include "chrome/browser/ash/profiles/profile_helper.h"
[email protected]af984882013-10-21 21:08:5165#include "chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.h"
Maksim Ivanov8738d332020-01-07 22:19:0166#include "chrome/browser/chromeos/extensions/signin_screen_extensions_external_loader.h"
Ahmed Fakhry9ef29e042017-09-01 16:32:0067#include "components/arc/arc_util.h"
Swapnil5eca0412021-02-12 08:32:5468#include "extensions/common/constants.h"
[email protected]b39d25712013-03-14 09:53:4069#else
Daniel Murphy3657906d2021-04-13 20:33:1270#include "chrome/browser/extensions/preinstalled_apps.h"
[email protected]86c6b9e32011-10-25 17:09:1071#endif
72
[email protected]8e4560b62011-01-14 10:09:1473#if defined(OS_WIN)
[email protected]5df038b2012-07-16 19:03:2774#include "chrome/browser/extensions/external_registry_loader_win.h"
[email protected]8e4560b62011-01-14 10:09:1475#endif
76
[email protected]631bb742011-11-02 11:29:3977using content::BrowserThread;
Gyuyoung Kim2e954c42021-03-19 14:06:2978using extensions::mojom::ManifestLocation;
[email protected]5df038b2012-07-16 19:03:2779
80namespace extensions {
[email protected]631bb742011-11-02 11:29:3981
Ahmed Fakhry9ef29e042017-09-01 16:32:0082namespace {
83
Yuta Hijikata1290fee22020-11-25 09:46:2884#if BUILDFLAG(IS_CHROMEOS_ASH)
Ahmed Fakhry9ef29e042017-09-01 16:32:0085
Daniel Murphy3657906d2021-04-13 20:33:1286// Certain pre-installed extensions are no longer needed on ARC devices as they
87// were replaced by their ARC counterparts.
Ahmed Fakhry9ef29e042017-09-01 16:32:0088bool ShouldUninstallExtensionReplacedByArcApp(const std::string& extension_id) {
Alex Newcomerf8c542f2018-08-13 23:48:5089 if (!arc::IsArcAvailable())
Ahmed Fakhry9ef29e042017-09-01 16:32:0090 return false;
91
92 if (extension_id == extension_misc::kGooglePlayBooksAppId ||
93 extension_id == extension_misc::kGooglePlayMoviesAppId ||
94 extension_id == extension_misc::kGooglePlayMusicAppId) {
95 return true;
96 }
97
98 return false;
99}
100
Yuta Hijikata1290fee22020-11-25 09:46:28101#endif // BUILDFLAG(IS_CHROMEOS_ASH)
Ahmed Fakhry9ef29e042017-09-01 16:32:00102
103} // namespace
104
[email protected]8e4560b62011-01-14 10:09:14105// Constants for keeping track of extension preferences in a dictionary.
[email protected]d8fd0fd2014-03-24 13:16:06106const char ExternalProviderImpl::kInstallParam[] = "install_parameter";
[email protected]5df038b2012-07-16 19:03:27107const char ExternalProviderImpl::kExternalCrx[] = "external_crx";
[email protected]7425d7df2012-11-28 14:35:42108const char ExternalProviderImpl::kExternalVersion[] = "external_version";
109const char ExternalProviderImpl::kExternalUpdateUrl[] = "external_update_url";
[email protected]7425d7df2012-11-28 14:35:42110const char ExternalProviderImpl::kIsBookmarkApp[] = "is_bookmark_app";
111const char ExternalProviderImpl::kIsFromWebstore[] = "is_from_webstore";
[email protected]19eac6d2013-05-30 06:51:03112const char ExternalProviderImpl::kKeepIfPresent[] = "keep_if_present";
[email protected]bf9fd5ae2014-04-09 22:50:06113const char ExternalProviderImpl::kWasInstalledByOem[] = "was_installed_by_oem";
Alan Cutterb81d0e02020-08-05 09:10:34114const char ExternalProviderImpl::kWebAppMigrationFlag[] =
115 "web_app_migration_flag";
[email protected]bf9fd5ae2014-04-09 22:50:06116const char ExternalProviderImpl::kSupportedLocales[] = "supported_locales";
[email protected]2b6a5802014-08-16 07:58:08117const char ExternalProviderImpl::kMayBeUntrusted[] = "may_be_untrusted";
dpolukhin2c6ef2932015-05-12 16:06:13118const char ExternalProviderImpl::kMinProfileCreatedByVersion[] =
119 "min_profile_created_by_version";
dpolukhin1687ef32015-06-22 11:12:37120const char ExternalProviderImpl::kDoNotInstallForEnterprise[] =
121 "do_not_install_for_enterprise";
[email protected]8e4560b62011-01-14 10:09:14122
[email protected]af984882013-10-21 21:08:51123ExternalProviderImpl::ExternalProviderImpl(
124 VisitorInterface* service,
125 const scoped_refptr<ExternalLoader>& loader,
126 Profile* profile,
Gyuyoung Kim2e954c42021-03-19 14:06:29127 ManifestLocation crx_location,
128 ManifestLocation download_location,
[email protected]af984882013-10-21 21:08:51129 int creation_flags)
[email protected]4b4c0132013-06-12 17:58:55130 : crx_location_(crx_location),
131 download_location_(download_location),
132 service_(service),
[email protected]4b4c0132013-06-12 17:58:55133 loader_(loader),
134 profile_(profile),
Toni Barzic87026682018-01-08 23:21:04135 creation_flags_(creation_flags) {
Oleg Davydov66246bd92019-09-26 16:31:51136 DCHECK(profile_);
[email protected]8e4560b62011-01-14 10:09:14137 loader_->Init(this);
138}
139
[email protected]5df038b2012-07-16 19:03:27140ExternalProviderImpl::~ExternalProviderImpl() {
Istiaque Ahmedf6e72622017-09-08 23:14:17141 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14142 loader_->OwnerShutdown();
143}
144
[email protected]5df038b2012-07-16 19:03:27145void ExternalProviderImpl::VisitRegisteredExtension() {
[email protected]8e4560b62011-01-14 10:09:14146 // The loader will call back to SetPrefs.
147 loader_->StartLoading();
148}
149
Istiaque Ahmeda7431b32017-08-20 18:33:37150void ExternalProviderImpl::SetPrefs(
151 std::unique_ptr<base::DictionaryValue> prefs) {
Istiaque Ahmedf6e72622017-09-08 23:14:17152 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14153
[email protected]47fc70c2011-12-06 07:29:51154 // Check if the service is still alive. It is possible that it went
[email protected]8e4560b62011-01-14 10:09:14155 // away while |loader_| was working on the FILE thread.
156 if (!service_) return;
157
Oleg Davydovdec175a2020-05-25 16:44:29158 InstallStageTracker* install_stage_tracker =
159 InstallStageTracker::Get(profile_);
Peter Kasting7c683fe2021-06-24 15:12:10160 for (auto it : prefs->DictItems()) {
Swapnil5e0e0dc2020-09-21 14:59:47161 install_stage_tracker->ReportInstallCreationStage(
162 it.first,
163 InstallStageTracker::InstallCreationStage::SEEN_BY_EXTERNAL_PROVIDER);
Oleg Davydov52db8742019-08-20 09:14:40164 }
165
Istiaque Ahmeda7431b32017-08-20 18:33:37166 prefs_ = std::move(prefs);
[email protected]8a839a02013-03-07 05:23:33167 ready_ = true; // Queries for extensions are allowed from this point.
[email protected]8e4560b62011-01-14 10:09:14168
Devlin Cronin19f70b6a2017-10-01 04:14:05169 std::vector<ExternalInstallInfoUpdateUrl> external_update_url_extensions;
170 std::vector<ExternalInstallInfoFile> external_file_extensions;
lazyboye8634172016-01-28 00:10:48171
172 RetrieveExtensionsFromPrefs(&external_update_url_extensions,
173 &external_file_extensions);
lazyboy4aeef202016-09-07 21:28:59174 for (const auto& extension : external_update_url_extensions)
Devlin Cronin19f70b6a2017-10-01 04:14:05175 service_->OnExternalExtensionUpdateUrlFound(extension, true);
lazyboye8634172016-01-28 00:10:48176
lazyboy4aeef202016-09-07 21:28:59177 for (const auto& extension : external_file_extensions)
Devlin Cronin19f70b6a2017-10-01 04:14:05178 service_->OnExternalExtensionFileFound(extension);
lazyboye8634172016-01-28 00:10:48179
180 service_->OnExternalProviderReady(this);
181}
182
Istiaque Ahmeda7431b32017-08-20 18:33:37183void ExternalProviderImpl::UpdatePrefs(
184 std::unique_ptr<base::DictionaryValue> prefs) {
Istiaque Ahmedf6e72622017-09-08 23:14:17185 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Toni Barzic87026682018-01-08 23:21:04186 CHECK(allow_updates_);
lazyboye8634172016-01-28 00:10:48187
188 // Check if the service is still alive. It is possible that it went
189 // away while |loader_| was working on the FILE thread.
190 if (!service_)
191 return;
192
193 std::set<std::string> removed_extensions;
194 // Find extensions that were removed by this ExternalProvider.
195 for (base::DictionaryValue::Iterator i(*prefs_); !i.IsAtEnd(); i.Advance()) {
196 const std::string& extension_id = i.key();
197 // Don't bother about invalid ids.
198 if (!crx_file::id_util::IdIsValid(extension_id))
199 continue;
200 if (!prefs->HasKey(extension_id))
201 removed_extensions.insert(extension_id);
202 }
203
Istiaque Ahmeda7431b32017-08-20 18:33:37204 prefs_ = std::move(prefs);
lazyboye8634172016-01-28 00:10:48205
Devlin Cronin19f70b6a2017-10-01 04:14:05206 std::vector<ExternalInstallInfoUpdateUrl> external_update_url_extensions;
207 std::vector<ExternalInstallInfoFile> external_file_extensions;
lazyboye8634172016-01-28 00:10:48208 RetrieveExtensionsFromPrefs(&external_update_url_extensions,
209 &external_file_extensions);
210
211 // Notify ExtensionService about completion of finding incremental updates
212 // from this provider.
213 // Provide the list of added and removed extensions.
214 service_->OnExternalProviderUpdateComplete(
215 this, external_update_url_extensions, external_file_extensions,
216 removed_extensions);
217}
218
219void ExternalProviderImpl::RetrieveExtensionsFromPrefs(
Devlin Cronin19f70b6a2017-10-01 04:14:05220 std::vector<ExternalInstallInfoUpdateUrl>* external_update_url_extensions,
221 std::vector<ExternalInstallInfoFile>* external_file_extensions) {
[email protected]9d32ded072011-10-11 16:31:05222 // Set of unsupported extensions that need to be deleted from prefs_.
223 std::set<std::string> unsupported_extensions;
Oleg Davydovdec175a2020-05-25 16:44:29224 InstallStageTracker* install_stage_tracker =
225 InstallStageTracker::Get(profile_);
[email protected]9d32ded072011-10-11 16:31:05226
lazyboye8634172016-01-28 00:10:48227 // Discover all the extensions this provider has.
[email protected]aeca23f2013-06-21 22:34:41228 for (base::DictionaryValue::Iterator i(*prefs_); !i.IsAtEnd(); i.Advance()) {
[email protected]02d9b272013-03-06 12:54:56229 const std::string& extension_id = i.key();
Bartek Nowierski3253b672020-06-01 20:37:12230 const base::DictionaryValue* extension = nullptr;
[email protected]ab22ba42011-01-14 16:36:38231
Yuta Hijikata1290fee22020-11-25 09:46:28232#if BUILDFLAG(IS_CHROMEOS_ASH)
Swapnil5eca0412021-02-12 08:32:54233 if (extension_id == extension_misc::kCameraAppId) {
234 unsupported_extensions.insert(extension_id);
235 install_stage_tracker->ReportFailure(
236 extension_id,
237 InstallStageTracker::FailureReason::REPLACED_BY_SYSTEM_APP);
238 continue;
239 }
240
Ahmed Fakhry9ef29e042017-09-01 16:32:00241 if (ShouldUninstallExtensionReplacedByArcApp(extension_id)) {
242 VLOG(1) << "Extension with key: " << extension_id << " was replaced "
243 << "by a default ARC app, and will be uninstalled.";
244 unsupported_extensions.emplace(extension_id);
Oleg Davydovdec175a2020-05-25 16:44:29245 install_stage_tracker->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51246 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29247 InstallStageTracker::FailureReason::REPLACED_BY_ARC_APP);
Ahmed Fakhry9ef29e042017-09-01 16:32:00248 continue;
249 }
Yuta Hijikata1290fee22020-11-25 09:46:28250#endif // BUILDFLAG(IS_CHROMEOS_ASH)
Ahmed Fakhry9ef29e042017-09-01 16:32:00251
[email protected]fdd28372014-08-21 02:27:26252 if (!crx_file::id_util::IdIsValid(extension_id)) {
[email protected]ab22ba42011-01-14 16:36:38253 LOG(WARNING) << "Malformed extension dictionary: key "
254 << extension_id.c_str() << " is not a valid id.";
Oleg Davydovdec175a2020-05-25 16:44:29255 install_stage_tracker->ReportFailure(
256 extension_id, InstallStageTracker::FailureReason::INVALID_ID);
[email protected]8e4560b62011-01-14 10:09:14257 continue;
[email protected]ab22ba42011-01-14 16:36:38258 }
259
[email protected]02d9b272013-03-06 12:54:56260 if (!i.value().GetAsDictionary(&extension)) {
[email protected]ab22ba42011-01-14 16:36:38261 LOG(WARNING) << "Malformed extension dictionary: key "
262 << extension_id.c_str()
263 << " has a value that is not a dictionary.";
Oleg Davydovdec175a2020-05-25 16:44:29264 install_stage_tracker->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51265 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29266 InstallStageTracker::FailureReason::MALFORMED_EXTENSION_DICT);
[email protected]ab22ba42011-01-14 16:36:38267 continue;
268 }
[email protected]8e4560b62011-01-14 10:09:14269
Peter Kasting141279b2021-02-09 22:34:20270 std::string external_crx;
Bartek Nowierski3253b672020-06-01 20:37:12271 const base::Value* external_version_value = nullptr;
[email protected]8e4560b62011-01-14 10:09:14272 std::string external_version;
273 std::string external_update_url;
274
275 bool has_external_crx = extension->GetString(kExternalCrx, &external_crx);
[email protected]0d461c52012-07-03 19:29:41276
277 bool has_external_version = false;
278 if (extension->Get(kExternalVersion, &external_version_value)) {
jdoerrie1f536b22017-10-23 17:15:11279 if (external_version_value->is_string()) {
Alex Rudenkoa4d75ab52021-07-09 15:39:44280 external_version = external_version_value->GetString();
[email protected]0d461c52012-07-03 19:29:41281 has_external_version = true;
282 } else {
Oleg Davydovdec175a2020-05-25 16:44:29283 install_stage_tracker->ReportFailure(
284 extension_id, InstallStageTracker::FailureReason::
Oleg Davydov66246bd92019-09-26 16:31:51285 MALFORMED_EXTENSION_DICT_VERSION);
[email protected]0d461c52012-07-03 19:29:41286 LOG(WARNING) << "Malformed extension dictionary for extension: "
287 << extension_id.c_str() << ". " << kExternalVersion
288 << " value must be a string.";
289 continue;
290 }
291 }
292
[email protected]8e4560b62011-01-14 10:09:14293 bool has_external_update_url = extension->GetString(kExternalUpdateUrl,
294 &external_update_url);
295 if (has_external_crx != has_external_version) {
Oleg Davydovdec175a2020-05-25 16:44:29296 install_stage_tracker->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51297 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29298 InstallStageTracker::FailureReason::MALFORMED_EXTENSION_DICT);
[email protected]8e4560b62011-01-14 10:09:14299 LOG(WARNING) << "Malformed extension dictionary for extension: "
300 << extension_id.c_str() << ". " << kExternalCrx
301 << " and " << kExternalVersion << " must be used together.";
302 continue;
303 }
304
305 if (has_external_crx == has_external_update_url) {
Oleg Davydovdec175a2020-05-25 16:44:29306 install_stage_tracker->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51307 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29308 InstallStageTracker::FailureReason::MALFORMED_EXTENSION_DICT);
[email protected]8e4560b62011-01-14 10:09:14309 LOG(WARNING) << "Malformed extension dictionary for extension: "
310 << extension_id.c_str() << ". Exactly one of the "
311 << "followng keys should be used: " << kExternalCrx
312 << ", " << kExternalUpdateUrl << ".";
313 continue;
314 }
315
[email protected]9d32ded072011-10-11 16:31:05316 // Check that extension supports current browser locale.
Bartek Nowierski3253b672020-06-01 20:37:12317 const base::ListValue* supported_locales = nullptr;
[email protected]9d32ded072011-10-11 16:31:05318 if (extension->GetList(kSupportedLocales, &supported_locales)) {
319 std::vector<std::string> browser_locales;
320 l10n_util::GetParentLocales(g_browser_process->GetApplicationLocale(),
321 &browser_locales);
322
323 size_t num_locales = supported_locales->GetSize();
324 bool locale_supported = false;
325 for (size_t j = 0; j < num_locales; j++) {
326 std::string current_locale;
327 if (supported_locales->GetString(j, &current_locale) &&
328 l10n_util::IsValidLocaleSyntax(current_locale)) {
329 current_locale = l10n_util::NormalizeLocale(current_locale);
Jan Wilken Dörrieade79222019-06-06 19:01:12330 if (base::Contains(browser_locales, current_locale)) {
[email protected]9d32ded072011-10-11 16:31:05331 locale_supported = true;
332 break;
333 }
334 } else {
335 LOG(WARNING) << "Unrecognized locale '" << current_locale
336 << "' found as supported locale for extension: "
337 << extension_id;
338 }
339 }
340
341 if (!locale_supported) {
342 unsupported_extensions.insert(extension_id);
Oleg Davydovdec175a2020-05-25 16:44:29343 install_stage_tracker->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51344 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29345 InstallStageTracker::FailureReason::LOCALE_NOT_SUPPORTED);
[email protected]19eac6d2013-05-30 06:51:03346 VLOG(1) << "Skip installing (or uninstall) external extension: "
347 << extension_id << " because the extension doesn't support "
348 << "the browser locale.";
[email protected]9d32ded072011-10-11 16:31:05349 continue;
350 }
351 }
352
[email protected]f121003b2012-05-04 21:57:47353 int creation_flags = creation_flags_;
354 bool is_bookmark_app;
355 if (extension->GetBoolean(kIsBookmarkApp, &is_bookmark_app) &&
356 is_bookmark_app) {
357 creation_flags |= Extension::FROM_BOOKMARK;
358 }
[email protected]2b6a5802014-08-16 07:58:08359 bool is_from_webstore = false;
[email protected]7425d7df2012-11-28 14:35:42360 if (extension->GetBoolean(kIsFromWebstore, &is_from_webstore) &&
361 is_from_webstore) {
362 creation_flags |= Extension::FROM_WEBSTORE;
363 }
Alan Cutterb81d0e02020-08-05 09:10:34364
365 // If the extension is in a web app migration treat it as "keep_if_present"
366 // so it can get uninstalled by WebAppUiManager::UninstallAndReplace() once
367 // the replacement web app has installed and migrated over user preferences.
368 // TODO(crbug.com/1099150): Remove this field after migration is complete.
369 const std::string* web_app_migration_flag =
370 extension->FindStringPath(kWebAppMigrationFlag);
371 bool is_migrating_to_web_app =
372 web_app_migration_flag &&
Alan Cutter52914e72021-05-05 09:35:48373 web_app::IsPreinstalledAppInstallFeatureEnabled(*web_app_migration_flag,
374 *profile_);
Alan Cutterb81d0e02020-08-05 09:10:34375 bool keep_if_present =
376 extension->FindBoolPath(kKeepIfPresent).value_or(false);
377 if (keep_if_present || is_migrating_to_web_app) {
David Bertoni58c113a2019-08-02 19:53:26378 ExtensionRegistry* extension_registry = ExtensionRegistry::Get(profile_);
379 const Extension* extension =
David Bertonia0b34722019-09-30 20:51:26380 extension_registry ? extension_registry->GetExtensionById(
381 extension_id, ExtensionRegistry::EVERYTHING)
382 : nullptr;
[email protected]19eac6d2013-05-30 06:51:03383 if (!extension) {
dpolukhin2c6ef2932015-05-12 16:06:13384 unsupported_extensions.insert(extension_id);
Oleg Davydovdec175a2020-05-25 16:44:29385 install_stage_tracker->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51386 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29387 InstallStageTracker::FailureReason::NOT_PERFORMING_NEW_INSTALL);
[email protected]19eac6d2013-05-30 06:51:03388 VLOG(1) << "Skip installing (or uninstall) external extension: "
389 << extension_id << " because the extension should be kept "
390 << "only if it is already installed.";
391 continue;
392 }
393 }
Alan Cutterb81d0e02020-08-05 09:10:34394
dpolukhind0be494a2015-05-28 09:43:17395 bool was_installed_by_oem = false;
396 if (extension->GetBoolean(kWasInstalledByOem, &was_installed_by_oem) &&
397 was_installed_by_oem) {
398 creation_flags |= Extension::WAS_INSTALLED_BY_OEM;
399 }
[email protected]2b6a5802014-08-16 07:58:08400 bool may_be_untrusted = false;
401 if (extension->GetBoolean(kMayBeUntrusted, &may_be_untrusted) &&
402 may_be_untrusted) {
403 creation_flags |= Extension::MAY_BE_UNTRUSTED;
404 }
[email protected]f121003b2012-05-04 21:57:47405
dpolukhin1687ef32015-06-22 11:12:37406 if (!HandleMinProfileVersion(extension, extension_id,
407 &unsupported_extensions)) {
dpolukhin2c6ef2932015-05-12 16:06:13408 continue;
dpolukhin1687ef32015-06-22 11:12:37409 }
410
411 if (!HandleDoNotInstallForEnterprise(extension, extension_id,
412 &unsupported_extensions)) {
413 continue;
414 }
dpolukhin2c6ef2932015-05-12 16:06:13415
[email protected]d8fd0fd2014-03-24 13:16:06416 std::string install_parameter;
417 extension->GetString(kInstallParam, &install_parameter);
418
[email protected]8e4560b62011-01-14 10:09:14419 if (has_external_crx) {
Gyuyoung Kim2e954c42021-03-19 14:06:29420 if (crx_location_ == ManifestLocation::kInvalidLocation) {
Oleg Davydovdec175a2020-05-25 16:44:29421 install_stage_tracker->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51422 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29423 InstallStageTracker::FailureReason::NOT_SUPPORTED_EXTENSION_DICT);
[email protected]8e4560b62011-01-14 10:09:14424 LOG(WARNING) << "This provider does not support installing external "
425 << "extensions from crx files.";
426 continue;
427 }
Peter Kasting141279b2021-02-09 22:34:20428
429 base::FilePath path = base::FilePath::FromUTF8Unsafe(external_crx);
430 if (path.value().find(base::FilePath::kParentDirectory) !=
[email protected]8e4560b62011-01-14 10:09:14431 base::StringPiece::npos) {
Oleg Davydovdec175a2020-05-25 16:44:29432 install_stage_tracker->ReportFailure(
433 extension_id, InstallStageTracker::FailureReason::
Oleg Davydov66246bd92019-09-26 16:31:51434 MALFORMED_EXTENSION_DICT_FILE_PATH);
[email protected]8e4560b62011-01-14 10:09:14435 LOG(WARNING) << "Path traversal not allowed in path: "
436 << external_crx.c_str();
437 continue;
438 }
439
[email protected]f0841cd2011-01-19 15:07:24440 // If the path is relative, and the provider has a base path,
441 // build the absolute path to the crx file.
Peter Kasting141279b2021-02-09 22:34:20442
[email protected]8e4560b62011-01-14 10:09:14443 if (!path.IsAbsolute()) {
[email protected]650b2d52013-02-10 03:41:45444 base::FilePath base_path = loader_->GetBaseCrxFilePath();
[email protected]f0841cd2011-01-19 15:07:24445 if (base_path.empty()) {
Oleg Davydovdec175a2020-05-25 16:44:29446 install_stage_tracker->ReportFailure(
447 extension_id, InstallStageTracker::FailureReason::
Oleg Davydov66246bd92019-09-26 16:31:51448 MALFORMED_EXTENSION_DICT_FILE_PATH);
[email protected]f0841cd2011-01-19 15:07:24449 LOG(WARNING) << "File path " << external_crx.c_str()
450 << " is relative. An absolute path is required.";
451 continue;
452 }
Peter Kasting141279b2021-02-09 22:34:20453 path = base_path.Append(path);
[email protected]8e4560b62011-01-14 10:09:14454 }
455
Devlin Cronind4c2a8f32017-09-29 17:08:30456 base::Version version(external_version);
457 if (!version.IsValid()) {
Oleg Davydovdec175a2020-05-25 16:44:29458 install_stage_tracker->ReportFailure(
459 extension_id, InstallStageTracker::FailureReason::
Oleg Davydov66246bd92019-09-26 16:31:51460 MALFORMED_EXTENSION_DICT_VERSION);
[email protected]8e4560b62011-01-14 10:09:14461 LOG(WARNING) << "Malformed extension dictionary for extension: "
462 << extension_id.c_str() << ". Invalid version string \""
463 << external_version << "\".";
464 continue;
465 }
Devlin Cronin19f70b6a2017-10-01 04:14:05466 external_file_extensions->emplace_back(
467 extension_id, version, path, crx_location_, creation_flags,
468 auto_acknowledge_, install_immediately_);
[email protected]8a839a02013-03-07 05:23:33469 } else { // if (has_external_update_url)
[email protected]8e4560b62011-01-14 10:09:14470 CHECK(has_external_update_url); // Checking of keys above ensures this.
Gyuyoung Kim2e954c42021-03-19 14:06:29471 if (download_location_ == ManifestLocation::kInvalidLocation) {
Oleg Davydovdec175a2020-05-25 16:44:29472 install_stage_tracker->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51473 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29474 InstallStageTracker::FailureReason::NOT_SUPPORTED_EXTENSION_DICT);
[email protected]8e4560b62011-01-14 10:09:14475 LOG(WARNING) << "This provider does not support installing external "
476 << "extensions from update URLs.";
477 continue;
478 }
Devlin Cronind4c2a8f32017-09-29 17:08:30479 GURL update_url(external_update_url);
480 if (!update_url.is_valid()) {
Oleg Davydovdec175a2020-05-25 16:44:29481 install_stage_tracker->ReportFailure(
482 extension_id, InstallStageTracker::FailureReason::
Oleg Davydov66246bd92019-09-26 16:31:51483 MALFORMED_EXTENSION_DICT_UPDATE_URL);
[email protected]8e4560b62011-01-14 10:09:14484 LOG(WARNING) << "Malformed extension dictionary for extension: "
[email protected]ab22ba42011-01-14 16:36:38485 << extension_id.c_str() << ". Key " << kExternalUpdateUrl
486 << " has value \"" << external_update_url
487 << "\", which is not a valid URL.";
[email protected]8e4560b62011-01-14 10:09:14488 continue;
489 }
Devlin Cronin19f70b6a2017-10-01 04:14:05490 external_update_url_extensions->emplace_back(
491 extension_id, install_parameter, std::move(update_url),
492 download_location_, creation_flags, auto_acknowledge_);
[email protected]8e4560b62011-01-14 10:09:14493 }
494 }
495
jdoerrie13cd648c82018-10-02 21:21:02496 for (auto it = unsupported_extensions.begin();
[email protected]9d32ded072011-10-11 16:31:05497 it != unsupported_extensions.end(); ++it) {
498 // Remove extension for the list of know external extensions. The extension
499 // will be uninstalled later because provider doesn't provide it anymore.
Song Fangzhencdbb7062021-07-07 11:13:53500 prefs_->RemoveKey(*it);
[email protected]9d32ded072011-10-11 16:31:05501 }
[email protected]8e4560b62011-01-14 10:09:14502}
503
[email protected]5df038b2012-07-16 19:03:27504void ExternalProviderImpl::ServiceShutdown() {
Bartek Nowierski3253b672020-06-01 20:37:12505 service_ = nullptr;
[email protected]8e4560b62011-01-14 10:09:14506}
507
[email protected]5df038b2012-07-16 19:03:27508bool ExternalProviderImpl::IsReady() const {
[email protected]8e4560b62011-01-14 10:09:14509 return ready_;
510}
511
[email protected]5df038b2012-07-16 19:03:27512bool ExternalProviderImpl::HasExtension(
[email protected]8e4560b62011-01-14 10:09:14513 const std::string& id) const {
Istiaque Ahmedf6e72622017-09-08 23:14:17514 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14515 CHECK(prefs_.get());
516 CHECK(ready_);
517 return prefs_->HasKey(id);
518}
519
[email protected]5df038b2012-07-16 19:03:27520bool ExternalProviderImpl::GetExtensionDetails(
dchengc963c7142016-04-08 03:55:22521 const std::string& id,
Gyuyoung Kim2e954c42021-03-19 14:06:29522 ManifestLocation* location,
pwnallcbd73192016-08-22 18:59:17523 std::unique_ptr<base::Version>* version) const {
Istiaque Ahmedf6e72622017-09-08 23:14:17524 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14525 CHECK(prefs_.get());
526 CHECK(ready_);
Bartek Nowierski3253b672020-06-01 20:37:12527 base::DictionaryValue* extension = nullptr;
[email protected]8e4560b62011-01-14 10:09:14528 if (!prefs_->GetDictionary(id, &extension))
529 return false;
530
Gyuyoung Kim2e954c42021-03-19 14:06:29531 ManifestLocation loc = ManifestLocation::kInvalidLocation;
[email protected]8e4560b62011-01-14 10:09:14532 if (extension->HasKey(kExternalUpdateUrl)) {
533 loc = download_location_;
534
535 } else if (extension->HasKey(kExternalCrx)) {
536 loc = crx_location_;
537
538 std::string external_version;
539 if (!extension->GetString(kExternalVersion, &external_version))
540 return false;
541
542 if (version)
Peter Boström924f8032021-04-02 20:36:02543 *version = std::make_unique<base::Version>(external_version);
[email protected]8e4560b62011-01-14 10:09:14544
545 } else {
546 NOTREACHED(); // Chrome should not allow prefs to get into this state.
547 return false;
548 }
549
550 if (location)
551 *location = loc;
552
553 return true;
554}
555
dpolukhin2c6ef2932015-05-12 16:06:13556bool ExternalProviderImpl::HandleMinProfileVersion(
557 const base::DictionaryValue* extension,
558 const std::string& extension_id,
559 std::set<std::string>* unsupported_extensions) {
560 std::string min_profile_created_by_version;
Oleg Davydov66246bd92019-09-26 16:31:51561 if (extension->GetString(kMinProfileCreatedByVersion,
dpolukhin2c6ef2932015-05-12 16:06:13562 &min_profile_created_by_version)) {
pwnallcbd73192016-08-22 18:59:17563 base::Version profile_version(
dpolukhin2c6ef2932015-05-12 16:06:13564 profile_->GetPrefs()->GetString(prefs::kProfileCreatedByVersion));
pwnallcbd73192016-08-22 18:59:17565 base::Version min_version(min_profile_created_by_version);
dpolukhin2c6ef2932015-05-12 16:06:13566 if (min_version.IsValid() && profile_version.CompareTo(min_version) < 0) {
567 unsupported_extensions->insert(extension_id);
Oleg Davydovdec175a2020-05-25 16:44:29568 InstallStageTracker::Get(profile_)->ReportFailure(
569 extension_id, InstallStageTracker::FailureReason::TOO_OLD_PROFILE);
dpolukhin2c6ef2932015-05-12 16:06:13570 VLOG(1) << "Skip installing (or uninstall) external extension: "
571 << extension_id
572 << " profile.created_by_version: " << profile_version.GetString()
573 << " min_profile_created_by_version: "
574 << min_profile_created_by_version;
575 return false;
576 }
577 }
578 return true;
579}
580
dpolukhin1687ef32015-06-22 11:12:37581bool ExternalProviderImpl::HandleDoNotInstallForEnterprise(
582 const base::DictionaryValue* extension,
583 const std::string& extension_id,
584 std::set<std::string>* unsupported_extensions) {
585 bool do_not_install_for_enterprise = false;
586 if (extension->GetBoolean(kDoNotInstallForEnterprise,
587 &do_not_install_for_enterprise) &&
588 do_not_install_for_enterprise) {
589 const policy::ProfilePolicyConnector* const connector =
Xi Hanfe39afc62019-04-29 14:50:14590 profile_->GetProfilePolicyConnector();
dpolukhin1687ef32015-06-22 11:12:37591 if (connector->IsManaged()) {
592 unsupported_extensions->insert(extension_id);
Oleg Davydovdec175a2020-05-25 16:44:29593 InstallStageTracker::Get(profile_)->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51594 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29595 InstallStageTracker::FailureReason::DO_NOT_INSTALL_FOR_ENTERPRISE);
dpolukhin1687ef32015-06-22 11:12:37596 VLOG(1) << "Skip installing (or uninstall) external extension "
597 << extension_id << " restricted for managed user";
598 return false;
599 }
600 }
601 return true;
602}
603
[email protected]8e4560b62011-01-14 10:09:14604// static
[email protected]5df038b2012-07-16 19:03:27605void ExternalProviderImpl::CreateExternalProviders(
[email protected]8e4560b62011-01-14 10:09:14606 VisitorInterface* service,
607 Profile* profile,
608 ProviderCollection* provider_list) {
rkaplowdd66a1342015-03-05 00:31:49609 TRACE_EVENT0("browser,startup",
610 "ExternalProviderImpl::CreateExternalProviders");
[email protected]af984882013-10-21 21:08:51611 scoped_refptr<ExternalLoader> external_loader;
binjincccacef2014-10-13 19:00:20612 scoped_refptr<ExternalLoader> external_recommended_loader;
Gyuyoung Kim2e954c42021-03-19 14:06:29613 ManifestLocation crx_location = ManifestLocation::kInvalidLocation;
achuithd3da4f02017-03-23 20:05:29614
Yuta Hijikata1290fee22020-11-25 09:46:28615#if BUILDFLAG(IS_CHROMEOS_ASH)
achuithd3da4f02017-03-23 20:05:29616 if (chromeos::ProfileHelper::IsSigninProfile(profile)) {
Maksim Ivanov12801d0d2020-02-18 10:23:41617 // Download extensions/apps installed by policy in the login profile.
618 // Extensions (not apps) installed through this path will have type
619 // |TYPE_LOGIN_SCREEN_EXTENSION| with limited API capabilities.
Gyuyoung Kim2e954c42021-03-19 14:06:29620 crx_location = ManifestLocation::kExternalPolicyDownload;
Maksim Ivanov8738d332020-01-07 22:19:01621 external_loader =
622 base::MakeRefCounted<chromeos::SigninScreenExtensionsExternalLoader>(
Oleg Davydovba7dd392021-03-18 09:47:44623 profile);
Jinho Bangb5216cec2018-01-17 19:43:11624 auto signin_profile_provider = std::make_unique<ExternalProviderImpl>(
achuithd3da4f02017-03-23 20:05:29625 service, external_loader, profile, crx_location,
Gyuyoung Kim2e954c42021-03-19 14:06:29626 ManifestLocation::kExternalPolicyDownload, Extension::FOR_LOGIN_SCREEN);
Maksim Ivanov8738d332020-01-07 22:19:01627 signin_profile_provider->set_auto_acknowledge(true);
Toni Barzic87026682018-01-08 23:21:04628 signin_profile_provider->set_allow_updates(true);
629 provider_list->push_back(std::move(signin_profile_provider));
achuithd3da4f02017-03-23 20:05:29630 return;
631 }
632
Yeunjoo Choi7227dba2021-08-04 06:35:47633 policy::BrowserPolicyConnectorAsh* connector =
634 g_browser_process->platform_part()->browser_policy_connector_ash();
[email protected]2d4cfed2014-01-14 13:59:57635 bool is_chrome_os_public_session = false;
[email protected]2fda9972014-07-23 14:51:59636 const user_manager::User* user =
[email protected]052e3ac2014-06-30 14:22:47637 chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
[email protected]2d4cfed2014-01-14 13:59:57638 policy::DeviceLocalAccount::Type account_type;
Roland Bock4ce23a922021-06-11 13:23:11639 if (user && connector->IsDeviceEnterpriseManaged() &&
alemate909aa58a2016-11-03 22:49:07640 policy::IsDeviceLocalAccountUser(user->GetAccountId().GetUserEmail(),
641 &account_type)) {
[email protected]2d4cfed2014-01-14 13:59:57642 if (account_type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
643 is_chrome_os_public_session = true;
[email protected]af984882013-10-21 21:08:51644 policy::DeviceLocalAccountPolicyBroker* broker =
[email protected]97275822014-01-21 19:30:36645 connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser(
alemate909aa58a2016-11-03 22:49:07646 user->GetAccountId().GetUserEmail());
[email protected]af984882013-10-21 21:08:51647 if (broker) {
648 external_loader = broker->extension_loader();
Gyuyoung Kim2e954c42021-03-19 14:06:29649 crx_location = ManifestLocation::kExternalPolicy;
[email protected]af984882013-10-21 21:08:51650 } else {
651 NOTREACHED();
652 }
653 } else {
Matthew Dentonef83a622019-08-30 02:07:00654 external_loader = base::MakeRefCounted<ExternalPolicyLoader>(
Oleg Davydov52db8742019-08-20 09:14:40655 profile, ExtensionManagementFactory::GetForBrowserContext(profile),
binjincccacef2014-10-13 19:00:20656 ExternalPolicyLoader::FORCED);
Matthew Dentonef83a622019-08-30 02:07:00657 external_recommended_loader = base::MakeRefCounted<ExternalPolicyLoader>(
Oleg Davydov52db8742019-08-20 09:14:40658 profile, ExtensionManagementFactory::GetForBrowserContext(profile),
binjincccacef2014-10-13 19:00:20659 ExternalPolicyLoader::RECOMMENDED);
[email protected]af984882013-10-21 21:08:51660 }
661#else
Matthew Dentonef83a622019-08-30 02:07:00662 external_loader = base::MakeRefCounted<ExternalPolicyLoader>(
Oleg Davydov52db8742019-08-20 09:14:40663 profile, ExtensionManagementFactory::GetForBrowserContext(profile),
binjincccacef2014-10-13 19:00:20664 ExternalPolicyLoader::FORCED);
Matthew Dentonef83a622019-08-30 02:07:00665 external_recommended_loader = base::MakeRefCounted<ExternalPolicyLoader>(
Oleg Davydov52db8742019-08-20 09:14:40666 profile, ExtensionManagementFactory::GetForBrowserContext(profile),
binjincccacef2014-10-13 19:00:20667 ExternalPolicyLoader::RECOMMENDED);
[email protected]af984882013-10-21 21:08:51668#endif
669
[email protected]b9f4fe52012-11-09 21:40:59670 // Policies are mandatory so they can't be skipped with command line flag.
dchengc7047942014-08-26 05:05:31671 if (external_loader.get()) {
Jinho Bangb5216cec2018-01-17 19:43:11672 auto policy_provider = std::make_unique<ExternalProviderImpl>(
lazyboyf33109d2016-08-31 00:37:08673 service, external_loader, profile, crx_location,
Gyuyoung Kim2e954c42021-03-19 14:06:29674 ManifestLocation::kExternalPolicyDownload, Extension::NO_FLAGS);
Toni Barzic87026682018-01-08 23:21:04675 policy_provider->set_allow_updates(true);
676 provider_list->push_back(std::move(policy_provider));
[email protected]af984882013-10-21 21:08:51677 }
[email protected]b9f4fe52012-11-09 21:40:59678
Anqing Zhaof0e96fb42020-12-11 23:21:21679 // Load the KioskAppExternalProvider when running in the Chrome App kiosk
680 // mode.
[email protected]ee3da0552014-07-16 05:27:31681 if (chrome::IsRunningInForcedAppMode()) {
Yuta Hijikata1290fee22020-11-25 09:46:28682#if BUILDFLAG(IS_CHROMEOS_ASH)
Anqing Zhaof0e96fb42020-12-11 23:21:21683 if (user && user->GetType() == user_manager::USER_TYPE_KIOSK_APP) {
684 // Kiosk primary app external provider.
685 // For enterprise managed kiosk apps, change the location to
686 // "force-installed by policy".
Yeunjoo Choi7227dba2021-08-04 06:35:47687 policy::BrowserPolicyConnectorAsh* const connector =
688 g_browser_process->platform_part()->browser_policy_connector_ash();
Gyuyoung Kim2e954c42021-03-19 14:06:29689 ManifestLocation location = ManifestLocation::kExternalPref;
Roland Bock4ce23a922021-06-11 13:23:11690 if (connector && connector->IsDeviceEnterpriseManaged())
Gyuyoung Kim2e954c42021-03-19 14:06:29691 location = ManifestLocation::kExternalPolicy;
pbond43ddd4f2015-09-08 16:39:19692
Anqing Zhaof0e96fb42020-12-11 23:21:21693 auto kiosk_app_provider = std::make_unique<ExternalProviderImpl>(
694 service,
Henrique Ferreiro26ed25a2021-02-01 21:59:29695 base::MakeRefCounted<ash::KioskAppExternalLoader>(
696 ash::KioskAppExternalLoader::AppClass::kPrimary),
Gyuyoung Kim2e954c42021-03-19 14:06:29697 profile, location, ManifestLocation::kInvalidLocation,
698 Extension::NO_FLAGS);
Anqing Zhaof0e96fb42020-12-11 23:21:21699 kiosk_app_provider->set_auto_acknowledge(true);
700 kiosk_app_provider->set_install_immediately(true);
701 kiosk_app_provider->set_allow_updates(true);
702 provider_list->push_back(std::move(kiosk_app_provider));
jennyz26b7f432015-09-03 20:59:27703
Anqing Zhaof0e96fb42020-12-11 23:21:21704 // Kiosk secondary app external provider.
705 auto secondary_kiosk_app_provider =
706 std::make_unique<ExternalProviderImpl>(
707 service,
Henrique Ferreiro26ed25a2021-02-01 21:59:29708 base::MakeRefCounted<ash::KioskAppExternalLoader>(
709 ash::KioskAppExternalLoader::AppClass::kSecondary),
Gyuyoung Kim2e954c42021-03-19 14:06:29710 profile, ManifestLocation::kExternalPref,
711 ManifestLocation::kExternalPrefDownload, Extension::NO_FLAGS);
Anqing Zhaof0e96fb42020-12-11 23:21:21712 secondary_kiosk_app_provider->set_auto_acknowledge(true);
713 secondary_kiosk_app_provider->set_install_immediately(true);
714 secondary_kiosk_app_provider->set_allow_updates(true);
715 provider_list->push_back(std::move(secondary_kiosk_app_provider));
716 }
[email protected]ee3da0552014-07-16 05:27:31717#endif
718 return;
719 }
720
binjincccacef2014-10-13 19:00:20721 // Extensions provided by recommended policies.
722 if (external_recommended_loader.get()) {
Nicolas Ouellet-Payeur93b74ca1d2020-12-09 23:33:12723 auto recommended_provider = std::make_unique<ExternalProviderImpl>(
lazyboyf33109d2016-08-31 00:37:08724 service, external_recommended_loader, profile, crx_location,
Gyuyoung Kim2e954c42021-03-19 14:06:29725 ManifestLocation::kExternalPrefDownload, Extension::NO_FLAGS);
Nicolas Ouellet-Payeur93b74ca1d2020-12-09 23:33:12726 recommended_provider->set_auto_acknowledge(true);
727 provider_list->push_back(std::move(recommended_provider));
binjincccacef2014-10-13 19:00:20728 }
729
Daniel Murphy3657906d2021-04-13 20:33:12730 // In tests don't install pre-installed apps.
[email protected]b9f4fe52012-11-09 21:40:59731 // It would only slowdown tests and make them flaky.
avi3ef9ec9e2014-12-22 22:50:17732 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
Daniel Murphy3657906d2021-04-13 20:33:12733 ::switches::kDisablePreinstalledApps)) {
[email protected]b9f4fe52012-11-09 21:40:59734 return;
[email protected]98820ac72019-01-24 19:47:16735 }
[email protected]73e4c362011-09-22 14:47:18736
Peter Kasting9c68b0f2021-07-27 09:47:40737#if !defined(OS_WIN)
[email protected]73e4c362011-09-22 14:47:18738 // On Mac OS, items in /Library/... should be written by the superuser.
739 // Check that all components of the path are writable by root only.
[email protected]5df038b2012-07-16 19:03:27740 ExternalPrefLoader::Options check_admin_permissions_on_mac;
Avi Drissman2e458df2020-07-29 16:24:31741#if defined(OS_MAC)
[email protected]0edc55412011-11-07 16:47:33742 check_admin_permissions_on_mac =
Peter Kasting9c68b0f2021-07-27 09:47:40743 ExternalPrefLoader::ENSURE_PATH_CONTROLLED_BY_ADMIN;
[email protected]73e4c362011-09-22 14:47:18744#else
[email protected]5df038b2012-07-16 19:03:27745 check_admin_permissions_on_mac = ExternalPrefLoader::NONE;
[email protected]73e4c362011-09-22 14:47:18746#endif
[email protected]d6f7b102012-05-04 13:59:05747 int bundled_extension_creation_flags = Extension::NO_FLAGS;
Peter Kastingbe940e92014-11-20 23:14:08748#endif
Yuta Hijikata1290fee22020-11-25 09:46:28749#if BUILDFLAG(IS_CHROMEOS_ASH)
[email protected]5861bcd2012-10-16 21:40:19750 bundled_extension_creation_flags = Extension::FROM_WEBSTORE |
751 Extension::WAS_INSTALLED_BY_DEFAULT;
[email protected]a4567732013-07-25 21:01:20752
rkcb526cd6b2014-12-18 16:54:37753 if (!is_chrome_os_public_session) {
[email protected]98820ac72019-01-24 19:47:16754 int pref_load_flags =
ginkagef66fae522015-03-03 16:38:16755 profile->IsNewProfile()
756 ? ExternalPrefLoader::DELAY_LOAD_UNTIL_PRIORITY_SYNC
757 : ExternalPrefLoader::NONE;
[email protected]98820ac72019-01-24 19:47:16758 pref_load_flags |= ExternalPrefLoader::USE_USER_TYPE_PROFILE_FILTER;
759 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
760 service,
Matthew Dentonef83a622019-08-30 02:07:00761 base::MakeRefCounted<ExternalPrefLoader>(
762 chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS, pref_load_flags,
763 profile),
Gyuyoung Kim2e954c42021-03-19 14:06:29764 profile, ManifestLocation::kExternalPref,
765 ManifestLocation::kExternalPrefDownload,
[email protected]98820ac72019-01-24 19:47:16766 bundled_extension_creation_flags));
[email protected]d0b28892014-03-05 18:56:31767
Daniel Murphy3657906d2021-04-13 20:33:12768 // OEM pre-installed apps.
[email protected]acc3c7c22014-03-19 06:23:39769 int oem_extension_creation_flags =
770 bundled_extension_creation_flags | Extension::WAS_INSTALLED_BY_OEM;
Yeunjoo Choicf61fba2021-04-23 02:43:09771 ash::ServicesCustomizationDocument* customization =
772 ash::ServicesCustomizationDocument::GetInstance();
Jinho Bangb5216cec2018-01-17 19:43:11773 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
lazyboyf33109d2016-08-31 00:37:08774 service, customization->CreateExternalLoader(profile), profile,
Gyuyoung Kim2e954c42021-03-19 14:06:29775 ManifestLocation::kExternalPref,
776 ManifestLocation::kExternalPrefDownload, oem_extension_creation_flags));
[email protected]ebb489f2013-09-19 22:08:52777 }
Toni Barzicdff51562018-07-24 19:55:46778
779 // For Chrome OS demo sessions, add pre-installed demo extensions and apps.
Henrique Ferreirod71de902021-05-10 18:57:11780 if (ash::DemoExtensionsExternalLoader::SupportedForProfile(profile)) {
Wenzhao Zang463f1142018-09-05 22:50:50781 base::FilePath cache_dir;
782 CHECK(base::PathService::Get(chromeos::DIR_DEVICE_EXTENSION_LOCAL_CACHE,
783 &cache_dir));
Henrique Ferreirod71de902021-05-10 18:57:11784 auto loader =
785 base::MakeRefCounted<ash::DemoExtensionsExternalLoader>(cache_dir);
Toni Barzicdff51562018-07-24 19:55:46786 std::unique_ptr<ExternalProviderImpl> demo_apps_provider =
787 std::make_unique<ExternalProviderImpl>(
Gyuyoung Kim2e954c42021-03-19 14:06:29788 service, loader, profile, ManifestLocation::kExternalPolicy,
789 ManifestLocation::kExternalPolicyDownload, Extension::NO_FLAGS);
Toni Barzicdff51562018-07-24 19:55:46790 demo_apps_provider->set_auto_acknowledge(true);
791 demo_apps_provider->set_install_immediately(true);
Henrique Ferreirod71de902021-05-10 18:57:11792 ash::DemoSession::Get()->SetExtensionsExternalLoader(loader);
Toni Barzicdff51562018-07-24 19:55:46793 provider_list->push_back(std::move(demo_apps_provider));
794 }
[email protected]5bed2ec32013-08-29 22:55:46795#endif
Dominique Fauteux-Chapleauff3bb352019-10-16 14:32:34796 if (!profile->GetPrefs()->GetBoolean(pref_names::kBlockExternalExtensions)) {
Yuta Hijikata1290fee22020-11-25 09:46:28797// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
798// of lacros-chrome is complete.
799#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
Taiju Tsuikib1879b72018-09-21 06:22:47800 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
801 service,
Matthew Dentonef83a622019-08-30 02:07:00802 base::MakeRefCounted<ExternalPrefLoader>(
Dominique Fauteux-Chapleauff3bb352019-10-16 14:32:34803 chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS,
804 ExternalPrefLoader::USE_USER_TYPE_PROFILE_FILTER, profile),
Gyuyoung Kim2e954c42021-03-19 14:06:29805 profile, ManifestLocation::kExternalPref,
806 ManifestLocation::kExternalPrefDownload,
Taiju Tsuikib1879b72018-09-21 06:22:47807 bundled_extension_creation_flags));
Dominique Fauteux-Chapleauff3bb352019-10-16 14:32:34808#endif
Dominique Fauteux-Chapleauff3bb352019-10-16 14:32:34809#if defined(OS_WIN)
Toby Huangf93f7002021-01-24 01:08:13810 auto registry_provider = std::make_unique<ExternalProviderImpl>(
811 service, new ExternalRegistryLoader, profile,
Gyuyoung Kim2e954c42021-03-19 14:06:29812 ManifestLocation::kExternalRegistry,
813 ManifestLocation::kExternalPrefDownload, Extension::NO_FLAGS);
Toby Huangf93f7002021-01-24 01:08:13814 registry_provider->set_allow_updates(true);
815 provider_list->push_back(std::move(registry_provider));
Dominique Fauteux-Chapleauff3bb352019-10-16 14:32:34816#else
Toby Huangf93f7002021-01-24 01:08:13817 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
818 service,
819 base::MakeRefCounted<ExternalPrefLoader>(
820 chrome::DIR_EXTERNAL_EXTENSIONS, check_admin_permissions_on_mac,
821 nullptr),
Gyuyoung Kim2e954c42021-03-19 14:06:29822 profile, ManifestLocation::kExternalPref,
823 ManifestLocation::kExternalPrefDownload,
Toby Huangf93f7002021-01-24 01:08:13824 bundled_extension_creation_flags));
[email protected]5bed2ec32013-08-29 22:55:46825
Toby Huangf93f7002021-01-24 01:08:13826 // Define a per-user source of external extensions.
Sean McAllister4a991b972020-08-19 17:38:51827#if defined(OS_MAC) || ((defined(OS_LINUX) || defined(OS_CHROMEOS)) && \
828 BUILDFLAG(CHROMIUM_BRANDING))
Toby Huangf93f7002021-01-24 01:08:13829 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
830 service,
Matthew Dentonef83a622019-08-30 02:07:00831 base::MakeRefCounted<ExternalPrefLoader>(
Toby Huangf93f7002021-01-24 01:08:13832 chrome::DIR_USER_EXTERNAL_EXTENSIONS, ExternalPrefLoader::NONE,
833 nullptr),
Gyuyoung Kim2e954c42021-03-19 14:06:29834 profile, ManifestLocation::kExternalPref,
835 ManifestLocation::kExternalPrefDownload, Extension::NO_FLAGS));
Toby Huangf93f7002021-01-24 01:08:13836#endif
837#endif
838 }
839
840#if !BUILDFLAG(IS_CHROMEOS_ASH)
Daniel Murphy3657906d2021-04-13 20:33:12841 // The pre-installed apps are installed as INTERNAL but use the external
Toby Huangf93f7002021-01-24 01:08:13842 // extension installer codeflow.
Daniel Murphy3657906d2021-04-13 20:33:12843 provider_list->push_back(std::make_unique<preinstalled_apps::Provider>(
Toby Huangf93f7002021-01-24 01:08:13844 profile, service,
845 base::MakeRefCounted<ExternalPrefLoader>(
846 chrome::DIR_DEFAULT_APPS, ExternalPrefLoader::NONE, nullptr),
Gyuyoung Kim2e954c42021-03-19 14:06:29847 ManifestLocation::kInternal, ManifestLocation::kInternal,
Toby Huangf93f7002021-01-24 01:08:13848 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT));
[email protected]98b4aca62011-09-28 01:27:23849#endif
xiyuan65b68ab12015-06-26 19:00:18850
Toby Huangf93f7002021-01-24 01:08:13851 std::unique_ptr<ExternalProviderImpl> drive_migration_provider(
852 new ExternalProviderImpl(
853 service,
854 base::MakeRefCounted<ExtensionMigrator>(
855 profile, extension_misc::kDriveHostedAppId,
856 extension_misc::kDocsOfflineExtensionId),
Gyuyoung Kim2e954c42021-03-19 14:06:29857 profile, ManifestLocation::kExternalPref,
858 ManifestLocation::kExternalPrefDownload,
Toby Huangf93f7002021-01-24 01:08:13859 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT));
860 drive_migration_provider->set_auto_acknowledge(true);
861 provider_list->push_back(std::move(drive_migration_provider));
treibcc82ab82015-03-02 09:41:49862
Jinho Bangb5216cec2018-01-17 19:43:11863 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
Matthew Dentonef83a622019-08-30 02:07:00864 service, base::MakeRefCounted<ExternalComponentLoader>(profile), profile,
Gyuyoung Kim2e954c42021-03-19 14:06:29865 ManifestLocation::kInvalidLocation, ManifestLocation::kExternalComponent,
lazyboyf33109d2016-08-31 00:37:08866 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT));
[email protected]8e4560b62011-01-14 10:09:14867}
[email protected]5df038b2012-07-16 19:03:27868
869} // namespace extensions