File: user_script_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 (154 lines) | stat: -rw-r--r-- 6,585 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
// Copyright 2021 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_USER_SCRIPT_MANAGER_H_
#define EXTENSIONS_BROWSER_USER_SCRIPT_MANAGER_H_

#include <map>
#include <memory>
#include <optional>
#include <set>

#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/values.h"
#include "extensions/browser/embedder_user_script_loader.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/browser/extension_user_script_loader.h"
#include "extensions/browser/pref_types.h"
#include "extensions/common/extension.h"
#include "extensions/common/mojom/host_id.mojom.h"
#include "extensions/common/user_script.h"

namespace content {
class BrowserContext;
}

namespace extensions {
class UserScriptLoader;

// Manages user scripts for all extensions and webview scripts from embedder
// pages. Owns one UserScriptLoader for manifest extension scripts, and a map
// of mojom::HostID to UserScriptLoaders for declarative extension and embedder
// scripts. File loading and shared memory management operations are delegated
// to these UserScriptLoaders.
class UserScriptManager : public ExtensionRegistryObserver {
 public:
  explicit UserScriptManager(content::BrowserContext* browser_context);
  ~UserScriptManager() override;
  UserScriptManager(const UserScriptManager& other) = delete;
  UserScriptManager& operator=(const UserScriptManager& other) = delete;

  // Key corresponding to whether the user has allowed user scripts to run for
  // the extension.
  static constexpr PrefMap kUserScriptsAllowedPref = {
      "user_scripts_enabled", PrefType::kBool, PrefScope::kExtensionSpecific};
  // Key corresponding to whether the migration from using the dev mode toggle
  // to the per-extension toggle for enabling dynamic user scripts usage has
  // completed.
  static constexpr PrefMap kUserScriptsToggleMigratedPref = {
      "migrated_user_scripts_toggle", PrefType::kBool, PrefScope::kProfile};

  UserScriptLoader* GetUserScriptLoaderByID(const mojom::HostID& host_id);

  ExtensionUserScriptLoader* GetUserScriptLoaderForExtension(
      const ExtensionId& extension_id);

  EmbedderUserScriptLoader* GetUserScriptLoaderForEmbedder(
      const mojom::HostID& host_id);

  // Sets whether scripts of the given `source` should be enabled for
  // (all) extensions. Does not affect embedder script loaders.
  void SetUserScriptSourceEnabledForExtensions(UserScript::Source source,
                                               bool enabled);

  // Returns true if the extension is allowed to use the userScripts API.
  // Note: this may also seed feature availability state the first time it is
  // called so that it is always accurate.
  bool AreUserScriptsAllowed(const Extension& extension);

  // Returns whether the extension has permission to run user scripts or can
  // request permission to do so.
  static bool IsUserScriptsAPIPermissionAvailable(const Extension& extension);

  bool IsUserScriptPrefEnabledForTesting(
      const ExtensionId& extension_id) const {
    return IsUserScriptPrefEnabled(extension_id);
  }

  // Set extension preference for userScripts API being allowed.
  void SetUserScriptPrefEnabled(const ExtensionId& extension_id, bool enabled);

 private:
  // ExtensionRegistryObserver implementation.
  void OnExtensionWillBeInstalled(content::BrowserContext* browser_context,
                                  const Extension* extension,
                                  bool is_update,
                                  const std::string& old_name) override;
  void OnExtensionLoaded(content::BrowserContext* browser_context,
                         const Extension* extension) override;
  void OnExtensionUnloaded(content::BrowserContext* browser_context,
                           const Extension* extension,
                           UnloadedExtensionReason reason) override;

  // Called when `loader` has finished loading its initial set of scripts. This
  // is only fired for extension script loaders.
  void OnInitialExtensionLoadComplete(UserScriptLoader* loader,
                                      const std::optional<std::string>& error);

  // Removes the given ID from `pending_initial_extension_loads_` and if there
  // are no more pending initial loads, signal to the UserScriptListener.
  void RemovePendingExtensionLoadAndSignal(const ExtensionId& extension_id);

  // Creates a ExtensionUserScriptLoader object.
  ExtensionUserScriptLoader* CreateExtensionUserScriptLoader(
      const Extension* extension);

  // Creates a EmbedderUserScriptLoader object.
  EmbedderUserScriptLoader* CreateEmbedderUserScriptLoader(
      const mojom::HostID& host_id);

  // Migrate an extension from dev mode toggle to per-extension toggle if not
  // done, otherwise just set the allowed state from the current allowed
  // preference.
  void InitializeUserScriptState(const Extension& extension);

  // Get extension preference for userScripts API being allowed.
  bool IsUserScriptPrefEnabled(const ExtensionId& extension_id) const;

  // Migrates an eligible extension to use the per-extension toggle.
  void MigrateUserScriptExtension(const Extension& extension);

  // Migrates all non-enabled extensions to use the per-extension toggle.
  void MigrateUserScriptExtensions();

  // A map of ExtensionUserScriptLoader for each extension host, with one loader
  // per extension. Currently, each loader is lazily initialized and contains
  // scripts from APIs webview tags.
  std::map<ExtensionId, std::unique_ptr<ExtensionUserScriptLoader>>
      extension_script_loaders_;

  // A map of EmbedderUserScriptLoader for each embedder host, each loader
  // contains webview content scripts for the corresponding embedder page and is
  // lazily initialized.
  std::map<mojom::HostID, std::unique_ptr<EmbedderUserScriptLoader>>
      embedder_script_loaders_;

  // Tracks the IDs of extensions with initial script loads (consisting of
  // manifest and persistent dynamic scripts) in progress.
  std::set<ExtensionId> pending_initial_extension_loads_;

  const raw_ptr<content::BrowserContext> browser_context_;

  base::ScopedObservation<ExtensionRegistry, ExtensionRegistryObserver>
      extension_registry_observation_{this};

  base::WeakPtrFactory<UserScriptManager> weak_factory_{this};
};

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_USER_SCRIPT_MANAGER_H_