blob: d6a158c9f3878aae3fb1f719995efbaa4154a052 [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"
Alan Cutterb81d0e02020-08-05 09:10:3438#include "chrome/browser/web_applications/components/external_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)
Wenzhao Zang463f1142018-09-05 22:50:5055#include "base/path_service.h"
Toni Barzic87026682018-01-08 23:21:0456#include "chrome/browser/chromeos/app_mode/kiosk_app_external_loader.h"
Satoru Takabayashi876d4e62014-12-03 04:52:2457#include "chrome/browser/chromeos/customization/customization_document.h"
[email protected]af984882013-10-21 21:08:5158#include "chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.h"
Maksim Ivanov8738d332020-01-07 22:19:0159#include "chrome/browser/chromeos/extensions/signin_screen_extensions_external_loader.h"
Toni Barzicdff51562018-07-24 19:55:4660#include "chrome/browser/chromeos/login/demo_mode/demo_extensions_external_loader.h"
Wenzhao Zang463f1142018-09-05 22:50:5061#include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
[email protected]97275822014-01-21 19:30:3662#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
[email protected]af984882013-10-21 21:08:5163#include "chrome/browser/chromeos/policy/device_local_account.h"
64#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
[email protected]052e3ac2014-06-30 14:22:4765#include "chrome/browser/chromeos/profiles/profile_helper.h"
Steven Bennetts38e9bde22019-01-03 17:31:1066#include "chromeos/constants/chromeos_paths.h"
Ahmed Fakhry9ef29e042017-09-01 16:32:0067#include "components/arc/arc_util.h"
[email protected]b39d25712013-03-14 09:53:4068#else
[email protected]86c6b9e32011-10-25 17:09:1069#include "chrome/browser/extensions/default_apps.h"
70#endif
71
[email protected]8e4560b62011-01-14 10:09:1472#if defined(OS_WIN)
[email protected]5df038b2012-07-16 19:03:2773#include "chrome/browser/extensions/external_registry_loader_win.h"
[email protected]8e4560b62011-01-14 10:09:1474#endif
75
[email protected]631bb742011-11-02 11:29:3976using content::BrowserThread;
[email protected]5df038b2012-07-16 19:03:2777
78namespace extensions {
[email protected]631bb742011-11-02 11:29:3979
Ahmed Fakhry9ef29e042017-09-01 16:32:0080namespace {
81
Yuta Hijikata1290fee22020-11-25 09:46:2882#if BUILDFLAG(IS_CHROMEOS_ASH)
Ahmed Fakhry9ef29e042017-09-01 16:32:0083
84// Certain default extensions are no longer needed on ARC devices as they were
85// replaced by their ARC counterparts.
86bool ShouldUninstallExtensionReplacedByArcApp(const std::string& extension_id) {
Alex Newcomerf8c542f2018-08-13 23:48:5087 if (!arc::IsArcAvailable())
Ahmed Fakhry9ef29e042017-09-01 16:32:0088 return false;
89
90 if (extension_id == extension_misc::kGooglePlayBooksAppId ||
91 extension_id == extension_misc::kGooglePlayMoviesAppId ||
92 extension_id == extension_misc::kGooglePlayMusicAppId) {
93 return true;
94 }
95
96 return false;
97}
98
Yuta Hijikata1290fee22020-11-25 09:46:2899#endif // BUILDFLAG(IS_CHROMEOS_ASH)
Ahmed Fakhry9ef29e042017-09-01 16:32:00100
101} // namespace
102
[email protected]8e4560b62011-01-14 10:09:14103// Constants for keeping track of extension preferences in a dictionary.
[email protected]d8fd0fd2014-03-24 13:16:06104const char ExternalProviderImpl::kInstallParam[] = "install_parameter";
[email protected]5df038b2012-07-16 19:03:27105const char ExternalProviderImpl::kExternalCrx[] = "external_crx";
[email protected]7425d7df2012-11-28 14:35:42106const char ExternalProviderImpl::kExternalVersion[] = "external_version";
107const char ExternalProviderImpl::kExternalUpdateUrl[] = "external_update_url";
[email protected]7425d7df2012-11-28 14:35:42108const char ExternalProviderImpl::kIsBookmarkApp[] = "is_bookmark_app";
109const char ExternalProviderImpl::kIsFromWebstore[] = "is_from_webstore";
[email protected]19eac6d2013-05-30 06:51:03110const char ExternalProviderImpl::kKeepIfPresent[] = "keep_if_present";
[email protected]bf9fd5ae2014-04-09 22:50:06111const char ExternalProviderImpl::kWasInstalledByOem[] = "was_installed_by_oem";
Alan Cutterb81d0e02020-08-05 09:10:34112const char ExternalProviderImpl::kWebAppMigrationFlag[] =
113 "web_app_migration_flag";
[email protected]bf9fd5ae2014-04-09 22:50:06114const char ExternalProviderImpl::kSupportedLocales[] = "supported_locales";
[email protected]2b6a5802014-08-16 07:58:08115const char ExternalProviderImpl::kMayBeUntrusted[] = "may_be_untrusted";
dpolukhin2c6ef2932015-05-12 16:06:13116const char ExternalProviderImpl::kMinProfileCreatedByVersion[] =
117 "min_profile_created_by_version";
dpolukhin1687ef32015-06-22 11:12:37118const char ExternalProviderImpl::kDoNotInstallForEnterprise[] =
119 "do_not_install_for_enterprise";
[email protected]8e4560b62011-01-14 10:09:14120
[email protected]af984882013-10-21 21:08:51121ExternalProviderImpl::ExternalProviderImpl(
122 VisitorInterface* service,
123 const scoped_refptr<ExternalLoader>& loader,
124 Profile* profile,
125 Manifest::Location crx_location,
126 Manifest::Location download_location,
127 int creation_flags)
[email protected]4b4c0132013-06-12 17:58:55128 : crx_location_(crx_location),
129 download_location_(download_location),
130 service_(service),
[email protected]4b4c0132013-06-12 17:58:55131 loader_(loader),
132 profile_(profile),
Toni Barzic87026682018-01-08 23:21:04133 creation_flags_(creation_flags) {
Oleg Davydov66246bd92019-09-26 16:31:51134 DCHECK(profile_);
[email protected]8e4560b62011-01-14 10:09:14135 loader_->Init(this);
136}
137
[email protected]5df038b2012-07-16 19:03:27138ExternalProviderImpl::~ExternalProviderImpl() {
Istiaque Ahmedf6e72622017-09-08 23:14:17139 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14140 loader_->OwnerShutdown();
141}
142
[email protected]5df038b2012-07-16 19:03:27143void ExternalProviderImpl::VisitRegisteredExtension() {
[email protected]8e4560b62011-01-14 10:09:14144 // The loader will call back to SetPrefs.
145 loader_->StartLoading();
146}
147
Istiaque Ahmeda7431b32017-08-20 18:33:37148void ExternalProviderImpl::SetPrefs(
149 std::unique_ptr<base::DictionaryValue> prefs) {
Istiaque Ahmedf6e72622017-09-08 23:14:17150 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14151
[email protected]47fc70c2011-12-06 07:29:51152 // Check if the service is still alive. It is possible that it went
[email protected]8e4560b62011-01-14 10:09:14153 // away while |loader_| was working on the FILE thread.
154 if (!service_) return;
155
Oleg Davydovdec175a2020-05-25 16:44:29156 InstallStageTracker* install_stage_tracker =
157 InstallStageTracker::Get(profile_);
Oleg Davydov52db8742019-08-20 09:14:40158 for (const auto& it : prefs->DictItems()) {
Swapnil5e0e0dc2020-09-21 14:59:47159 install_stage_tracker->ReportInstallCreationStage(
160 it.first,
161 InstallStageTracker::InstallCreationStage::SEEN_BY_EXTERNAL_PROVIDER);
Oleg Davydov52db8742019-08-20 09:14:40162 }
163
Istiaque Ahmeda7431b32017-08-20 18:33:37164 prefs_ = std::move(prefs);
[email protected]8a839a02013-03-07 05:23:33165 ready_ = true; // Queries for extensions are allowed from this point.
[email protected]8e4560b62011-01-14 10:09:14166
Devlin Cronin19f70b6a2017-10-01 04:14:05167 std::vector<ExternalInstallInfoUpdateUrl> external_update_url_extensions;
168 std::vector<ExternalInstallInfoFile> external_file_extensions;
lazyboye8634172016-01-28 00:10:48169
170 RetrieveExtensionsFromPrefs(&external_update_url_extensions,
171 &external_file_extensions);
lazyboy4aeef202016-09-07 21:28:59172 for (const auto& extension : external_update_url_extensions)
Devlin Cronin19f70b6a2017-10-01 04:14:05173 service_->OnExternalExtensionUpdateUrlFound(extension, true);
lazyboye8634172016-01-28 00:10:48174
lazyboy4aeef202016-09-07 21:28:59175 for (const auto& extension : external_file_extensions)
Devlin Cronin19f70b6a2017-10-01 04:14:05176 service_->OnExternalExtensionFileFound(extension);
lazyboye8634172016-01-28 00:10:48177
178 service_->OnExternalProviderReady(this);
179}
180
Istiaque Ahmeda7431b32017-08-20 18:33:37181void ExternalProviderImpl::UpdatePrefs(
182 std::unique_ptr<base::DictionaryValue> prefs) {
Istiaque Ahmedf6e72622017-09-08 23:14:17183 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Toni Barzic87026682018-01-08 23:21:04184 CHECK(allow_updates_);
lazyboye8634172016-01-28 00:10:48185
186 // Check if the service is still alive. It is possible that it went
187 // away while |loader_| was working on the FILE thread.
188 if (!service_)
189 return;
190
191 std::set<std::string> removed_extensions;
192 // Find extensions that were removed by this ExternalProvider.
193 for (base::DictionaryValue::Iterator i(*prefs_); !i.IsAtEnd(); i.Advance()) {
194 const std::string& extension_id = i.key();
195 // Don't bother about invalid ids.
196 if (!crx_file::id_util::IdIsValid(extension_id))
197 continue;
198 if (!prefs->HasKey(extension_id))
199 removed_extensions.insert(extension_id);
200 }
201
Istiaque Ahmeda7431b32017-08-20 18:33:37202 prefs_ = std::move(prefs);
lazyboye8634172016-01-28 00:10:48203
Devlin Cronin19f70b6a2017-10-01 04:14:05204 std::vector<ExternalInstallInfoUpdateUrl> external_update_url_extensions;
205 std::vector<ExternalInstallInfoFile> external_file_extensions;
lazyboye8634172016-01-28 00:10:48206 RetrieveExtensionsFromPrefs(&external_update_url_extensions,
207 &external_file_extensions);
208
209 // Notify ExtensionService about completion of finding incremental updates
210 // from this provider.
211 // Provide the list of added and removed extensions.
212 service_->OnExternalProviderUpdateComplete(
213 this, external_update_url_extensions, external_file_extensions,
214 removed_extensions);
215}
216
217void ExternalProviderImpl::RetrieveExtensionsFromPrefs(
Devlin Cronin19f70b6a2017-10-01 04:14:05218 std::vector<ExternalInstallInfoUpdateUrl>* external_update_url_extensions,
219 std::vector<ExternalInstallInfoFile>* external_file_extensions) {
[email protected]9d32ded072011-10-11 16:31:05220 // Set of unsupported extensions that need to be deleted from prefs_.
221 std::set<std::string> unsupported_extensions;
Oleg Davydovdec175a2020-05-25 16:44:29222 InstallStageTracker* install_stage_tracker =
223 InstallStageTracker::Get(profile_);
[email protected]9d32ded072011-10-11 16:31:05224
lazyboye8634172016-01-28 00:10:48225 // Discover all the extensions this provider has.
[email protected]aeca23f2013-06-21 22:34:41226 for (base::DictionaryValue::Iterator i(*prefs_); !i.IsAtEnd(); i.Advance()) {
[email protected]02d9b272013-03-06 12:54:56227 const std::string& extension_id = i.key();
Bartek Nowierski3253b672020-06-01 20:37:12228 const base::DictionaryValue* extension = nullptr;
[email protected]ab22ba42011-01-14 16:36:38229
Yuta Hijikata1290fee22020-11-25 09:46:28230#if BUILDFLAG(IS_CHROMEOS_ASH)
Ahmed Fakhry9ef29e042017-09-01 16:32:00231 if (ShouldUninstallExtensionReplacedByArcApp(extension_id)) {
232 VLOG(1) << "Extension with key: " << extension_id << " was replaced "
233 << "by a default ARC app, and will be uninstalled.";
234 unsupported_extensions.emplace(extension_id);
Oleg Davydovdec175a2020-05-25 16:44:29235 install_stage_tracker->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51236 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29237 InstallStageTracker::FailureReason::REPLACED_BY_ARC_APP);
Ahmed Fakhry9ef29e042017-09-01 16:32:00238 continue;
239 }
Yuta Hijikata1290fee22020-11-25 09:46:28240#endif // BUILDFLAG(IS_CHROMEOS_ASH)
Ahmed Fakhry9ef29e042017-09-01 16:32:00241
[email protected]fdd28372014-08-21 02:27:26242 if (!crx_file::id_util::IdIsValid(extension_id)) {
[email protected]ab22ba42011-01-14 16:36:38243 LOG(WARNING) << "Malformed extension dictionary: key "
244 << extension_id.c_str() << " is not a valid id.";
Oleg Davydovdec175a2020-05-25 16:44:29245 install_stage_tracker->ReportFailure(
246 extension_id, InstallStageTracker::FailureReason::INVALID_ID);
[email protected]8e4560b62011-01-14 10:09:14247 continue;
[email protected]ab22ba42011-01-14 16:36:38248 }
249
[email protected]02d9b272013-03-06 12:54:56250 if (!i.value().GetAsDictionary(&extension)) {
[email protected]ab22ba42011-01-14 16:36:38251 LOG(WARNING) << "Malformed extension dictionary: key "
252 << extension_id.c_str()
253 << " has a value that is not a dictionary.";
Oleg Davydovdec175a2020-05-25 16:44:29254 install_stage_tracker->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51255 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29256 InstallStageTracker::FailureReason::MALFORMED_EXTENSION_DICT);
[email protected]ab22ba42011-01-14 16:36:38257 continue;
258 }
[email protected]8e4560b62011-01-14 10:09:14259
[email protected]650b2d52013-02-10 03:41:45260 base::FilePath::StringType external_crx;
Bartek Nowierski3253b672020-06-01 20:37:12261 const base::Value* external_version_value = nullptr;
[email protected]8e4560b62011-01-14 10:09:14262 std::string external_version;
263 std::string external_update_url;
264
265 bool has_external_crx = extension->GetString(kExternalCrx, &external_crx);
[email protected]0d461c52012-07-03 19:29:41266
267 bool has_external_version = false;
268 if (extension->Get(kExternalVersion, &external_version_value)) {
jdoerrie1f536b22017-10-23 17:15:11269 if (external_version_value->is_string()) {
[email protected]0d461c52012-07-03 19:29:41270 external_version_value->GetAsString(&external_version);
271 has_external_version = true;
272 } else {
Oleg Davydovdec175a2020-05-25 16:44:29273 install_stage_tracker->ReportFailure(
274 extension_id, InstallStageTracker::FailureReason::
Oleg Davydov66246bd92019-09-26 16:31:51275 MALFORMED_EXTENSION_DICT_VERSION);
[email protected]0d461c52012-07-03 19:29:41276 LOG(WARNING) << "Malformed extension dictionary for extension: "
277 << extension_id.c_str() << ". " << kExternalVersion
278 << " value must be a string.";
279 continue;
280 }
281 }
282
[email protected]8e4560b62011-01-14 10:09:14283 bool has_external_update_url = extension->GetString(kExternalUpdateUrl,
284 &external_update_url);
285 if (has_external_crx != has_external_version) {
Oleg Davydovdec175a2020-05-25 16:44:29286 install_stage_tracker->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51287 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29288 InstallStageTracker::FailureReason::MALFORMED_EXTENSION_DICT);
[email protected]8e4560b62011-01-14 10:09:14289 LOG(WARNING) << "Malformed extension dictionary for extension: "
290 << extension_id.c_str() << ". " << kExternalCrx
291 << " and " << kExternalVersion << " must be used together.";
292 continue;
293 }
294
295 if (has_external_crx == has_external_update_url) {
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() << ". Exactly one of the "
301 << "followng keys should be used: " << kExternalCrx
302 << ", " << kExternalUpdateUrl << ".";
303 continue;
304 }
305
[email protected]9d32ded072011-10-11 16:31:05306 // Check that extension supports current browser locale.
Bartek Nowierski3253b672020-06-01 20:37:12307 const base::ListValue* supported_locales = nullptr;
[email protected]9d32ded072011-10-11 16:31:05308 if (extension->GetList(kSupportedLocales, &supported_locales)) {
309 std::vector<std::string> browser_locales;
310 l10n_util::GetParentLocales(g_browser_process->GetApplicationLocale(),
311 &browser_locales);
312
313 size_t num_locales = supported_locales->GetSize();
314 bool locale_supported = false;
315 for (size_t j = 0; j < num_locales; j++) {
316 std::string current_locale;
317 if (supported_locales->GetString(j, &current_locale) &&
318 l10n_util::IsValidLocaleSyntax(current_locale)) {
319 current_locale = l10n_util::NormalizeLocale(current_locale);
Jan Wilken Dörrieade79222019-06-06 19:01:12320 if (base::Contains(browser_locales, current_locale)) {
[email protected]9d32ded072011-10-11 16:31:05321 locale_supported = true;
322 break;
323 }
324 } else {
325 LOG(WARNING) << "Unrecognized locale '" << current_locale
326 << "' found as supported locale for extension: "
327 << extension_id;
328 }
329 }
330
331 if (!locale_supported) {
332 unsupported_extensions.insert(extension_id);
Oleg Davydovdec175a2020-05-25 16:44:29333 install_stage_tracker->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51334 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29335 InstallStageTracker::FailureReason::LOCALE_NOT_SUPPORTED);
[email protected]19eac6d2013-05-30 06:51:03336 VLOG(1) << "Skip installing (or uninstall) external extension: "
337 << extension_id << " because the extension doesn't support "
338 << "the browser locale.";
[email protected]9d32ded072011-10-11 16:31:05339 continue;
340 }
341 }
342
[email protected]f121003b2012-05-04 21:57:47343 int creation_flags = creation_flags_;
344 bool is_bookmark_app;
345 if (extension->GetBoolean(kIsBookmarkApp, &is_bookmark_app) &&
346 is_bookmark_app) {
347 creation_flags |= Extension::FROM_BOOKMARK;
348 }
[email protected]2b6a5802014-08-16 07:58:08349 bool is_from_webstore = false;
[email protected]7425d7df2012-11-28 14:35:42350 if (extension->GetBoolean(kIsFromWebstore, &is_from_webstore) &&
351 is_from_webstore) {
352 creation_flags |= Extension::FROM_WEBSTORE;
353 }
Alan Cutterb81d0e02020-08-05 09:10:34354
355 // If the extension is in a web app migration treat it as "keep_if_present"
356 // so it can get uninstalled by WebAppUiManager::UninstallAndReplace() once
357 // the replacement web app has installed and migrated over user preferences.
358 // TODO(crbug.com/1099150): Remove this field after migration is complete.
359 const std::string* web_app_migration_flag =
360 extension->FindStringPath(kWebAppMigrationFlag);
361 bool is_migrating_to_web_app =
362 web_app_migration_flag &&
363 web_app::IsExternalAppInstallFeatureEnabled(*web_app_migration_flag);
364 bool keep_if_present =
365 extension->FindBoolPath(kKeepIfPresent).value_or(false);
366 if (keep_if_present || is_migrating_to_web_app) {
David Bertoni58c113a2019-08-02 19:53:26367 ExtensionRegistry* extension_registry = ExtensionRegistry::Get(profile_);
368 const Extension* extension =
David Bertonia0b34722019-09-30 20:51:26369 extension_registry ? extension_registry->GetExtensionById(
370 extension_id, ExtensionRegistry::EVERYTHING)
371 : nullptr;
[email protected]19eac6d2013-05-30 06:51:03372 if (!extension) {
dpolukhin2c6ef2932015-05-12 16:06:13373 unsupported_extensions.insert(extension_id);
Oleg Davydovdec175a2020-05-25 16:44:29374 install_stage_tracker->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51375 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29376 InstallStageTracker::FailureReason::NOT_PERFORMING_NEW_INSTALL);
[email protected]19eac6d2013-05-30 06:51:03377 VLOG(1) << "Skip installing (or uninstall) external extension: "
378 << extension_id << " because the extension should be kept "
379 << "only if it is already installed.";
380 continue;
381 }
382 }
Alan Cutterb81d0e02020-08-05 09:10:34383
dpolukhind0be494a2015-05-28 09:43:17384 bool was_installed_by_oem = false;
385 if (extension->GetBoolean(kWasInstalledByOem, &was_installed_by_oem) &&
386 was_installed_by_oem) {
387 creation_flags |= Extension::WAS_INSTALLED_BY_OEM;
388 }
[email protected]2b6a5802014-08-16 07:58:08389 bool may_be_untrusted = false;
390 if (extension->GetBoolean(kMayBeUntrusted, &may_be_untrusted) &&
391 may_be_untrusted) {
392 creation_flags |= Extension::MAY_BE_UNTRUSTED;
393 }
[email protected]f121003b2012-05-04 21:57:47394
dpolukhin1687ef32015-06-22 11:12:37395 if (!HandleMinProfileVersion(extension, extension_id,
396 &unsupported_extensions)) {
dpolukhin2c6ef2932015-05-12 16:06:13397 continue;
dpolukhin1687ef32015-06-22 11:12:37398 }
399
400 if (!HandleDoNotInstallForEnterprise(extension, extension_id,
401 &unsupported_extensions)) {
402 continue;
403 }
dpolukhin2c6ef2932015-05-12 16:06:13404
[email protected]d8fd0fd2014-03-24 13:16:06405 std::string install_parameter;
406 extension->GetString(kInstallParam, &install_parameter);
407
[email protected]8e4560b62011-01-14 10:09:14408 if (has_external_crx) {
[email protected]1d5e58b2013-01-31 08:41:40409 if (crx_location_ == Manifest::INVALID_LOCATION) {
Oleg Davydovdec175a2020-05-25 16:44:29410 install_stage_tracker->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51411 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29412 InstallStageTracker::FailureReason::NOT_SUPPORTED_EXTENSION_DICT);
[email protected]8e4560b62011-01-14 10:09:14413 LOG(WARNING) << "This provider does not support installing external "
414 << "extensions from crx files.";
415 continue;
416 }
[email protected]650b2d52013-02-10 03:41:45417 if (external_crx.find(base::FilePath::kParentDirectory) !=
[email protected]8e4560b62011-01-14 10:09:14418 base::StringPiece::npos) {
Oleg Davydovdec175a2020-05-25 16:44:29419 install_stage_tracker->ReportFailure(
420 extension_id, InstallStageTracker::FailureReason::
Oleg Davydov66246bd92019-09-26 16:31:51421 MALFORMED_EXTENSION_DICT_FILE_PATH);
[email protected]8e4560b62011-01-14 10:09:14422 LOG(WARNING) << "Path traversal not allowed in path: "
423 << external_crx.c_str();
424 continue;
425 }
426
[email protected]f0841cd2011-01-19 15:07:24427 // If the path is relative, and the provider has a base path,
428 // build the absolute path to the crx file.
[email protected]650b2d52013-02-10 03:41:45429 base::FilePath path(external_crx);
[email protected]8e4560b62011-01-14 10:09:14430 if (!path.IsAbsolute()) {
[email protected]650b2d52013-02-10 03:41:45431 base::FilePath base_path = loader_->GetBaseCrxFilePath();
[email protected]f0841cd2011-01-19 15:07:24432 if (base_path.empty()) {
Oleg Davydovdec175a2020-05-25 16:44:29433 install_stage_tracker->ReportFailure(
434 extension_id, InstallStageTracker::FailureReason::
Oleg Davydov66246bd92019-09-26 16:31:51435 MALFORMED_EXTENSION_DICT_FILE_PATH);
[email protected]f0841cd2011-01-19 15:07:24436 LOG(WARNING) << "File path " << external_crx.c_str()
437 << " is relative. An absolute path is required.";
438 continue;
439 }
[email protected]8e4560b62011-01-14 10:09:14440 path = base_path.Append(external_crx);
441 }
442
Devlin Cronind4c2a8f32017-09-29 17:08:30443 base::Version version(external_version);
444 if (!version.IsValid()) {
Oleg Davydovdec175a2020-05-25 16:44:29445 install_stage_tracker->ReportFailure(
446 extension_id, InstallStageTracker::FailureReason::
Oleg Davydov66246bd92019-09-26 16:31:51447 MALFORMED_EXTENSION_DICT_VERSION);
[email protected]8e4560b62011-01-14 10:09:14448 LOG(WARNING) << "Malformed extension dictionary for extension: "
449 << extension_id.c_str() << ". Invalid version string \""
450 << external_version << "\".";
451 continue;
452 }
Devlin Cronin19f70b6a2017-10-01 04:14:05453 external_file_extensions->emplace_back(
454 extension_id, version, path, crx_location_, creation_flags,
455 auto_acknowledge_, install_immediately_);
[email protected]8a839a02013-03-07 05:23:33456 } else { // if (has_external_update_url)
[email protected]8e4560b62011-01-14 10:09:14457 CHECK(has_external_update_url); // Checking of keys above ensures this.
[email protected]1d5e58b2013-01-31 08:41:40458 if (download_location_ == Manifest::INVALID_LOCATION) {
Oleg Davydovdec175a2020-05-25 16:44:29459 install_stage_tracker->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51460 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29461 InstallStageTracker::FailureReason::NOT_SUPPORTED_EXTENSION_DICT);
[email protected]8e4560b62011-01-14 10:09:14462 LOG(WARNING) << "This provider does not support installing external "
463 << "extensions from update URLs.";
464 continue;
465 }
Devlin Cronind4c2a8f32017-09-29 17:08:30466 GURL update_url(external_update_url);
467 if (!update_url.is_valid()) {
Oleg Davydovdec175a2020-05-25 16:44:29468 install_stage_tracker->ReportFailure(
469 extension_id, InstallStageTracker::FailureReason::
Oleg Davydov66246bd92019-09-26 16:31:51470 MALFORMED_EXTENSION_DICT_UPDATE_URL);
[email protected]8e4560b62011-01-14 10:09:14471 LOG(WARNING) << "Malformed extension dictionary for extension: "
[email protected]ab22ba42011-01-14 16:36:38472 << extension_id.c_str() << ". Key " << kExternalUpdateUrl
473 << " has value \"" << external_update_url
474 << "\", which is not a valid URL.";
[email protected]8e4560b62011-01-14 10:09:14475 continue;
476 }
Devlin Cronin19f70b6a2017-10-01 04:14:05477 external_update_url_extensions->emplace_back(
478 extension_id, install_parameter, std::move(update_url),
479 download_location_, creation_flags, auto_acknowledge_);
[email protected]8e4560b62011-01-14 10:09:14480 }
481 }
482
jdoerrie13cd648c82018-10-02 21:21:02483 for (auto it = unsupported_extensions.begin();
[email protected]9d32ded072011-10-11 16:31:05484 it != unsupported_extensions.end(); ++it) {
485 // Remove extension for the list of know external extensions. The extension
486 // will be uninstalled later because provider doesn't provide it anymore.
Bartek Nowierski3253b672020-06-01 20:37:12487 prefs_->Remove(*it, nullptr);
[email protected]9d32ded072011-10-11 16:31:05488 }
[email protected]8e4560b62011-01-14 10:09:14489}
490
[email protected]5df038b2012-07-16 19:03:27491void ExternalProviderImpl::ServiceShutdown() {
Bartek Nowierski3253b672020-06-01 20:37:12492 service_ = nullptr;
[email protected]8e4560b62011-01-14 10:09:14493}
494
[email protected]5df038b2012-07-16 19:03:27495bool ExternalProviderImpl::IsReady() const {
[email protected]8e4560b62011-01-14 10:09:14496 return ready_;
497}
498
[email protected]5df038b2012-07-16 19:03:27499bool ExternalProviderImpl::HasExtension(
[email protected]8e4560b62011-01-14 10:09:14500 const std::string& id) const {
Istiaque Ahmedf6e72622017-09-08 23:14:17501 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14502 CHECK(prefs_.get());
503 CHECK(ready_);
504 return prefs_->HasKey(id);
505}
506
[email protected]5df038b2012-07-16 19:03:27507bool ExternalProviderImpl::GetExtensionDetails(
dchengc963c7142016-04-08 03:55:22508 const std::string& id,
509 Manifest::Location* location,
pwnallcbd73192016-08-22 18:59:17510 std::unique_ptr<base::Version>* version) const {
Istiaque Ahmedf6e72622017-09-08 23:14:17511 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]8e4560b62011-01-14 10:09:14512 CHECK(prefs_.get());
513 CHECK(ready_);
Bartek Nowierski3253b672020-06-01 20:37:12514 base::DictionaryValue* extension = nullptr;
[email protected]8e4560b62011-01-14 10:09:14515 if (!prefs_->GetDictionary(id, &extension))
516 return false;
517
[email protected]1d5e58b2013-01-31 08:41:40518 Manifest::Location loc = Manifest::INVALID_LOCATION;
[email protected]8e4560b62011-01-14 10:09:14519 if (extension->HasKey(kExternalUpdateUrl)) {
520 loc = download_location_;
521
522 } else if (extension->HasKey(kExternalCrx)) {
523 loc = crx_location_;
524
525 std::string external_version;
526 if (!extension->GetString(kExternalVersion, &external_version))
527 return false;
528
529 if (version)
pwnallcbd73192016-08-22 18:59:17530 version->reset(new base::Version(external_version));
[email protected]8e4560b62011-01-14 10:09:14531
532 } else {
533 NOTREACHED(); // Chrome should not allow prefs to get into this state.
534 return false;
535 }
536
537 if (location)
538 *location = loc;
539
540 return true;
541}
542
dpolukhin2c6ef2932015-05-12 16:06:13543bool ExternalProviderImpl::HandleMinProfileVersion(
544 const base::DictionaryValue* extension,
545 const std::string& extension_id,
546 std::set<std::string>* unsupported_extensions) {
547 std::string min_profile_created_by_version;
Oleg Davydov66246bd92019-09-26 16:31:51548 if (extension->GetString(kMinProfileCreatedByVersion,
dpolukhin2c6ef2932015-05-12 16:06:13549 &min_profile_created_by_version)) {
pwnallcbd73192016-08-22 18:59:17550 base::Version profile_version(
dpolukhin2c6ef2932015-05-12 16:06:13551 profile_->GetPrefs()->GetString(prefs::kProfileCreatedByVersion));
pwnallcbd73192016-08-22 18:59:17552 base::Version min_version(min_profile_created_by_version);
dpolukhin2c6ef2932015-05-12 16:06:13553 if (min_version.IsValid() && profile_version.CompareTo(min_version) < 0) {
554 unsupported_extensions->insert(extension_id);
Oleg Davydovdec175a2020-05-25 16:44:29555 InstallStageTracker::Get(profile_)->ReportFailure(
556 extension_id, InstallStageTracker::FailureReason::TOO_OLD_PROFILE);
dpolukhin2c6ef2932015-05-12 16:06:13557 VLOG(1) << "Skip installing (or uninstall) external extension: "
558 << extension_id
559 << " profile.created_by_version: " << profile_version.GetString()
560 << " min_profile_created_by_version: "
561 << min_profile_created_by_version;
562 return false;
563 }
564 }
565 return true;
566}
567
dpolukhin1687ef32015-06-22 11:12:37568bool ExternalProviderImpl::HandleDoNotInstallForEnterprise(
569 const base::DictionaryValue* extension,
570 const std::string& extension_id,
571 std::set<std::string>* unsupported_extensions) {
572 bool do_not_install_for_enterprise = false;
573 if (extension->GetBoolean(kDoNotInstallForEnterprise,
574 &do_not_install_for_enterprise) &&
575 do_not_install_for_enterprise) {
576 const policy::ProfilePolicyConnector* const connector =
Xi Hanfe39afc62019-04-29 14:50:14577 profile_->GetProfilePolicyConnector();
dpolukhin1687ef32015-06-22 11:12:37578 if (connector->IsManaged()) {
579 unsupported_extensions->insert(extension_id);
Oleg Davydovdec175a2020-05-25 16:44:29580 InstallStageTracker::Get(profile_)->ReportFailure(
Oleg Davydov66246bd92019-09-26 16:31:51581 extension_id,
Oleg Davydovdec175a2020-05-25 16:44:29582 InstallStageTracker::FailureReason::DO_NOT_INSTALL_FOR_ENTERPRISE);
dpolukhin1687ef32015-06-22 11:12:37583 VLOG(1) << "Skip installing (or uninstall) external extension "
584 << extension_id << " restricted for managed user";
585 return false;
586 }
587 }
588 return true;
589}
590
[email protected]8e4560b62011-01-14 10:09:14591// static
[email protected]5df038b2012-07-16 19:03:27592void ExternalProviderImpl::CreateExternalProviders(
[email protected]8e4560b62011-01-14 10:09:14593 VisitorInterface* service,
594 Profile* profile,
Alexander Hendrich13fffaf2020-09-03 03:55:33595 PendingExtensionManager* pending_extension_manager,
[email protected]8e4560b62011-01-14 10:09:14596 ProviderCollection* provider_list) {
rkaplowdd66a1342015-03-05 00:31:49597 TRACE_EVENT0("browser,startup",
598 "ExternalProviderImpl::CreateExternalProviders");
[email protected]af984882013-10-21 21:08:51599 scoped_refptr<ExternalLoader> external_loader;
binjincccacef2014-10-13 19:00:20600 scoped_refptr<ExternalLoader> external_recommended_loader;
[email protected]af984882013-10-21 21:08:51601 extensions::Manifest::Location crx_location = Manifest::INVALID_LOCATION;
achuithd3da4f02017-03-23 20:05:29602
Yuta Hijikata1290fee22020-11-25 09:46:28603#if BUILDFLAG(IS_CHROMEOS_ASH)
achuithd3da4f02017-03-23 20:05:29604 if (chromeos::ProfileHelper::IsSigninProfile(profile)) {
Maksim Ivanov12801d0d2020-02-18 10:23:41605 // Download extensions/apps installed by policy in the login profile.
606 // Extensions (not apps) installed through this path will have type
607 // |TYPE_LOGIN_SCREEN_EXTENSION| with limited API capabilities.
Maksim Ivanov8738d332020-01-07 22:19:01608 crx_location = Manifest::EXTERNAL_POLICY_DOWNLOAD;
609 external_loader =
610 base::MakeRefCounted<chromeos::SigninScreenExtensionsExternalLoader>(
Alexander Hendrich13fffaf2020-09-03 03:55:33611 profile, pending_extension_manager);
Jinho Bangb5216cec2018-01-17 19:43:11612 auto signin_profile_provider = std::make_unique<ExternalProviderImpl>(
achuithd3da4f02017-03-23 20:05:29613 service, external_loader, profile, crx_location,
Maksim Ivanov12801d0d2020-02-18 10:23:41614 Manifest::EXTERNAL_POLICY_DOWNLOAD, Extension::FOR_LOGIN_SCREEN);
Maksim Ivanov8738d332020-01-07 22:19:01615 signin_profile_provider->set_auto_acknowledge(true);
Toni Barzic87026682018-01-08 23:21:04616 signin_profile_provider->set_allow_updates(true);
617 provider_list->push_back(std::move(signin_profile_provider));
achuithd3da4f02017-03-23 20:05:29618 return;
619 }
620
[email protected]97275822014-01-21 19:30:36621 policy::BrowserPolicyConnectorChromeOS* connector =
622 g_browser_process->platform_part()->browser_policy_connector_chromeos();
[email protected]2d4cfed2014-01-14 13:59:57623 bool is_chrome_os_public_session = false;
[email protected]2fda9972014-07-23 14:51:59624 const user_manager::User* user =
[email protected]052e3ac2014-06-30 14:22:47625 chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
[email protected]2d4cfed2014-01-14 13:59:57626 policy::DeviceLocalAccount::Type account_type;
alemate909aa58a2016-11-03 22:49:07627 if (user && connector->IsEnterpriseManaged() &&
628 policy::IsDeviceLocalAccountUser(user->GetAccountId().GetUserEmail(),
629 &account_type)) {
[email protected]2d4cfed2014-01-14 13:59:57630 if (account_type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
631 is_chrome_os_public_session = true;
[email protected]af984882013-10-21 21:08:51632 policy::DeviceLocalAccountPolicyBroker* broker =
[email protected]97275822014-01-21 19:30:36633 connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser(
alemate909aa58a2016-11-03 22:49:07634 user->GetAccountId().GetUserEmail());
[email protected]af984882013-10-21 21:08:51635 if (broker) {
636 external_loader = broker->extension_loader();
637 crx_location = Manifest::EXTERNAL_POLICY;
638 } else {
639 NOTREACHED();
640 }
641 } else {
Matthew Dentonef83a622019-08-30 02:07:00642 external_loader = base::MakeRefCounted<ExternalPolicyLoader>(
Oleg Davydov52db8742019-08-20 09:14:40643 profile, ExtensionManagementFactory::GetForBrowserContext(profile),
binjincccacef2014-10-13 19:00:20644 ExternalPolicyLoader::FORCED);
Matthew Dentonef83a622019-08-30 02:07:00645 external_recommended_loader = base::MakeRefCounted<ExternalPolicyLoader>(
Oleg Davydov52db8742019-08-20 09:14:40646 profile, ExtensionManagementFactory::GetForBrowserContext(profile),
binjincccacef2014-10-13 19:00:20647 ExternalPolicyLoader::RECOMMENDED);
[email protected]af984882013-10-21 21:08:51648 }
649#else
Matthew Dentonef83a622019-08-30 02:07:00650 external_loader = base::MakeRefCounted<ExternalPolicyLoader>(
Oleg Davydov52db8742019-08-20 09:14:40651 profile, ExtensionManagementFactory::GetForBrowserContext(profile),
binjincccacef2014-10-13 19:00:20652 ExternalPolicyLoader::FORCED);
Matthew Dentonef83a622019-08-30 02:07:00653 external_recommended_loader = base::MakeRefCounted<ExternalPolicyLoader>(
Oleg Davydov52db8742019-08-20 09:14:40654 profile, ExtensionManagementFactory::GetForBrowserContext(profile),
binjincccacef2014-10-13 19:00:20655 ExternalPolicyLoader::RECOMMENDED);
[email protected]af984882013-10-21 21:08:51656#endif
657
[email protected]b9f4fe52012-11-09 21:40:59658 // Policies are mandatory so they can't be skipped with command line flag.
dchengc7047942014-08-26 05:05:31659 if (external_loader.get()) {
Jinho Bangb5216cec2018-01-17 19:43:11660 auto policy_provider = std::make_unique<ExternalProviderImpl>(
lazyboyf33109d2016-08-31 00:37:08661 service, external_loader, profile, crx_location,
Toni Barzic87026682018-01-08 23:21:04662 Manifest::EXTERNAL_POLICY_DOWNLOAD, Extension::NO_FLAGS);
663 policy_provider->set_allow_updates(true);
664 provider_list->push_back(std::move(policy_provider));
[email protected]af984882013-10-21 21:08:51665 }
[email protected]b9f4fe52012-11-09 21:40:59666
Anqing Zhaof0e96fb42020-12-11 23:21:21667 // Load the KioskAppExternalProvider when running in the Chrome App kiosk
668 // mode.
[email protected]ee3da0552014-07-16 05:27:31669 if (chrome::IsRunningInForcedAppMode()) {
Yuta Hijikata1290fee22020-11-25 09:46:28670#if BUILDFLAG(IS_CHROMEOS_ASH)
Anqing Zhaof0e96fb42020-12-11 23:21:21671 if (user && user->GetType() == user_manager::USER_TYPE_KIOSK_APP) {
672 // Kiosk primary app external provider.
673 // For enterprise managed kiosk apps, change the location to
674 // "force-installed by policy".
675 policy::BrowserPolicyConnectorChromeOS* const connector =
676 g_browser_process->platform_part()
677 ->browser_policy_connector_chromeos();
678 Manifest::Location location = Manifest::EXTERNAL_PREF;
679 if (connector && connector->IsEnterpriseManaged())
680 location = Manifest::EXTERNAL_POLICY;
pbond43ddd4f2015-09-08 16:39:19681
Anqing Zhaof0e96fb42020-12-11 23:21:21682 auto kiosk_app_provider = std::make_unique<ExternalProviderImpl>(
683 service,
684 base::MakeRefCounted<chromeos::KioskAppExternalLoader>(
685 chromeos::KioskAppExternalLoader::AppClass::kPrimary),
686 profile, location, Manifest::INVALID_LOCATION, Extension::NO_FLAGS);
687 kiosk_app_provider->set_auto_acknowledge(true);
688 kiosk_app_provider->set_install_immediately(true);
689 kiosk_app_provider->set_allow_updates(true);
690 provider_list->push_back(std::move(kiosk_app_provider));
jennyz26b7f432015-09-03 20:59:27691
Anqing Zhaof0e96fb42020-12-11 23:21:21692 // Kiosk secondary app external provider.
693 auto secondary_kiosk_app_provider =
694 std::make_unique<ExternalProviderImpl>(
695 service,
696 base::MakeRefCounted<chromeos::KioskAppExternalLoader>(
697 chromeos::KioskAppExternalLoader::AppClass::kSecondary),
698 profile, Manifest::EXTERNAL_PREF,
699 Manifest::EXTERNAL_PREF_DOWNLOAD, Extension::NO_FLAGS);
700 secondary_kiosk_app_provider->set_auto_acknowledge(true);
701 secondary_kiosk_app_provider->set_install_immediately(true);
702 secondary_kiosk_app_provider->set_allow_updates(true);
703 provider_list->push_back(std::move(secondary_kiosk_app_provider));
704 }
[email protected]ee3da0552014-07-16 05:27:31705#endif
706 return;
707 }
708
binjincccacef2014-10-13 19:00:20709 // Extensions provided by recommended policies.
710 if (external_recommended_loader.get()) {
Nicolas Ouellet-Payeur93b74ca1d2020-12-09 23:33:12711 auto recommended_provider = std::make_unique<ExternalProviderImpl>(
lazyboyf33109d2016-08-31 00:37:08712 service, external_recommended_loader, profile, crx_location,
Nicolas Ouellet-Payeur93b74ca1d2020-12-09 23:33:12713 Manifest::EXTERNAL_PREF_DOWNLOAD, Extension::NO_FLAGS);
714 recommended_provider->set_auto_acknowledge(true);
715 provider_list->push_back(std::move(recommended_provider));
binjincccacef2014-10-13 19:00:20716 }
717
[email protected]b9f4fe52012-11-09 21:40:59718 // In tests don't install extensions from default external sources.
719 // It would only slowdown tests and make them flaky.
avi3ef9ec9e2014-12-22 22:50:17720 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]98820ac72019-01-24 19:47:16721 ::switches::kDisableDefaultApps)) {
[email protected]b9f4fe52012-11-09 21:40:59722 return;
[email protected]98820ac72019-01-24 19:47:16723 }
[email protected]73e4c362011-09-22 14:47:18724
725 // On Mac OS, items in /Library/... should be written by the superuser.
726 // Check that all components of the path are writable by root only.
[email protected]5df038b2012-07-16 19:03:27727 ExternalPrefLoader::Options check_admin_permissions_on_mac;
Avi Drissman2e458df2020-07-29 16:24:31728#if defined(OS_MAC)
[email protected]0edc55412011-11-07 16:47:33729 check_admin_permissions_on_mac =
[email protected]5df038b2012-07-16 19:03:27730 ExternalPrefLoader::ENSURE_PATH_CONTROLLED_BY_ADMIN;
[email protected]73e4c362011-09-22 14:47:18731#else
[email protected]5df038b2012-07-16 19:03:27732 check_admin_permissions_on_mac = ExternalPrefLoader::NONE;
[email protected]73e4c362011-09-22 14:47:18733#endif
Peter Kastingbe940e92014-11-20 23:14:08734#if !defined(OS_WIN)
[email protected]d6f7b102012-05-04 13:59:05735 int bundled_extension_creation_flags = Extension::NO_FLAGS;
Peter Kastingbe940e92014-11-20 23:14:08736#endif
Yuta Hijikata1290fee22020-11-25 09:46:28737#if BUILDFLAG(IS_CHROMEOS_ASH)
[email protected]5861bcd2012-10-16 21:40:19738 bundled_extension_creation_flags = Extension::FROM_WEBSTORE |
739 Extension::WAS_INSTALLED_BY_DEFAULT;
[email protected]a4567732013-07-25 21:01:20740
rkcb526cd6b2014-12-18 16:54:37741 if (!is_chrome_os_public_session) {
[email protected]98820ac72019-01-24 19:47:16742 int pref_load_flags =
ginkagef66fae522015-03-03 16:38:16743 profile->IsNewProfile()
744 ? ExternalPrefLoader::DELAY_LOAD_UNTIL_PRIORITY_SYNC
745 : ExternalPrefLoader::NONE;
[email protected]98820ac72019-01-24 19:47:16746 pref_load_flags |= ExternalPrefLoader::USE_USER_TYPE_PROFILE_FILTER;
747 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
748 service,
Matthew Dentonef83a622019-08-30 02:07:00749 base::MakeRefCounted<ExternalPrefLoader>(
750 chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS, pref_load_flags,
751 profile),
[email protected]98820ac72019-01-24 19:47:16752 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
753 bundled_extension_creation_flags));
[email protected]d0b28892014-03-05 18:56:31754
755 // OEM default apps.
[email protected]acc3c7c22014-03-19 06:23:39756 int oem_extension_creation_flags =
757 bundled_extension_creation_flags | Extension::WAS_INSTALLED_BY_OEM;
[email protected]d0b28892014-03-05 18:56:31758 chromeos::ServicesCustomizationDocument* customization =
759 chromeos::ServicesCustomizationDocument::GetInstance();
Jinho Bangb5216cec2018-01-17 19:43:11760 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
lazyboyf33109d2016-08-31 00:37:08761 service, customization->CreateExternalLoader(profile), profile,
762 Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
763 oem_extension_creation_flags));
[email protected]ebb489f2013-09-19 22:08:52764 }
Toni Barzicdff51562018-07-24 19:55:46765
766 // For Chrome OS demo sessions, add pre-installed demo extensions and apps.
767 if (chromeos::DemoExtensionsExternalLoader::SupportedForProfile(profile)) {
Wenzhao Zang463f1142018-09-05 22:50:50768 base::FilePath cache_dir;
769 CHECK(base::PathService::Get(chromeos::DIR_DEVICE_EXTENSION_LOCAL_CACHE,
770 &cache_dir));
771 scoped_refptr<chromeos::DemoExtensionsExternalLoader> loader =
772 base::MakeRefCounted<chromeos::DemoExtensionsExternalLoader>(cache_dir);
Toni Barzicdff51562018-07-24 19:55:46773 std::unique_ptr<ExternalProviderImpl> demo_apps_provider =
774 std::make_unique<ExternalProviderImpl>(
Michael Giuffrida00afa042019-01-29 08:41:09775 service, loader, profile, Manifest::EXTERNAL_POLICY,
776 Manifest::EXTERNAL_POLICY_DOWNLOAD, Extension::NO_FLAGS);
Toni Barzicdff51562018-07-24 19:55:46777 demo_apps_provider->set_auto_acknowledge(true);
778 demo_apps_provider->set_install_immediately(true);
Wenzhao Zanga90de072018-09-19 02:39:26779 chromeos::DemoSession::Get()->SetExtensionsExternalLoader(loader);
Toni Barzicdff51562018-07-24 19:55:46780 provider_list->push_back(std::move(demo_apps_provider));
781 }
[email protected]5bed2ec32013-08-29 22:55:46782#endif
Dominique Fauteux-Chapleauff3bb352019-10-16 14:32:34783 if (!profile->GetPrefs()->GetBoolean(pref_names::kBlockExternalExtensions)) {
Yuta Hijikata1290fee22020-11-25 09:46:28784// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
785// of lacros-chrome is complete.
786#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
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>(
Dominique Fauteux-Chapleauff3bb352019-10-16 14:32:34790 chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS,
791 ExternalPrefLoader::USE_USER_TYPE_PROFILE_FILTER, profile),
Taiju Tsuikib1879b72018-09-21 06:22:47792 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
793 bundled_extension_creation_flags));
Dominique Fauteux-Chapleauff3bb352019-10-16 14:32:34794#endif
795 if (!profile->IsLegacySupervised()) {
796#if defined(OS_WIN)
797 auto registry_provider = std::make_unique<ExternalProviderImpl>(
798 service, new ExternalRegistryLoader, profile,
799 Manifest::EXTERNAL_REGISTRY, Manifest::EXTERNAL_PREF_DOWNLOAD,
800 Extension::NO_FLAGS);
801 registry_provider->set_allow_updates(true);
802 provider_list->push_back(std::move(registry_provider));
803#else
804 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
805 service,
806 base::MakeRefCounted<ExternalPrefLoader>(
807 chrome::DIR_EXTERNAL_EXTENSIONS, check_admin_permissions_on_mac,
808 nullptr),
809 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
810 bundled_extension_creation_flags));
[email protected]5bed2ec32013-08-29 22:55:46811
Dominique Fauteux-Chapleauff3bb352019-10-16 14:32:34812 // Define a per-user source of external extensions.
Sean McAllister4a991b972020-08-19 17:38:51813#if defined(OS_MAC) || ((defined(OS_LINUX) || defined(OS_CHROMEOS)) && \
814 BUILDFLAG(CHROMIUM_BRANDING))
Dominique Fauteux-Chapleauff3bb352019-10-16 14:32:34815 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
816 service,
817 base::MakeRefCounted<ExternalPrefLoader>(
818 chrome::DIR_USER_EXTERNAL_EXTENSIONS, ExternalPrefLoader::NONE,
819 nullptr),
820 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
821 Extension::NO_FLAGS));
[email protected]a29a517a2011-01-21 21:11:12822#endif
[email protected]8e4560b62011-01-14 10:09:14823#endif
Dominique Fauteux-Chapleauff3bb352019-10-16 14:32:34824 }
825 }
[email protected]ed7bbb52012-05-02 11:07:29826
Dominique Fauteux-Chapleauff3bb352019-10-16 14:32:34827 if (!profile->IsLegacySupervised()) {
Yuta Hijikata1290fee22020-11-25 09:46:28828#if !BUILDFLAG(IS_CHROMEOS_ASH)
[email protected]7da12212013-02-14 10:53:49829 // The default apps are installed as INTERNAL but use the external
830 // extension installer codeflow.
Taiju Tsuikib1879b72018-09-21 06:22:47831 provider_list->push_back(std::make_unique<default_apps::Provider>(
832 profile, service,
Matthew Dentonef83a622019-08-30 02:07:00833 base::MakeRefCounted<ExternalPrefLoader>(
834 chrome::DIR_DEFAULT_APPS, ExternalPrefLoader::NONE, nullptr),
Taiju Tsuikib1879b72018-09-21 06:22:47835 Manifest::INTERNAL, Manifest::INTERNAL,
836 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT));
[email protected]98b4aca62011-09-28 01:27:23837#endif
xiyuan65b68ab12015-06-26 19:00:18838
Taiju Tsuikib1879b72018-09-21 06:22:47839 std::unique_ptr<ExternalProviderImpl> drive_migration_provider(
840 new ExternalProviderImpl(
841 service,
Matthew Dentonef83a622019-08-30 02:07:00842 base::MakeRefCounted<ExtensionMigrator>(
843 profile, extension_misc::kDriveHostedAppId,
844 extension_misc::kDocsOfflineExtensionId),
Taiju Tsuikib1879b72018-09-21 06:22:47845 profile, Manifest::EXTERNAL_PREF, Manifest::EXTERNAL_PREF_DOWNLOAD,
846 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT));
847 drive_migration_provider->set_auto_acknowledge(true);
848 provider_list->push_back(std::move(drive_migration_provider));
849 }
treibcc82ab82015-03-02 09:41:49850
Jinho Bangb5216cec2018-01-17 19:43:11851 provider_list->push_back(std::make_unique<ExternalProviderImpl>(
Matthew Dentonef83a622019-08-30 02:07:00852 service, base::MakeRefCounted<ExternalComponentLoader>(profile), profile,
lazyboyf33109d2016-08-31 00:37:08853 Manifest::INVALID_LOCATION, Manifest::EXTERNAL_COMPONENT,
854 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT));
[email protected]8e4560b62011-01-14 10:09:14855}
[email protected]5df038b2012-07-16 19:03:27856
857} // namespace extensions