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 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef EXTENSIONS_BROWSER_PENDING_EXTENSION_MANAGER_H_
#define EXTENSIONS_BROWSER_PENDING_EXTENSION_MANAGER_H_
#include <list>
#include <map>
#include <optional>
#include <string>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "components/keyed_service/core/keyed_service.h"
#include "extensions/browser/pending_extension_info.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/manifest.h"
#include "third_party/blink/public/mojom/manifest/manifest.mojom-shared.h"
class GURL;
namespace base {
class Version;
}
namespace content {
class BrowserContext;
}
namespace extensions {
FORWARD_DECLARE_TEST(ExtensionServiceTest,
UpdatePendingExtensionAlreadyInstalled);
class PendingExtensionManager;
class ExtensionUpdaterTest;
void SetupPendingExtensionManagerForTest(
int count,
const GURL& update_url,
PendingExtensionManager* pending_extension_manager);
// Class PendingExtensionManager manages the set of extensions which are
// being installed or updated. In general, installation and updates take
// time, because they involve downloading, unpacking, and installing.
// This class allows us to avoid race cases where multiple sources install
// the same extension.
// The ExtensionService creates an instance of this class, and manages its
// lifetime. This class should only be used from the UI thread.
class PendingExtensionManager : public KeyedService {
public:
// Observer of changes in the PendingExtensionManager state
class Observer : public base::CheckedObserver {
public:
// Called when an extension is added to the pending list.
//
// This means the extension with the given `id` is currently being
// installed or updated.
virtual void OnExtensionAdded(const std::string& id) {}
// Called when an extension is removed from the pending list.
//
// This means the extension with the given `id` is no longer being installed
// or updated. Note that this doesn't mean the operation actually succeeded.
// It just means the operation on this extenison is no longer taking place
// (ie, pending completion).
virtual void OnExtensionRemoved(const std::string& id) {}
};
explicit PendingExtensionManager(content::BrowserContext* context);
PendingExtensionManager(const PendingExtensionManager&) = delete;
PendingExtensionManager& operator=(const PendingExtensionManager&) = delete;
~PendingExtensionManager() override;
// Returns the instance for the given `browser_context`.
static PendingExtensionManager* Get(content::BrowserContext* browser_context);
// TODO(skerner): Many of these methods can be private once code in
// ExtensionService is moved into methods of this class.
// Remove extension with id `id` from the set of pending extensions. Returns
// true if such an extension was found and removed, false otherwise.
bool Remove(const std::string& id);
// Get the information for a pending extension. Returns a pointer to the
// pending extension with id `id`, or NULL if there is no such extension.
const PendingExtensionInfo* GetById(const std::string& id) const;
// Is `id` in the set of pending extensions?
bool IsIdPending(const std::string& id) const;
// Returns true if there are any extensions pending.
bool HasPendingExtensions() const;
// Whether there is pending extension install from sync.
bool HasPendingExtensionFromSync() const;
// Whether there is a high-priority pending extension (one from either policy
// or an external component extension).
bool HasHighPriorityPendingExtension() const;
// Adds an extension in a pending state; the extension with the
// given info will be installed on the next auto-update cycle.
// Return true if the extension was added. Will return false
// if the extension is pending from another source which overrides
// sync installs (such as a policy extension) or if the extension
// is already installed.
// After installation, the extension will be granted permissions iff
// `version` is valid and matches the actual installed version.
bool AddFromSync(
const std::string& id,
const GURL& update_url,
const base::Version& version,
PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
bool remote_install);
// Adds an extension that was depended on by another extension.
bool AddFromExtensionImport(
const std::string& id,
const GURL& update_url,
PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install);
// Given an extension id and an update URL, schedule the extension
// to be fetched, installed, and activated.
bool AddFromExternalUpdateUrl(const std::string& id,
const std::string& install_parameter,
const GURL& update_url,
mojom::ManifestLocation location,
int creation_flags,
bool mark_acknowledged);
// Add a pending extension record for an external CRX file.
// Return true if the CRX should be installed, false if an existing
// pending record overrides it.
bool AddFromExternalFile(const std::string& id,
mojom::ManifestLocation location,
const base::Version& version,
int creation_flags,
bool mark_acknowledged);
// Get the list of pending IDs that should be installed from an update URL.
// Pending extensions that will be installed from local files will not be
// included in the set.
std::list<std::string> GetPendingIdsForUpdateCheck() const;
// Adds an observer to the observer list.
void AddObserver(Observer* observer);
// Removes an observer from the observer list.
void RemoveObserver(Observer* observer);
private:
// Assumes an extension with id `id` is not already installed.
// Return true if the extension was added.
bool AddExtensionImpl(
const std::string& id,
const std::string& install_parameter,
const GURL& update_url,
const base::Version& version,
PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
bool is_from_sync,
mojom::ManifestLocation install_source,
int creation_flags,
bool mark_acknowledged,
bool remote_install);
// Add a pending extension record directly. Used for unit tests that need
// to set an inital state. Use friendship to allow the tests to call this
// method.
void AddForTesting(PendingExtensionInfo pending_extension_info);
// Adds the given key and value to the pending_extensions_ map.
// Do it only via this method to ensure observers are consistently
// notified.
void AddToMap(const std::string& id, PendingExtensionInfo info);
// The BrowserContext with which the manager is associated.
raw_ptr<content::BrowserContext, DanglingUntriaged> context_;
std::map<std::string, PendingExtensionInfo> pending_extensions_;
base::ObserverList<Observer> observers_;
FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
UpdatePendingExtensionAlreadyInstalled);
friend class ExtensionUpdaterTest;
friend void SetupPendingExtensionManagerForTest(
int count,
const GURL& update_url,
PendingExtensionManager* pending_extension_manager);
};
} // namespace extensions
#endif // EXTENSIONS_BROWSER_PENDING_EXTENSION_MANAGER_H_
|