File: pending_extension_manager.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (199 lines) | stat: -rw-r--r-- 7,733 bytes parent folder | download | duplicates (5)
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_