| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/web_applications/extension_status_utils.h" |
| |
| #include "base/feature_list.h" |
| #include "base/metrics/field_trial_params.h" |
| #include "base/one_shot_event.h" |
| #include "base/strings/string_split.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/extensions/extension_management.h" |
| #include "chrome/browser/extensions/preinstalled_apps.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/common/chrome_features.h" |
| #include "extensions/browser/extension_prefs.h" |
| #include "extensions/browser/extension_registry.h" |
| #include "extensions/browser/extension_system.h" |
| #include "extensions/browser/management_policy.h" |
| #include "extensions/browser/pref_names.h" |
| #include "extensions/common/constants.h" |
| #include "extensions/common/extension.h" |
| |
| namespace { |
| |
| const char* g_preinstalled_app_for_testing = nullptr; |
| |
| #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ |
| BUILDFLAG(IS_FUCHSIA) |
| base::Feature kChromeAppsDeprecationExcludeForceInstalls( |
| "ChromeAppsDeprecationExcludeForceInstalls", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| base::FeatureParam<std::string> kChromeAppAllowlist{ |
| &features::kChromeAppsDeprecation, "allow_list", ""}; |
| #endif |
| |
| } // namespace |
| |
| namespace extensions { |
| |
| bool IsExtensionBlockedByPolicy(content::BrowserContext* context, |
| const std::string& extension_id) { |
| auto* registry = ExtensionRegistry::Get(context); |
| // May be nullptr in unit tests. |
| if (!registry) |
| return false; |
| |
| const Extension* extension = registry->GetInstalledExtension(extension_id); |
| ExtensionManagement* management = |
| ExtensionManagementFactory::GetForBrowserContext(context); |
| ExtensionManagement::InstallationMode mode = |
| extension ? management->GetInstallationMode(extension) |
| : management->GetInstallationMode(extension_id, |
| /*update_url=*/std::string()); |
| return mode == ExtensionManagement::INSTALLATION_BLOCKED || |
| mode == ExtensionManagement::INSTALLATION_REMOVED; |
| } |
| |
| bool IsExtensionInstalled(content::BrowserContext* context, |
| const std::string& extension_id) { |
| auto* registry = ExtensionRegistry::Get(context); |
| // May be nullptr in unit tests. |
| return registry && registry->GetInstalledExtension(extension_id); |
| } |
| |
| bool IsExtensionForceInstalled(content::BrowserContext* context, |
| const std::string& extension_id, |
| std::u16string* reason) { |
| auto* registry = ExtensionRegistry::Get(context); |
| // May be nullptr in unit tests. |
| if (!registry) |
| return false; |
| |
| auto* extension_system = ExtensionSystem::Get(context); |
| if (!extension_system) |
| return false; |
| |
| const Extension* extension = registry->GetInstalledExtension(extension_id); |
| return extension && |
| extension_system->management_policy()->MustRemainInstalled(extension, |
| reason); |
| } |
| |
| bool IsExtensionDefaultInstalled(content::BrowserContext* context, |
| const std::string& extension_id) { |
| auto* registry = ExtensionRegistry::Get(context); |
| // May be nullptr in unit tests. |
| if (!registry) |
| return false; |
| const Extension* extension = registry->GetInstalledExtension(extension_id); |
| return extension && |
| (extension->creation_flags() & Extension::WAS_INSTALLED_BY_DEFAULT); |
| } |
| |
| bool IsExternalExtensionUninstalled(content::BrowserContext* context, |
| const std::string& extension_id) { |
| auto* prefs = ExtensionPrefs::Get(context); |
| // May be nullptr in unit tests. |
| return prefs && prefs->IsExternalExtensionUninstalled(extension_id); |
| } |
| |
| #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ |
| BUILDFLAG(IS_FUCHSIA) |
| bool IsExtensionUnsupportedDeprecatedApp(content::BrowserContext* context, |
| const std::string& extension_id) { |
| if (!base::FeatureList::IsEnabled(features::kChromeAppsDeprecation)) |
| return false; |
| |
| if (extension_id == extensions::kWebStoreAppId) |
| return false; |
| |
| const auto* prefs = Profile::FromBrowserContext(context)->GetPrefs(); |
| if (prefs->GetBoolean(pref_names::kChromeAppsEnabled)) |
| return false; |
| |
| auto* registry = ExtensionRegistry::Get(context); |
| // May be nullptr in unit tests. |
| if (!registry) |
| return false; |
| |
| const extensions::Extension* app = registry->GetExtensionById( |
| extension_id, extensions::ExtensionRegistry::EVERYTHING); |
| if (!app || !app->is_app()) |
| return false; |
| |
| bool force_installed = |
| IsExtensionForceInstalled(context, extension_id, nullptr); |
| bool preinstalled = IsPreinstalledAppId(extension_id); |
| |
| // This feature allows us to keep chrome apps that are force installed AND |
| // preinstalled. |
| if (base::FeatureList::IsEnabled( |
| features::kKeepForceInstalledPreinstalledApps) && |
| force_installed && preinstalled) { |
| return false; |
| } |
| |
| if (base::FeatureList::IsEnabled( |
| kChromeAppsDeprecationExcludeForceInstalls) && |
| force_installed) { |
| return false; |
| } |
| |
| // This feature parameter can specify specific extension ids to continue |
| // allowing. |
| if (!kChromeAppAllowlist.Get().empty()) { |
| std::vector<std::string> allowed_extension_ids = |
| base::SplitString(kChromeAppAllowlist.Get(), ",", base::TRIM_WHITESPACE, |
| base::SPLIT_WANT_NONEMPTY); |
| for (std::string allowed_extension_id : allowed_extension_ids) { |
| if (extension_id == allowed_extension_id) |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| #endif |
| |
| void OnExtensionSystemReady(content::BrowserContext* context, |
| base::OnceClosure callback) { |
| ExtensionSystem::Get(context)->ready().Post(FROM_HERE, std::move(callback)); |
| } |
| |
| bool DidPreinstalledAppsPerformNewInstallation(Profile* profile) { |
| #if !BUILDFLAG(IS_CHROMEOS) |
| return preinstalled_apps::Provider::DidPerformNewInstallationForProfile( |
| profile); |
| #else |
| return false; |
| #endif |
| } |
| |
| bool IsPreinstalledAppId(const std::string& app_id) { |
| if (g_preinstalled_app_for_testing && |
| app_id == g_preinstalled_app_for_testing) |
| return true; |
| |
| // Also update the duplicated function in extensions/common/constants.cc when |
| // changing the logic here. |
| return app_id == extension_misc::kGmailAppId || |
| app_id == extension_misc::kGoogleDocsAppId || |
| app_id == extension_misc::kGoogleDriveAppId || |
| app_id == extension_misc::kGoogleSheetsAppId || |
| app_id == extension_misc::kGoogleSlidesAppId || |
| app_id == extension_misc::kYoutubeAppId; |
| } |
| |
| void SetPreinstalledAppIdForTesting(const char* app_id) { |
| g_preinstalled_app_for_testing = app_id; |
| } |
| |
| } // namespace extensions |