chromium/chrome/browser/extensions/extension_service.cc

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/extension_service.h"

#include <stddef.h>

#include <iterator>
#include <memory>
#include <optional>
#include <set>
#include <utility>

#include "base/barrier_closure.h"
#include "base/check_op.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/debug/alias.h"
#include "base/debug/dump_without_crashing.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/observer_list.h"
#include "base/one_shot_event.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/syslog_logging.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/data_deleter.h"
#include "chrome/browser/extensions/extension_action_storage_manager.h"
#include "chrome/browser/extensions/extension_assets_manager.h"
#include "chrome/browser/extensions/extension_disabled_ui.h"
#include "chrome/browser/extensions/extension_error_controller.h"
#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "chrome/browser/extensions/extension_sync_service.h"
#include "chrome/browser/extensions/external_install_manager.h"
#include "chrome/browser/extensions/external_provider_impl.h"
#include "chrome/browser/extensions/forced_extensions/install_stage_tracker.h"
#include "chrome/browser/extensions/install_verifier.h"
#include "chrome/browser/extensions/installed_loader.h"
#include "chrome/browser/extensions/omaha_attributes_handler.h"
#include "chrome/browser/extensions/pending_extension_manager.h"
#include "chrome/browser/extensions/permissions/permissions_updater.h"
#include "chrome/browser/extensions/profile_util.h"
#include "chrome/browser/extensions/shared_module_service.h"
#include "chrome/browser/extensions/unpacked_installer.h"
#include "chrome/browser/extensions/updater/chrome_extension_downloader_factory.h"
#include "chrome/browser/extensions/updater/extension_updater.h"
#include "chrome/browser/google/google_brand.h"
#include "chrome/browser/lifetime/termination_notification.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
#include "chrome/browser/ui/webui/favicon_source.h"
#include "chrome/browser/ui/webui/theme_source.h"
#include "chrome/browser/upgrade_detector/upgrade_detector.h"
#include "chrome/common/buildflags.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/crx_file/id_util.h"
#include "components/favicon_base/favicon_url_parser.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "components/supervised_user/core/browser/supervised_user_preferences.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
#include "extensions/browser/blocklist_extension_prefs.h"
#include "extensions/browser/blocklist_state.h"
#include "extensions/browser/disable_reason.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_file_task_runner.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extension_util.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/external_install_info.h"
#include "extensions/browser/install_flag.h"
#include "extensions/browser/management_policy.h"
#include "extensions/browser/pref_names.h"
#include "extensions/browser/process_map.h"
#include "extensions/browser/renderer_startup_helper.h"
#include "extensions/browser/uninstall_reason.h"
#include "extensions/browser/unloaded_extension_reason.h"
#include "extensions/browser/update_observer.h"
#include "extensions/browser/updater/extension_cache.h"
#include "extensions/browser/updater/extension_downloader.h"
#include "extensions/browser/updater/manifest_fetch_data.h"
#include "extensions/common/constants.h"
#include "extensions/common/crash_keys.h"
#include "extensions/common/extension_features.h"
#include "extensions/common/extension_urls.h"
#include "extensions/common/features/feature_developer_mode_only.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/manifest_handlers/incognito_info.h"
#include "extensions/common/manifest_handlers/shared_module_info.h"
#include "extensions/common/manifest_url_handlers.h"
#include "extensions/common/permissions/api_permission.h"
#include "extensions/common/permissions/permission_message_provider.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/switches.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "chromeos/constants/chromeos_features.h"
#endif

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "base/system/sys_info.h"
#include "chrome/browser/ash/extensions/install_limiter.h"
#include "chrome/browser/ash/fileapi/file_system_backend.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "storage/browser/file_system/file_system_context.h"
#endif

BrowserContext;
BrowserThread;
ManifestLocation;

