blob: 9e72e921e79a74b6f7e1d9384864861ca7f20eae [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_EXTENSIONS_EXTERNAL_PROVIDER_MANAGER_H_
#define CHROME_BROWSER_EXTENSIONS_EXTERNAL_PROVIDER_MANAGER_H_
#include <optional>
#include <string>
#include "base/auto_reset.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "components/keyed_service/core/keyed_service.h"
#include "extensions/browser/external_provider_interface.h"
#include "extensions/buildflags/buildflags.h"
static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));
namespace content {
class BrowserContext;
}
namespace extensions {
class CrxInstallError;
class ExtensionErrorController;
class ExtensionPrefs;
class ExtensionRegistry;
class PendingExtensionManager;
// Class ExternalProviderManager manages the set of external extension
// providers, and installs/uninstalls the extensions they provide.
class ExternalProviderManager
: public KeyedService,
public ExternalProviderInterface::VisitorInterface {
public:
explicit ExternalProviderManager(content::BrowserContext* context);
ExternalProviderManager(const ExternalProviderManager&) = delete;
ExternalProviderManager& operator=(const ExternalProviderManager&) = delete;
~ExternalProviderManager() override;
// KeyedService:
void Shutdown() override;
// Returns the instance for the given `browser_context`.
static ExternalProviderManager* Get(content::BrowserContext* browser_context);
// ExternalProviderInterface::VisitorInterface:
bool OnExternalExtensionFileFound(
const ExternalInstallInfoFile& info) override;
bool OnExternalExtensionUpdateUrlFound(
const ExternalInstallInfoUpdateUrl& info,
bool force_update) override;
void OnExternalProviderReady(
const ExternalProviderInterface* provider) override;
void OnExternalProviderUpdateComplete(
const ExternalProviderInterface* provider,
const std::vector<ExternalInstallInfoUpdateUrl>& update_url_extensions,
const std::vector<ExternalInstallInfoFile>& file_extensions,
const std::set<std::string>& removed_extensions) override;
// Creates external extension providers.
void CreateExternalProviders();
// Checks for updates (or potentially new extensions from external providers)
void CheckForExternalUpdates();
// Ask each external extension provider to call
// OnExternalExtension(File|UpdateUrl)Found() with their known extensions.
// This will trigger an update/reinstall of the extensions saved in the
// provider's prefs.
void ReinstallProviderExtensions();
// Clears all ExternalProviders.
void ClearProvidersForTesting();
// Adds an ExternalProviderInterface for the service to use during testing.
void AddProviderForTesting(
std::unique_ptr<ExternalProviderInterface> test_provider);
// Sets a callback to be called when all external providers are ready and
// their extensions have been installed.
void set_external_updates_finished_callback_for_test(
base::OnceClosure callback) {
external_updates_finished_callback_ = std::move(callback);
}
// While disabled all calls to CheckForExternalUpdates() will bail out.
static base::AutoReset<bool> DisableExternalUpdatesForTesting();
private:
// Returns true if all the external extension providers are ready.
bool AreAllExternalProvidersReady() const;
// Called once all external providers are ready. Checks for unclaimed
// external extensions.
void OnAllExternalProvidersReady();
// For the extension in `version_path` with `id`, check to see if it's an
// externally managed extension. If so, uninstall it.
void CheckExternalUninstall(const std::string& id);
// Callback for installation finish of an extension from external file, since
// we need to remove this extension from the pending extension manager in case
// of installation failure. This is only a need for extensions installed
// by file, since extensions installed by URL will be intentionally kept in
// the manager and retried later.
void InstallationFromExternalFileFinished(
const std::string& extension_id,
const std::optional<CrxInstallError>& error);
// Are we expecting a reinstall of the extension due to corruption?
bool IsReinstallForCorruptionExpected(const ExtensionId& id) const;
// The BrowserContext with which the manager is associated.
raw_ptr<content::BrowserContext> context_;
// A collection of external extension providers. Each provider reads
// a source of external extension information. Examples include the
// windows registry and external_extensions.json.
ProviderCollection external_extension_providers_;
// Preferences for the owning profile.
raw_ptr<ExtensionPrefs> extension_prefs_ = nullptr;
// Sets of enabled/disabled/terminated/blocklisted extensions. Not owned.
raw_ptr<ExtensionRegistry> registry_ = nullptr;
// Hold the set of pending extensions. Not owned.
raw_ptr<PendingExtensionManager> pending_extension_manager_ = nullptr;
// The controller for the UI that alerts the user about any blocklisted
// extensions.
raw_ptr<ExtensionErrorController> error_controller_;
// Set to true by OnExternalExtensionUpdateUrlFound() when an external
// extension URL is found, and by CheckForUpdatesSoon() when an update check
// has to wait for the external providers. Used in
// OnAllExternalProvidersReady() to determine if an update check is needed to
// install pending extensions.
bool update_once_all_providers_are_ready_ = false;
// A callback to be called when all external providers are ready and their
// extensions have been installed. This happens on initial load and whenever
// a new entry is found. Normally this is a null callback, but is used in
// external provider related tests.
base::OnceClosure external_updates_finished_callback_;
base::WeakPtrFactory<ExternalProviderManager> weak_ptr_factory_{this};
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_EXTERNAL_PROVIDER_MANAGER_H_