1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
// 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_
|