namespace extensions {

LoadErrorBehavior;

namespace {

bool g_external_updates_disabled_for_test_ =;

// Wait this long after an extensions becomes idle before updating it.
constexpr base::TimeDelta kUpdateIdleDelay =;

// IDs of component extensions that have been obsoleted and need to be
// uninstalled.
// Note: We preserve at least one entry here for continued testing coverage.
const char* const kObsoleteComponentExtensionIds[] =;

const char kBlockLoadCommandline[] =;

// ExtensionUnpublishedAvailability policy default value.
constexpr int kAllowUnpublishedExtensions =;

// When uninstalling an extension, determine if the extension's directory
// should be deleted when uninstalling. Returns `true` iff extension is
// unpacked and installed outside the unpacked extensions installations dir.
// Example: packed extensions are always deleted. But unpacked extensions are
// in a folder outside the profile dir are not deleted.
bool SkipDeleteExtensionDir(const Extension& extension,
                            const base::FilePath& profile_path) {}

bool ShouldBlockCommandLineExtension(Profile& profile) {}
}  // namespace

// ExtensionService.

void ExtensionService::CheckExternalUninstall(const std::string& id) {}

void ExtensionService::ClearProvidersForTesting() {}

void ExtensionService::AddProviderForTesting(
    std::unique_ptr<ExternalProviderInterface> test_provider) {}

void ExtensionService::BlocklistExtensionForTest(
    const std::string& extension_id) {}

void ExtensionService::GreylistExtensionForTest(
    const std::string& extension_id,
    const BitMapBlocklistState& state) {}

bool ExtensionService::OnExternalExtensionUpdateUrlFound(
    const ExternalInstallInfoUpdateUrl& info,
    bool force_update) {}

void ExtensionService::OnExternalProviderUpdateComplete(
    const ExternalProviderInterface* provider,
    const std::vector<ExternalInstallInfoUpdateUrl>& update_url_extensions,
    const std::vector<ExternalInstallInfoFile>& file_extensions,
    const std::set<std::string>& removed_extensions) {}

ExtensionService::ExtensionService(
    Profile* profile,
    const base::CommandLine* command_line,
    const base::FilePath& install_directory,
    const base::FilePath& unpacked_install_directory,
    ExtensionPrefs* extension_prefs,
    Blocklist* blocklist,
    bool autoupdate_enabled,
    bool extensions_enabled,
    base::OneShotEvent* ready)
    :{}

PendingExtensionManager* ExtensionService::pending_extension_manager() {}

CorruptedExtensionReinstaller*
ExtensionService::corrupted_extension_reinstaller() {}

base::WeakPtr<ExtensionServiceInterface> ExtensionService::AsWeakPtr() {}

ExtensionService::~ExtensionService() {}

void ExtensionService::Shutdown() {}

void ExtensionService::Init() {}

void ExtensionService::EnabledReloadableExtensions() {}

void ExtensionService::MaybeFinishShutdownDelayed() {}

scoped_refptr<CrxInstaller> ExtensionService::CreateUpdateInstaller(
    const CRXFileInfo& file,
    bool file_ownership_passed) {}

base::AutoReset<bool> ExtensionService::DisableExternalUpdatesForTesting() {}

void ExtensionService::LoadExtensionsFromCommandLineFlag(
    const char* switch_name) {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
void ExtensionService::LoadSigninProfileTestExtension(const std::string& path) {
  base::SysInfo::CrashIfChromeOSNonTestImage();
  std::string extension_id;
  const bool installing = UnpackedInstaller::Create(this)->LoadFromCommandLine(
      base::FilePath(path), &extension_id, false /*only-allow-apps*/);
  CHECK(installing);
  CHECK_EQ(extension_id, extension_misc::kSigninProfileTestExtensionId)
      << extension_id
      << " extension not allowed to load from the command line in the "
         "signin profile";
}
#endif

// TODO(michaelpg): Group with other ExtensionRegistrar::Delegate overrides
// according to header file once diffs have settled down.
void ExtensionService::LoadExtensionForReload(
    const ExtensionId& extension_id,
    const base::FilePath& path,
    LoadErrorBehavior load_error_behavior) {}

void ExtensionService::OnUnpackedReloadFailure(const Extension* extension,
                                               const base::FilePath& file_path,
                                               const std::string& error) {}

void ExtensionService::ReloadExtension(const std::string& extension_id) {}

void ExtensionService::ReloadExtensionWithQuietFailure(
    const std::string& extension_id) {}

bool ExtensionService::UninstallExtension(
    // "transient" because the process of uninstalling may cause the reference
    // to become invalid. Instead, use |extension->id()|.
    const std::string& transient_extension_id,
    UninstallReason reason,
    std::u16string* error,
    base::OnceClosure done_callback) {}

// static
void ExtensionService::UninstallExtensionOnFileThread(
    const std::string& id,
    const std::string& profile_user_name,
    const base::FilePath& extensions_install_dir,
    const base::FilePath& extension_dir_to_delete,
    const base::FilePath& profile_dir) {}

bool ExtensionService::IsExtensionEnabled(
    const std::string& extension_id) const {}

void ExtensionService::PerformActionBasedOnOmahaAttributes(
    const std::string& extension_id,
    const base::Value::Dict& attributes) {}

void ExtensionService::PerformActionBasedOnExtensionTelemetryServiceVerdicts(
    const Blocklist::BlocklistStateMap& blocklist_state_map) {}

void ExtensionService::OnGreylistStateRemoved(const std::string& extension_id) {}

void ExtensionService::OnGreylistStateAdded(const std::string& extension_id,
                                            BitMapBlocklistState new_state) {}

void ExtensionService::OnBlocklistStateRemoved(
    const std::string& extension_id) {}

void ExtensionService::OnBlocklistStateAdded(const std::string& extension_id) {}

void ExtensionService::RemoveDisableReasonAndMaybeEnable(
    const std::string& extension_id,
    disable_reason::DisableReason reason_to_remove) {}

void ExtensionService::EnableExtension(const std::string& extension_id) {}

void ExtensionService::DisableExtension(const std::string& extension_id,
                                        int disable_reasons) {}

void ExtensionService::DisableExtensionWithSource(
    const Extension* source_extension,
    const std::string& extension_id,
    disable_reason::DisableReason disable_reasons) {}

void ExtensionService::DisableUserExtensionsExcept(
    const std::vector<std::string>& except_ids) {}

// Extensions that are not locked, components or forced by policy should be
// locked. Extensions are no longer considered enabled or disabled. Blocklisted
// extensions are now considered both blocklisted and locked.
void ExtensionService::BlockAllExtensions() {}

// All locked extensions should revert to being either enabled or disabled
// as appropriate.
void ExtensionService::UnblockAllExtensions() {}

void ExtensionService::GrantPermissionsAndEnableExtension(
    const Extension* extension) {}

void ExtensionService::GrantPermissions(const Extension* extension) {}

// static
void ExtensionService::RecordPermissionMessagesHistogram(
    const Extension* extension,
    const char* histogram_basename,
    bool log_user_profile_histograms) {}

// TODO(michaelpg): Group with other ExtensionRegistrar::Delegate overrides
// according to header file once diffs have settled down.
void ExtensionService::PostActivateExtension(
    scoped_refptr<const Extension> extension) {}

// TODO(michaelpg): Group with other ExtensionRegistrar::Delegate overrides
// according to header file once diffs have settled down.
void ExtensionService::PostDeactivateExtension(
    scoped_refptr<const Extension> extension) {}

content::BrowserContext* ExtensionService::GetBrowserContext() const {}

void ExtensionService::CheckManagementPolicy() {}

void ExtensionService::CheckForUpdatesSoon() {}

// Some extensions will autoupdate themselves externally from Chrome.  These
// are typically part of some larger client application package. To support
// these, the extension will register its location in the preferences file
// (and also, on Windows, in the registry) and this code will periodically
// check that location for a .crx file, which it will then install locally if
// a new version is available.
// Errors are reported through LoadErrorReporter. Success is not reported.
void ExtensionService::CheckForExternalUpdates() {}

void ExtensionService::ReinstallProviderExtensions() {}

void ExtensionService::OnExternalProviderReady(
    const ExternalProviderInterface* provider) {}

bool ExtensionService::AreAllExternalProvidersReady() const {}

void ExtensionService::OnAllExternalProvidersReady() {}

void ExtensionService::UnloadExtension(const std::string& extension_id,
                                       UnloadedExtensionReason reason) {}

void ExtensionService::RemoveComponentExtension(
    const std::string& extension_id) {}

void ExtensionService::UnloadAllExtensionsForTest() {}

void ExtensionService::ReloadExtensionsForTest() {}

void ExtensionService::SetReadyAndNotifyListeners() {}

void ExtensionService::AddExtension(const Extension* extension) {}

void ExtensionService::AddComponentExtension(const Extension* extension) {}

void ExtensionService::CheckPermissionsIncrease(const Extension* extension,
                                                bool is_extension_loaded) {}

void ExtensionService::UpdateActiveExtensionsInCrashReporter() {}

void ExtensionService::OnExtensionInstalled(
    const Extension* extension,
    const syncer::StringOrdinal& page_ordinal,
    int install_flags,
    base::Value::Dict ruleset_install_prefs) {}

void ExtensionService::OnExtensionManagementSettingsChanged() {}

void ExtensionService::AddNewOrUpdatedExtension(
    const Extension* extension,
    Extension::State initial_state,
    int install_flags,
    const syncer::StringOrdinal& page_ordinal,
    const std::string& install_parameter,
    base::Value::Dict ruleset_install_prefs) {}

bool ExtensionService::FinishDelayedInstallationIfReady(
    const std::string& extension_id,
    bool install_immediately) {}

void ExtensionService::FinishInstallation(const Extension* extension) {}

const Extension* ExtensionService::GetPendingExtensionUpdate(
    const std::string& id) const {}

void ExtensionService::TerminateExtension(const std::string& extension_id) {}

bool ExtensionService::OnExternalExtensionFileFound(
    const ExternalInstallInfoFile& info) {}

void ExtensionService::InstallationFromExternalFileFinished(
    const std::string& extension_id,
    const std::optional<CrxInstallError>& error) {}

void ExtensionService::DidCreateMainFrameForBackgroundPage(
    ExtensionHost* host) {}

void ExtensionService::OnExtensionHostRenderProcessGone(
    content::BrowserContext* browser_context,
    ExtensionHost* extension_host) {}

void ExtensionService::OnAppTerminating() {}

void ExtensionService::OnRenderProcessHostCreated(
    content::RenderProcessHost* host) {}

void ExtensionService::RenderProcessHostDestroyed(
    content::RenderProcessHost* host) {}

int ExtensionService::GetDisableReasonsOnInstalled(const Extension* extension) {}

// Helper method to determine if an extension can be blocked.
bool ExtensionService::CanBlockExtension(const Extension* extension) const {}

InstallGate::Action ExtensionService::ShouldDelayExtensionInstall(
    const Extension* extension,
    bool install_immediately,
    ExtensionPrefs::DelayReason* reason) const {}

void ExtensionService::MaybeFinishDelayedInstallations() {}

void ExtensionService::OnBlocklistUpdated() {}

void ExtensionService::OnCWSInfoChanged() {}

void ExtensionService::OnUpgradeRecommended() {}

void ExtensionService::PreAddExtension(const Extension* extension,
                                       const Extension* old_extension) {}

bool ExtensionService::CanEnableExtension(const Extension* extension) {}

bool ExtensionService::CanDisableExtension(const Extension* extension) {}

bool ExtensionService::ShouldBlockExtension(const Extension* extension) {}

void ExtensionService::OnProfileMarkedForPermanentDeletion(Profile* profile) {}

void ExtensionService::ManageBlocklist(
    const Blocklist::BlocklistStateMap& state_map) {}

void ExtensionService::AddUpdateObserver(UpdateObserver* observer) {}

void ExtensionService::RemoveUpdateObserver(UpdateObserver* observer) {}

void ExtensionService::RegisterInstallGate(ExtensionPrefs::DelayReason reason,
                                           InstallGate* install_delayer) {}

void ExtensionService::UnregisterInstallGate(InstallGate* install_delayer) {}

bool ExtensionService::UserCanDisableInstalledExtension(
    const std::string& extension_id) {}

// Used only by test code.
void ExtensionService::UnloadAllExtensionsInternal() {}

void ExtensionService::OnInstalledExtensionsLoaded() {}

void ExtensionService::UninstallMigratedExtensions() {}

}  // namespace extensions