File: unpacked_installer.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 (244 lines) | stat: -rw-r--r-- 8,886 bytes parent folder | download | duplicates (3)
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
// Copyright 2012 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_UNPACKED_INSTALLER_H_
#define CHROME_BROWSER_EXTENSIONS_UNPACKED_INSTALLER_H_

#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "base/callback_list.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/scoped_observation.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile_observer.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/preload_check.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/manifest.h"

static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));

class Profile;

namespace content {
class BrowserContext;
}

namespace extensions {

class Extension;
class ExtensionService;
class PreloadCheckGroup;

// Installs and loads an unpacked extension. Because internal state needs to be
// held about the installation process, only one call to Load*() should be made
// per UnpackedInstaller.
// TODO(erikkay): It might be useful to be able to load a packed extension
// (presumably into memory) without installing it.
class UnpackedInstaller : public base::RefCountedThreadSafe<
                              UnpackedInstaller,
                              content::BrowserThread::DeleteOnUIThread>,
                          public ProfileObserver {
 public:
  // Manifest settings override types.
  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  //
  // LINT.IfChange(ManifestSettingsOverrideType)
  enum ManifestSettingsOverrideType {
    // No overrides.
    kNoOverride = 0,
    // Overrides the default search engine.
    kSearchEngine = 1,
    // Overrides the new tab page.
    kNewTabPage = 2,
    // Overrides the default search engine and new tab page.
    kSearchEngineAndNewTabPage = 3,

    kMaxValue = kSearchEngineAndNewTabPage,
  };
  // LINT.ThenChange(/tools/metrics/histograms/metadata/extensions/enums.xml:ManifestSettingsOverrideType)

  using CompletionCallback = base::OnceCallback<void(const Extension* extension,
                                                     const base::FilePath&,
                                                     const std::string&)>;

  UnpackedInstaller(const UnpackedInstaller&) = delete;
  UnpackedInstaller& operator=(const UnpackedInstaller&) = delete;

  static scoped_refptr<UnpackedInstaller> Create(
      content::BrowserContext* context);

  // Loads the extension from the directory `extension_path`, which is
  // the top directory of a specific extension where its manifest file lives.
  // Errors are reported through LoadErrorReporter. On success,
  // ExtensionService::AddExtension() is called.
  void Load(const base::FilePath& extension_path);

  // Loads the extension from the directory `extension_path`;
  // for use with command line switch --load-extension=path or
  // --load-and-launch-app=path.
  // This is equivalent to Load, except that it reads the extension from
  // `extension_path` synchronously.
  // The return value indicates whether the installation has begun successfully.
  // The id of the extension being loaded is returned in `extension_id`.
  // `only_allow_apps` is used to avoid side-loading of non-app extensions.
  bool LoadFromCommandLine(const base::FilePath& extension_path,
                           std::string* extension_id,
                           bool only_allow_apps);

  // Allows overriding of whether modern manifest versions are required;
  // intended for testing.
  bool require_modern_manifest_version() const {
    return require_modern_manifest_version_;
  }
  void set_require_modern_manifest_version(bool val) {
    require_modern_manifest_version_ = val;
  }

  void set_be_noisy_on_failure(bool be_noisy_on_failure) {
    be_noisy_on_failure_ = be_noisy_on_failure;
  }

  void set_completion_callback(CompletionCallback callback) {
    callback_ = std::move(callback);
  }

  void set_allow_file_access(bool allow) { allow_file_access_ = allow; }

  void set_allow_incognito_access(bool allow) {
    allow_incognito_access_ = allow;
  }

  void set_install_param(const std::string& param) { install_param_ = param; }

 private:
  friend struct content::BrowserThread::DeleteOnThread<
      content::BrowserThread::UI>;
  friend class base::DeleteHelper<UnpackedInstaller>;

  explicit UnpackedInstaller(content::BrowserContext* context);
  ~UnpackedInstaller() override;

  // Must be called from the UI thread. Begin management policy and requirements
  // checks.
  void StartInstallChecks();

  // Callback from PreloadCheckGroup.
  void OnInstallChecksComplete(const PreloadCheck::Errors& errors);

  // Verifies if loading unpacked extensions is allowed.
  bool IsLoadingUnpackedAllowed() const;

  // We change the input extension path to an absolute path, on the file thread.
  // Then we need to check the file access preference, which needs
  // to happen back on the UI thread, so it posts CheckExtensionFileAccess on
  // the UI thread. In turn, once that gets the pref, it goes back to the
  // file thread with LoadWithFileAccess.
  // TODO(yoz): It would be nice to remove this ping-pong, but we need to know
  // what file access flags to pass to file_util::LoadExtension.
  void GetAbsolutePathOnFileThread();
  void CheckExtensionFileAccess();
  void LoadWithFileAccessOnFileThread(int flags);

  // Notify the frontend that an attempt to retry will not be necessary.
  void UnregisterLoadRetryListener();

  // Notify the frontend that there was an error loading an extension.
  void ReportExtensionLoadError(const std::string& error);

  // Passes the extension onto extension service.
  void InstallExtension();

  // Helper to get the Extension::CreateFlags for the installing extension.
  int GetFlags();

  // Helper to load an extension. Should be called on a sequence where file IO
  // is allowed. Loads the extension, validates extension locales and persists
  // the ruleset for the Declarative Net Request API, if needed. In case of an
  // error, returns false and populates `error`.
  bool LoadExtension(mojom::ManifestLocation location,
                     int flags,
                     std::string* error);

  // Reads the Declarative Net Request JSON rulesets for the extension, if it
  // provided any, and persists the indexed rulesets. Returns false and
  // populates `error` in case of an error. Should be called on a sequence where
  // file IO is allowed.
  bool IndexAndPersistRulesIfNeeded(std::string* error);

  // Records command-line extension metrics, emitted when a command line
  // extension is installed.
  void RecordCommandLineMetrics();

  // ProfileObserver
  void OnProfileWillBeDestroyed(Profile* profile) override;

  // Called when the browser is terminating.
  void OnBrowserTerminating();

  const Extension* extension() { return extension_.get(); }

  // The service we will report results back to.
  raw_ptr<ExtensionService> service_ = nullptr;

  // The Profile the extension is being installed in.
  raw_ptr<Profile, DanglingUntriaged> profile_;

  // Observes profile destruction.
  base::ScopedObservation<Profile, ProfileObserver> profile_observation_{this};

  // The pathname of the directory to load from, which is an absolute path
  // after GetAbsolutePath has been called.
  base::FilePath extension_path_;

  // The extension being installed.
  scoped_refptr<Extension> extension_;

  // Whether to require the extension installed to have a modern manifest
  // version.
  bool require_modern_manifest_version_;

  // Whether or not to be noisy (show a dialog) on failure. Defaults to true.
  bool be_noisy_on_failure_;

  // Checks to run before the extension can be installed.
  std::unique_ptr<PreloadCheck> policy_check_;
  std::unique_ptr<PreloadCheck> requirements_check_;

  // Runs the above checks.
  std::unique_ptr<PreloadCheckGroup> check_group_;

  // Install prefs needed for the Declarative Net Request API.
  base::Value::Dict ruleset_install_prefs_;

  CompletionCallback callback_;

  // Override default file access.
  std::optional<bool> allow_file_access_;

  // Override default incognito access.
  std::optional<bool> allow_incognito_access_;

  // Specify an install param.
  std::optional<std::string> install_param_;

  // True if the browser is terminating.
  bool browser_terminating_ = false;

  // Subscription to browser termination.
  base::CallbackListSubscription on_browser_terminating_subscription_;
};

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_UNPACKED_INSTALLER_H_